initial commit version 0.0.1

This commit is contained in:
louis
2014-09-27 09:25:14 +02:00
commit b0509b5182
503 changed files with 24368 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
#define __STL_CONFIG_H
#include <vdr/menu.h>
#include "displayaudiotracksview.h"
cDisplayAudiotracksView::cDisplayAudiotracksView(int numTracks, cTemplateView *tmplView) : cView(tmplView) {
DeleteOsdOnExit();
SetFadeTime(tmplView->GetNumericParameter(ptFadeTime));
this->numTracks = numTracks;
cTemplateViewList *tmplMenuItems = tmplView->GetViewList(vlMenuItem);
listView = NULL;
if (tmplMenuItems) {
listView = new cDisplayMenuListView(tmplMenuItems, numTracks);
}
}
cDisplayAudiotracksView::~cDisplayAudiotracksView() {
if (listView)
delete listView;
CancelSave();
FadeOut();
}
bool cDisplayAudiotracksView::createOsd(void) {
cRect osdSize = tmplView->GetOsdSize();
bool ok = CreateOsd(cOsd::OsdLeft() + osdSize.X(),
cOsd::OsdTop() + osdSize.Y(),
osdSize.Width(),
osdSize.Height());
return ok;
}
void cDisplayAudiotracksView::DrawBackground(void) {
if (!ViewElementImplemented(veBackground)) {
return;
}
map < string, string > stringTokens;
map < string, int > intTokens;
intTokens.insert(pair<string,int>("numtracks", numTracks));
DrawViewElement(veBackground, &stringTokens, &intTokens);
}
void cDisplayAudiotracksView::DrawHeader(const char *title, int audioChannel) {
if (!ViewElementImplemented(veHeader)) {
return;
}
map < string, string > stringTokens;
map < string, int > intTokens;
intTokens.insert(pair<string,int>("numtracks", numTracks));
if (audioChannel < 0) {
intTokens.insert(pair<string,int>("isac3", true));
intTokens.insert(pair<string,int>("isstereo", false));
} else {
intTokens.insert(pair<string,int>("isac3", false));
intTokens.insert(pair<string,int>("isstereo", true));
}
stringTokens.insert(pair<string,string>("title", title));
ClearViewElement(veHeader);
DrawViewElement(veHeader, &stringTokens, &intTokens);
}
void cDisplayAudiotracksView::RenderMenuItems(void) {
if (listView)
listView->Render();
}
void cDisplayAudiotracksView::Action(void) {
SetInitFinished();
FadeIn();
DoFlush();
cView::Action();
}

View File

@@ -0,0 +1,24 @@
#ifndef __DISPLAYAUDIOTRACKSVIEW_H
#define __DISPLAYAUDIOTRACKSVIEW_H
#include "../libtemplate/template.h"
#include "displaymenulistview.h"
class cDisplayAudiotracksView : public cView {
protected:
int numTracks;
cDisplayMenuListView *listView;
virtual void Action(void);
public:
cDisplayAudiotracksView(int numTracks, cTemplateView *tmplView);
virtual ~cDisplayAudiotracksView();
bool createOsd(void);
void DrawBackground(void);
void DrawHeader(const char *title, int audioChannel);
cDisplayMenuListView *GetListView(void) { return listView; };
void DoFadeIn(void) { Start(); };
void Flush(void) { DoFlush(); };
void RenderMenuItems(void);
};
#endif //__DISPLAYAUDIOTRACKSVIEW_H

452
views/displaychannelview.c Normal file
View File

@@ -0,0 +1,452 @@
#define __STL_CONFIG_H
#include <vdr/menu.h>
#include "../services/scraper2vdr.h"
#include "displaychannelview.h"
#include "../libcore/timers.h"
#include "../libcore/helpers.h"
cDisplayChannelView::cDisplayChannelView(cTemplateView *tmplView) : cView(tmplView) {
lastDate = "";
lastScreenWidth = 0;
lastScreenHeight = 0;
lastSignalDisplay = 0;
lastSignalStrength = 0;
lastSignalQuality = 0;
DeleteOsdOnExit();
SetFadeTime(tmplView->GetNumericParameter(ptFadeTime));
}
cDisplayChannelView::~cDisplayChannelView() {
CancelSave();
FadeOut();
}
bool cDisplayChannelView::createOsd(void) {
cRect osdSize = tmplView->GetOsdSize();
bool ok = CreateOsd(cOsd::OsdLeft() + osdSize.X(),
cOsd::OsdTop() + osdSize.Y(),
osdSize.Width(),
osdSize.Height());
return ok;
}
void cDisplayChannelView::DrawBackground(void) {
map < string, string > stringTokens;
map < string, int > intTokens;
DrawViewElement(veBackground, &stringTokens, &intTokens);
}
void cDisplayChannelView::DrawChannel(cString &number, cString &name, cString &id, bool switching) {
map < string, string > stringTokens;
map < string, int > intTokens;
stringTokens.insert(pair<string,string>("channelname", *name));
stringTokens.insert(pair<string,string>("channelnumber", *number));
stringTokens.insert(pair<string,string>("channelid", *id));
intTokens.insert(pair<string, int>("switching", switching));
bool logoExisis = imgCache->LogoExists(*id);
intTokens.insert(pair<string, int>("channellogoexists", logoExisis));
DrawViewElement(veChannelInfo, &stringTokens, &intTokens);
}
void cDisplayChannelView::ClearChannel(void) {
ClearViewElement(veChannelInfo);
}
void cDisplayChannelView::DrawDate(void) {
if (!ViewElementImplemented(veDateTime)) {
return;
}
cString curDate = DayDateTime();
if (strcmp(curDate, lastDate)) {
map < string, string > stringTokens;
map < string, int > intTokens;
time_t t = time(0); // get time now
struct tm * now = localtime(&t);
intTokens.insert(pair<string, int>("year", now->tm_year + 1900));
intTokens.insert(pair<string, int>("day", now->tm_mday));
char monthname[20];
char monthshort[10];
strftime(monthshort, sizeof(monthshort), "%b", now);
strftime(monthname, sizeof(monthname), "%B", now);
stringTokens.insert(pair<string,string>("monthname", monthname));
stringTokens.insert(pair<string,string>("monthnameshort", monthshort));
stringTokens.insert(pair<string,string>("month", *cString::sprintf("%02d", now->tm_mon + 1)));
stringTokens.insert(pair<string,string>("dayleadingzero", *cString::sprintf("%02d", now->tm_mday)));
stringTokens.insert(pair<string,string>("dayname", *WeekDayNameFull(now->tm_wday)));
stringTokens.insert(pair<string,string>("daynameshort", *WeekDayName(now->tm_wday)));
stringTokens.insert(pair<string,string>("time", *TimeString(t)));
ClearViewElement(veDateTime);
DrawViewElement(veDateTime, &stringTokens, &intTokens);
lastDate = curDate;
}
}
void cDisplayChannelView::DrawProgressBar(cString &start, cString &stop, int Current, int Total) {
if (!ViewElementImplemented(veProgressBar)) {
return;
}
map < string, string > stringTokens;
map < string, int > intTokens;
stringTokens.insert(pair<string, string>("start", *start));
stringTokens.insert(pair<string, string>("stop", *stop));
intTokens.insert(pair<string, int>("duration", Total));
intTokens.insert(pair<string, int>("elapsed", Current));
intTokens.insert(pair<string, int>("remaining", Total - Current));
DrawViewElement(veProgressBar, &stringTokens, &intTokens);
}
void cDisplayChannelView::ClearProgressBar(void) {
ClearViewElement(veProgressBar);
}
void cDisplayChannelView::DrawProgressBarBack(void) {
DrawViewElement(veProgressBarBack);
}
void cDisplayChannelView::ClearProgressBarBack(void) {
ClearViewElement(veProgressBarBack);
}
void cDisplayChannelView::DrawEPGInfo(const cEvent *present, const cEvent *next, bool presentRecording, bool nextRecording) {
map < string, string > stringTokens;
map < string, int > intTokens;
if (present) {
stringTokens.insert(pair<string,string>("currenttitle", (present->Title())?present->Title():""));
stringTokens.insert(pair<string,string>("currentsubtitle", (present->ShortText())?present->ShortText():""));
stringTokens.insert(pair<string,string>("currentstart", *present->GetTimeString()));
stringTokens.insert(pair<string,string>("currentstop", *present->GetEndTimeString()));
intTokens.insert(pair<string,int>("currentduration", present->Duration() / 60));
intTokens.insert(pair<string,int>("currentelapsed", (int)round((time(NULL) - present->StartTime())/60)));
intTokens.insert(pair<string,int>("currentremaining", (int)round((present->EndTime() - time(NULL))/60)));
intTokens.insert(pair<string,int>("currentrecording", presentRecording ? 1 : 0));
} else {
stringTokens.insert(pair<string,string>("currenttitle", ""));
stringTokens.insert(pair<string,string>("currentsubtitle", ""));
stringTokens.insert(pair<string,string>("currentstart", ""));
stringTokens.insert(pair<string,string>("currentstop", ""));
intTokens.insert(pair<string,int>("currentduration", 0));
intTokens.insert(pair<string,int>("currentelapsed", 0));
intTokens.insert(pair<string,int>("currentremaining", 0));
intTokens.insert(pair<string,int>("currentrecording", 0));
}
if (next) {
stringTokens.insert(pair<string,string>("nexttitle", (next->Title())?next->Title():""));
stringTokens.insert(pair<string,string>("nextsubtitle", (next->ShortText())?next->ShortText():""));
stringTokens.insert(pair<string,string>("nextstart", *next->GetTimeString()));
stringTokens.insert(pair<string,string>("nextstop", *next->GetEndTimeString()));
intTokens.insert(pair<string,int>("nextduration", next->Duration() / 60));
intTokens.insert(pair<string,int>("nextrecording", nextRecording ? 1 : 0));
} else {
stringTokens.insert(pair<string,string>("nexttitle", ""));
stringTokens.insert(pair<string,string>("nextsubtitle", ""));
stringTokens.insert(pair<string,string>("nextstart", ""));
stringTokens.insert(pair<string,string>("nextstop", ""));
intTokens.insert(pair<string,int>("nextduration", 0));
intTokens.insert(pair<string,int>("nextrecording", 0));
}
DrawViewElement(veEpgInfo, &stringTokens, &intTokens);
}
void cDisplayChannelView::ClearEPGInfo(void) {
ClearViewElement(veEpgInfo);
}
void cDisplayChannelView::DrawStatusIcons(const cChannel *Channel) {
if (!ViewElementImplemented(veStatusInfo)) {
return;
}
bool isRadio = !Channel->Vpid() && Channel->Apid(0);
bool hasVT = Channel->Vpid() && Channel->Tpid();
bool isStereo = Channel->Apid(0);
bool isDolby = Channel->Dpid(0);
bool isEncrypted = Channel->Ca();
bool isRecording = cRecordControls::Active();
cGlobalSortedTimers SortedTimers;// local and remote timers
for (int i = 0; i < SortedTimers.Size() && !isRecording; i++)
if (const cTimer *Timer = SortedTimers[i])
if (Timer->Recording())
isRecording = true;
map < string, int > intTokens;
intTokens.insert(pair<string,int>("isRadio", isRadio));
intTokens.insert(pair<string,int>("hasVT", hasVT));
intTokens.insert(pair<string,int>("isStereo", isStereo));
intTokens.insert(pair<string,int>("isDolby", isDolby));
intTokens.insert(pair<string,int>("isEncrypted", isEncrypted));
intTokens.insert(pair<string,int>("isRecording", isRecording));
DrawViewElement(veStatusInfo, NULL, &intTokens);
}
void cDisplayChannelView::ClearStatusIcons(void) {
ClearViewElement(veStatusInfo);
}
void cDisplayChannelView::DrawScreenResolution(void) {
if (!ViewElementImplemented(veScreenResolution)) {
return;
}
int screenWidth = 0;
int screenHeight = 0;
double aspect = 0;
cDevice::PrimaryDevice()->GetVideoSize(screenWidth, screenHeight, aspect);
if ((lastScreenWidth == screenWidth) && (lastScreenHeight == screenHeight))
return;
if ((screenWidth == 0) && (screenHeight == 0))
return;
lastScreenWidth = screenWidth;
lastScreenHeight = screenHeight;
bool isHD = false;
string resName = GetScreenResolutionString(screenWidth, screenHeight, &isHD);
bool isWideScreen = false;
string aspectName = GetScreenAspectString(aspect, &isWideScreen);
map < string, string > stringTokens;
map < string, int > intTokens;
intTokens.insert(pair<string,int>("screenwidth", screenWidth));
intTokens.insert(pair<string,int>("screenheight", screenHeight));
intTokens.insert(pair<string,int>("isHD", isHD));
intTokens.insert(pair<string,int>("isWideScreen", isWideScreen));
stringTokens.insert(pair<string,string>("resolution", resName));
stringTokens.insert(pair<string,string>("aspect", aspectName));
ClearViewElement(veScreenResolution);
DrawViewElement(veScreenResolution, &stringTokens, &intTokens);
}
void cDisplayChannelView::ClearScreenResolution(void) {
ClearViewElement(veScreenResolution);
lastScreenWidth = 0;
lastScreenHeight = 0;
}
string cDisplayChannelView::GetScreenResolutionString(int width, int height, bool *isHD) {
string name = "";
switch (width) {
case 1920:
case 1440:
name = "hd1080i";
*isHD = true;
break;
case 1280:
if (height == 720)
name = "hd720p";
else
name = "hd1080i";
*isHD = true;
break;
case 720:
name = "sd576i";
break;
default:
name = "sd576i";
break;
}
return name;
}
string cDisplayChannelView::GetScreenAspectString(double aspect, bool *isWideScreen) {
string name = "";
*isWideScreen = false;
if (aspect == 4.0/3.0) {
name = "4:3";
*isWideScreen = false;
} else if (aspect == 16.0/9.0) {
name = "16:9";
*isWideScreen = true;
} else if (aspect == 2.21) {
name = "21:9";
*isWideScreen = true;
}
return name;
}
void cDisplayChannelView::DrawScraperContent(const cEvent *event) {
if (!event)
return;
if (!ViewElementImplemented(veScraperContent)) {
return;
}
static cPlugin *pScraper = GetScraperPlugin();
if (!pScraper) {
return;
}
ScraperGetPosterBanner call;
call.event = event;
if (pScraper->Service("GetPosterBanner", &call)) {
int mediaWidth = 0;
int mediaHeight = 0;
std::string mediaPath = "";
bool isBanner = false;
if ((call.type == tSeries) && call.banner.path.size() > 0) {
mediaWidth = call.banner.width;
mediaHeight = call.banner.height;
mediaPath = call.banner.path;
isBanner = true;
} else if (call.type == tMovie && call.poster.path.size() > 0 && call.poster.height > 0) {
mediaWidth = call.poster.width;
mediaHeight = call.poster.height;
mediaPath = call.poster.path;
} else
return;
map < string, int > intTokens;
map < string, string > stringTokens;
intTokens.insert(pair<string,int>("mediawidth", mediaWidth));
intTokens.insert(pair<string,int>("mediaheight", mediaHeight));
intTokens.insert(pair<string,int>("isbanner", isBanner));
stringTokens.insert(pair<string,string>("mediapath", mediaPath));
ClearViewElement(veScraperContent);
DrawViewElement(veScraperContent, &stringTokens, &intTokens);
}
}
void cDisplayChannelView::ClearScraperContent(void) {
ClearViewElement(veScraperContent);
}
void cDisplayChannelView::DrawSignal(void) {
if (!ViewElementImplemented(veSignalQuality)) {
return;
}
time_t Now = time(NULL);
if (Now != lastSignalDisplay) {
int SignalStrength = cDevice::ActualDevice()->SignalStrength();
int SignalQuality = cDevice::ActualDevice()->SignalQuality();
if (SignalStrength < 0) SignalStrength = 0;
if (SignalQuality < 0) SignalQuality = 0;
if ((SignalStrength == 0)&&(SignalQuality==0))
return;
if ((lastSignalStrength != SignalStrength) || (lastSignalQuality != SignalQuality)) {
map < string, int > intTokens;
map < string, string > stringTokens;
intTokens.insert(pair<string,int>("signalstrength", SignalStrength));
intTokens.insert(pair<string,int>("signalquality", SignalQuality));
ClearViewElement(veSignalQuality);
DrawViewElement(veSignalQuality, &stringTokens, &intTokens);
}
lastSignalStrength = SignalStrength;
lastSignalQuality = SignalQuality;
lastSignalDisplay = Now;
}
}
void cDisplayChannelView::DrawSignalBackground(void) {
if (!ViewElementImplemented(veSignalQualityBack)) {
return;
}
DrawViewElement(veSignalQualityBack);
}
void cDisplayChannelView::ClearSignal(void) {
ClearViewElement(veSignalQuality);
}
void cDisplayChannelView::ClearSignalBackground(void) {
ClearViewElement(veSignalQualityBack);
}
void cDisplayChannelView::DrawChannelGroups(const cChannel *Channel, cString ChannelName) {
if (!ViewElementImplemented(veChannelGroup)) {
return;
}
bool separatorExists = imgCache->SeparatorLogoExists(*ChannelName);
string separatorPath = separatorExists ? *ChannelName : "";
std::string prevChannelSep = GetChannelSep(Channel, true);
std::string nextChannelSep = GetChannelSep(Channel, false);
bool prevAvailable = (prevChannelSep.size() > 0)?true:false;
bool nextAvailable = (nextChannelSep.size() > 0)?true:false;
map < string, string > stringTokens;
map < string, int > intTokens;
intTokens.insert(pair<string,int>("sepexists", separatorExists));
intTokens.insert(pair<string,int>("prevAvailable", prevAvailable));
intTokens.insert(pair<string,int>("nextAvailable", nextAvailable));
stringTokens.insert(pair<string,string>("group", *ChannelName));
stringTokens.insert(pair<string,string>("nextgroup", nextChannelSep));
stringTokens.insert(pair<string,string>("prevgroup", prevChannelSep));
stringTokens.insert(pair<string,string>("seppath", separatorPath));
ClearViewElement(veChannelGroup);
DrawViewElement(veChannelGroup, &stringTokens, &intTokens);
}
void cDisplayChannelView::ClearChannelGroups(void) {
ClearViewElement(veChannelGroup);
}
string cDisplayChannelView::GetChannelSep(const cChannel *channel, bool prev) {
std::string sepName = "";
const cChannel *sep = prev ? Channels.Prev(channel) :
Channels.Next(channel);
for (; sep; (prev)?(sep = Channels.Prev(sep)):(sep = Channels.Next(sep))) {
if (sep->GroupSep()) {
sepName = sep->Name();
break;
}
}
return sepName;
}
void cDisplayChannelView::DisplayMessage(eMessageType Type, const char *Text) {
if (!Text) {
ClearViewElement(veMessage);
}
map < string, string > stringTokens;
map < string, int > intTokens;
stringTokens.insert(pair<string,string>("text", Text));
intTokens.insert(pair<string,int>("status", (Type == mtStatus) ? true : false));
intTokens.insert(pair<string,int>("info", (Type == mtInfo) ? true : false));
intTokens.insert(pair<string,int>("warning", (Type == mtWarning) ? true : false));
intTokens.insert(pair<string,int>("error", (Type == mtError) ? true : false));
ClearViewElement(veMessage);
DrawViewElement(veMessage, &stringTokens, &intTokens);
}
void cDisplayChannelView::Action(void) {
SetInitFinished();
FadeIn();
DoFlush();
cView::Action();
}

View File

@@ -0,0 +1,49 @@
#ifndef __DISPLAYCHANNELVIEW_H
#define __DISPLAYCHANNELVIEW_H
#include "../libtemplate/template.h"
#include "view.h"
class cDisplayChannelView : public cView {
private:
cString lastDate;
int lastScreenWidth;
int lastScreenHeight;
int lastSignalDisplay;
int lastSignalStrength;
int lastSignalQuality;
string GetScreenResolutionString(int width, int height, bool *isHD);
string GetScreenAspectString(double aspect, bool *isWideScreen);
string GetChannelSep(const cChannel *channel, bool prev);
virtual void Action(void);
public:
cDisplayChannelView(cTemplateView *tmplView);
virtual ~cDisplayChannelView();
bool createOsd(void);
void DrawBackground(void);
void DrawChannel(cString &number, cString &name, cString &id, bool switching);
void ClearChannel(void);
void DrawDate(void);
void DrawProgressBar(cString &start, cString &stop, int Current, int Total);
void ClearProgressBar(void);
void DrawProgressBarBack(void);
void ClearProgressBarBack(void);
void DrawEPGInfo(const cEvent *present, const cEvent *next, bool presentRecording, bool nextRecording);
void ClearEPGInfo(void);
void DrawStatusIcons(const cChannel *Channel);
void ClearStatusIcons(void);
void DrawScreenResolution(void);
void ClearScreenResolution(void);
void DrawScraperContent(const cEvent *event);
void ClearScraperContent(void);
void DrawSignal(void);
void DrawSignalBackground(void);
void ClearSignal(void);
void ClearSignalBackground(void);
void DrawChannelGroups(const cChannel *Channel, cString ChannelName);
void ClearChannelGroups(void);
void DisplayMessage(eMessageType Type, const char *Text);
void DoStart(void) { Start(); };
void Flush(void) { DoFlush(); };
};
#endif //__DISPLAYCHANNELVIEW_H

View File

@@ -0,0 +1,929 @@
#include "displaymenudetailview.h"
#include "../libcore/helpers.h"
#include "../services/scraper2vdr.h"
#include "../services/epgsearch.h"
cDisplayMenuDetailView::cDisplayMenuDetailView(cTemplateView *tmplDetailView) : cView(tmplDetailView) {
event = NULL;
recording = NULL;
text = NULL;
detailViewInit = true;
currentTmplTab = NULL;
tabView = NULL;
}
cDisplayMenuDetailView::~cDisplayMenuDetailView() {
CancelSave();
if (tabView)
delete tabView;
}
void cDisplayMenuDetailView::Clear(void) {
ClearViewElement(veDetailHeader);
ClearViewElement(veScrollbar);
ClearViewElement(veTabLabels);
}
void cDisplayMenuDetailView::Render(void) {
if (detailViewInit) {
DrawHeader();
DoFlush();
SetTokens();
InitTabs();
currentTmplTab = *atIt;
detailViewInit = false;
}
if (!tabView) {
tabView = new cDisplayMenuTabView(currentTmplTab);
tabView->SetTokens(&intTokens, &stringTokens, &loopTokens);
tabView->CreateTab();
tabView->Start();
}
DrawScrollbar();
DrawTabLabels();
}
void cDisplayMenuDetailView::KeyLeft(void) {
if (activeTabs.size() > 1) {
currentTmplTab = GetPrevTab();
delete tabView;
tabView = NULL;
Render();
DoFlush();
} else {
bool scrolled = tabView->KeyLeft();
if (scrolled) {
DrawScrollbar();
DoFlush();
}
}
}
void cDisplayMenuDetailView::KeyRight(void) {
if (activeTabs.size() > 1) {
currentTmplTab = GetNextTab();
delete tabView;
tabView = NULL;
Render();
DoFlush();
} else {
bool scrolled = tabView->KeyRight();
if (scrolled) {
DrawScrollbar();
DoFlush();
}
}
}
void cDisplayMenuDetailView::KeyUp(void) {
if (!tabView)
return;
bool scrolled = tabView->KeyUp();
if (scrolled) {
DrawScrollbar();
DoFlush();
}
}
void cDisplayMenuDetailView::KeyDown(void) {
if (!tabView)
return;
bool scrolled = tabView->KeyDown();
if (scrolled) {
DrawScrollbar();
DoFlush();
}
}
void cDisplayMenuDetailView::SetTokens(void) {
if (event) {
stringTokens.insert(pair<string,string>("title", event->Title() ? event->Title() : ""));
stringTokens.insert(pair<string,string>("shorttext", event->ShortText() ? event->ShortText() : ""));
stringTokens.insert(pair<string,string>("description", event->Description() ? event->Description() : ""));
stringTokens.insert(pair<string,string>("start", *(event->GetTimeString())));
stringTokens.insert(pair<string,string>("stop", *(event->GetEndTimeString())));
stringTokens.insert(pair<string,string>("day", *WeekDayName(event->StartTime())));
stringTokens.insert(pair<string,string>("date", *ShortDateString(event->StartTime())));
stringTokens.insert(pair<string,string>("channelid", *(event->ChannelID().ToString())));
bool isRunning = false;
time_t now = time(NULL);
if ((now >= event->StartTime()) && (now <= event->EndTime()))
isRunning = true;
intTokens.insert(pair<string,int>("running", isRunning));
if (isRunning) {
intTokens.insert(pair<string,int>("elapsed", (now - event->StartTime())/60));
} else {
intTokens.insert(pair<string,int>("elapsed", 0));
}
intTokens.insert(pair<string,int>("duration", event->Duration() / 60));
vector< map< string, string > > reruns;
bool hasReruns = LoadReruns(&reruns);
loopTokens.insert(pair<string, vector< map< string, string > > >("reruns", reruns));
intTokens.insert(pair<string,int>("hasreruns", hasReruns));
SetScraperTokens();
SetEpgPictures(event->EventID());
} else if (recording) {
string name = recording->Name() ? recording->Name() : "";
stringTokens.insert(pair<string,string>("name", name));
const cRecordingInfo *info = recording->Info();
if (info) {
stringTokens.insert(pair<string,string>("shorttext", info->ShortText() ? info->ShortText() : ""));
stringTokens.insert(pair<string,string>("description", info->Description() ? info->Description() : ""));
const cEvent *event = info->GetEvent();
if (event) {
string recDate = *(event->GetDateString());
string recTime = *(event->GetTimeString());
if (recDate.find("1970") != string::npos) {
time_t start = recording->Start();
recDate = *DateString(start);
recTime = *TimeString(start);
}
int duration = event->Duration() / 60;
int recDuration = recording->LengthInSeconds();
recDuration = (recDuration>0)?(recDuration / 60):0;
stringTokens.insert(pair<string,string>("date", recDate.c_str()));
stringTokens.insert(pair<string,string>("time", recTime.c_str()));
intTokens.insert(pair<string,int>("duration", recDuration));
intTokens.insert(pair<string,int>("durationevent", duration));
}
} else {
stringTokens.insert(pair<string,string>("shorttext", ""));
stringTokens.insert(pair<string,string>("description", ""));
int recDuration = recording->LengthInSeconds();
recDuration = (recDuration>0)?(recDuration / 60):0;
stringTokens.insert(pair<string,string>("date", ""));
stringTokens.insert(pair<string,string>("time", ""));
intTokens.insert(pair<string,int>("duration", recDuration));
intTokens.insert(pair<string,int>("durationevent", 0));
}
LoadRecordingInformation();
SetScraperTokens();
SetRecordingImages(recording->FileName());
} else if (text) {
stringTokens.insert(pair<string,string>("text", text));
} else {
intTokens.insert(pair<string,int>("running", false));
intTokens.insert(pair<string,int>("hasreruns", false));
}
}
void cDisplayMenuDetailView::SetScraperTokens(void) {
static cPlugin *pScraper = GetScraperPlugin();
if (!pScraper || (!event && !recording)) {
intTokens.insert(pair<string,int>("ismovie", false));
intTokens.insert(pair<string,int>("isseries", false));
return;
}
ScraperGetEventType getType;
getType.event = event;
getType.recording = recording;
if (!pScraper->Service("GetEventType", &getType)) {
intTokens.insert(pair<string,int>("ismovie", false));
intTokens.insert(pair<string,int>("isseries", false));
return;
}
if (getType.type == tMovie) {
cMovie movie;
movie.movieId = getType.movieId;
pScraper->Service("GetMovie", &movie);
intTokens.insert(pair<string,int>("ismovie", true));
intTokens.insert(pair<string,int>("isseries", false));
stringTokens.insert(pair<string,string>("movietitle", movie.title));
stringTokens.insert(pair<string,string>("movieoriginalTitle", movie.originalTitle));
stringTokens.insert(pair<string,string>("movietagline", movie.tagline));
stringTokens.insert(pair<string,string>("movieoverview", movie.overview));
stringTokens.insert(pair<string,string>("moviegenres", movie.genres));
stringTokens.insert(pair<string,string>("moviehomepage", movie.homepage));
stringTokens.insert(pair<string,string>("moviereleasedate", movie.releaseDate));
stringstream pop;
pop << movie.popularity;
stringTokens.insert(pair<string,string>("moviepopularity", pop.str()));
stringstream vote;
vote << movie.voteAverage;
stringTokens.insert(pair<string,string>("movievoteaverage", pop.str()));
stringTokens.insert(pair<string,string>("posterpath", movie.poster.path));
stringTokens.insert(pair<string,string>("fanartpath", movie.fanart.path));
stringTokens.insert(pair<string,string>("collectionposterpath", movie.collectionPoster.path));
stringTokens.insert(pair<string,string>("collectionfanartpath", movie.collectionFanart.path));
intTokens.insert(pair<string,int>("movieadult", movie.adult));
intTokens.insert(pair<string,int>("moviebudget", movie.budget));
intTokens.insert(pair<string,int>("movierevenue", movie.revenue));
intTokens.insert(pair<string,int>("movieruntime", movie.runtime));
intTokens.insert(pair<string,int>("posterwidth", movie.poster.width));
intTokens.insert(pair<string,int>("posterheight", movie.poster.height));
intTokens.insert(pair<string,int>("fanartwidth", movie.fanart.width));
intTokens.insert(pair<string,int>("fanartheight", movie.fanart.height));
intTokens.insert(pair<string,int>("collectionposterwidth", movie.collectionPoster.width));
intTokens.insert(pair<string,int>("collectionposterheight", movie.collectionPoster.height));
intTokens.insert(pair<string,int>("collectionfanartwidth", movie.collectionFanart.width));
intTokens.insert(pair<string,int>("collectionfanartheight", movie.collectionFanart.height));
vector< map< string, string > > actors;
for (vector<cActor>::iterator act = movie.actors.begin(); act != movie.actors.end(); act++) {
map< string, string > actor;
actor.insert(pair<string, string>("actors[name]", (*act).name));
actor.insert(pair<string, string>("actors[role]", (*act).role));
actor.insert(pair<string, string>("actors[thumb]", (*act).actorThumb.path));
stringstream actWidth, actHeight;
actWidth << (*act).actorThumb.width;
actHeight << (*act).actorThumb.height;
actor.insert(pair<string, string>("actors[thumbwidth]", actWidth.str()));
actor.insert(pair<string, string>("actors[thumbheight]", actHeight.str()));
actors.push_back(actor);
}
loopTokens.insert(pair<string, vector< map< string, string > > >("actors", actors));
} else if (getType.type == tSeries) {
cSeries series;
series.seriesId = getType.seriesId;
series.episodeId = getType.episodeId;
pScraper->Service("GetSeries", &series);
intTokens.insert(pair<string,int>("ismovie", false));
intTokens.insert(pair<string,int>("isseries", true));
//Series Basics
stringTokens.insert(pair<string,string>("seriesname", series.name));
stringTokens.insert(pair<string,string>("seriesoverview", series.overview));
stringTokens.insert(pair<string,string>("seriesfirstaired", series.firstAired));
stringTokens.insert(pair<string,string>("seriesnetwork", series.network));
stringTokens.insert(pair<string,string>("seriesgenre", series.genre));
stringstream rating;
rating << series.rating;
stringTokens.insert(pair<string,string>("seriesrating", rating.str()));
stringTokens.insert(pair<string,string>("seriesstatus", series.status));
//Episode Information
intTokens.insert(pair<string,int>("episodenumber", series.episode.number));
intTokens.insert(pair<string,int>("episodeseason", series.episode.season));
stringTokens.insert(pair<string,string>("episodetitle", series.episode.name));
stringTokens.insert(pair<string,string>("episodefirstaired", series.episode.firstAired));
stringTokens.insert(pair<string,string>("episodegueststars", series.episode.guestStars));
stringTokens.insert(pair<string,string>("episodeoverview", series.episode.overview));
stringstream eprating;
eprating << series.episode.rating;
stringTokens.insert(pair<string,string>("episoderating", eprating.str()));
intTokens.insert(pair<string,int>("episodeimagewidth", series.episode.episodeImage.width));
intTokens.insert(pair<string,int>("episodeimageheight", series.episode.episodeImage.height));
stringTokens.insert(pair<string,string>("episodeimagepath", series.episode.episodeImage.path));
//Seasonposter
intTokens.insert(pair<string,int>("seasonposterwidth", series.seasonPoster.width));
intTokens.insert(pair<string,int>("seasonposterheight", series.seasonPoster.height));
stringTokens.insert(pair<string,string>("seasonposterpath", series.seasonPoster.path));
//Posters
int current = 1;
for(vector<cTvMedia>::iterator poster = series.posters.begin(); poster != series.posters.end(); poster++) {
stringstream labelWidth, labelHeight, labelPath;
labelWidth << "seriesposter" << current << "width";
labelHeight << "seriesposter" << current << "height";
labelPath << "seriesposter" << current << "path";
intTokens.insert(pair<string,int>(labelWidth.str(), (*poster).width));
intTokens.insert(pair<string,int>(labelHeight.str(), (*poster).height));
stringTokens.insert(pair<string,string>(labelPath.str(), (*poster).path));
current++;
}
if (current < 3) {
for (; current < 4; current++) {
stringstream labelWidth, labelHeight, labelPath;
labelWidth << "seriesposter" << current << "width";
labelHeight << "seriesposter" << current << "height";
labelPath << "seriesposter" << current << "path";
intTokens.insert(pair<string,int>(labelWidth.str(), 0));
intTokens.insert(pair<string,int>(labelHeight.str(), 0));
stringTokens.insert(pair<string,string>(labelPath.str(), ""));
}
}
//Banners
current = 1;
for(vector<cTvMedia>::iterator banner = series.banners.begin(); banner != series.banners.end(); banner++) {
stringstream labelWidth, labelHeight, labelPath;
labelWidth << "seriesbanner" << current << "width";
labelHeight << "seriesbanner" << current << "height";
labelPath << "seriesbanner" << current << "path";
intTokens.insert(pair<string,int>(labelWidth.str(), (*banner).width));
intTokens.insert(pair<string,int>(labelHeight.str(), (*banner).height));
stringTokens.insert(pair<string,string>(labelPath.str(), (*banner).path));
current++;
}
if (current < 3) {
for (; current < 4; current++) {
stringstream labelWidth, labelHeight, labelPath;
labelWidth << "seriesbanner" << current << "width";
labelHeight << "seriesbanner" << current << "height";
labelPath << "seriesbanner" << current << "path";
intTokens.insert(pair<string,int>(labelWidth.str(), 0));
intTokens.insert(pair<string,int>(labelHeight.str(), 0));
stringTokens.insert(pair<string,string>(labelPath.str(), ""));
}
}
//Fanarts
current = 1;
for(vector<cTvMedia>::iterator fanart = series.fanarts.begin(); fanart != series.fanarts.end(); fanart++) {
stringstream labelWidth, labelHeight, labelPath;
labelWidth << "seriesfanart" << current << "width";
labelHeight << "seriesfanart" << current << "height";
labelPath << "seriesfanart" << current << "path";
intTokens.insert(pair<string,int>(labelWidth.str(), (*fanart).width));
intTokens.insert(pair<string,int>(labelHeight.str(), (*fanart).height));
stringTokens.insert(pair<string,string>(labelPath.str(), (*fanart).path));
current++;
}
if (current < 3) {
for (; current < 4; current++) {
stringstream labelWidth, labelHeight, labelPath;
labelWidth << "seriesfanart" << current << "width";
labelHeight << "seriesfanart" << current << "height";
labelPath << "seriesfanart" << current << "path";
intTokens.insert(pair<string,int>(labelWidth.str(), 0));
intTokens.insert(pair<string,int>(labelHeight.str(), 0));
stringTokens.insert(pair<string,string>(labelPath.str(), ""));
}
}
//Actors
vector< map< string, string > > actors;
for (vector<cActor>::iterator act = series.actors.begin(); act != series.actors.end(); act++) {
map< string, string > actor;
actor.insert(pair<string, string>("actors[name]", (*act).name));
actor.insert(pair<string, string>("actors[role]", (*act).role));
actor.insert(pair<string, string>("actors[thumb]", (*act).actorThumb.path));
stringstream actWidth, actHeight;
actWidth << (*act).actorThumb.width;
actHeight << (*act).actorThumb.height;
actor.insert(pair<string, string>("actors[thumbwidth]", actWidth.str()));
actor.insert(pair<string, string>("actors[thumbheight]", actHeight.str()));
actors.push_back(actor);
}
loopTokens.insert(pair<string, vector< map< string, string > > >("actors", actors));
} else {
intTokens.insert(pair<string,int>("ismovie", false));
intTokens.insert(pair<string,int>("isseries", false));
}
}
void cDisplayMenuDetailView::InitTabs(void) {
tmplView->InitViewTabIterator();
cTemplateViewTab *tmplTab = NULL;
while(tmplTab = tmplView->GetNextViewTab()) {
tmplTab->ParseDynamicParameters(&intTokens, true);
tmplTab->ClearDynamicFunctionParameters();
tmplTab->ParseDynamicFunctionParameters(&stringTokens, &intTokens);
if (tmplTab->DoExecute()) {
activeTabs.push_back(tmplTab);
}
}
atIt = activeTabs.begin();
}
bool cDisplayMenuDetailView::LoadReruns(vector< map< string, string > > *reruns) {
if (!event)
return false;
cPlugin *epgSearchPlugin = cPluginManager::GetPlugin("epgsearch");
if (!epgSearchPlugin)
return false;
if (isempty(event->Title()))
return false;
int maxNumReruns = 10;
Epgsearch_searchresults_v1_0 data;
string strQuery = event->Title();
data.useSubTitle = true;
data.query = (char *)strQuery.c_str();
data.mode = 0;
data.channelNr = 0;
data.useTitle = true;
data.useDescription = false;
bool foundRerun = false;
if (epgSearchPlugin->Service("Epgsearch-searchresults-v1.0", &data)) {
cList<Epgsearch_searchresults_v1_0::cServiceSearchResult>* list = data.pResultList;
if (list && (list->Count() > 1)) {
foundRerun = true;
int i = 0;
for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = list->First(); r && i < maxNumReruns; r = list->Next(r)) {
if ((event->ChannelID() == r->event->ChannelID()) && (event->StartTime() == r->event->StartTime()))
continue;
i++;
map< string, string > rerun;
rerun.insert(pair<string, string>("reruns[title]", r->event->Title() ? r->event->Title() : ""));
rerun.insert(pair<string, string>("reruns[shorttext]", r->event->ShortText() ? r->event->ShortText() : ""));
rerun.insert(pair<string, string>("reruns[start]", *(r->event->GetTimeString())));
rerun.insert(pair<string, string>("reruns[start]", *(r->event->GetTimeString())));
rerun.insert(pair<string, string>("reruns[stop]", *(r->event->GetEndTimeString())));
rerun.insert(pair<string, string>("reruns[date]", *ShortDateString(r->event->StartTime())));
rerun.insert(pair<string, string>("reruns[day]", *WeekDayName(r->event->StartTime())));
string channelID = *(r->event->ChannelID().ToString());
rerun.insert(pair<string, string>("reruns[channelid]", channelID));
bool logoExists = imgCache->LogoExists(channelID);
rerun.insert(pair<string, string>("reruns[channellogoexists]", logoExists ? "1" : "0"));
cChannel *channel = Channels.GetByChannelID(r->event->ChannelID(), true, true);
if (channel) {
stringstream channelNumber;
channelNumber << channel->Number();
rerun.insert(pair<string, string>("reruns[channelname]", channel->ShortName(true)));
rerun.insert(pair<string, string>("reruns[channelnumber]", channelNumber.str()));
} else {
rerun.insert(pair<string, string>("reruns[channelname]", ""));
rerun.insert(pair<string, string>("reruns[channelnumber]", ""));
}
reruns->push_back(rerun);
}
delete list;
}
}
return foundRerun;
}
void cDisplayMenuDetailView::LoadRecordingInformation(void) {
const cRecordingInfo *Info = recording->Info();
if (!Info)
return;
unsigned long long nRecSize = -1;
unsigned long long nFileSize[1000];
nFileSize[0] = 0;
int i = 0;
struct stat filebuf;
cString filename;
int rc = 0;
do {
if (recording->IsPesRecording())
filename = cString::sprintf("%s/%03d.vdr", recording->FileName(), ++i);
else
filename = cString::sprintf("%s/%05d.ts", recording->FileName(), ++i);
rc = stat(filename, &filebuf);
if (rc == 0)
nFileSize[i] = nFileSize[i-1] + filebuf.st_size;
else
if (ENOENT != errno) {
nRecSize = -1;
}
} while (i <= 999 && !rc);
nRecSize = nFileSize[i-1];
cMarks marks;
bool fHasMarks = marks.Load(recording->FileName(), recording->FramesPerSecond(), recording->IsPesRecording()) && marks.Count();
cIndexFile *index = new cIndexFile(recording->FileName(), false, recording->IsPesRecording());
int nCutLength = 0;
long nCutInFrame = 0;
unsigned long long nRecSizeCut = nRecSize < 0 ? -1 : 0;
unsigned long long nCutInOffset = 0;
if (fHasMarks && index) {
uint16_t FileNumber;
off_t FileOffset;
bool fCutIn = true;
cMark *mark = marks.First();
while (mark) {
int pos = mark->Position();
index->Get(pos, &FileNumber, &FileOffset); //TODO: will disc spin up?
if (fCutIn) {
nCutInFrame = pos;
fCutIn = false;
if (nRecSize >= 0)
nCutInOffset = nFileSize[FileNumber-1] + FileOffset;
} else {
nCutLength += pos - nCutInFrame;
fCutIn = true;
if (nRecSize >= 0)
nRecSizeCut += nFileSize[FileNumber-1] + FileOffset - nCutInOffset;
}
cMark *nextmark = marks.Next(mark);
mark = nextmark;
}
if (!fCutIn) {
nCutLength += index->Last() - nCutInFrame;
index->Get(index->Last() - 1, &FileNumber, &FileOffset);
if (nRecSize >= 0)
nRecSizeCut += nFileSize[FileNumber-1] + FileOffset - nCutInOffset;
}
}
if (nRecSize < 0) {
if ((nRecSize = ReadSizeVdr(recording->FileName())) < 0) {
nRecSize = DirSizeMB(recording->FileName());
}
}
if (nRecSize >= 0) {
cString strRecSize = "";
cString strRecSizeCut = "";
if (fHasMarks) {
if (nRecSize > MEGABYTE(1023)) {
strRecSize = cString::sprintf("%.2f GB", (float)nRecSize / MEGABYTE(1024));
strRecSizeCut = cString::sprintf("%.2f GB", (float)nRecSizeCut / MEGABYTE(1024));
} else {
strRecSize = cString::sprintf("%lld MB", nRecSize / MEGABYTE(1));
strRecSizeCut = cString::sprintf("%lld MB", nRecSizeCut / MEGABYTE(1));
}
} else {
if (nRecSize > MEGABYTE(1023)) {
strRecSize = cString::sprintf("%.2f GB", (float)nRecSize / MEGABYTE(1024));
strRecSizeCut = strRecSize;
} else {
strRecSize = cString::sprintf("%lld MB", nRecSize / MEGABYTE(1));
strRecSizeCut = strRecSize;
}
}
stringTokens.insert(pair<string,string>("recordingsize", *strRecSize));
stringTokens.insert(pair<string,string>("recordingsizecutted", *strRecSizeCut));
} else {
stringTokens.insert(pair<string,string>("recordingsize", ""));
stringTokens.insert(pair<string,string>("recordingsizecutted", ""));
}
cChannel *channel = Channels.GetByChannelID(Info->ChannelID());
if (channel) {
stringTokens.insert(pair<string,string>("recchannelname", channel->Name()));
intTokens.insert(pair<string,int>("recchannelnumber", channel->Number()));
}
if (index) {
int nLastIndex = index->Last();
if (nLastIndex) {
string strLength = *IndexToHMSF(nLastIndex, false, recording->FramesPerSecond());
string strLengthCutted = "";
if (fHasMarks) {
strLengthCutted = *IndexToHMSF(nCutLength, false, recording->FramesPerSecond());
} else {
strLengthCutted = strLength;
}
string strBitrate = *cString::sprintf("%.2f MBit/s", (float)nRecSize / nLastIndex * recording->FramesPerSecond() * 8 / MEGABYTE(1));
stringTokens.insert(pair<string,string>("recordinglength", strLength));
stringTokens.insert(pair<string,string>("recordinglengthcutted", strLengthCutted));
stringTokens.insert(pair<string,string>("recordingbitrate", strBitrate));
}
delete index;
}
string recFormat = recording->IsPesRecording() ? "PES" : "TS";
stringTokens.insert(pair<string,string>("recordingformat", recFormat));
bool searchTimerFound = false;
if (Info) {
const char *aux = NULL;
aux = Info->Aux();
if (aux) {
string strAux = aux;
string auxEpgsearch = StripXmlTag(strAux, "epgsearch");
if (!auxEpgsearch.empty()) {
string searchTimer = StripXmlTag(auxEpgsearch, "searchtimer");
if (!searchTimer.empty()) {
stringTokens.insert(pair<string,string>("searchtimer", searchTimer));
searchTimerFound = true;
}
}
}
}
if (!searchTimerFound)
stringTokens.insert(pair<string,string>("searchtimer", "n.a."));
}
string cDisplayMenuDetailView::StripXmlTag(string &Line, const char *Tag) {
// set the search strings
stringstream strStart, strStop;
strStart << "<" << Tag << ">";
strStop << "</" << Tag << ">";
// find the strings
string::size_type locStart = Line.find(strStart.str());
string::size_type locStop = Line.find(strStop.str());
if (locStart == string::npos || locStop == string::npos)
return "";
// extract relevant text
int pos = locStart + strStart.str().size();
int len = locStop - pos;
return len < 0 ? "" : Line.substr(pos, len);
}
int cDisplayMenuDetailView::ReadSizeVdr(const char *strPath) {
int dirSize = -1;
char buffer[20];
char *strFilename = NULL;
if (-1 != asprintf(&strFilename, "%s/size.vdr", strPath)) {
struct stat st;
if (stat(strFilename, &st) == 0) {
int fd = open(strFilename, O_RDONLY);
if (fd >= 0) {
if (safe_read(fd, &buffer, sizeof(buffer)) >= 0) {
dirSize = atoi(buffer);
}
close(fd);
}
}
free(strFilename);
}
return dirSize;
}
void cDisplayMenuDetailView::SetEpgPictures(int eventId) {
for (int i=0; i<3; i++) {
stringstream picName;
picName << eventId << "_" << i;
bool epgPicAvailable = FileExists(*config.epgImagePath, picName.str(), "jpg");
stringstream available;
stringstream path;
available << "epgpic" << i+1 << "avaialble";
path << "epgpic" << i+1 << "path";
if (epgPicAvailable) {
intTokens.insert(pair<string,int>(available.str(), true));
stringTokens.insert(pair<string,string>(path.str(), *cString::sprintf("%s%s.jpg", *config.epgImagePath, picName.str().c_str())));
} else {
intTokens.insert(pair<string,int>(available.str(), false));
stringTokens.insert(pair<string,string>(path.str(), ""));
}
}
}
void cDisplayMenuDetailView::SetRecordingImages(const char *recPath) {
if (!recPath) {
intTokens.insert(pair<string,int>("recimg1avaialble", false));
intTokens.insert(pair<string,int>("recimg2avaialble", false));
intTokens.insert(pair<string,int>("recimg3avaialble", false));
stringTokens.insert(pair<string,string>("recimg1path", ""));
stringTokens.insert(pair<string,string>("recimg2path", ""));
stringTokens.insert(pair<string,string>("recimg3path", ""));
return;
}
string path = recPath;
DIR *dirHandle;
struct dirent *dirEntry;
dirHandle = opendir(recPath);
if (!dirHandle) {
intTokens.insert(pair<string,int>("recimg1avaialble", false));
intTokens.insert(pair<string,int>("recimg2avaialble", false));
intTokens.insert(pair<string,int>("recimg3avaialble", false));
stringTokens.insert(pair<string,string>("recimg1path", ""));
stringTokens.insert(pair<string,string>("recimg2path", ""));
stringTokens.insert(pair<string,string>("recimg3path", ""));
return;
}
int picsFound = 0;
while ( 0 != (dirEntry = readdir(dirHandle))) {
if (endswith(dirEntry->d_name, "jpg")) {
string fileName = dirEntry->d_name;
stringstream available;
available << "recimg" << picsFound+1 << "avaialble";
stringstream path;
path << "recimg" << picsFound+1 << "path";
intTokens.insert(pair<string,int>(available.str(), true));
stringTokens.insert(pair<string,string>(path.str(), *cString::sprintf("%s/%s", recPath, fileName.c_str())));
picsFound++;
}
if (picsFound == 3) {
break;
}
}
for (int i=picsFound; i<3; i++) {
stringstream available;
available << "recimg" << i+1 << "avaialble";
stringstream path;
path << "recimg" << i+1 << "path";
intTokens.insert(pair<string,int>(available.str(), false));
stringTokens.insert(pair<string,string>(path.str(), ""));
}
closedir(dirHandle);
}
void cDisplayMenuDetailView::DrawHeader(void) {
map < string, string > headerStringTokens;
map < string, int > headerIntTokens;
if (event || recording) {
static cPlugin *pScraper = GetScraperPlugin();
if (!pScraper) {
headerIntTokens.insert(pair<string,int>("ismovie", false));
headerIntTokens.insert(pair<string,int>("isseries", false));
headerIntTokens.insert(pair<string,int>("posteravailable", false));
headerIntTokens.insert(pair<string,int>("banneravailable", false));
} else {
ScraperGetEventType getType;
getType.event = event;
getType.recording = recording;
if (!pScraper->Service("GetEventType", &getType)) {
headerIntTokens.insert(pair<string,int>("ismovie", false));
headerIntTokens.insert(pair<string,int>("isseries", false));
headerIntTokens.insert(pair<string,int>("posteravailable", false));
headerIntTokens.insert(pair<string,int>("banneravailable", false));
} else {
if (getType.type == tMovie) {
cMovie movie;
movie.movieId = getType.movieId;
pScraper->Service("GetMovie", &movie);
headerIntTokens.insert(pair<string,int>("ismovie", true));
headerIntTokens.insert(pair<string,int>("isseries", false));
headerIntTokens.insert(pair<string,int>("posteravailable", true));
headerIntTokens.insert(pair<string,int>("banneravailable", false));
headerStringTokens.insert(pair<string,string>("posterpath", movie.poster.path));
headerIntTokens.insert(pair<string,int>("posterwidth", movie.poster.width));
headerIntTokens.insert(pair<string,int>("posterheight", movie.poster.height));
} else if (getType.type == tSeries) {
cSeries series;
series.seriesId = getType.seriesId;
series.episodeId = getType.episodeId;
pScraper->Service("GetSeries", &series);
headerIntTokens.insert(pair<string,int>("ismovie", false));
headerIntTokens.insert(pair<string,int>("isseries", true));
vector<cTvMedia>::iterator poster = series.posters.begin();
if (poster != series.posters.end()) {
headerIntTokens.insert(pair<string,int>("posterwidth", (*poster).width));
headerIntTokens.insert(pair<string,int>("posterheight", (*poster).height));
headerStringTokens.insert(pair<string,string>("posterpath", (*poster).path));
headerIntTokens.insert(pair<string,int>("posteravailable", true));
} else {
headerIntTokens.insert(pair<string,int>("posterwidth", 0));
headerIntTokens.insert(pair<string,int>("posterheight", 0));
headerStringTokens.insert(pair<string,string>("posterpath", ""));
headerIntTokens.insert(pair<string,int>("posteravailable", false));
}
vector<cTvMedia>::iterator banner = series.banners.begin();
if (banner != series.banners.end()) {
headerIntTokens.insert(pair<string,int>("bannerwidth", (*banner).width));
headerIntTokens.insert(pair<string,int>("bannerheight", (*banner).height));
headerStringTokens.insert(pair<string,string>("bannerpath", (*banner).path));
headerIntTokens.insert(pair<string,int>("banneravailable", true));
} else {
headerIntTokens.insert(pair<string,int>("bannerwidth", 0));
headerIntTokens.insert(pair<string,int>("bannerheight", 0));
headerStringTokens.insert(pair<string,string>("bannerpath", ""));
headerIntTokens.insert(pair<string,int>("banneravailable", false));
}
} else {
headerIntTokens.insert(pair<string,int>("ismovie", false));
headerIntTokens.insert(pair<string,int>("isseries", false));
headerIntTokens.insert(pair<string,int>("posteravailable", false));
headerIntTokens.insert(pair<string,int>("banneravailable", false));
}
}
}
}
if (event) {
headerStringTokens.insert(pair<string,string>("title", event->Title() ? event->Title() : ""));
headerStringTokens.insert(pair<string,string>("shorttext", event->ShortText() ? event->ShortText() : ""));
headerStringTokens.insert(pair<string,string>("start", *(event->GetTimeString())));
headerStringTokens.insert(pair<string,string>("stop", *(event->GetEndTimeString())));
headerStringTokens.insert(pair<string,string>("day", *WeekDayName(event->StartTime())));
headerStringTokens.insert(pair<string,string>("date", *ShortDateString(event->StartTime())));
headerStringTokens.insert(pair<string,string>("channelid", *(event->ChannelID().ToString())));
bool isRunning = false;
time_t now = time(NULL);
if ((now >= event->StartTime()) && (now <= event->EndTime()))
isRunning = true;
headerIntTokens.insert(pair<string,int>("running", isRunning));
if (isRunning) {
headerIntTokens.insert(pair<string,int>("elapsed", (now - event->StartTime())/60));
} else {
headerIntTokens.insert(pair<string,int>("elapsed", 0));
}
headerIntTokens.insert(pair<string,int>("duration", event->Duration() / 60));
stringstream epgImageName;
epgImageName << event->EventID();
bool epgPicAvailable = FileExists(*config.epgImagePath, epgImageName.str(), "jpg");
if (epgPicAvailable) {
headerIntTokens.insert(pair<string,int>("epgpicavailable", true));
headerStringTokens.insert(pair<string,string>("epgpicpath", *cString::sprintf("%s%s.jpg", *config.epgImagePath, epgImageName.str().c_str())));
} else {
epgImageName << "_0";
epgPicAvailable = FileExists(*config.epgImagePath, epgImageName.str(), "jpg");
if (epgPicAvailable) {
headerIntTokens.insert(pair<string,int>("epgpicavailable", true));
headerStringTokens.insert(pair<string,string>("epgpicpath", *cString::sprintf("%s%s.jpg", *config.epgImagePath, epgImageName.str().c_str())));
} else {
headerIntTokens.insert(pair<string,int>("epgpicavailable", false));
headerStringTokens.insert(pair<string,string>("epgpicpath", ""));
}
}
DrawViewElement(veDetailHeader, &headerStringTokens, &headerIntTokens);
} else if (recording) {
string name = recording->Name() ? recording->Name() : "";
headerStringTokens.insert(pair<string,string>("name", name));
const cRecordingInfo *info = recording->Info();
if (info) {
headerStringTokens.insert(pair<string,string>("shorttext", info->ShortText() ? info->ShortText() : ""));
const cEvent *event = info->GetEvent();
if (event) {
string recDate = *(event->GetDateString());
string recTime = *(event->GetTimeString());
if (recDate.find("1970") != string::npos) {
time_t start = recording->Start();
recDate = *DateString(start);
recTime = *TimeString(start);
}
int duration = event->Duration() / 60;
int recDuration = recording->LengthInSeconds();
recDuration = (recDuration>0)?(recDuration / 60):0;
headerStringTokens.insert(pair<string,string>("date", recDate.c_str()));
headerStringTokens.insert(pair<string,string>("time", recTime.c_str()));
headerIntTokens.insert(pair<string,int>("duration", recDuration));
headerIntTokens.insert(pair<string,int>("durationevent", duration));
}
} else {
headerStringTokens.insert(pair<string,string>("shorttext", ""));
int recDuration = recording->LengthInSeconds();
recDuration = (recDuration>0)?(recDuration / 60):0;
headerStringTokens.insert(pair<string,string>("date", ""));
headerStringTokens.insert(pair<string,string>("time", ""));
headerIntTokens.insert(pair<string,int>("duration", recDuration));
headerIntTokens.insert(pair<string,int>("durationevent", 0));
}
string recImage = "";
string path = recording->FileName() ? recording->FileName() : "";
string extension = ".jpg";
if (FirstFileInFolder(path, extension, recImage)) {
headerIntTokens.insert(pair<string,int>("recimgavailable", true));
headerStringTokens.insert(pair<string,string>("recimgpath", *cString::sprintf("%s/%s", path.c_str(), recImage.c_str())));
} else {
headerIntTokens.insert(pair<string,int>("recimgavailable", false));
headerStringTokens.insert(pair<string,string>("recimgpath", ""));
}
DrawViewElement(veDetailHeader, &headerStringTokens, &headerIntTokens);
}
}
void cDisplayMenuDetailView::DrawScrollbar(void) {
map < string, string > scrollbarStringTokens;
map < string, int > scrollbarIntTokens;
int barTop = 0;
int barHeight = 0;
tabView->GetScrollbarPosition(barTop, barHeight);
scrollbarIntTokens.insert(pair<string,int>("height", barHeight));
scrollbarIntTokens.insert(pair<string,int>("offset", barTop));
ClearViewElement(veScrollbar);
DrawViewElement(veScrollbar, &scrollbarStringTokens, &scrollbarIntTokens);
}
void cDisplayMenuDetailView::DrawTabLabels(void) {
if (!ViewElementImplemented(veTabLabels)) {
return;
}
map < string, string > labelStringTokens;
map < string, int > labelIntTokens;
map < string, vector< map< string, string > > > labelLoopTokens;
vector< map< string, string > > tabLabels;
for (list<cTemplateViewTab*>::iterator it = activeTabs.begin(); it != activeTabs.end(); it++) {
cTemplateViewTab *tab = *it;
map< string, string > tabLabel;
tabLabel.insert(pair< string, string >("tabs[title]", tab->GetName()));
if (tab == currentTmplTab) {
tabLabel.insert(pair< string, string >("tabs[current]", "1"));
} else {
tabLabel.insert(pair< string, string >("tabs[current]", "0"));
}
tabLabels.push_back(tabLabel);
}
labelLoopTokens.insert(pair< string, vector< map< string, string > > >("tabs", tabLabels));
ClearViewElement(veTabLabels);
DrawViewElement(veTabLabels, &labelStringTokens, &labelIntTokens, &labelLoopTokens);
}
cTemplateViewTab *cDisplayMenuDetailView::GetPrevTab(void) {
if (atIt == activeTabs.begin()) {
atIt = activeTabs.end();
}
atIt--;
return *atIt;
}
cTemplateViewTab *cDisplayMenuDetailView::GetNextTab(void) {
atIt++;
if (atIt == activeTabs.end()) {
atIt = activeTabs.begin();
}
return *atIt;
}

View File

@@ -0,0 +1,50 @@
#ifndef __DISPLAYMENUDETAILVIEW_H
#define __DISPLAYMENUDETAILVIEW_H
#include <list>
#include "../libtemplate/template.h"
#include "view.h"
#include "displaymenutabview.h"
class cDisplayMenuDetailView : public cView {
private:
bool detailViewInit;
const cEvent *event;
const cRecording *recording;
const char *text;
cTemplateViewTab *currentTmplTab;
list<cTemplateViewTab*> activeTabs;
list<cTemplateViewTab*>::iterator atIt;
cDisplayMenuTabView *tabView;
map < string, string > stringTokens;
map < string, int > intTokens;
map < string, vector< map< string, string > > > loopTokens;
void SetTokens(void);
void SetScraperTokens(void);
void InitTabs(void);
bool LoadReruns(vector< map< string, string > > *reruns);
void LoadRecordingInformation(void);
void SetEpgPictures(int eventId);
void SetRecordingImages(const char *recPath);
string StripXmlTag(string &Line, const char *Tag);
int ReadSizeVdr(const char *strPath);
void DrawHeader(void);
void DrawScrollbar(void);
void DrawTabLabels(void);
cTemplateViewTab *GetPrevTab(void);
cTemplateViewTab *GetNextTab(void);
public:
cDisplayMenuDetailView(cTemplateView *tmplDetailView);
virtual ~cDisplayMenuDetailView();
void SetEvent(const cEvent *event) { this->event = event; };
void SetRecording(const cRecording *recording) { this->recording = recording; };
void SetText(const char *text) { this->text = text; };
void Clear(void);
void Render(void);
void KeyLeft(void);
void KeyRight(void);
void KeyUp(void);
void KeyDown(void);
};
#endif //__DISPLAYMENUDETAILVIEW_H

View File

@@ -0,0 +1,561 @@
#include "../services/scraper2vdr.h"
#include "../libcore/helpers.h"
#include "displaymenuitemcurrentview.h"
cDisplayMenuItemCurrentView::cDisplayMenuItemCurrentView(cTemplateViewElement *tmplCurrent) : cView(tmplCurrent) {
delay = tmplItem->GetNumericParameter(ptDelay);
SetFadeTime(tmplItem->GetNumericParameter(ptFadeTime));
}
cDisplayMenuItemCurrentView::~cDisplayMenuItemCurrentView() {
CancelSave();
}
void cDisplayMenuItemCurrentView::SetPosMenuItem(cRect &pos) {
posMenuItem.SetX(pos.X());
posMenuItem.SetY(pos.Y());
posMenuItem.SetWidth(pos.Width());
posMenuItem.SetHeight(pos.Height());
}
void cDisplayMenuItemCurrentView::SetTokensPosMenuItem(void) {
intTokens.insert(pair<string,int>("menuitemx", posMenuItem.X()));
intTokens.insert(pair<string,int>("menuitemy", posMenuItem.Y()));
intTokens.insert(pair<string,int>("menuitemwidth", posMenuItem.Width()));
intTokens.insert(pair<string,int>("menuitemheight", posMenuItem.Height()));
}
void cDisplayMenuItemCurrentView::SetScraperPoster(const cEvent *event, const cRecording *recording) {
static cPlugin *pScraper = GetScraperPlugin();
if (!pScraper || (!event && !recording)) {
intTokens.insert(pair<string,int>("hasposter", false));
intTokens.insert(pair<string,int>("posterwidth", -1));
intTokens.insert(pair<string,int>("posterheight", -1));
stringTokens.insert(pair<string,string>("posterpath", ""));
return;
}
ScraperGetPoster call;
call.event = event;
call.recording = recording;
if (pScraper->Service("GetPoster", &call)) {
intTokens.insert(pair<string,int>("hasposter", true));
intTokens.insert(pair<string,int>("posterwidth", call.poster.width));
intTokens.insert(pair<string,int>("posterheight", call.poster.height));
stringTokens.insert(pair<string,string>("posterpath", call.poster.path));
} else {
intTokens.insert(pair<string,int>("hasposter", false));
intTokens.insert(pair<string,int>("posterwidth", -1));
intTokens.insert(pair<string,int>("posterheight", -1));
stringTokens.insert(pair<string,string>("posterpath", ""));
}
}
/*************************************************************
* cDisplayMenuItemCurrentMainView
*************************************************************/
cDisplayMenuItemCurrentMainView::cDisplayMenuItemCurrentMainView(cTemplateViewElement *tmplCurrent, string number, string label, string icon)
: cDisplayMenuItemCurrentView(tmplCurrent) {
this->number = number;
this->label = label;
this->icon = icon;
}
cDisplayMenuItemCurrentMainView::~cDisplayMenuItemCurrentMainView() {
}
void cDisplayMenuItemCurrentMainView::Prepare(void) {
}
void cDisplayMenuItemCurrentMainView::Render(void) {
stringTokens.insert(pair<string,string>("number", number));
stringTokens.insert(pair<string,string>("label", label));
stringTokens.insert(pair<string,string>("icon", icon));
SetTokensPosMenuItem();
DrawViewElement(veMenuCurrentItemDetail, &stringTokens, &intTokens);
}
void cDisplayMenuItemCurrentMainView::Clear(void) {
}
void cDisplayMenuItemCurrentMainView::Action(void) {
SetInitFinished();
DoSleep(delay);
Render();
FadeIn();
DoFlush();
if (scrolling) {
DoSleep(scrollDelay);
if (scrollOrientation == orHorizontal) {
ScrollHorizontal(scrollingPix, scrollDelay, scrollSpeed, scrollMode);
} else {
ScrollVertical(scrollingPix, scrollDelay, scrollSpeed);
}
}
}
/*************************************************************
* cDisplayMenuItemCurrentSchedulesView
*************************************************************/
cDisplayMenuItemCurrentSchedulesView::cDisplayMenuItemCurrentSchedulesView(cTemplateViewElement *tmplCurrent, const cEvent *event, const cChannel *channel, eTimerMatch timerMatch, eMenuCategory cat)
: cDisplayMenuItemCurrentView(tmplCurrent) {
this->event = event;
this->channel = channel;
this->timerMatch = timerMatch;
this->cat = cat;
}
cDisplayMenuItemCurrentSchedulesView::~cDisplayMenuItemCurrentSchedulesView() {
}
void cDisplayMenuItemCurrentSchedulesView::Prepare(void) {
}
void cDisplayMenuItemCurrentSchedulesView::Render(void) {
intTokens.insert(pair<string,int>("whatson", (cat == mcSchedule) ? true: false));
intTokens.insert(pair<string,int>("whatsonnow", (cat == mcScheduleNow) ? true: false));
intTokens.insert(pair<string,int>("whatsonnext", (cat == mcScheduleNext) ? true: false));
if (timerMatch == tmFull) {
intTokens.insert(pair<string,int>("timerpartitial", false));
intTokens.insert(pair<string,int>("timerfull", true));
} else if (timerMatch == tmPartial) {
intTokens.insert(pair<string,int>("timerpartitial", true));
intTokens.insert(pair<string,int>("timerfull", false));
} else {
intTokens.insert(pair<string,int>("timerpartitial", false));
intTokens.insert(pair<string,int>("timerfull", false));
}
if (event) {
stringTokens.insert(pair<string,string>("title", event->Title() ? event->Title() : ""));
stringTokens.insert(pair<string,string>("shorttext", event->ShortText() ? event->ShortText() : ""));
stringTokens.insert(pair<string,string>("description", event->Description() ? event->Description() : ""));
stringTokens.insert(pair<string,string>("start", *(event->GetTimeString())));
stringTokens.insert(pair<string,string>("stop", *(event->GetEndTimeString())));
stringTokens.insert(pair<string,string>("day", *WeekDayName(event->StartTime())));
stringTokens.insert(pair<string,string>("date", *ShortDateString(event->StartTime())));
bool isRunning = false;
time_t now = time(NULL);
if ((now >= event->StartTime()) && (now <= event->EndTime()))
isRunning = true;
intTokens.insert(pair<string,int>("running", isRunning));
if (isRunning) {
intTokens.insert(pair<string,int>("elapsed", (now - event->StartTime())/60));
} else {
intTokens.insert(pair<string,int>("elapsed", 0));
}
intTokens.insert(pair<string,int>("duration", event->Duration() / 60));
SetScraperPoster(event);
}
if (channel) {
stringTokens.insert(pair<string,string>("channelid", *(channel->GetChannelID().ToString())));
}
vector< map<string,string> > schedulesTokens;
if (cat == mcScheduleNow || cat == mcScheduleNext) {
ReadSchedules(&schedulesTokens);
}
map < string, vector< map< string, string > > > loopTokens;
loopTokens.insert(pair<string, vector< map< string, string > > >("schedule", schedulesTokens));
SetTokensPosMenuItem();
DrawViewElement(veMenuCurrentItemDetail, &stringTokens, &intTokens, &loopTokens);
}
void cDisplayMenuItemCurrentSchedulesView::Clear(void) {
}
void cDisplayMenuItemCurrentSchedulesView::Action(void) {
SetInitFinished();
DoSleep(delay);
Render();
FadeIn();
DoFlush();
if (scrolling) {
DoSleep(scrollDelay);
if (scrollOrientation == orHorizontal) {
ScrollHorizontal(scrollingPix, scrollDelay, scrollSpeed, scrollMode);
} else {
ScrollVertical(scrollingPix, scrollDelay, scrollSpeed);
}
}
}
void cDisplayMenuItemCurrentSchedulesView::ReadSchedules(vector< map<string,string> > *schedulesTokens) {
if (!event)
return;
const cSchedule *schedule = event->Schedule();
const cEvent *curEvent = event;
int num = 0;
for (; curEvent; curEvent = schedule->Events()->Next(curEvent)) {
if (num == 0) {
num++;
continue;
}
map<string,string> element;
element.insert(pair<string,string>("schedule[start]", *(curEvent->GetTimeString())));
element.insert(pair<string,string>("schedule[stop]", *(curEvent->GetEndTimeString())));
element.insert(pair<string,string>("schedule[title]", curEvent->Title() ? curEvent->Title() : ""));
element.insert(pair<string,string>("schedule[shorttext]", curEvent->ShortText() ? curEvent->ShortText() : ""));
schedulesTokens->push_back(element);
num++;
if (num > 10)
break;
}
}
/*************************************************************
* cDisplayMenuItemCurrentChannelView
*************************************************************/
cDisplayMenuItemCurrentChannelView::cDisplayMenuItemCurrentChannelView(cTemplateViewElement *tmplCurrent, const cChannel *channel)
: cDisplayMenuItemCurrentView(tmplCurrent) {
this->channel = channel;
}
cDisplayMenuItemCurrentChannelView::~cDisplayMenuItemCurrentChannelView() {
}
void cDisplayMenuItemCurrentChannelView::Prepare(void) {
}
void cDisplayMenuItemCurrentChannelView::Render(void) {
if (!channel)
return;
//general channel information
intTokens.insert(pair<string,int>("number", channel->Number()));
intTokens.insert(pair<string,int>("transponder", channel->Transponder()));
intTokens.insert(pair<string,int>("frequency", channel->Frequency()));
stringTokens.insert(pair<string,string>("name", channel->Name() ? channel->Name() : ""));
stringTokens.insert(pair<string,string>("channelid", *(channel->GetChannelID().ToString())));
//Channel Source Information
const cSource *source = Sources.Get(channel->Source());
if (source) {
stringTokens.insert(pair<string,string>("source", *cSource::ToString(source->Code())));
stringTokens.insert(pair<string,string>("sourcedescription", source->Description() ? source->Description() : ""));
stringTokens.insert(pair<string,string>("source", *cSource::ToString(source->Code())));
intTokens.insert(pair<string,int>("isAtsc", source->IsAtsc(source->Code())));
intTokens.insert(pair<string,int>("isCable", source->IsCable(source->Code())));
intTokens.insert(pair<string,int>("isSat", source->IsSat(source->Code())));
intTokens.insert(pair<string,int>("isTerr", source->IsTerr(source->Code())));
}
//current schedule
cSchedulesLock schedulesLock;
const cSchedules *schedules = cSchedules::Schedules(schedulesLock);
const cSchedule *schedule = NULL;
schedule = schedules->GetSchedule(channel);
if (schedule) {
const cEvent *presentEvent = schedule->GetPresentEvent();
if (presentEvent) {
stringTokens.insert(pair<string,string>("presenteventtitle", presentEvent->Title() ? presentEvent->Title() : ""));
stringTokens.insert(pair<string,string>("presenteventshorttext", presentEvent->ShortText() ? presentEvent->ShortText() : ""));
stringTokens.insert(pair<string,string>("presenteventdescription", presentEvent->Description() ? presentEvent->Description() : ""));
stringTokens.insert(pair<string,string>("presenteventstart", *presentEvent->GetTimeString()));
stringTokens.insert(pair<string,string>("presenteventstop", *presentEvent->GetEndTimeString()));
stringTokens.insert(pair<string,string>("presenteventday", *WeekDayName(presentEvent->StartTime())));
stringTokens.insert(pair<string,string>("presenteventdate", *ShortDateString(presentEvent->StartTime())));
intTokens.insert(pair<string,int>("presenteventelapsed", (time(0) - presentEvent->StartTime())/60));
intTokens.insert(pair<string,int>("presenteventduration", presentEvent->Duration() / 60));
SetScraperPoster(presentEvent);
} else {
stringTokens.insert(pair<string,string>("presenteventtitle", ""));
stringTokens.insert(pair<string,string>("presenteventshorttext", ""));
stringTokens.insert(pair<string,string>("presenteventdescription", ""));
stringTokens.insert(pair<string,string>("presenteventstart", ""));
stringTokens.insert(pair<string,string>("presenteventstop", ""));
stringTokens.insert(pair<string,string>("presenteventday", ""));
stringTokens.insert(pair<string,string>("presenteventdate", ""));
intTokens.insert(pair<string,int>("presenteventelapsed", 0));
intTokens.insert(pair<string,int>("presenteventduration", 0));
}
const cList<cEvent> *events = schedule->Events();
bool inserted = false;
if (events && presentEvent) {
const cEvent *nextEvent = events->Next(presentEvent);
if (nextEvent) {
stringTokens.insert(pair<string,string>("nexteventtitle", nextEvent->Title() ? nextEvent->Title() : ""));
stringTokens.insert(pair<string,string>("nexteventshorttext", nextEvent->ShortText() ? nextEvent->ShortText() : ""));
stringTokens.insert(pair<string,string>("nexteventdescription", nextEvent->Description() ? nextEvent->Description() : ""));
stringTokens.insert(pair<string,string>("nexteventstart", *nextEvent->GetTimeString()));
stringTokens.insert(pair<string,string>("nexteventstop", *nextEvent->GetEndTimeString()));
stringTokens.insert(pair<string,string>("nexteventday", *WeekDayName(nextEvent->StartTime())));
stringTokens.insert(pair<string,string>("nexteventdate", *ShortDateString(nextEvent->StartTime())));
intTokens.insert(pair<string,int>("nexteventduration", nextEvent->Duration() / 60));
inserted = true;
}
}
if (!inserted) {
stringTokens.insert(pair<string,string>("nexteventtitle", ""));
stringTokens.insert(pair<string,string>("nexteventshorttext", ""));
stringTokens.insert(pair<string,string>("nexteventdescription", ""));
stringTokens.insert(pair<string,string>("nexteventstart", ""));
stringTokens.insert(pair<string,string>("nexteventstop", ""));
stringTokens.insert(pair<string,string>("nexteventday", ""));
stringTokens.insert(pair<string,string>("nexteventdate", ""));
intTokens.insert(pair<string,int>("nexteventduration", 0));
}
}
vector< map<string,string> > schedulesTokens;
ReadSchedules(&schedulesTokens);
map < string, vector< map< string, string > > > loopTokens;
loopTokens.insert(pair<string, vector< map< string, string > > >("schedule", schedulesTokens));
SetTokensPosMenuItem();
DrawViewElement(veMenuCurrentItemDetail, &stringTokens, &intTokens, &loopTokens);
}
void cDisplayMenuItemCurrentChannelView::Clear(void) {
}
void cDisplayMenuItemCurrentChannelView::Action(void) {
SetInitFinished();
DoSleep(delay);
Render();
FadeIn();
DoFlush();
if (scrolling) {
DoSleep(scrollDelay);
if (scrollOrientation == orHorizontal) {
ScrollHorizontal(scrollingPix, scrollDelay, scrollSpeed, scrollMode);
} else {
ScrollVertical(scrollingPix, scrollDelay, scrollSpeed);
}
}
}
void cDisplayMenuItemCurrentChannelView::ReadSchedules(vector< map<string,string> > *schedulesTokens) {
cSchedulesLock schedulesLock;
const cSchedules *schedules = cSchedules::Schedules(schedulesLock);
const cSchedule *schedule = NULL;
schedule = schedules->GetSchedule(channel);
if (!schedule) {
return;
}
const cEvent *curEvent = schedule->GetPresentEvent();
int num = 0;
for (; curEvent; curEvent = schedule->Events()->Next(curEvent)) {
if (num < 2) {
num++;
continue;
}
map<string,string> element;
element.insert(pair<string,string>("schedule[start]", *(curEvent->GetTimeString())));
element.insert(pair<string,string>("schedule[stop]", *(curEvent->GetEndTimeString())));
element.insert(pair<string,string>("schedule[title]", curEvent->Title() ? curEvent->Title() : ""));
element.insert(pair<string,string>("schedule[shorttext]", curEvent->ShortText() ? curEvent->ShortText() : ""));
schedulesTokens->push_back(element);
num++;
if (num > 11)
break;
}
}
/*************************************************************
* cDisplayMenuItemCurrentTimerView
*************************************************************/
cDisplayMenuItemCurrentTimerView::cDisplayMenuItemCurrentTimerView(cTemplateViewElement *tmplCurrent, const cTimer *timer)
: cDisplayMenuItemCurrentView(tmplCurrent) {
this->timer = timer;
}
cDisplayMenuItemCurrentTimerView::~cDisplayMenuItemCurrentTimerView() {
}
void cDisplayMenuItemCurrentTimerView::Prepare(void) {
}
void cDisplayMenuItemCurrentTimerView::Render(void) {
if (!timer)
return;
intTokens.insert(pair<string,int>("flagactive", timer->HasFlags(tfActive)));
intTokens.insert(pair<string,int>("flaginstant", timer->HasFlags(tfInstant)));
intTokens.insert(pair<string,int>("flagvps", timer->HasFlags(tfVps)));
intTokens.insert(pair<string,int>("flagrecording", timer->Recording()));
intTokens.insert(pair<string,int>("flagpending", timer->Pending()));
const char *file = Setup.FoldersInTimerMenu ? NULL : strrchr(timer->File(), FOLDERDELIMCHAR);
if (file && strcmp(file + 1, TIMERMACRO_TITLE) && strcmp(file + 1, TIMERMACRO_EPISODE))
file++;
else
file = timer->File();
stringTokens.insert(pair<string,string>("title", file));
stringTokens.insert(pair<string,string>("timerstart", *cString::sprintf("%02d:%02d", timer->Start() / 100, timer->Start() % 100)));
stringTokens.insert(pair<string,string>("timerstop", *cString::sprintf("%02d:%02d", timer->Stop() / 100, timer->Stop() % 100)));
string day = "";
string dayName = "";
if (timer->WeekDays())
day = timer->PrintDay(0, timer->WeekDays(), false);
else if (timer->Day() - time(NULL) < 28 * SECSINDAY) {
day = itoa(timer->GetMDay(timer->Day()));
dayName = WeekDayName(timer->Day());
} else {
struct tm tm_r;
time_t Day = timer->Day();
localtime_r(&Day, &tm_r);
char buffer[16];
strftime(buffer, sizeof(buffer), "%Y%m%d", &tm_r);
day = buffer;
}
stringTokens.insert(pair<string,string>("day", day));
stringTokens.insert(pair<string,string>("dayname", dayName));
const cChannel *channel = timer->Channel();
if (channel) {
stringTokens.insert(pair<string,string>("channelname", channel->Name() ? channel->Name() : ""));
stringTokens.insert(pair<string,string>("channelid", *(channel->GetChannelID().ToString())));
intTokens.insert(pair<string,int>("channelnumber", channel->Number()));
} else {
stringTokens.insert(pair<string,string>("channelname", ""));
stringTokens.insert(pair<string,string>("channelid", ""));
intTokens.insert(pair<string,int>("channelnumber", 0));
}
const cEvent *event = timer->Event();
if (event) {
stringTokens.insert(pair<string,string>("eventtitle", event->Title() ? event->Title() : ""));
stringTokens.insert(pair<string,string>("eventstart", *event->GetTimeString()));
stringTokens.insert(pair<string,string>("eventstop", *event->GetEndTimeString()));
stringTokens.insert(pair<string,string>("eventshorttext", event->ShortText() ? event->ShortText() : ""));
stringTokens.insert(pair<string,string>("eventdescription", event->Description() ? event->Description() : ""));
SetScraperPoster(event);
} else {
stringTokens.insert(pair<string,string>("eventtitle", ""));
stringTokens.insert(pair<string,string>("eventtitle", ""));
stringTokens.insert(pair<string,string>("eventstop", ""));
stringTokens.insert(pair<string,string>("eventshorttext", ""));
stringTokens.insert(pair<string,string>("eventdescription", ""));
}
SetTokensPosMenuItem();
DrawViewElement(veMenuCurrentItemDetail, &stringTokens, &intTokens);
}
void cDisplayMenuItemCurrentTimerView::Clear(void) {
}
void cDisplayMenuItemCurrentTimerView::Action(void) {
SetInitFinished();
DoSleep(delay);
Render();
FadeIn();
DoFlush();
if (scrolling) {
DoSleep(scrollDelay);
if (scrollOrientation == orHorizontal) {
ScrollHorizontal(scrollingPix, scrollDelay, scrollSpeed, scrollMode);
} else {
ScrollVertical(scrollingPix, scrollDelay, scrollSpeed);
}
}
}
/*************************************************************
* cDisplayMenuItemCurrentRecordingView
*************************************************************/
cDisplayMenuItemCurrentRecordingView::cDisplayMenuItemCurrentRecordingView(cTemplateViewElement *tmplCurrent, const cRecording *recording, int level, int total, int newRecs)
: cDisplayMenuItemCurrentView(tmplCurrent) {
this->recording = recording;
this->level = level;
this->total = total;
this->newRecs = newRecs;
}
cDisplayMenuItemCurrentRecordingView::~cDisplayMenuItemCurrentRecordingView() {
}
void cDisplayMenuItemCurrentRecordingView::Prepare(void) {
}
void cDisplayMenuItemCurrentRecordingView::Render(void) {
if (!recording)
return;
bool isFolder = (total > 0) ? true : false;
intTokens.insert(pair<string,int>("folder", isFolder));
string name = recording->Name() ? recording->Name() : "";
string buffer = "";
try {
vector<string> tokens;
istringstream f(name.c_str());
string s;
while (getline(f, s, FOLDERDELIMCHAR)) {
tokens.push_back(s);
}
buffer = tokens.at(level);
if (!isFolder && recording->IsEdited()) {
buffer = buffer.substr(1);
}
} catch (...) {
buffer = name.c_str();
}
stringTokens.insert(pair<string,string>("name", buffer.c_str()));
intTokens.insert(pair<string,int>("new", recording->IsNew()));
intTokens.insert(pair<string,int>("newrecordingsfolder", newRecs));
intTokens.insert(pair<string,int>("numrecordingsfolder", total));
intTokens.insert(pair<string,int>("cutted", recording->IsEdited()));
SetScraperPoster(NULL, recording);
const cRecordingInfo *info = recording->Info();
if (!info) return;
stringTokens.insert(pair<string,string>("shorttext", info->ShortText() ? info->ShortText() : ""));
stringTokens.insert(pair<string,string>("description", info->Description() ? info->Description() : ""));
const cEvent *event = info->GetEvent();
if (!event) return;
string recDate = *(event->GetDateString());
string recTime = *(event->GetTimeString());
if (recDate.find("1970") != string::npos) {
time_t start = recording->Start();
recDate = *DateString(start);
recTime = *TimeString(start);
}
int duration = event->Duration() / 60;
int recDuration = recording->LengthInSeconds();
recDuration = (recDuration>0)?(recDuration / 60):0;
stringTokens.insert(pair<string,string>("date", recDate.c_str()));
stringTokens.insert(pair<string,string>("time", recTime.c_str()));
intTokens.insert(pair<string,int>("duration", recDuration));
intTokens.insert(pair<string,int>("durationevent", duration));
SetTokensPosMenuItem();
DrawViewElement(veMenuCurrentItemDetail, &stringTokens, &intTokens);
}
void cDisplayMenuItemCurrentRecordingView::Clear(void) {
}
void cDisplayMenuItemCurrentRecordingView::Action(void) {
SetInitFinished();
DoSleep(delay);
Render();
FadeIn();
DoFlush();
if (scrolling) {
DoSleep(scrollDelay);
if (scrollOrientation == orHorizontal) {
ScrollHorizontal(scrollingPix, scrollDelay, scrollSpeed, scrollMode);
} else {
ScrollVertical(scrollingPix, scrollDelay, scrollSpeed);
}
}
}

View File

@@ -0,0 +1,94 @@
#ifndef __DISPLAYMENUITEMCURRENTVIEW_H
#define __DISPLAYMENUITEMCURRENTVIEW_H
#include "../libtemplate/template.h"
#include "view.h"
class cDisplayMenuItemCurrentView : public cView {
private:
protected:
int delay;
map < string, string > stringTokens;
map < string, int > intTokens;
cRect posMenuItem;
void SetTokensPosMenuItem(void);
void SetScraperPoster(const cEvent *event, const cRecording *recording=NULL);
public:
cDisplayMenuItemCurrentView(cTemplateViewElement *tmplCurrent);
virtual ~cDisplayMenuItemCurrentView();
void SetPosMenuItem(cRect &pos);
virtual void Prepare(void) {};
virtual void Render(void) {};
virtual void Clear(void) {};
};
class cDisplayMenuItemCurrentMainView: public cDisplayMenuItemCurrentView {
private:
string number;
string label;
string icon;
void Action(void);
public:
cDisplayMenuItemCurrentMainView(cTemplateViewElement *tmplCurrent, string number, string label, string icon);
virtual ~cDisplayMenuItemCurrentMainView();
void Prepare(void);
void Render(void);
void Clear(void);
};
class cDisplayMenuItemCurrentSchedulesView: public cDisplayMenuItemCurrentView {
private:
const cEvent *event;
const cChannel *channel;
eTimerMatch timerMatch;
eMenuCategory cat;
void Action(void);
void ReadSchedules(vector< map<string,string> > *schedulesTokens);
public:
cDisplayMenuItemCurrentSchedulesView(cTemplateViewElement *tmplCurrent, const cEvent *event, const cChannel *channel, eTimerMatch timerMatch, eMenuCategory cat);
virtual ~cDisplayMenuItemCurrentSchedulesView();
void Prepare(void);
void Render(void);
void Clear(void);
};
class cDisplayMenuItemCurrentChannelView: public cDisplayMenuItemCurrentView {
private:
const cChannel *channel;
void Action(void);
void ReadSchedules(vector< map<string,string> > *schedulesTokens);
public:
cDisplayMenuItemCurrentChannelView(cTemplateViewElement *tmplCurrent, const cChannel *channel);
virtual ~cDisplayMenuItemCurrentChannelView();
void Prepare(void);
void Render(void);
void Clear(void);
};
class cDisplayMenuItemCurrentTimerView: public cDisplayMenuItemCurrentView {
private:
const cTimer *timer;
void Action(void);
public:
cDisplayMenuItemCurrentTimerView(cTemplateViewElement *tmplCurrent, const cTimer *timer);
virtual ~cDisplayMenuItemCurrentTimerView();
void Prepare(void);
void Render(void);
void Clear(void);
};
class cDisplayMenuItemCurrentRecordingView: public cDisplayMenuItemCurrentView {
private:
const cRecording *recording;
int level;
int total;
int newRecs;
void Action(void);
public:
cDisplayMenuItemCurrentRecordingView(cTemplateViewElement *tmplCurrent, const cRecording *recording, int level, int total, int newRecs);
virtual ~cDisplayMenuItemCurrentRecordingView();
void Prepare(void);
void Render(void);
void Clear(void);
};
#endif //__DISPLAYMENUITEMCURRENTVIEW_H

731
views/displaymenuitemview.c Normal file
View File

@@ -0,0 +1,731 @@
#include "displaymenuitemview.h"
#include "../services/scraper2vdr.h"
#include "../config.h"
#include "../libcore/helpers.h"
#include <sstream>
#include <algorithm>
/*************************************************************
* cDisplayMenuItemView
*************************************************************/
cDisplayMenuItemView::cDisplayMenuItemView(cTemplateViewList *tmplList, bool current, bool selectable) : cViewListItem(tmplList->GetListElement()) {
this->tmplList = tmplList;
this->current = current;
this->selectable = selectable;
itemInit = true;
dirty = true;
num = 0;
currentView = NULL;
}
cDisplayMenuItemView::~cDisplayMenuItemView() {
if (currentView)
delete currentView;
CancelSave();
}
void cDisplayMenuItemView::SetCurrent(bool cur) {
current = cur;
intTokens.erase("current");
intTokens.insert(pair<string,int>("current", current));
dirty = true;
};
void cDisplayMenuItemView::ArrangeContainer(void) {
if (pos > -1)
return;
SetInitFinished();
pos = num;
numTotal = tmplList->GetNumericParameter(ptNumElements);
container.SetX(tmplList->GetNumericParameter(ptX));
container.SetY(tmplList->GetNumericParameter(ptY));
container.SetWidth(tmplList->GetNumericParameter(ptWidth));
container.SetHeight(tmplList->GetNumericParameter(ptHeight));
align = tmplList->GetNumericParameter(ptAlign);
listOrientation = tmplList->GetNumericParameter(ptOrientation);
}
void cDisplayMenuItemView::Clear(void) {
ClearListItem();
if (currentView) {
delete currentView;
currentView = NULL;
}
}
void cDisplayMenuItemView::PrepareScrolling(void) {
currentlyScrolling = true;
ClearListItem();
DrawListItem(&stringTokens, &intTokens);
}
void cDisplayMenuItemView::EndScrolling(void) {
const cPoint p(0,0);
SetDrawPortPoint(scrollingPix, p);
currentlyScrolling = false;
ClearListItem();
DrawListItem(&stringTokens, &intTokens);
}
void cDisplayMenuItemView::Action(void) {
if (scrolling) {
DoSleep(scrollDelay);
PrepareScrolling();
if (scrollOrientation == orHorizontal) {
ScrollHorizontal(scrollingPix, scrollDelay, scrollSpeed, scrollMode);
} else {
ScrollVertical(scrollingPix, scrollDelay, scrollSpeed);
}
}
}
void cDisplayMenuItemView::Stop(void) {
if (Running()) {
CancelSave();
EndScrolling();
}
}
void cDisplayMenuItemView::Debug(void) {
esyslog("skindesigner: current %d, selectable %d", current, selectable);
esyslog("skindesigner: pos %d, numTotal %d", pos, numTotal);
esyslog("skindesigner: container x = %d, y = %d, width = %d, height = %d", container.X(), container.Y(), container.Width(), container.Height());
}
/*************************************************************
* cDisplayMenuItemDefaultView
*************************************************************/
cDisplayMenuItemDefaultView::cDisplayMenuItemDefaultView(cTemplateViewList *tmplList, string *tabTexts, int *tabs, int *tabWidths, bool current, bool selectable)
: cDisplayMenuItemView(tmplList, current, selectable) {
this->tabTexts = tabTexts;
this->tabs = tabs;
this->tabWidths = tabWidths;
maxTabs = cSkinDisplayMenu::MaxTabs;
}
cDisplayMenuItemDefaultView::~cDisplayMenuItemDefaultView() {
delete[] tabTexts;
}
void cDisplayMenuItemDefaultView::SetTabTexts(string *tabTexts) {
delete[] this->tabTexts;
this->tabTexts = tabTexts;
}
void cDisplayMenuItemDefaultView::SetTokens(void) {
stringTokens.clear();
intTokens.clear();
for (int i=0; i<maxTabs; i++) {
stringstream name;
name << "column" << (i+1);
stringstream nameUsed;
nameUsed << name.str() << "set";
stringstream nameX;
nameX << name.str() << "x";
stringstream nameWidth;
nameWidth << name.str() << "width";
stringTokens.insert(pair<string,string>(name.str(), tabTexts[i]));
if (i>0)
intTokens.insert(pair<string,int>(nameUsed.str(), (tabTexts[i].size() > 0) ? 1 : 0 ));
intTokens.insert(pair<string,int>(nameX.str(), tabs[i]));
intTokens.insert(pair<string,int>(nameWidth.str(), tabWidths[i]));
}
intTokens.insert(pair<string,int>("current", current));
intTokens.insert(pair<string,int>("separator", !selectable));
}
void cDisplayMenuItemDefaultView::Prepare(void) {
ArrangeContainer();
}
void cDisplayMenuItemDefaultView::Render(void) {
DrawListItem(&stringTokens, &intTokens);
dirty = false;
}
void cDisplayMenuItemDefaultView::Debug(void) {
esyslog("skindesigner: Default Menu Item ---------------");
cDisplayMenuItemView::Debug();
for (int i=0; i<maxTabs; i++) {
esyslog("skindesigner: tab %d: text: %s, x: %d", i, tabTexts[i].c_str(), tabs[i]);
}
}
/*************************************************************
* Private Functions
*************************************************************/
/*************************************************************
* cDisplayMenuItemMainView
*************************************************************/
cDisplayMenuItemMainView::cDisplayMenuItemMainView(cTemplateViewList *tmplList, string itemText, bool current, bool selectable)
: cDisplayMenuItemView(tmplList, current, selectable) {
text = itemText;
number = "";
label = "";
icon = "";
}
cDisplayMenuItemMainView::~cDisplayMenuItemMainView() {
}
void cDisplayMenuItemMainView::SetTokens(void) {
if (!itemInit)
return;
itemInit = false;
stringTokens.insert(pair<string,string>("number", number));
stringTokens.insert(pair<string,string>("label", label));
stringTokens.insert(pair<string,string>("icon", icon));
intTokens.insert(pair<string,int>("current", current));
intTokens.insert(pair<string,int>("separator", !selectable));
}
void cDisplayMenuItemMainView::Prepare(void) {
ArrangeContainer();
SplitMenuText();
icon = imgCache->GetIconName(label);
}
void cDisplayMenuItemMainView::Render(void) {
cRect pos = DrawListItem(&stringTokens, &intTokens);
if (current) {
cTemplateViewElement *tmplCurrent = tmplList->GetListElementCurrent();
if (tmplCurrent) {
currentView = new cDisplayMenuItemCurrentMainView(tmplCurrent, number, label, icon);
currentView->SetPosMenuItem(pos);
currentView->Start();
}
}
dirty = false;
}
void cDisplayMenuItemMainView::Debug(void) {
esyslog("skindesigner: Main Menu Item ---------------");
cDisplayMenuItemView::Debug();
esyslog("skindesigner: item Text: %s", text.c_str());
esyslog("skindesigner: item Number: %s, Label: %s", number.c_str(), label.c_str());
esyslog("skindesigner: Icon: %s", icon.c_str());
}
/*************************************************************
* Private Functions
*************************************************************/
void cDisplayMenuItemMainView::SplitMenuText(void) {
string textPlain = skipspace(text.c_str());
bool found = false;
bool doBreak = false;
size_t i = 0;
for (; i < textPlain.length(); i++) {
char s = textPlain.at(i);
if (i==0) {
//if text directly starts with nonnumeric, break
if (!(s >= '0' && s <= '9')) {
break;
}
}
if (found) {
if (!(s >= '0' && s <= '9')) {
doBreak = true;
}
}
if (s >= '0' && s <= '9') {
found = true;
}
if (doBreak)
break;
if (i>4)
break;
}
if (found) {
number = skipspace(textPlain.substr(0,i).c_str());
label = skipspace(textPlain.substr(i).c_str());
} else {
number = "";
label = textPlain.c_str();
}
}
/*************************************************************
* cDisplayMenuItemSchedulesView
*************************************************************/
cDisplayMenuItemSchedulesView::cDisplayMenuItemSchedulesView(cTemplateViewList *tmplList, const cEvent *event,
const cChannel *channel, eTimerMatch timerMatch,
eMenuCategory cat, bool current, bool selectable)
: cDisplayMenuItemView(tmplList, current, selectable) {
this->event = event;
this->channel = channel;
this->timerMatch = timerMatch;
this->cat = cat;
}
cDisplayMenuItemSchedulesView::~cDisplayMenuItemSchedulesView() {
}
void cDisplayMenuItemSchedulesView::SetTokens(void) {
if (!itemInit)
return;
itemInit = false;
intTokens.insert(pair<string,int>("current", current));
intTokens.insert(pair<string,int>("separator", !selectable));
intTokens.insert(pair<string,int>("whatson", (cat == mcSchedule) ? true: false));
intTokens.insert(pair<string,int>("whatsonnow", (cat == mcScheduleNow) ? true: false));
intTokens.insert(pair<string,int>("whatsonnext", (cat == mcScheduleNext) ? true: false));
if (timerMatch == tmFull) {
intTokens.insert(pair<string,int>("timerpartitial", false));
intTokens.insert(pair<string,int>("timerfull", true));
} else if (timerMatch == tmPartial) {
intTokens.insert(pair<string,int>("timerpartitial", true));
intTokens.insert(pair<string,int>("timerfull", false));
} else {
intTokens.insert(pair<string,int>("timerpartitial", false));
intTokens.insert(pair<string,int>("timerfull", false));
}
if (event) {
if (selectable) {
stringTokens.insert(pair<string,string>("title", event->Title() ? event->Title() : ""));
stringTokens.insert(pair<string,string>("shorttext", event->ShortText() ? event->ShortText() : ""));
stringTokens.insert(pair<string,string>("start", *(event->GetTimeString())));
stringTokens.insert(pair<string,string>("stop", *(event->GetEndTimeString())));
stringTokens.insert(pair<string,string>("day", *WeekDayName(event->StartTime())));
stringTokens.insert(pair<string,string>("date", *ShortDateString(event->StartTime())));
bool isRunning = false;
time_t now = time(NULL);
if ((now >= event->StartTime()) && (now <= event->EndTime()))
isRunning = true;
intTokens.insert(pair<string,int>("running", isRunning));
if (isRunning) {
intTokens.insert(pair<string,int>("elapsed", (now - event->StartTime())/60));
} else {
intTokens.insert(pair<string,int>("elapsed", 0));
}
intTokens.insert(pair<string,int>("duration", event->Duration() / 60));
} else {
stringTokens.insert(pair<string,string>("title", event->Title() ? ParseSeparator(event->Title()) : ""));
}
}
if (channel) {
stringTokens.insert(pair<string,string>("channelid", *(channel->GetChannelID().ToString())));
if (!event && !selectable) {
stringTokens.insert(pair<string,string>("title", channel->Name() ? ParseSeparator(channel->Name()) : ""));
}
}
}
void cDisplayMenuItemSchedulesView::Prepare(void) {
ArrangeContainer();
}
void cDisplayMenuItemSchedulesView::Render(void) {
DrawListItem(&stringTokens, &intTokens);
if (current) {
cTemplateViewElement *tmplCurrent = tmplList->GetListElementCurrent();
if (tmplCurrent) {
currentView = new cDisplayMenuItemCurrentSchedulesView(tmplCurrent, event, channel, timerMatch, cat);
currentView->Start();
}
}
dirty = false;
}
void cDisplayMenuItemSchedulesView::Debug(void) {
esyslog("skindesigner: Schedules Menu Item ---------------");
cDisplayMenuItemView::Debug();
esyslog("skindesigner: Event: %s", event ? event->Title() : "Event is NULL");
}
/*************************************************************
* Private Functions
*************************************************************/
string cDisplayMenuItemSchedulesView::ParseSeparator(string sep) {
string separator = sep;
try {
if (separator.find_first_not_of("-") > 0)
separator.erase(0, separator.find_first_not_of("-")+1);
if (separator.find_last_not_of("-") != string::npos)
separator.erase(separator.find_last_not_of("-")+1);
} catch (...) {}
return separator;
}
/*************************************************************
* cDisplayMenuItemChannelsView
*************************************************************/
cDisplayMenuItemChannelsView::cDisplayMenuItemChannelsView(cTemplateViewList *tmplList, const cChannel *channel,
bool withProvider, bool current, bool selectable)
: cDisplayMenuItemView(tmplList, current, selectable) {
this->channel = channel;
this->withProvider = withProvider;
}
cDisplayMenuItemChannelsView::~cDisplayMenuItemChannelsView() {
}
void cDisplayMenuItemChannelsView::SetTokens(void) {
if (!itemInit)
return;
itemInit = false;
if (!channel)
return;
//general channel information
intTokens.insert(pair<string,int>("current", current));
intTokens.insert(pair<string,int>("separator", !selectable));
intTokens.insert(pair<string,int>("number", channel->Number()));
intTokens.insert(pair<string,int>("transponder", channel->Transponder()));
intTokens.insert(pair<string,int>("frequency", channel->Frequency()));
stringTokens.insert(pair<string,string>("name", channel->Name() ? channel->Name() : ""));
stringTokens.insert(pair<string,string>("channelid", *(channel->GetChannelID().ToString())));
//Channel Source Information
const cSource *source = Sources.Get(channel->Source());
if (source) {
stringTokens.insert(pair<string,string>("source", *cSource::ToString(source->Code())));
stringTokens.insert(pair<string,string>("sourcedescription", source->Description() ? source->Description() : ""));
stringTokens.insert(pair<string,string>("source", *cSource::ToString(source->Code())));
intTokens.insert(pair<string,int>("isAtsc", source->IsAtsc(source->Code())));
intTokens.insert(pair<string,int>("isCable", source->IsCable(source->Code())));
intTokens.insert(pair<string,int>("isSat", source->IsSat(source->Code())));
intTokens.insert(pair<string,int>("isTerr", source->IsTerr(source->Code())));
}
//current schedule
cSchedulesLock schedulesLock;
const cSchedules *schedules = cSchedules::Schedules(schedulesLock);
const cSchedule *schedule = NULL;
schedule = schedules->GetSchedule(channel);
bool inserted = false;
if (schedule) {
const cEvent *presentEvent = schedule->GetPresentEvent();
if (presentEvent) {
stringTokens.insert(pair<string,string>("presenteventtitle", presentEvent->Title() ? presentEvent->Title() : ""));
stringTokens.insert(pair<string,string>("presenteventstart", *presentEvent->GetTimeString()));
stringTokens.insert(pair<string,string>("presenteventstop", *presentEvent->GetEndTimeString()));
inserted = true;
}
}
if (!inserted) {
stringTokens.insert(pair<string,string>("presenteventtitle", ""));
stringTokens.insert(pair<string,string>("presenteventstart", ""));
stringTokens.insert(pair<string,string>("presenteventstop", ""));
}
}
void cDisplayMenuItemChannelsView::Prepare(void) {
ArrangeContainer();
}
void cDisplayMenuItemChannelsView::Render(void) {
DrawListItem(&stringTokens, &intTokens);
if (current) {
cTemplateViewElement *tmplCurrent = tmplList->GetListElementCurrent();
if (tmplCurrent) {
currentView = new cDisplayMenuItemCurrentChannelView(tmplCurrent, channel);
currentView->Start();
}
}
dirty = false;
}
void cDisplayMenuItemChannelsView::Debug(void) {
esyslog("skindesigner: Channels Menu Item ---------------");
cDisplayMenuItemView::Debug();
esyslog("skindesigner: Channel: %s", channel ? channel->Name() : "Channel is NULL");
}
/*************************************************************
* Private Functions
*************************************************************/
/*************************************************************
* cDisplayMenuItemTimersView
*************************************************************/
cDisplayMenuItemTimersView::cDisplayMenuItemTimersView(cTemplateViewList *tmplList, const cTimer *timer, bool current, bool selectable)
: cDisplayMenuItemView(tmplList, current, selectable) {
this->timer = timer;
}
cDisplayMenuItemTimersView::~cDisplayMenuItemTimersView() {
}
void cDisplayMenuItemTimersView::SetTokens(void) {
if (!timer)
return;
if (!itemInit) {
intTokens.erase("flagactive");
intTokens.insert(pair<string,int>("flagactive", timer->HasFlags(tfActive)));
return;
}
itemInit = false;
intTokens.insert(pair<string,int>("current", current));
intTokens.insert(pair<string,int>("flagactive", timer->HasFlags(tfActive)));
intTokens.insert(pair<string,int>("flaginstant", timer->HasFlags(tfInstant)));
intTokens.insert(pair<string,int>("flagvps", timer->HasFlags(tfVps)));
intTokens.insert(pair<string,int>("flagrecording", timer->Recording()));
intTokens.insert(pair<string,int>("flagpending", timer->Pending()));
const char *file = Setup.FoldersInTimerMenu ? NULL : strrchr(timer->File(), FOLDERDELIMCHAR);
if (file && strcmp(file + 1, TIMERMACRO_TITLE) && strcmp(file + 1, TIMERMACRO_EPISODE))
file++;
else
file = timer->File();
stringTokens.insert(pair<string,string>("title", file));
stringTokens.insert(pair<string,string>("timerstart", *cString::sprintf("%02d:%02d", timer->Start() / 100, timer->Start() % 100)));
stringTokens.insert(pair<string,string>("timerstop", *cString::sprintf("%02d:%02d", timer->Stop() / 100, timer->Stop() % 100)));
string day = "";
string dayName = "";
if (timer->WeekDays())
day = timer->PrintDay(0, timer->WeekDays(), false);
else if (timer->Day() - time(NULL) < 28 * SECSINDAY) {
day = itoa(timer->GetMDay(timer->Day()));
dayName = WeekDayName(timer->Day());
} else {
struct tm tm_r;
time_t Day = timer->Day();
localtime_r(&Day, &tm_r);
char buffer[16];
strftime(buffer, sizeof(buffer), "%Y%m%d", &tm_r);
day = buffer;
}
stringTokens.insert(pair<string,string>("day", day));
stringTokens.insert(pair<string,string>("dayname", dayName));
const cChannel *channel = timer->Channel();
if (channel) {
stringTokens.insert(pair<string,string>("channelname", channel->Name() ? channel->Name() : ""));
stringTokens.insert(pair<string,string>("channelid", *(channel->GetChannelID().ToString())));
intTokens.insert(pair<string,int>("channelnumber", channel->Number()));
} else {
stringTokens.insert(pair<string,string>("channelname", ""));
stringTokens.insert(pair<string,string>("channelid", ""));
intTokens.insert(pair<string,int>("channelnumber", 0));
}
const cEvent *event = timer->Event();
if (event) {
stringTokens.insert(pair<string,string>("eventtitle", event->Title() ? event->Title() : ""));
stringTokens.insert(pair<string,string>("eventstart", *event->GetTimeString()));
stringTokens.insert(pair<string,string>("eventstop", *event->GetEndTimeString()));
} else {
stringTokens.insert(pair<string,string>("eventtitle", ""));
stringTokens.insert(pair<string,string>("eventtitle", ""));
stringTokens.insert(pair<string,string>("eventstop", ""));
}
}
void cDisplayMenuItemTimersView::Prepare(void) {
ArrangeContainer();
}
void cDisplayMenuItemTimersView::Render(void) {
DrawListItem(&stringTokens, &intTokens);
if (current) {
cTemplateViewElement *tmplCurrent = tmplList->GetListElementCurrent();
if (tmplCurrent) {
currentView = new cDisplayMenuItemCurrentTimerView(tmplCurrent, timer);
currentView->Start();
}
}
dirty = false;
}
void cDisplayMenuItemTimersView::Debug(void) {
esyslog("skindesigner: Timers Menu Item ---------------");
cDisplayMenuItemView::Debug();
esyslog("skindesigner: Timer: %s", timer ? *(timer->ToDescr()) : "Timer is NULL");
}
/*************************************************************
* Private Functions
*************************************************************/
/*************************************************************
* cDisplayMenuItemRecordingView
*************************************************************/
cDisplayMenuItemRecordingView::cDisplayMenuItemRecordingView(cTemplateViewList *tmplList, const cRecording *recording, int level, int total, int newRecs, bool current, bool selectable)
: cDisplayMenuItemView(tmplList, current, selectable) {
this->recording = recording;
this->level = level;
this->total = total;
this->newRecs = newRecs;
}
cDisplayMenuItemRecordingView::~cDisplayMenuItemRecordingView() {
}
void cDisplayMenuItemRecordingView::SetTokens(void) {
if (!itemInit) return;
itemInit = false;
if (!recording) return;
intTokens.insert(pair<string,int>("current", current));
bool isFolder = (total > 0) ? true : false;
intTokens.insert(pair<string,int>("folder", isFolder));
string name = recording->Name() ? recording->Name() : "";
string buffer = "";
try {
vector<string> tokens;
istringstream f(name.c_str());
string s;
while (getline(f, s, FOLDERDELIMCHAR)) {
tokens.push_back(s);
}
buffer = tokens.at(level);
if (!isFolder && recording->IsEdited()) {
buffer = buffer.substr(1);
}
} catch (...) {
buffer = name.c_str();
}
stringTokens.insert(pair<string,string>("name", buffer.c_str()));
intTokens.insert(pair<string,int>("new", recording->IsNew()));
intTokens.insert(pair<string,int>("newrecordingsfolder", newRecs));
intTokens.insert(pair<string,int>("numrecordingsfolder", total));
intTokens.insert(pair<string,int>("cutted", recording->IsEdited()));
const cEvent *event = NULL;
const cRecordingInfo *info = recording->Info();
if (!info) return;
event = info->GetEvent();
if (!event) return;
string recDate = *(event->GetDateString());
string recTime = *(event->GetTimeString());
if (recDate.find("1970") != string::npos) {
time_t start = recording->Start();
recDate = *DateString(start);
recTime = *TimeString(start);
}
int duration = event->Duration() / 60;
int recDuration = recording->LengthInSeconds();
recDuration = (recDuration>0)?(recDuration / 60):0;
stringTokens.insert(pair<string,string>("date", recDate.c_str()));
stringTokens.insert(pair<string,string>("time", recTime.c_str()));
intTokens.insert(pair<string,int>("duration", recDuration));
intTokens.insert(pair<string,int>("durationevent", duration));
static cPlugin *pScraper = GetScraperPlugin();
if (!pScraper || !recording) {
intTokens.insert(pair<string,int>("hasposterthumbnail", false));
intTokens.insert(pair<string,int>("thumbnailbwidth", -1));
intTokens.insert(pair<string,int>("thumbnailheight", -1));
stringTokens.insert(pair<string,string>("thumbnailpath", ""));
return;
}
ScraperGetPosterThumb call;
call.event = NULL;
call.recording = recording;
if (pScraper->Service("GetPosterThumb", &call)) {
intTokens.insert(pair<string,int>("hasposterthumbnail", true));
intTokens.insert(pair<string,int>("thumbnailbwidth", call.poster.width));
intTokens.insert(pair<string,int>("thumbnailheight", call.poster.height));
stringTokens.insert(pair<string,string>("thumbnailpath", call.poster.path));
} else {
intTokens.insert(pair<string,int>("hasposterthumbnail", false));
intTokens.insert(pair<string,int>("thumbnailbwidth", -1));
intTokens.insert(pair<string,int>("thumbnailheight", -1));
stringTokens.insert(pair<string,string>("thumbnailpath", ""));
}
}
void cDisplayMenuItemRecordingView::Prepare(void) {
ArrangeContainer();
}
void cDisplayMenuItemRecordingView::Render(void) {
DrawListItem(&stringTokens, &intTokens);
if (current) {
cTemplateViewElement *tmplCurrent = tmplList->GetListElementCurrent();
if (tmplCurrent) {
currentView = new cDisplayMenuItemCurrentRecordingView(tmplCurrent, recording, level, total, newRecs);
currentView->Start();
}
}
dirty = false;
}
void cDisplayMenuItemRecordingView::Debug(void) {
esyslog("skindesigner: Recording Menu Item ---------------");
cDisplayMenuItemView::Debug();
esyslog("skindesigner: Recording: %s", recording ? recording->Title() : "Recording is NULL");
}
/*************************************************************
* cDisplayMenuItemTrackView
*************************************************************/
cDisplayMenuItemTrackView::cDisplayMenuItemTrackView(cTemplateViewList *tmplList, const char *title, bool current, bool selectable, int numTracks)
: cDisplayMenuItemView(tmplList, current, selectable) {
this->title = title;
this->numTracks = numTracks;
}
cDisplayMenuItemTrackView::~cDisplayMenuItemTrackView() {
}
void cDisplayMenuItemTrackView::SetTokens(void) {
if (!itemInit) return;
itemInit = false;
if (!title) return;
stringTokens.insert(pair<string,string>("title", title));
}
void cDisplayMenuItemTrackView::Prepare(void) {
ArrangeContainer();
}
void cDisplayMenuItemTrackView::Render(void) {
DrawListItem(&stringTokens, &intTokens);
dirty = false;
}
void cDisplayMenuItemTrackView::Debug(void) {
esyslog("skindesigner: Tracks Menu Item ---------------");
cDisplayMenuItemView::Debug();
esyslog("skindesigner: Title: %s", title);
}

141
views/displaymenuitemview.h Normal file
View File

@@ -0,0 +1,141 @@
#ifndef __DISPLAYMENUITEMVIEW_H
#define __DISPLAYMENUITEMVIEW_H
#include "../libtemplate/template.h"
#include "view.h"
#include "displaymenuitemcurrentview.h"
class cDisplayMenuItemView : public cViewListItem {
private:
protected:
bool itemInit;
bool dirty;
bool current;
bool selectable;
int num;
cTemplateViewList *tmplList;
map < string, string > stringTokens;
map < string, int > intTokens;
cDisplayMenuItemCurrentView *currentView;
virtual void Action(void);
public:
cDisplayMenuItemView(cTemplateViewList *tmplList, bool current, bool selectable);
virtual ~cDisplayMenuItemView();
void SetCurrent(bool cur);
void SetNumber(int n) { num = n; };
void ArrangeContainer(void);
bool Current(void) { return current; };
void PrepareScrolling(void);
void EndScrolling(void);
virtual void SetTokens(void) {};
virtual void Prepare(void) {};
virtual void Render(void) {};
virtual void Clear(void);
bool Dirty(void) { return dirty; };
void Stop(void);
virtual void Debug(void);
};
class cDisplayMenuItemDefaultView: public cDisplayMenuItemView {
private:
int *tabs;
int *tabWidths;
string *tabTexts;
int maxTabs;
public:
cDisplayMenuItemDefaultView(cTemplateViewList *tmplList, string *tabTexts, int *tabs, int *tabWidths, bool current, bool selectable);
virtual ~cDisplayMenuItemDefaultView();
void SetTabTexts(string *tabTexts);
void SetTokens(void);
void Prepare(void);
void Render(void);
void Debug(void);
};
class cDisplayMenuItemMainView: public cDisplayMenuItemView {
private:
string text;
string number;
string label;
string icon;
void SplitMenuText(void);
public:
cDisplayMenuItemMainView(cTemplateViewList *tmplList, string itemText, bool current, bool selectable);
virtual ~cDisplayMenuItemMainView();
void SetTokens(void);
void Prepare(void);
void Render(void);
void Debug(void);
};
class cDisplayMenuItemSchedulesView: public cDisplayMenuItemView {
private:
const cEvent *event;
const cChannel *channel;
eTimerMatch timerMatch;
eMenuCategory cat;
string ParseSeparator(string sep);
public:
cDisplayMenuItemSchedulesView(cTemplateViewList *tmplList, const cEvent *event, const cChannel *channel, eTimerMatch timerMatch,
eMenuCategory cat, bool current, bool selectable);
virtual ~cDisplayMenuItemSchedulesView();
void SetTokens(void);
void Prepare(void);
void Render(void);
void Debug(void);
};
class cDisplayMenuItemChannelsView: public cDisplayMenuItemView {
private:
const cChannel *channel;
bool withProvider;
public:
cDisplayMenuItemChannelsView(cTemplateViewList *tmplList, const cChannel *channel, bool withProvider, bool current, bool selectable);
virtual ~cDisplayMenuItemChannelsView();
void SetTokens(void);
void Prepare(void);
void Render(void);
void Debug(void);
};
class cDisplayMenuItemTimersView: public cDisplayMenuItemView {
private:
const cTimer *timer;
public:
cDisplayMenuItemTimersView(cTemplateViewList *tmplList, const cTimer *timer, bool current, bool selectable);
virtual ~cDisplayMenuItemTimersView();
void SetTokens(void);
void Prepare(void);
void Render(void);
void Debug(void);
};
class cDisplayMenuItemRecordingView: public cDisplayMenuItemView {
private:
const cRecording *recording;
int level;
int total;
int newRecs;
public:
cDisplayMenuItemRecordingView(cTemplateViewList *tmplList, const cRecording *recording, int level, int total, int newRecs, bool current, bool selectable);
virtual ~cDisplayMenuItemRecordingView();
void SetTokens(void);
void Prepare(void);
void Render(void);
void Debug(void);
};
class cDisplayMenuItemTrackView: public cDisplayMenuItemView {
private:
const char *title;
int numTracks;
public:
cDisplayMenuItemTrackView(cTemplateViewList *tmplList, const char *title, bool current, bool selectable, int numTracks);
virtual ~cDisplayMenuItemTrackView();
void SetTokens(void);
void Prepare(void);
void Render(void);
void Debug(void);
};
#endif //__DISPLAYMENUITEMVIEW_H

216
views/displaymenulistview.c Normal file
View File

@@ -0,0 +1,216 @@
#include <vdr/menu.h>
#include "displaymenulistview.h"
cDisplayMenuListView::cDisplayMenuListView(cTemplateViewList *tmplList, int count) {
oneColumn = true;
this->tmplList = tmplList;
if (count < 0) {
//if count is not set, the fixed number of items is configured in the template
itemCount = tmplList->GetNumericParameter(ptNumElements);
} else {
//else use the actual numbers of elements
itemCount = count;
map < string, int > intTokens;
intTokens.insert(pair<string,int>("numelements", count));
tmplList->CalculateListParameters(&intTokens);
}
menuItems = new cDisplayMenuItemView*[itemCount];
for (int i=0; i<itemCount; i++)
menuItems[i] = NULL;
tabs = new int[cSkinDisplayMenu::MaxTabs];
for (int i=0; i<cSkinDisplayMenu::MaxTabs; i++)
tabs[i] = 0;
tabWidths = new int[cSkinDisplayMenu::MaxTabs];
for (int i=0; i<cSkinDisplayMenu::MaxTabs; i++)
tabWidths[i] = 0;
}
cDisplayMenuListView::~cDisplayMenuListView() {
Clear();
delete[] menuItems;
delete[] tabs;
delete[] tabWidths;
}
void cDisplayMenuListView::SetTabs(int tab1, int tab2, int tab3, int tab4, int tab5) {
int menuItemWidth = 1920;
int averageFontWidth = 20;
if (tmplList) {
menuItemWidth = tmplList->GetMenuItemWidth();
averageFontWidth = tmplList->GetAverageFontWidth();
}
if (!tab1) {
tabs[0] = 0;
tabWidths[0] = menuItemWidth;
} else {
tabs[0] = 0;
if (!tab2) {
tabs[1] = menuItemWidth/2;
tabWidths[0] = tabs[1];
tabWidths[1] = tabs[1];
} else {
tabs[0] = 0;
tabs[1] = tab1 ? tabs[0] + tab1 : 0;
tabs[2] = tab2 ? tabs[1] + tab2 : 0;
tabs[3] = tab3 ? tabs[2] + tab3 : 0;
tabs[4] = tab4 ? tabs[3] + tab4 : 0;
tabs[5] = tab5 ? tabs[4] + tab5 : 0;
for (int i = 1; i < cSkinDisplayMenu::MaxTabs; i++)
tabs[i] *= averageFontWidth;
for (int i = 0; i < cSkinDisplayMenu::MaxTabs; i++) {
if (i == cSkinDisplayMenu::MaxTabs - 1) {
tabWidths[i] = menuItemWidth - tabs[i];
} else {
tabWidths[i] = tabs[i+1] - tabs[i];
}
}
}
}
}
int cDisplayMenuListView::GetListWidth(void) {
if (tmplList) {
return tmplList->GetMenuItemWidth();
}
return 1920;
}
void cDisplayMenuListView::Clear(void) {
for (int i=0; i<itemCount; i++) {
if (menuItems[i]) {
delete menuItems[i];
menuItems[i] = NULL;
}
}
oneColumn = true;
for (int i=0; i<cSkinDisplayMenu::MaxTabs; i++) {
tabs[i] = 0;
tabWidths[i] = 0;
}
}
void cDisplayMenuListView::AddDefaultMenuItem(int index, string *tabTexts, bool current, bool selectable) {
if (menuItems[index]) {
cDisplayMenuItemDefaultView *menuItem = dynamic_cast<cDisplayMenuItemDefaultView*>(menuItems[index]);
if (!menuItem)
return;
menuItem->SetCurrent(current);
menuItem->SetTabTexts(tabTexts);
return;
}
for (int i=1; i<cSkinDisplayMenu::MaxTabs; i++) {
if (tabTexts[i].size() > 0) {
oneColumn = false;
break;
}
}
cDisplayMenuItemView *item = new cDisplayMenuItemDefaultView(tmplList, tabTexts, tabs, tabWidths, current, selectable);
menuItems[index] = item;
}
void cDisplayMenuListView::AddMainMenuItem(int index, const char *itemText, bool current, bool selectable) {
if (menuItems[index]) {
menuItems[index]->SetCurrent(current);
return;
}
cDisplayMenuItemView *item = new cDisplayMenuItemMainView(tmplList, itemText, current, selectable);
menuItems[index] = item;
}
void cDisplayMenuListView::AddSetupMenuItem(int index, const char *itemText, bool current, bool selectable) {
if (menuItems[index]) {
menuItems[index]->SetCurrent(current);
return;
}
cDisplayMenuItemView *item = new cDisplayMenuItemMainView(tmplList, itemText, current, selectable);
menuItems[index] = item;
}
void cDisplayMenuListView::AddSchedulesMenuItem(int index, const cEvent *event, const cChannel *channel, eTimerMatch timerMatch,
eMenuCategory cat, bool current, bool selectable) {
if (menuItems[index]) {
menuItems[index]->SetCurrent(current);
return;
}
cDisplayMenuItemView *item = new cDisplayMenuItemSchedulesView(tmplList, event, channel, timerMatch, cat, current, selectable);
menuItems[index] = item;
}
void cDisplayMenuListView::AddChannelsMenuItem(int index, const cChannel *channel, bool withProvider, bool current, bool selectable) {
if (menuItems[index]) {
menuItems[index]->SetCurrent(current);
return;
}
cDisplayMenuItemView *item = new cDisplayMenuItemChannelsView(tmplList, channel, withProvider, current, selectable);
menuItems[index] = item;
}
void cDisplayMenuListView::AddTimersMenuItem(int index, const cTimer *timer, bool current, bool selectable) {
if (menuItems[index]) {
menuItems[index]->SetCurrent(current);
return;
}
cDisplayMenuItemView *item = new cDisplayMenuItemTimersView(tmplList, timer, current, selectable);
menuItems[index] = item;
}
void cDisplayMenuListView::AddRecordingMenuItem(int index, const cRecording *recording, int level, int total, int isNew, bool current, bool selectable) {
if (menuItems[index]) {
menuItems[index]->SetCurrent(current);
return;
}
cDisplayMenuItemView *item = new cDisplayMenuItemRecordingView(tmplList, recording, level, total, isNew, current, selectable);
menuItems[index] = item;
}
void cDisplayMenuListView::AddTracksMenuItem(int index, const char *title, bool current, bool selectable) {
if (menuItems[index]) {
menuItems[index]->SetCurrent(current);
return;
}
cDisplayMenuItemView *item = new cDisplayMenuItemTrackView(tmplList, title, current, selectable, itemCount);
menuItems[index] = item;
}
void cDisplayMenuListView::Render(void) {
if (tabs[1] && oneColumn) {
tabs[0] = 0;
tabWidths[0] = tmplList->GetMenuItemWidth();
for (int i=1; i<cSkinDisplayMenu::MaxTabs; i++) {
tabs[i] = 0;
tabWidths[i] = 0;
}
}
int current = -1;
for (int i=0; i<itemCount; i++) {
if (menuItems[i] && menuItems[i]->Dirty()) {
menuItems[i]->Clear();
menuItems[i]->SetNumber(i);
menuItems[i]->Prepare();
menuItems[i]->SetTokens();
menuItems[i]->Render();
if (menuItems[i]->Current()) {
current = i;
} else {
menuItems[i]->Stop();
}
}
}
if (current > -1) {
menuItems[current]->Start();
}
}
void cDisplayMenuListView::Debug(void) {
for (int i=0; i<itemCount; i++) {
esyslog("skindesigner: item %d", i);
if (menuItems[i]) {
menuItems[i]->Debug();
}
}
}

View File

@@ -0,0 +1,35 @@
#ifndef __DISPLAYMENULISTVIEW_H
#define __DISPLAYMENULISTVIEW_H
#include "../libtemplate/template.h"
#include "view.h"
#include "displaymenuitemview.h"
class cDisplayMenuListView {
private:
cTemplateViewList *tmplList;
int itemCount;
cDisplayMenuItemView **menuItems;
int *tabs;
int *tabWidths;
bool oneColumn;
public:
cDisplayMenuListView(cTemplateViewList *tmplList, int count = -1);
virtual ~cDisplayMenuListView();
void Clear(void);
void SetTabs(int tab1, int tab2, int tab3, int tab4, int tab5);
int GetMaxItems(void) { return itemCount; };
int GetListWidth(void);
void AddDefaultMenuItem(int index, string *tabTexts, bool current, bool selectable);
void AddMainMenuItem(int index, const char *itemText, bool current, bool selectable);
void AddSetupMenuItem(int index, const char *itemText, bool current, bool selectable);
void AddSchedulesMenuItem(int index, const cEvent *event, const cChannel *channel, eTimerMatch timerMatch, eMenuCategory cat, bool current, bool selectable);
void AddChannelsMenuItem(int index, const cChannel *channel, bool withProvider, bool current, bool selectable);
void AddTimersMenuItem(int index, const cTimer *timer, bool current, bool selectable);
void AddRecordingMenuItem(int index, const cRecording *recording, int level, int total, int isNew, bool current, bool selectable);
void AddTracksMenuItem(int index, const char *title, bool current, bool selectable);
void Render(void);
void Debug(void);
};
#endif //__DISPLAYMENULISTVIEW_H

495
views/displaymenurootview.c Normal file
View File

@@ -0,0 +1,495 @@
#define __STL_CONFIG_H
#include <vdr/menu.h>
#include "displaymenurootview.h"
#include "../config.h"
#include "../libcore/helpers.h"
cDisplayMenuRootView::cDisplayMenuRootView(cTemplateView *rootView) : cView(rootView) {
viewType = svUndefined;
subView = NULL;
subViewAvailable = false;
view = NULL;
listView = NULL;
detailView = NULL;
defaultBackgroundDrawn = false;
defaultHeaderDrawn = false;
defaultButtonsDrawn = false;
defaultDateTimeDrawn = false;
defaultMessageDrawn = false;
DeleteOsdOnExit();
SetFadeTime(tmplView->GetNumericParameter(ptFadeTime));
}
cDisplayMenuRootView::~cDisplayMenuRootView() {
if (view)
delete view;
if (listView)
delete listView;
if (detailView)
delete detailView;
}
/*******************************************************************
* Public Functions
*******************************************************************/
bool cDisplayMenuRootView::createOsd(void) {
cRect osdSize = tmplView->GetOsdSize();
bool ok = CreateOsd(cOsd::OsdLeft() + osdSize.X(),
cOsd::OsdTop() + osdSize.Y(),
osdSize.Width(),
osdSize.Height());
return ok;
}
/* Categories:
mcUndefined = -1,
mcUnknown = 0,
1 mcMain,
2 mcSchedule,
3 mcScheduleNow,
4 mcScheduleNext,
5 mcChannel,
6 mcChannelEdit,
7 mcTimer,
8 mcTimerEdit,
9 mcRecording,
10 mcRecordingInfo,
11 mcPlugin,
12 mcPluginSetup,
13 mcSetup,
14 mcSetupOsd,
15 mcSetupEpg,
16 mcSetupDvb,
17 mcSetupLnb,
18 mcSetupCam,
19 mcSetupRecord,
20 mcSetupReplay,
21 mcSetupMisc,
22 mcSetupPlugins,
23 mcCommand,
24 mcEvent,
25 mcText,
26 mcFolder,
27 mcCam
*/
void cDisplayMenuRootView::SetMenu(eMenuCategory menuCat, bool menuInit) {
eSubView newViewType = svUndefined;
bool isListView = true;
switch (menuCat) {
case mcMain:
newViewType = svMenuMain;
break;
case mcSetup:
newViewType = svMenuSetup;
break;
case mcSchedule:
case mcScheduleNow:
case mcScheduleNext:
newViewType = svMenuSchedules;
if (view)
view->SetMenuCat(menuCat);
break;
case mcChannel:
newViewType = svMenuChannels;
break;
case mcTimer:
newViewType = svMenuTimers;
break;
case mcRecording:
newViewType = svMenuRecordings;
break;
case mcEvent:
newViewType = svMenuDetailedEpg;
isListView = false;
break;
case mcRecordingInfo:
newViewType = svMenuDetailedRecording;
isListView = false;
break;
case mcText:
newViewType = svMenuDetailedText;
isListView = false;
break;
default:
newViewType = svMenuDefault;
break;
}
if (newViewType != viewType) {
subView = tmplView->GetSubView(newViewType);
if (!subView) {
subViewAvailable = false;
subView = tmplView->GetSubView(svMenuDefault);
} else {
subViewAvailable = true;
}
//Cleanup
if (view) {
delete view;
view = NULL;
}
if (listView) {
delete listView;
listView = NULL;
}
if (detailView) {
delete detailView;
detailView = NULL;
}
//Create new View
switch (newViewType) {
case svMenuMain:
view = new cDisplayMenuMainView(subView, menuInit);
break;
case svMenuSchedules:
if (subViewAvailable)
view = new cDisplayMenuSchedulesView(subView, menuCat, menuInit);
else
view = new cDisplayMenuView(subView, menuInit);
break;
default:
view = new cDisplayMenuView(subView, menuInit);
}
//Cleanup root view
ClearRootView();
if (isListView) {
//Create menu item list
cTemplateViewList *tmplMenuItems = subView->GetViewList(vlMenuItem);
if (!tmplMenuItems)
return;
listView = new cDisplayMenuListView(tmplMenuItems);
} else {
//Create detailed view
detailView = new cDisplayMenuDetailView(subView);
}
viewType = newViewType;
}
}
void cDisplayMenuRootView::SetTitle(const char *title) {
menuTitle = title;
if (view)
view->SetTitle(title);
}
void cDisplayMenuRootView::SetButtonTexts(const char *Red, const char *Green, const char *Yellow, const char *Blue) {
if (Red)
buttonTexts[0] = Red;
else
buttonTexts[0] = "";
if (Green)
buttonTexts[1] = Green;
else
buttonTexts[1] = "";
if (Yellow)
buttonTexts[2] = Yellow;
else
buttonTexts[2] = "";
if (Blue)
buttonTexts[3] = Blue;
else
buttonTexts[3] = "";
if (view)
view->SetButtonTexts(buttonTexts);
}
void cDisplayMenuRootView::SetTabs(int tab1, int tab2, int tab3, int tab4, int tab5) {
if (listView) {
listView->SetTabs(tab1, tab2, tab3, tab4, tab5);
}
}
void cDisplayMenuRootView::SetMessage(eMessageType type, const char *text) {
if (!view)
return;
if (!view->DrawMessage(type, text)) {
defaultMessageDrawn = true;
DrawMessage(type, text);
} else {
defaultMessageDrawn = false;
}
}
void cDisplayMenuRootView::SetDetailedViewEvent(const cEvent *event) {
if (!detailView)
detailView = new cDisplayMenuDetailView(subView);
detailView->SetEvent(event);
}
void cDisplayMenuRootView::SetDetailedViewRecording(const cRecording *recording) {
if (!detailView)
detailView = new cDisplayMenuDetailView(subView);
detailView->SetRecording(recording);
}
void cDisplayMenuRootView::SetDetailedViewText(const char *text) {
if (!detailView)
detailView = new cDisplayMenuDetailView(subView);
detailView->SetText(text);
}
void cDisplayMenuRootView::KeyInput(bool up, bool page) {
if (!detailView)
return;
if (up && page) {
detailView->KeyLeft();
} else if (!up && page) {
detailView->KeyRight();
} else if (up && !page) {
detailView->KeyUp();
} else if (!up && !page) {
detailView->KeyDown();
}
}
void cDisplayMenuRootView::Clear(void) {
if (listView) {
listView->Clear();
}
if (detailView) {
delete detailView;
detailView = NULL;
}
}
void cDisplayMenuRootView::ClearRootView(void) {
if (defaultBackgroundDrawn && view->BackgroundImplemented())
ClearViewElement(veBackground);
if (defaultHeaderDrawn)
ClearViewElement(veHeader);
if (defaultButtonsDrawn)
ClearViewElement(veButtons);
if (defaultDateTimeDrawn)
ClearViewElement(veDateTime);
if (defaultMessageDrawn)
ClearViewElement(veMessage);
}
int cDisplayMenuRootView::GetMaxItems(void) {
if (listView) {
return listView->GetMaxItems();
}
return 0;
}
int cDisplayMenuRootView::GetListViewWidth(void) {
if (listView) {
return listView->GetListWidth();
}
return 0;
}
int cDisplayMenuRootView::GetTextAreaWidth(void) {
if (!tmplView)
return 1900;
cTemplateView *tempSubView = tmplView->GetSubView(svMenuDefault);
if (!tempSubView)
return 1900;
int areaWidth = tempSubView->GetNumericParameter(ptWidth);
if (areaWidth > 0)
return areaWidth;
return 1900;
}
void cDisplayMenuRootView::Render(void) {
if (!view->DrawBackground()) {
if (!defaultBackgroundDrawn) {
defaultBackgroundDrawn = true;
DrawBackground();
}
} else {
defaultBackgroundDrawn = false;
}
if (!view->DrawHeader()) {
defaultHeaderDrawn = true;
DrawHeader();
} else {
defaultHeaderDrawn = false;
}
if (!view->DrawColorButtons()) {
defaultButtonsDrawn = true;
DrawColorButtons();
} else {
defaultButtonsDrawn = false;
}
if (!view->DrawDateTime()) {
defaultDateTimeDrawn = true;
DrawDateTime();
} else {
defaultDateTimeDrawn = false;
}
view->DrawStaticViewElements();
view->DrawDynamicViewElements();
}
void cDisplayMenuRootView::RenderMenuItems(void) {
if (listView)
listView->Render();
}
void cDisplayMenuRootView::RenderDetailView(void) {
if (detailView)
detailView->Render();
}
void cDisplayMenuRootView::RenderMenuScrollBar(int Total, int Offset) {
if (!listView)
return;
view->DrawScrollbar(listView->GetMaxItems(), Total, Offset);
}
bool cDisplayMenuRootView::RenderDynamicElements(void) {
return view->DrawDynamicViewElements();
}
/*******************************************************************
* Private Functions
*******************************************************************/
void cDisplayMenuRootView::DrawBackground(void) {
DrawViewElement(veBackground);
}
void cDisplayMenuRootView::DrawHeader(void) {
if (!ViewElementImplemented(veHeader)) {
return;
}
map < string, string > stringTokens;
map < string, int > intTokens;
stringTokens.insert(pair<string,string>("title", menuTitle));
stringTokens.insert(pair<string,string>("vdrversion", VDRVERSION));
//check for standard menu entries
bool hasIcon = false;
string icon = imgCache->GetIconName(menuTitle);
if (icon.size() > 0)
hasIcon = true;
stringTokens.insert(pair<string,string>("icon", icon));
intTokens.insert(pair<string,int>("hasicon", hasIcon));
ClearViewElement(veHeader);
DrawViewElement(veHeader, &stringTokens, &intTokens);
}
void cDisplayMenuRootView::DrawDateTime(void) {
if (!ViewElementImplemented(veDateTime)) {
return;
}
map < string, string > stringTokens;
map < string, int > intTokens;
time_t t = time(0); // get time now
struct tm * now = localtime(&t);
intTokens.insert(pair<string, int>("year", now->tm_year + 1900));
intTokens.insert(pair<string, int>("day", now->tm_mday));
char monthname[20];
char monthshort[10];
strftime(monthshort, sizeof(monthshort), "%b", now);
strftime(monthname, sizeof(monthname), "%B", now);
stringTokens.insert(pair<string,string>("monthname", monthname));
stringTokens.insert(pair<string,string>("monthnameshort", monthshort));
stringTokens.insert(pair<string,string>("month", *cString::sprintf("%02d", now->tm_mon + 1)));
stringTokens.insert(pair<string,string>("dayleadingzero", *cString::sprintf("%02d", now->tm_mday)));
stringTokens.insert(pair<string,string>("dayname", *WeekDayNameFull(now->tm_wday)));
stringTokens.insert(pair<string,string>("daynameshort", *WeekDayName(now->tm_wday)));
stringTokens.insert(pair<string,string>("time", *TimeString(t)));
ClearViewElement(veDateTime);
DrawViewElement(veDateTime, &stringTokens, &intTokens);
}
void cDisplayMenuRootView::DrawColorButtons(void) {
if (!ViewElementImplemented(veButtons)) {
return;
}
map < string, string > stringTokens;
map < string, int > intTokens;
stringTokens.insert(pair<string,string>("red", buttonTexts[0]));
stringTokens.insert(pair<string,string>("green", buttonTexts[1]));
stringTokens.insert(pair<string,string>("yellow", buttonTexts[2]));
stringTokens.insert(pair<string,string>("blue", buttonTexts[3]));
int colorKeys[4] = { Setup.ColorKey0, Setup.ColorKey1, Setup.ColorKey2, Setup.ColorKey3 };
for (int button = 1; button < 5; button++) {
string red = *cString::sprintf("red%d", button);
string green = *cString::sprintf("green%d", button);
string yellow = *cString::sprintf("yellow%d", button);
string blue = *cString::sprintf("blue%d", button);
bool isRed = false;
bool isGreen = false;
bool isYellow = false;
bool isBlue = false;
switch (colorKeys[button-1]) {
case 0:
isRed = true;
break;
case 1:
isGreen = true;
break;
case 2:
isYellow = true;
break;
case 3:
isBlue = true;
break;
default:
break;
}
intTokens.insert(pair<string, int>(red, isRed));
intTokens.insert(pair<string, int>(green, isGreen));
intTokens.insert(pair<string, int>(yellow, isYellow));
intTokens.insert(pair<string, int>(blue, isBlue));
}
ClearViewElement(veButtons);
DrawViewElement(veButtons, &stringTokens, &intTokens);
}
void cDisplayMenuRootView::DrawMessage(eMessageType type, const char *text) {
if (!text) {
ClearViewElement(veMessage);
return;
}
map < string, string > stringTokens;
map < string, int > intTokens;
intTokens.insert(pair<string, int>("status", (type == mtStatus) ? true : false));
intTokens.insert(pair<string, int>("info", (type == mtInfo) ? true : false));
intTokens.insert(pair<string, int>("warning", (type == mtWarning) ? true : false));
intTokens.insert(pair<string, int>("error", (type == mtError) ? true : false));
stringTokens.insert(pair<string,string>("text", text));
ClearViewElement(veMessage);
DrawViewElement(veMessage, &stringTokens, &intTokens);
}
void cDisplayMenuRootView::Action(void) {
SetInitFinished();
Render();
view->Start();
FadeIn();
DoFlush();
}

View File

@@ -0,0 +1,57 @@
#ifndef __DISPLAYMENUROOTVIEW_H
#define __DISPLAYMENUROOTVIEW_H
#include "../libtemplate/template.h"
#include "displaymenuview.h"
#include "displaymenulistview.h"
#include "displaymenudetailview.h"
class cDisplayMenuRootView : public cView {
private:
eSubView viewType;
cTemplateView *subView;
bool subViewAvailable;
cDisplayMenuView *view;
cDisplayMenuListView *listView;
cDisplayMenuDetailView *detailView;
string menuTitle;
string buttonTexts[4];
bool defaultBackgroundDrawn;
bool defaultHeaderDrawn;
bool defaultButtonsDrawn;
bool defaultDateTimeDrawn;
bool defaultMessageDrawn;
void DrawBackground(void);
void DrawHeader(void);
void DrawDateTime(void);
void DrawColorButtons(void);
void DrawMessage(eMessageType type, const char *text);
void ClearRootView(void);
virtual void Action(void);
public:
cDisplayMenuRootView(cTemplateView *rootView);
virtual ~cDisplayMenuRootView();
bool createOsd(void);
void SetMenu(eMenuCategory menuCat, bool menuInit);
void SetTitle(const char *title);
void SetChannel(const cChannel *channel) { view->SetChannel(channel); };
void SetButtonTexts(const char *Red, const char *Green, const char *Yellow, const char *Blue);
void SetTabs(int tab1, int tab2, int tab3, int tab4, int tab5);
void SetMessage(eMessageType type, const char *text);
void SetDetailedViewEvent(const cEvent *event);
void SetDetailedViewRecording(const cRecording *recording);
void SetDetailedViewText(const char *text);
void KeyInput(bool up, bool page);
void Clear(void);
int GetMaxItems(void);
int GetListViewWidth(void);
int GetTextAreaWidth(void);
bool SubViewAvailable(void) { return subViewAvailable; };
cDisplayMenuListView *GetListView(void) { return listView; };
void Render(void);
void RenderMenuItems(void);
void RenderDetailView(void);
void RenderMenuScrollBar(int Total, int Offset);
bool RenderDynamicElements(void);
};
#endif //__DISPLAYMENUROOTVIEW_H

126
views/displaymenutabview.c Normal file
View File

@@ -0,0 +1,126 @@
#include "displaymenutabview.h"
cDisplayMenuTabView::cDisplayMenuTabView(cTemplateViewTab *tmplTab) : cView(tmplTab) {
}
cDisplayMenuTabView::~cDisplayMenuTabView() {
CancelSave();
}
void cDisplayMenuTabView::SetTokens(map < string, int > *intTokens, map < string, string > *stringTokens, map < string, vector< map< string, string > > > *loopTokens) {
this->intTokens = intTokens;
this->stringTokens = stringTokens;
this->loopTokens = loopTokens;
}
void cDisplayMenuTabView::Clear(void) {
Fill(0, clrTransparent);
}
void cDisplayMenuTabView::CreateTab(void) {
//Create Pixmap
if (!PixmapExists(0)) {
cSize drawportSize;
scrolling = tmplTab->CalculateDrawPortSize(drawportSize, loopTokens);
if (scrolling) {
CreateScrollingPixmap(0, tmplTab, drawportSize);
scrollingPix = 0;
scrollOrientation = orVertical;
scrollMode = smNone;
} else {
CreateViewPixmap(0, tmplTab);
}
}
}
void cDisplayMenuTabView::Render(void) {
if (tmplTab->DoDebug()) {
tmplTab->Debug();
}
//Draw Tab, flushing every loop
DrawPixmap(0, tmplTab, loopTokens, true);
}
bool cDisplayMenuTabView::KeyUp(void) {
if (!scrolling)
return false;
int scrollStep = tmplTab->GetScrollStep();
int aktHeight = DrawportY(0);
if (aktHeight >= 0) {
return false;
}
int newY = aktHeight + scrollStep;
if (newY > 0)
newY = 0;
SetDrawPortPoint(0, cPoint(0, newY));
return true;
}
bool cDisplayMenuTabView::KeyDown(void) {
if (!scrolling)
return false;
int scrollStep = tmplTab->GetScrollStep();
int aktHeight = DrawportY(0);
int totalHeight = DrawportHeight(0);
int screenHeight = Height(0);
if (totalHeight - ((-1)*aktHeight) == screenHeight) {
return false;
}
int newY = aktHeight - scrollStep;
if ((-1)*newY > totalHeight - screenHeight)
newY = (-1)*(totalHeight - screenHeight);
SetDrawPortPoint(0, cPoint(0, newY));
return true;
}
bool cDisplayMenuTabView::KeyLeft(void) {
if (!scrolling)
return false;
if (!PixmapExists(0))
return false;
int aktHeight = DrawportY(0);
int screenHeight = Height(0);
int newY = aktHeight + screenHeight;
if (newY > 0)
newY = 0;
SetDrawPortPoint(0, cPoint(0, newY));
return true;
}
bool cDisplayMenuTabView::KeyRight(void) {
if (!scrolling)
return false;
if (!PixmapExists(0))
return false;
int aktHeight = DrawportY(0);
int screenHeight = Height(0);
int totalHeight = DrawportHeight(0);
int newY = aktHeight - screenHeight;
if ((-1)*newY > totalHeight - screenHeight)
newY = (-1)*(totalHeight - screenHeight);
SetDrawPortPoint(0, cPoint(0, newY));
return true;
}
void cDisplayMenuTabView::GetScrollbarPosition(int &barTop, int &barHeight) {
int y = (-1)*DrawportY(0);
int totalHeight = DrawportHeight(0);
int screenHeight = Height(0);
if (totalHeight == 0)
return;
if (totalHeight <= screenHeight)
barHeight = 1000;
else {
barHeight = (double)screenHeight / (double) totalHeight * 1000;
}
barTop = (double)y / (double) totalHeight * 1000;
}
void cDisplayMenuTabView::Action(void) {
Render();
DoFlush();
}

View File

@@ -0,0 +1,27 @@
#ifndef __DISPLAYMENUTABVIEW_H
#define __DISPLAYMENUTABVIEW_H
#include "../libtemplate/template.h"
#include "view.h"
class cDisplayMenuTabView : public cView {
private:
map < string, string > *stringTokens;
map < string, int > *intTokens;
map < string, vector< map< string, string > > > *loopTokens;
void Action(void);
public:
cDisplayMenuTabView(cTemplateViewTab *tmplTab);
virtual ~cDisplayMenuTabView();
void SetTokens(map < string, int > *intTokens, map < string, string > *stringTokens, map < string, vector< map< string, string > > > *loopTokens);
void Clear(void);
void CreateTab(void);
void Render(void);
bool KeyUp(void);
bool KeyDown(void);
bool KeyLeft(void);
bool KeyRight(void);
void GetScrollbarPosition(int &barTop, int &barHeight);
};
#endif //__DISPLAYMENUTABVIEW_H

539
views/displaymenuview.c Normal file
View File

@@ -0,0 +1,539 @@
#define __STL_CONFIG_H
#include <vdr/menu.h>
#include <vdr/videodir.h>
#include "displaymenuview.h"
#include "../config.h"
#include "../libcore/helpers.h"
#include "../libcore/timers.h"
cDisplayMenuView::cDisplayMenuView(cTemplateView *tmplView, bool menuInit) : cView(tmplView) {
if (menuInit)
SetFadeTime(tmplView->GetNumericParameter(ptFadeTime));
else
SetFadeTime(0);
cat = mcUndefined;
}
cDisplayMenuView::~cDisplayMenuView() {
CancelSave();
FadeOut();
}
bool cDisplayMenuView::DrawBackground(void) {
if (!ViewElementImplemented(veBackground)) {
return false;
}
DrawViewElement(veBackground);
return true;
}
bool cDisplayMenuView::DrawHeader(void) {
if (!ViewElementImplemented(veHeader)) {
return false;
}
map < string, string > stringTokens;
map < string, int > intTokens;
stringTokens.insert(pair<string,string>("title", menuTitle));
stringTokens.insert(pair<string,string>("vdrversion", VDRVERSION));
//check for standard menu entries
bool hasIcon = false;
string icon = imgCache->GetIconName(menuTitle);
if (icon.size() > 0)
hasIcon = true;
stringTokens.insert(pair<string,string>("icon", icon));
intTokens.insert(pair<string,int>("hasicon", hasIcon));
ClearViewElement(veHeader);
DrawViewElement(veHeader, &stringTokens, &intTokens);
return true;
}
bool cDisplayMenuView::DrawDateTime(void) {
if (!ViewElementImplemented(veDateTime)) {
return false;
}
cString curDate = DayDateTime();
map < string, string > stringTokens;
map < string, int > intTokens;
time_t t = time(0); // get time now
struct tm * now = localtime(&t);
intTokens.insert(pair<string, int>("year", now->tm_year + 1900));
intTokens.insert(pair<string, int>("day", now->tm_mday));
char monthname[20];
char monthshort[10];
strftime(monthshort, sizeof(monthshort), "%b", now);
strftime(monthname, sizeof(monthname), "%B", now);
stringTokens.insert(pair<string,string>("monthname", monthname));
stringTokens.insert(pair<string,string>("monthnameshort", monthshort));
stringTokens.insert(pair<string,string>("month", *cString::sprintf("%02d", now->tm_mon + 1)));
stringTokens.insert(pair<string,string>("dayleadingzero", *cString::sprintf("%02d", now->tm_mday)));
stringTokens.insert(pair<string,string>("dayname", *WeekDayNameFull(now->tm_wday)));
stringTokens.insert(pair<string,string>("daynameshort", *WeekDayName(now->tm_wday)));
stringTokens.insert(pair<string,string>("time", *TimeString(t)));
ClearViewElement(veDateTime);
DrawViewElement(veDateTime, &stringTokens, &intTokens);
return true;
}
bool cDisplayMenuView::DrawColorButtons(void) {
if (!ViewElementImplemented(veButtons)) {
return false;
}
map < string, string > stringTokens;
map < string, int > intTokens;
stringTokens.insert(pair<string,string>("red", buttonTexts[0]));
stringTokens.insert(pair<string,string>("green", buttonTexts[1]));
stringTokens.insert(pair<string,string>("yellow", buttonTexts[2]));
stringTokens.insert(pair<string,string>("blue", buttonTexts[3]));
int colorKeys[4] = { Setup.ColorKey0, Setup.ColorKey1, Setup.ColorKey2, Setup.ColorKey3 };
for (int button = 1; button < 5; button++) {
string red = *cString::sprintf("red%d", button);
string green = *cString::sprintf("green%d", button);
string yellow = *cString::sprintf("yellow%d", button);
string blue = *cString::sprintf("blue%d", button);
bool isRed = false;
bool isGreen = false;
bool isYellow = false;
bool isBlue = false;
switch (colorKeys[button-1]) {
case 0:
isRed = true;
break;
case 1:
isGreen = true;
break;
case 2:
isYellow = true;
break;
case 3:
isBlue = true;
break;
default:
break;
}
intTokens.insert(pair<string, int>(red, isRed));
intTokens.insert(pair<string, int>(green, isGreen));
intTokens.insert(pair<string, int>(yellow, isYellow));
intTokens.insert(pair<string, int>(blue, isBlue));
}
ClearViewElement(veButtons);
DrawViewElement(veButtons, &stringTokens, &intTokens);
return true;
}
bool cDisplayMenuView::DrawMessage(eMessageType type, const char *text) {
if (!ViewElementImplemented(veMessage)) {
return false;
}
if (!text) {
ClearViewElement(veMessage);
return true;
}
map < string, string > stringTokens;
map < string, int > intTokens;
intTokens.insert(pair<string, int>("status", (type == mtStatus) ? true : false));
intTokens.insert(pair<string, int>("info", (type == mtInfo) ? true : false));
intTokens.insert(pair<string, int>("warning", (type == mtWarning) ? true : false));
intTokens.insert(pair<string, int>("error", (type == mtError) ? true : false));
stringTokens.insert(pair<string,string>("text", text));
ClearViewElement(veMessage);
DrawViewElement(veMessage, &stringTokens, &intTokens);
return true;
}
void cDisplayMenuView::DrawScrollbar(int numMax, int numDisplayed, int offset) {
if (!ViewElementImplemented(veScrollbar)) {
return;
}
map < string, string > stringTokens;
map < string, int > intTokens;
if (numDisplayed < 1)
return;
int barHeight = 0;
if (numDisplayed < numMax)
barHeight = 1000;
else
barHeight = (double)numMax * 1000 / (double)numDisplayed;
int barOffset = (double)offset * 1000 / (double)numDisplayed;
intTokens.insert(pair<string, int>("height", barHeight));
intTokens.insert(pair<string, int>("offset", barOffset));
ClearViewElement(veScrollbar);
DrawViewElement(veScrollbar, &stringTokens, &intTokens);
}
bool cDisplayMenuView::BackgroundImplemented(void) {
if (!ViewElementImplemented(veBackground)) {
return false;
}
return true;
}
void cDisplayMenuView::Action(void) {
SetInitFinished();
FadeIn();
DoFlush();
}
/************************************************************************
* cDisplayMenuMainView
************************************************************************/
cDisplayMenuMainView::cDisplayMenuMainView(cTemplateView *tmplView, bool menuInit) : cDisplayMenuView(tmplView, menuInit) {
initial = true;
lastSystemLoad = 0.0;
InitDevices();
}
cDisplayMenuMainView::~cDisplayMenuMainView() {
CancelSave();
FadeOut();
delete[] lastSignalStrength;
delete[] lastSignalQuality;
delete[] recDevices;
}
void cDisplayMenuMainView::DrawStaticViewElements(void) {
DrawTimers();
DrawDiscUsage();
}
bool cDisplayMenuMainView::DrawDynamicViewElements(void) {
bool loadChanged = DrawLoad();
bool devicesChanged = DrawDevices();
initial = false;
return loadChanged || devicesChanged;
}
void cDisplayMenuMainView::DrawTimers(void) {
if (!ViewElementImplemented(veTimers)) {
return;
}
map < string, string > stringTokens;
map < string, int > intTokens;
map < string, vector< map< string, string > > > timerLoopTokens;
vector< map< string, string > > timers;
cGlobalSortedTimers SortedTimers;// local and remote timers
int numTimers = SortedTimers.Size();
intTokens.insert(pair<string, int>("numtimers", numTimers));
int numTimerConflicts = SortedTimers.NumTimerConfilicts();
intTokens.insert(pair<string, int>("numtimerconflicts", numTimerConflicts));
for (int i=0; i<15; i++) {
stringstream name;
name << "timer" << i+1 << "exists";
if (i < numTimers) {
intTokens.insert(pair<string, int>(name.str(), true));
} else {
intTokens.insert(pair<string, int>(name.str(), false));
}
}
for (int i = 0; i < numTimers; i++) {
if (i >=15)
break;
map< string, string > timerVals;
const cTimer *Timer = SortedTimers[i];
const cEvent *event = Timer->Event();
if (event) {
timerVals.insert(pair< string, string >("timers[title]", event->Title()));
} else {
const char *File = Setup.FoldersInTimerMenu ? NULL : strrchr(Timer->File(), FOLDERDELIMCHAR);
if (File && strcmp(File + 1, TIMERMACRO_TITLE) && strcmp(File + 1, TIMERMACRO_EPISODE))
File++;
else
File = Timer->File();
timerVals.insert(pair< string, string >("timers[title]", File));
}
const cChannel *channel = Timer->Channel();
if (channel) {
timerVals.insert(pair< string, string >("timers[channelname]", channel->Name()));
stringstream chanNum;
chanNum << channel->Number();
timerVals.insert(pair< string, string >("timers[channelnumber]", chanNum.str()));
string channelID = *(channel->GetChannelID().ToString());
timerVals.insert(pair< string, string >("timers[channelid]", channelID));
bool logoExists = imgCache->LogoExists(channelID);
timerVals.insert(pair< string, string >("timers[channellogoexists]", logoExists ? "1" : "0"));
} else {
timerVals.insert(pair< string, string >("timers[channelname]", ""));
timerVals.insert(pair< string, string >("timers[channelnumber]", "0"));
timerVals.insert(pair< string, string >("timers[channelid]", ""));
timerVals.insert(pair< string, string >("timers[channellogoexists]", "0"));
}
timerVals.insert(pair< string, string >("timers[recording]", Timer->Recording() ? "1" : "0"));
cString timerDate("");
if (Timer->Recording()) {
timerDate = cString::sprintf("-%s", *TimeString(Timer->StopTime()));
} else {
time_t Now = time(NULL);
cString Today = WeekDayName(Now);
cString Time = TimeString(Timer->StartTime());
cString Day = WeekDayName(Timer->StartTime());
if (Timer->StartTime() > Now + 6 * SECSINDAY) {
time_t ttm = Timer->StartTime();
struct tm * timerTime = localtime(&ttm);
timerDate = cString::sprintf("%02d.%02d %s", timerTime->tm_mday, timerTime->tm_mon + 1, *Time);
} else if (strcmp(Day, Today) != 0)
timerDate = cString::sprintf("%s %s", *Day, *Time);
else
timerDate = Time;
if (Timer->Flags() & tfVps)
timerDate = cString::sprintf("VPS %s", *timerDate);
}
timerVals.insert(pair< string, string >("timers[datetime]", *timerDate));
timers.push_back(timerVals);
}
timerLoopTokens.insert(pair< string, vector< map< string, string > > >("timers", timers));
ClearViewElement(veTimers);
DrawViewElement(veTimers, &stringTokens, &intTokens, &timerLoopTokens);
}
void cDisplayMenuMainView::DrawDiscUsage(void) {
if (!ViewElementImplemented(veDiscUsage)) {
return;
}
map < string, string > stringTokens;
map < string, int > intTokens;
string vdrUsageString = *cVideoDiskUsage::String();
int discUsage = cVideoDiskUsage::UsedPercent();
bool discAlert = (discUsage > 95) ? true : false;
string freeTime = *cString::sprintf("%02d:%02d", cVideoDiskUsage::FreeMinutes() / 60, cVideoDiskUsage::FreeMinutes() % 60);
int freeGB = cVideoDiskUsage::FreeMB() / 1024;
intTokens.insert(pair<string, int>("usedpercent", discUsage));
intTokens.insert(pair<string, int>("freepercent", 100-discUsage));
intTokens.insert(pair<string, int>("discalert", discAlert));
intTokens.insert(pair<string, int>("freegb", freeGB));
stringTokens.insert(pair<string,string>("freetime", freeTime));
stringTokens.insert(pair<string,string>("vdrusagestring", vdrUsageString));
ClearViewElement(veDiscUsage);
DrawViewElement(veDiscUsage, &stringTokens, &intTokens);
}
void cDisplayMenuMainView::InitDevices(void) {
int numDevices = cDevice::NumDevices();
lastSignalStrength = new int[numDevices];
lastSignalQuality = new int[numDevices];
recDevices = new bool[numDevices];
for (int i=0; i<numDevices; i++) {
lastSignalStrength[i] = 0;
lastSignalQuality[i] = 0;
recDevices[i] = false;
}
}
bool cDisplayMenuMainView::DrawLoad(void) {
if (!ViewElementImplemented(veSystemLoad)) {
return false;
}
map < string, string > stringTokens;
map < string, int > intTokens;
double systemLoad;
if (getloadavg(&systemLoad, 1) > 0) {
if (lastSystemLoad == systemLoad) {
return false;
}
string load = *cString::sprintf("%.2f", systemLoad);
stringTokens.insert(pair<string,string>("load", load));
lastSystemLoad = systemLoad;
}
ClearViewElement(veSystemLoad);
DrawViewElement(veSystemLoad, &stringTokens, &intTokens);
return true;
}
bool cDisplayMenuMainView::DrawDevices(void) {
if (!ViewElementImplemented(veDevices)) {
return false;
}
int numDevices = cDevice::NumDevices();
if (!initial) {
//check if drawing is necessary
bool changed = false;
for (int i = 0; i < numDevices; i++) {
const cDevice *device = cDevice::GetDevice(i);
if (!device || !device->NumProvidedSystems()) {
continue;
}
if ((device->SignalStrength() != lastSignalStrength[i]) || (device->SignalQuality() != lastSignalQuality[i])) {
changed = true;
break;
}
}
if (!changed) {
return false;
}
}
map < string, string > stringTokens;
map < string, int > intTokens;
map < string, vector< map< string, string > > > deviceLoopTokens;
vector< map< string, string > > devices;
//check device which currently displays live tv
int deviceLiveTV = -1;
cDevice *primaryDevice = cDevice::PrimaryDevice();
if (primaryDevice) {
if (!primaryDevice->Replaying() || primaryDevice->Transferring())
deviceLiveTV = cDevice::ActualDevice()->DeviceNumber();
else
deviceLiveTV = primaryDevice->DeviceNumber();
}
//check currently recording devices
for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) {
if (!timer->Recording()) {
continue;
}
if (cRecordControl *RecordControl = cRecordControls::GetRecordControl(timer)) {
const cDevice *recDevice = RecordControl->Device();
if (recDevice) {
recDevices[recDevice->DeviceNumber()] = true;
}
}
}
int actualNumDevices = 0;
for (int i = 0; i < numDevices; i++) {
const cDevice *device = cDevice::GetDevice(i);
if (!device || !device->NumProvidedSystems()) {
continue;
}
actualNumDevices++;
map< string, string > deviceVals;
stringstream strNum;
strNum << actualNumDevices;
deviceVals.insert(pair< string, string >("devices[num]", strNum.str()));
deviceVals.insert(pair< string, string >("devices[type]", *(device->DeviceType())));
cCamSlot *camSlot = device->CamSlot();
int camNumber = -1;
if (camSlot) {
camNumber = camSlot->SlotNumber();
deviceVals.insert(pair< string, string >("devices[hascam]", "1"));
} else {
deviceVals.insert(pair< string, string >("devices[hascam]", "0"));
}
int signalStrength = device->SignalStrength();
int signalQuality = device->SignalQuality();
stringstream strCamNumber;
strCamNumber << camNumber;
deviceVals.insert(pair< string, string >("devices[cam]", strCamNumber.str()));
stringstream strStrength;
strStrength << signalStrength;
deviceVals.insert(pair< string, string >("devices[signalstrength]", strStrength.str()));
stringstream strQuality;
strQuality << signalQuality;
deviceVals.insert(pair< string, string >("devices[signalquality]", strQuality.str()));
deviceVals.insert(pair< string, string >("devices[livetv]", i == deviceLiveTV ? "1" : "0"));
deviceVals.insert(pair< string, string >("devices[recording]", recDevices[i] ? "1" : "0"));
const cChannel *channel = device->GetCurrentlyTunedTransponder();
const cSource *source = (channel) ? Sources.Get(channel->Source()) : NULL;
if (channel && channel->Number() > 0) {
stringstream strChanNum;
strChanNum << channel->Number();
deviceVals.insert(pair< string, string >("devices[channelnumber]", strChanNum.str()));
deviceVals.insert(pair< string, string >("devices[channelname]", channel->Name()));
deviceVals.insert(pair< string, string >("devices[channelid]", *(channel->GetChannelID().ToString())));
deviceVals.insert(pair< string, string >("devices[istuned]", "1"));
} else {
deviceVals.insert(pair< string, string >("devices[channelnumber]", "0"));
deviceVals.insert(pair< string, string >("devices[channelname]", ""));
deviceVals.insert(pair< string, string >("devices[channelid]", ""));
deviceVals.insert(pair< string, string >("devices[istuned]", "0"));
}
deviceVals.insert(pair< string, string >("devices[source]", source ? source->Description() : ""));
devices.push_back(deviceVals);
lastSignalStrength[i] = signalStrength;
lastSignalQuality[i] = signalQuality;
}
deviceLoopTokens.insert(pair< string, vector< map< string, string > > >("devices", devices));
intTokens.insert(pair<string, int>("numdevices", actualNumDevices));
ClearViewElement(veDevices);
DrawViewElement(veDevices, &stringTokens, &intTokens, &deviceLoopTokens);
return true;
}
/************************************************************************
* cDisplayMenuSchedulesView
************************************************************************/
cDisplayMenuSchedulesView::cDisplayMenuSchedulesView(cTemplateView *tmplView, eMenuCategory menuCat, bool menuInit) : cDisplayMenuView(tmplView, menuInit) {
cat = menuCat;
channel = NULL;
}
cDisplayMenuSchedulesView::~cDisplayMenuSchedulesView() {
CancelSave();
FadeOut();
}
bool cDisplayMenuSchedulesView::DrawHeader(void) {
if (!ViewElementImplemented(veHeader)) {
return false;
}
map < string, string > stringTokens;
map < string, int > intTokens;
intTokens.insert(pair<string,int>("whatson", (cat == mcSchedule) ? true: false));
intTokens.insert(pair<string,int>("whatsonnow", (cat == mcScheduleNow) ? true: false));
intTokens.insert(pair<string,int>("whatsonnext", (cat == mcScheduleNext) ? true: false));
stringTokens.insert(pair<string,string>("title", menuTitle));
stringTokens.insert(pair<string,string>("vdrversion", VDRVERSION));
if (channel) {
stringTokens.insert(pair<string,string>("channelnumber", *cString::sprintf("%d", channel->Number())));
stringTokens.insert(pair<string,string>("channelname", channel->Name()));
stringTokens.insert(pair<string,string>("channelid", *(channel->GetChannelID().ToString())));
}
ClearViewElement(veHeader);
DrawViewElement(veHeader, &stringTokens, &intTokens);
return true;
}

60
views/displaymenuview.h Normal file
View File

@@ -0,0 +1,60 @@
#ifndef __DISPLAYMENUVIEW_H
#define __DISPLAYMENUVIEW_H
#include "../libtemplate/template.h"
#include "displaymenulistview.h"
class cDisplayMenuView : public cView {
protected:
eMenuCategory cat;
string menuTitle;
string *buttonTexts;
virtual void Action(void);
public:
cDisplayMenuView(cTemplateView *tmplView, bool menuInit);
virtual ~cDisplayMenuView();
void SetMenuCat(eMenuCategory newCat) { cat = newCat; };
void SetTitle(const char *title) {menuTitle = title; };
virtual void SetChannel(const cChannel *channel) {};
void SetButtonTexts(string *buttonTexts) { this->buttonTexts = buttonTexts; };
bool DrawBackground(void);
virtual bool DrawHeader(void);
bool DrawDateTime(void);
bool DrawColorButtons(void);
bool DrawMessage(eMessageType type, const char *text);
void DrawScrollbar(int numMax, int numDisplayed, int offset);
virtual void DrawStaticViewElements(void) {};
virtual bool DrawDynamicViewElements(void) { return false; };
bool BackgroundImplemented(void);
};
class cDisplayMenuMainView : public cDisplayMenuView {
private:
bool initial;
int* lastSignalStrength;
int* lastSignalQuality;
double lastSystemLoad;
bool* recDevices;
void DrawTimers(void);
void DrawDiscUsage(void);
bool DrawLoad(void);
void InitDevices(void);
bool DrawDevices(void);
public:
cDisplayMenuMainView(cTemplateView *tmplView, bool menuInit);
virtual ~cDisplayMenuMainView();
void DrawStaticViewElements(void);
bool DrawDynamicViewElements(void);
};
class cDisplayMenuSchedulesView : public cDisplayMenuView {
private:
const cChannel *channel;
public:
cDisplayMenuSchedulesView(cTemplateView *tmplView, eMenuCategory menuCat, bool menuInit);
virtual ~cDisplayMenuSchedulesView();
void SetChannel(const cChannel *channel) { this->channel = channel; };
bool DrawHeader(void);
};
#endif //__DISPLAYMENUVIEW_H

View File

@@ -0,0 +1,49 @@
#define __STL_CONFIG_H
#include <vdr/menu.h>
#include "displaymessageview.h"
cDisplayMessageView::cDisplayMessageView(cTemplateView *tmplView) : cView(tmplView) {
DeleteOsdOnExit();
SetFadeTime(tmplView->GetNumericParameter(ptFadeTime));
}
cDisplayMessageView::~cDisplayMessageView() {
CancelSave();
FadeOut();
}
bool cDisplayMessageView::createOsd(void) {
cRect osdSize = tmplView->GetOsdSize();
bool ok = CreateOsd(cOsd::OsdLeft() + osdSize.X(),
cOsd::OsdTop() + osdSize.Y(),
osdSize.Width(),
osdSize.Height());
return ok;
}
void cDisplayMessageView::DrawBackground(void) {
map < string, string > stringTokens;
map < string, int > intTokens;
DrawViewElement(veBackground, &stringTokens, &intTokens);
}
void cDisplayMessageView::DrawMessage(eMessageType type, const char *text) {
map < string, string > stringTokens;
map < string, int > intTokens;
stringTokens.insert(pair<string,string>("text", text));
intTokens.insert(pair<string,int>("status", (type == mtStatus) ? true : false));
intTokens.insert(pair<string,int>("info", (type == mtInfo) ? true : false));
intTokens.insert(pair<string,int>("warning", (type == mtWarning) ? true : false));
intTokens.insert(pair<string,int>("error", (type == mtError) ? true : false));
DrawViewElement(veMessage, &stringTokens, &intTokens);
}
void cDisplayMessageView::Action(void) {
SetInitFinished();
FadeIn();
DoFlush();
cView::Action();
}

View File

@@ -0,0 +1,19 @@
#ifndef __DISPLAYMESSAGEVIEW_H
#define __DISPLAYMESSAGEVIEW_H
#include "../libtemplate/template.h"
#include "view.h"
class cDisplayMessageView : public cView {
private:
virtual void Action(void);
public:
cDisplayMessageView(cTemplateView *tmplView);
virtual ~cDisplayMessageView();
bool createOsd(void);
void DrawBackground(void);
void DrawMessage(eMessageType type, const char *text);
void DoFadeIn(void) { Start(); };
void Flush(void) { DoFlush(); };
};
#endif //__DISPLAYMESSAGEVIEW_H

376
views/displayreplayview.c Normal file
View File

@@ -0,0 +1,376 @@
#define __STL_CONFIG_H
#include <vdr/menu.h>
#include "../services/scraper2vdr.h"
#include "displayreplayview.h"
#include "../libcore/helpers.h"
cDisplayReplayView::cDisplayReplayView(cTemplateView *tmplView) : cView(tmplView) {
lastDate = "";
DeleteOsdOnExit();
SetFadeTime(tmplView->GetNumericParameter(ptFadeTime));
}
cDisplayReplayView::~cDisplayReplayView() {
CancelSave();
FadeOut();
}
bool cDisplayReplayView::createOsd(void) {
cRect osdSize = tmplView->GetOsdSize();
bool ok = CreateOsd(cOsd::OsdLeft() + osdSize.X(),
cOsd::OsdTop() + osdSize.Y(),
osdSize.Width(),
osdSize.Height());
return ok;
}
void cDisplayReplayView::DrawBackground(bool modeOnly) {
map < string, string > stringTokens;
map < string, int > intTokens;
if (modeOnly)
DrawViewElement(veBackgroundModeOnly, &stringTokens, &intTokens);
else
DrawViewElement(veBackground, &stringTokens, &intTokens);
}
void cDisplayReplayView::DrawDate(bool modeOnly) {
if (modeOnly)
return;
if (!ViewElementImplemented(veDateTime)) {
return;
}
cString curDate = DayDateTime();
if (strcmp(curDate, lastDate)) {
map < string, string > stringTokens;
map < string, int > intTokens;
time_t t = time(0); // get time now
struct tm * now = localtime(&t);
intTokens.insert(pair<string, int>("year", now->tm_year + 1900));
intTokens.insert(pair<string, int>("day", now->tm_mday));
char monthname[20];
char monthshort[10];
strftime(monthshort, sizeof(monthshort), "%b", now);
strftime(monthname, sizeof(monthname), "%B", now);
stringTokens.insert(pair<string,string>("monthname", monthname));
stringTokens.insert(pair<string,string>("monthnameshort", monthshort));
stringTokens.insert(pair<string,string>("month", *cString::sprintf("%02d", now->tm_mon + 1)));
stringTokens.insert(pair<string,string>("dayleadingzero", *cString::sprintf("%02d", now->tm_mday)));
stringTokens.insert(pair<string,string>("dayname", *WeekDayNameFull(now->tm_wday)));
stringTokens.insert(pair<string,string>("daynameshort", *WeekDayName(now->tm_wday)));
stringTokens.insert(pair<string,string>("time", *TimeString(t)));
ClearViewElement(veDateTime);
DrawViewElement(veDateTime, &stringTokens, &intTokens);
lastDate = curDate;
}
}
void cDisplayReplayView::DrawTitle(const cRecording *recording) {
map < string, string > stringTokens;
map < string, int > intTokens;
const char *recName = NULL;
const cRecordingInfo *recInfo = recording->Info();
if (recInfo) {
recName = recInfo->Title();
}
if (!recName)
recName = recording->Name();
string recShortText = recInfo->ShortText() ? recInfo->ShortText() : "";
string recDate = *ShortDateString(recording->Start());
string recTime = *TimeString(recording->Start());
stringTokens.insert(pair<string,string>("rectitle", recName ? recName : ""));
stringTokens.insert(pair<string,string>("recsubtitle", recShortText));
stringTokens.insert(pair<string,string>("recdate", recDate));
stringTokens.insert(pair<string,string>("rectime", recTime));
DrawViewElement(veRecTitle, &stringTokens, &intTokens);
}
void cDisplayReplayView::DrawRecordingInformation(const cRecording *recording) {
map < string, string > stringTokens;
map < string, int > intTokens;
int screenWidth = 0;
int screenHeight = 0;
double aspect = 0;
cDevice::PrimaryDevice()->GetVideoSize(screenWidth, screenHeight, aspect);
bool isHD = false;
string resName = GetScreenResolutionString(screenWidth, screenHeight, &isHD);
bool isWideScreen = false;
string aspectName = GetScreenAspectString(aspect, &isWideScreen);
intTokens.insert(pair<string,int>("screenwidth", screenWidth));
intTokens.insert(pair<string,int>("screenheight", screenHeight));
intTokens.insert(pair<string,int>("isHD", isHD));
intTokens.insert(pair<string,int>("isWideScreen", isWideScreen));
stringTokens.insert(pair<string,string>("resolution", resName));
stringTokens.insert(pair<string,string>("aspect", aspectName));
ClearViewElement(veRecInfo);
DrawViewElement(veRecInfo, &stringTokens, &intTokens);
}
void cDisplayReplayView::DrawScraperContent(const cRecording *recording) {
if (!recording)
return;
if (!ViewElementImplemented(veScraperContent)) {
return;
}
static cPlugin *pScraper = GetScraperPlugin();
if (!pScraper) {
return;
}
ScraperGetPosterBannerV2 call;
call.event = NULL;
call.recording = recording;
if (pScraper->Service("GetPosterBannerV2", &call)) {
int mediaWidth = 0;
int mediaHeight = 0;
std::string mediaPath = "";
bool isBanner = false;
if ((call.type == tSeries) && call.banner.path.size() > 0) {
mediaWidth = call.banner.width;
mediaHeight = call.banner.height;
mediaPath = call.banner.path;
isBanner = true;
} else if (call.type == tMovie && call.poster.path.size() > 0 && call.poster.height > 0) {
mediaWidth = call.poster.width;
mediaHeight = call.poster.height;
mediaPath = call.poster.path;
} else
return;
map < string, int > intTokens;
map < string, string > stringTokens;
intTokens.insert(pair<string,int>("mediawidth", mediaWidth));
intTokens.insert(pair<string,int>("mediaheight", mediaHeight));
intTokens.insert(pair<string,int>("isbanner", isBanner));
stringTokens.insert(pair<string,string>("mediapath", mediaPath));
ClearViewElement(veScraperContent);
DrawViewElement(veScraperContent, &stringTokens, &intTokens);
}
}
void cDisplayReplayView::DrawCurrent(const char *current) {
map < string, string > stringTokens;
map < string, int > intTokens;
stringTokens.insert(pair<string,string>("reccurrent", current));
ClearViewElement(veRecCurrent);
DrawViewElement(veRecCurrent, &stringTokens, &intTokens);
}
void cDisplayReplayView::DrawTotal(const char *total) {
map < string, string > stringTokens;
map < string, int > intTokens;
stringTokens.insert(pair<string,string>("rectotal", total));
ClearViewElement(veRecTotal);
DrawViewElement(veRecTotal, &stringTokens, &intTokens);
}
void cDisplayReplayView::DrawProgressBar(int current, int total) {
map < string, string > stringTokens;
map < string, int > intTokens;
intTokens.insert(pair<string,int>("current", current));
intTokens.insert(pair<string,int>("total", total));
stringTokens.insert(pair<string,string>("dummy", ""));
ClearViewElement(veRecProgressBar);
DrawViewElement(veRecProgressBar, &stringTokens, &intTokens);
}
void cDisplayReplayView::DrawMarks(const cMarks *marks, int total) {
if (!marks)
return;
map < string, string > stringTokens;
map < string, int > intTokens;
map < string, vector< map< string, string > > > loopTokens;
vector< map< string, string > > markTokens;
stringstream tot;
tot << total;
bool isStartMark = true;
for (const cMark *m = marks->First(); m; m = marks->Next(m)) {
map< string, string > markVals;
stringstream pos;
pos << m->Position();
markVals.insert(pair< string, string >("marks[position]", pos.str()));
markVals.insert(pair< string, string >("marks[total]", tot.str()));
markVals.insert(pair< string, string >("marks[startmark]", isStartMark ? "1" : "0"));
const cMark *m2 = marks->Next(m);
if (m2) {
stringstream posNext;
posNext << m2->Position();
markVals.insert(pair< string, string >("marks[endposition]", posNext.str()));
} else {
markVals.insert(pair< string, string >("marks[endposition]", tot.str()));
}
isStartMark = !isStartMark;
markTokens.push_back(markVals);
}
loopTokens.insert(pair< string, vector< map< string, string > > >("marks", markTokens));
ClearViewElement(veCuttingMarks);
DrawViewElement(veCuttingMarks, &stringTokens, &intTokens, &loopTokens);
}
void cDisplayReplayView::DrawControlIcons(bool play, bool forward, int speed, bool modeOnly) {
map < string, string > stringTokens;
map < string, int > intTokens;
bool isPlay = false;
bool isPause = false;
bool isFF = false;
bool isFF1x = false;
bool isFF2x = false;
bool isFF3x = false;
bool isRew = false;
bool isRew1x = false;
bool isRew2x = false;
bool isRew3x = false;
if (speed == -1) {
if (play) {
isPlay = true;
} else {
isPause = true;
}
} else if (forward) {
if (!play) {
isPause = true;
}
if (speed == 1) {
isFF1x = true;
} else if (speed == 2) {
isFF2x = true;
} else if (speed == 3) {
isFF3x = true;
} else {
isFF = true;
}
} else {
if (!play) {
isPause = true;
}
if (speed == 1) {
isRew1x = true;
} else if (speed == 2) {
isRew2x = true;
} else if (speed == 3) {
isRew3x = true;
} else {
isRew = true;
}
}
intTokens.insert(pair<string,int>("play", isPlay));
intTokens.insert(pair<string,int>("pause", isPause));
intTokens.insert(pair<string,int>("forward", isFF));
intTokens.insert(pair<string,int>("forward1x", isFF1x));
intTokens.insert(pair<string,int>("forward2x", isFF2x));
intTokens.insert(pair<string,int>("forward3x", isFF3x));
intTokens.insert(pair<string,int>("rewind", isRew));
intTokens.insert(pair<string,int>("rewind1x", isRew1x));
intTokens.insert(pair<string,int>("rewind2x", isRew2x));
intTokens.insert(pair<string,int>("rewind3x", isRew3x));
if (modeOnly) {
ClearViewElement(veControlIconsModeOnly);
DrawViewElement(veControlIconsModeOnly, &stringTokens, &intTokens);
} else {
ClearViewElement(veControlIcons);
DrawViewElement(veControlIcons, &stringTokens, &intTokens);
}
}
void cDisplayReplayView::DrawJump(const char *jump) {
if (!jump) {
ClearViewElement(veRecJump);
return;
}
map < string, string > stringTokens;
map < string, int > intTokens;
stringTokens.insert(pair<string,string>("jump", jump));
ClearViewElement(veRecJump);
DrawViewElement(veRecJump, &stringTokens, &intTokens);
}
void cDisplayReplayView::DrawMessage(eMessageType type, const char *text) {
if (!text) {
ClearViewElement(veMessage);
}
map < string, string > stringTokens;
map < string, int > intTokens;
stringTokens.insert(pair<string,string>("text", text));
intTokens.insert(pair<string,int>("status", (type == mtStatus) ? true : false));
intTokens.insert(pair<string,int>("info", (type == mtInfo) ? true : false));
intTokens.insert(pair<string,int>("warning", (type == mtWarning) ? true : false));
intTokens.insert(pair<string,int>("error", (type == mtError) ? true : false));
ClearViewElement(veMessage);
DrawViewElement(veMessage, &stringTokens, &intTokens);
}
void cDisplayReplayView::Action(void) {
SetInitFinished();
FadeIn();
DoFlush();
cView::Action();
}
string cDisplayReplayView::GetScreenResolutionString(int width, int height, bool *isHD) {
string name = "";
switch (width) {
case 1920:
case 1440:
name = "hd1080i";
*isHD = true;
break;
case 1280:
if (height == 720)
name = "hd720p";
else
name = "hd1080i";
*isHD = true;
break;
case 720:
name = "sd576i";
break;
default:
name = "sd576i";
break;
}
return name;
}
string cDisplayReplayView::GetScreenAspectString(double aspect, bool *isWideScreen) {
string name = "";
*isWideScreen = false;
if (aspect == 4.0/3.0) {
name = "4:3";
*isWideScreen = false;
} else if (aspect == 16.0/9.0) {
name = "16:9";
*isWideScreen = true;
} else if (aspect == 2.21) {
name = "21:9";
*isWideScreen = true;
}
return name;
}

32
views/displayreplayview.h Normal file
View File

@@ -0,0 +1,32 @@
#ifndef __DISPLAYREPLAYVIEW_H
#define __DISPLAYREPLAYVIEW_H
#include "../libtemplate/template.h"
#include "view.h"
class cDisplayReplayView : public cView {
private:
cString lastDate;
string GetScreenResolutionString(int width, int height, bool *isHD);
string GetScreenAspectString(double aspect, bool *isWideScreen);
virtual void Action(void);
public:
cDisplayReplayView(cTemplateView *tmplView);
virtual ~cDisplayReplayView();
bool createOsd(void);
void DrawBackground(bool modeOnly);
void DrawDate(bool modeOnly);
void DrawTitle(const cRecording *recording);
void DrawRecordingInformation(const cRecording *recording);
void DrawScraperContent(const cRecording *recording);
void DrawCurrent(const char *current);
void DrawTotal(const char *total);
void DrawProgressBar(int current, int total);
void DrawMarks(const cMarks *marks, int total);
void DrawControlIcons(bool play, bool forward, int speed, bool modeOnly);
void DrawJump(const char *jump);
void DrawMessage(eMessageType type, const char *text);
void DoFadeIn(void) { Start(); };
void Flush(void) { DoFlush(); };
};
#endif //__DISPLAYREPLAYVIEW_H

55
views/displayvolumeview.c Normal file
View File

@@ -0,0 +1,55 @@
#define __STL_CONFIG_H
#include <vdr/menu.h>
#include "displayvolumeview.h"
cDisplayVolumeView::cDisplayVolumeView(cTemplateView *tmplView) : cView(tmplView) {
volumeLast = -1;
muteLast = false;
DeleteOsdOnExit();
SetFadeTime(tmplView->GetNumericParameter(ptFadeTime));
}
cDisplayVolumeView::~cDisplayVolumeView() {
CancelSave();
FadeOut();
}
bool cDisplayVolumeView::createOsd(void) {
cRect osdSize = tmplView->GetOsdSize();
bool ok = CreateOsd(cOsd::OsdLeft() + osdSize.X(),
cOsd::OsdTop() + osdSize.Y(),
osdSize.Width(),
osdSize.Height());
return ok;
}
void cDisplayVolumeView::DrawBackground(void) {
map < string, string > stringTokens;
map < string, int > intTokens;
DrawViewElement(veBackground, &stringTokens, &intTokens);
}
void cDisplayVolumeView::DrawVolume(int current, int total, bool mute) {
if ((volumeLast == current) && (muteLast == mute))
return;
volumeLast = current;
muteLast = mute;
map < string, string > stringTokens;
map < string, int > intTokens;
intTokens.insert(pair<string,int>("volume", current));
intTokens.insert(pair<string,int>("maxvolume", total));
intTokens.insert(pair<string,int>("volumepercent", (double)current *100 / (double)total));
intTokens.insert(pair<string,int>("mute", mute));
ClearViewElement(veVolume);
DrawViewElement(veVolume, &stringTokens, &intTokens);
}
void cDisplayVolumeView::Action(void) {
SetInitFinished();
FadeIn();
DoFlush();
cView::Action();
}

21
views/displayvolumeview.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef __DISPLAYVOLUMEVIEW_H
#define __DISPLAYVOLUMEVIEW_H
#include "../libtemplate/template.h"
#include "view.h"
class cDisplayVolumeView : public cView {
private:
int volumeLast;
bool muteLast;
virtual void Action(void);
public:
cDisplayVolumeView(cTemplateView *tmplView);
virtual ~cDisplayVolumeView();
bool createOsd(void);
void DrawBackground(void);
void DrawVolume(int current, int total, bool mute);
void DoFadeIn(void) { Start(); };
void Flush(void) { DoFlush(); };
};
#endif //__DISPLAYVOLUMEVIEW_H

809
views/view.c Normal file
View File

@@ -0,0 +1,809 @@
#include "view.h"
#include "../config.h"
#include "../libcore/helpers.h"
#include "../libcore/imageloader.h"
using namespace std;
cView::cView(cTemplateView *tmplView) : cPixmapContainer(tmplView->GetNumPixmaps()) {
this->tmplView = tmplView;
tvScaled = tmplView->GetScalingWindow(scalingWindow);
if (tvScaled) {
cDevice::PrimaryDevice()->ScaleVideo(scalingWindow);
}
tmplItem = NULL;
tmplTab = NULL;
Init();
}
cView::cView(cTemplateViewElement *tmplItem) : cPixmapContainer(tmplItem->GetNumPixmaps()) {
this->tmplItem = tmplItem;
tmplView = NULL;
tmplTab = NULL;
tvScaled = false;
Init();
}
cView::cView(cTemplateViewTab *tmplTab) : cPixmapContainer(1) {
this->tmplTab = tmplTab;
tmplView = NULL;
tmplItem = NULL;
tvScaled = false;
Init();
}
cView::~cView() {
if (tvScaled) {
cDevice::PrimaryDevice()->ScaleVideo(cRect::Null);
}
}
void cView::Init(void) {
viewInit = true;
scrolling = false;
veScroll = veUndefined;
scrollingPix = -1;
scrollOrientation = orHorizontal;
scrollDelay = 0;
scrollMode = smNone;
scrollSpeed = ssMedium;
currentlyScrolling = false;
}
void cView::Action(void) {
if (scrolling) {
DoSleep(scrollDelay);
if (scrollOrientation == orHorizontal) {
ActivateScrolling();
ScrollHorizontal(scrollingPix, scrollDelay, scrollSpeed, scrollMode);
} else {
ScrollVertical(scrollingPix, scrollDelay, scrollSpeed);
}
}
}
void cView::Stop(void) {
CancelSave();
}
/********************************************************************************
* Protected Functions
********************************************************************************/
void cView::DrawViewElement(eViewElement ve, map <string,string> *stringTokens, map <string,int> *intTokens, map < string, vector< map< string, string > > > *loopTokens) {
//setting correct ViewElement, depending which constructor was used
cTemplateViewElement *viewElement;
if (tmplItem && ve == veMenuCurrentItemDetail) {
viewElement = tmplItem;
} else if (tmplView) {
viewElement = tmplView->GetViewElement(ve);
}
if (!viewElement)
return;
if (viewElement->DebugTokens()) {
DebugTokens(tmplView ? (tmplView->GetViewElementName(ve)) : "current view", stringTokens, intTokens, loopTokens);
}
//iterate through pixmaps of viewelement
int pixCurrent = viewElement->GetPixOffset();
if (pixCurrent < 0)
return;
viewElement->InitIterator();
cTemplatePixmap *pix = NULL;
while(pix = viewElement->GetNextPixmap()) {
//reset Template
pix->ClearDynamicParameters();
//create Pixmap if already fully parsed
if (!PixmapExists(pixCurrent) && pix->Ready() && pix->DoExecute() && !pix->Scrolling()) {
CreateViewPixmap(pixCurrent, pix);
}
//check if pixmap needs dynamic parameters
if ((!pix->Ready() || !pix->DoExecute()) && !pix->Scrolling()) {
//parse dynamic parameters and initiate functions
pix->ParseDynamicParameters(intTokens, true);
if (pix->Ready() && pix->DoExecute()) {
CreateViewPixmap(pixCurrent, pix);
}
} else {
//parse dynamic parameters but not initiate functions
pix->ParseDynamicParameters(intTokens, false);
}
//if pixmap still not valid, skip
if (!pix->Ready() && !pix->Scrolling()) {
pixCurrent++;
continue;
}
//if condition for pixmap set, check if cond is true
if (!pix->DoExecute()) {
pixCurrent++;
continue;
}
//parse dynamic tokens of pixmap functions
pix->ClearDynamicFunctionParameters();
pix->ParseDynamicFunctionParameters(stringTokens, intTokens);
if (!PixmapExists(pixCurrent) && pix->Scrolling()) {
cSize drawportSize;
scrolling = pix->CalculateDrawPortSize(drawportSize, loopTokens);
if (scrolling) {
CreateScrollingPixmap(pixCurrent, pix, drawportSize);
pix->SetScrollingTextWidth();
veScroll = ve;
scrollingPix = pixCurrent;
scrollOrientation = pix->GetNumericParameter(ptOrientation);
scrollMode = pix->GetNumericParameter(ptScrollMode);
scrollDelay = pix->GetNumericParameter(ptDelay);
scrollSpeed = pix->GetNumericParameter(ptScrollSpeed);
} else {
CreateViewPixmap(pixCurrent, pix);
}
}
if (pix->DoDebug()) {
pix->Debug();
}
DrawPixmap(pixCurrent, pix, loopTokens);
pixCurrent++;
}
}
void cView::ClearViewElement(eViewElement ve) {
if (!tmplView)
return;
cTemplateViewElement *viewElement = tmplView->GetViewElement(ve);
if (!viewElement)
return;
int pixCurrent = viewElement->GetPixOffset();
if (pixCurrent < 0)
return;
cTemplatePixmap *pix = NULL;
viewElement->InitIterator();
while(pix = viewElement->GetNextPixmap()) {
Fill(pixCurrent, clrTransparent);
pixCurrent++;
}
}
void cView::ActivateScrolling(void) {
if (veScroll == veUndefined)
return;
cTemplateViewElement *scrollViewElement = NULL;
if (tmplView) {
scrollViewElement = tmplView->GetViewElement(veScroll);
}
if (!scrollViewElement)
return;
ClearViewElement(veScroll);
currentlyScrolling = true;
int pixCurrent = scrollViewElement->GetPixOffset();
if (pixCurrent < 0)
return;
scrollViewElement->InitIterator();
cTemplatePixmap *pix = NULL;
while(pix = scrollViewElement->GetNextPixmap()) {
DrawPixmap(pixCurrent, pix);
pixCurrent++;
}
}
bool cView::ViewElementImplemented(eViewElement ve) {
return tmplView->GetNumPixmapsViewElement(ve);
}
void cView::CreateViewPixmap(int num, cTemplatePixmap *pix, cRect *size) {
cRect pixSize;
if (size) {
pixSize = *size;
} else {
pixSize = pix->GetPixmapSize();
}
int layer = pix->GetNumericParameter(ptLayer);
int transparency = pix->GetNumericParameter(ptTransparency);
SetTransparency(num, transparency);
CreatePixmap(num, layer, pixSize);
}
void cView::CreateScrollingPixmap(int num, cTemplatePixmap *pix, cSize &drawportSize) {
cRect pixViewPort = pix->GetPixmapSize();
cRect drawPort;
drawPort.SetX(0);
drawPort.SetY(0);
drawPort.SetWidth(drawportSize.Width());
drawPort.SetHeight(drawportSize.Height());
int layer = pix->GetNumericParameter(ptLayer);
int transparency = pix->GetNumericParameter(ptTransparency);
SetTransparency(num, transparency);
CreatePixmap(num, layer, pixViewPort, drawPort);
}
void cView::DrawPixmap(int num, cTemplatePixmap *pix, map < string, vector< map< string, string > > > *loopTokens, bool flushPerLoop) {
pix->InitIterator();
cTemplateFunction *func = NULL;
while(func = pix->GetNextFunction()) {
eFuncType type = func->GetType();
if (func->DoDebug()) {
func->Debug();
}
if (!func->DoExecute()) {
continue;
}
switch (type) {
case ftFill:
DoFill(num, func);
break;
case ftDrawText:
DoDrawText(num, func);
break;
case ftDrawTextBox: {
int floating = func->GetNumericParameter(ptFloat);
if (floating > flNone) {
DoDrawFloatingTextBox(num, func);
} else {
DoDrawTextBox(num, func);
}
break; }
case ftDrawRectangle:
DoDrawRectangle(num, func);
break;
case ftDrawEllipse:
DoDrawEllipse(num, func);
break;
case ftDrawImage:
DoDrawImage(num, func);
break;
case ftLoop:
if (loopTokens)
DrawLoop(num, func, loopTokens);
break;
default:
break;
}
if (flushPerLoop) {
DoFlush();
}
}
}
void cView::DrawLoop(int numPixmap, cTemplateFunction *func, map < string, vector< map< string, string > > > *loopTokens) {
cTemplateLoopFunction *loopFunc = dynamic_cast<cTemplateLoopFunction*>(func);
if (!loopFunc)
return;
int loopX0 = loopFunc->GetNumericParameter(ptX);
if (loopX0 < 0) loopX0 = 0;
int loopY0 = loopFunc->GetNumericParameter(ptY);
if (loopY0 < 0) loopY0 = 0;
int orientation = loopFunc->GetNumericParameter(ptOrientation);
int loopWidth = loopFunc->GetNumericParameter(ptWidth);
if (loopWidth <= 0)
loopWidth = loopFunc->GetContainerWidth();
int loopHeight = loopFunc->GetNumericParameter(ptHeight);
if (loopHeight <= 0)
loopHeight = loopFunc->GetContainerHeight();
int columnWidth = loopFunc->GetNumericParameter(ptColumnWidth);
int rowHeight = loopFunc->GetNumericParameter(ptRowHeight);
int overflow = loopFunc->GetNumericParameter(ptOverflow);
int maxItems = loopFunc->GetNumericParameter(ptNumElements);
int x0 = loopX0;
int y0 = loopY0;
string loopTokenName = loopFunc->GetParameter(ptName);
map < string, vector< map< string, string > > >::iterator hit = loopTokens->find(loopTokenName);
if (hit == loopTokens->end())
return;
vector< map<string,string> > loopToken = hit->second;
int lineNumber=0;
for (vector< map<string,string> >::iterator line = loopToken.begin(); line != loopToken.end(); line++) {
//check overflow behaviour
if (overflow == otCut) {
if (orientation == orHorizontal) {
if (lineNumber * columnWidth > loopWidth) {
return;
}
} else if (orientation == orVertical) {
if (lineNumber * rowHeight > loopHeight) {
return;
}
}
} else if (overflow == otWrap && orientation == orHorizontal) {
if (x0 + columnWidth > loopWidth) {
x0 = loopX0;
if (rowHeight > 0) {
y0 += rowHeight;
} else {
y0 += loopFunc->GetLoopElementsHeight();
}
}
}
map<string,string> tokens = *line;
loopFunc->ClearDynamicParameters();
loopFunc->ParseDynamicParameters(&tokens);
loopFunc->InitIterator();
cTemplateFunction *func = NULL;
while(func = loopFunc->GetNextFunction()) {
//do debug?
if (func->DoDebug())
func->Debug();
//check if set condition is true
if (!func->DoExecute()) {
continue;
}
//execute
eFuncType type = func->GetType();
switch (type) {
case ftDrawText:
DoDrawText(numPixmap, func, x0, y0);
break;
case ftDrawTextBox:
DoDrawTextBox(numPixmap, func, x0, y0);
break;
case ftDrawRectangle:
DoDrawRectangle(numPixmap, func, x0, y0);
break;
case ftDrawEllipse:
DoDrawEllipse(numPixmap, func, x0, y0);
break;
case ftDrawImage:
DoDrawImage(numPixmap, func, x0, y0);
break;
default:
break;
}
}
//calculate position of next loop element
if (orientation == orHorizontal) {
if (columnWidth > 0) {
x0 += columnWidth;
} else {
x0 += loopFunc->GetLoopElementsWidth();
}
} else if (orientation == orVertical) {
if (rowHeight > 0) {
y0 += rowHeight;
} else {
y0 += loopFunc->GetLoopElementsHeight();
}
}
lineNumber++;
//DoFlush();
}
}
void cView::DebugTokens(string viewElement, map<string,string> *stringTokens, map<string,int> *intTokens, map < string, vector< map< string, string > > > *loopTokens) {
esyslog("skindesigner: ------------------------------ Tokens for %s:", viewElement.c_str());
if (stringTokens) {
for (map<string,string>::iterator st = stringTokens->begin(); st != stringTokens->end(); st++) {
esyslog("skindesigner: string var \"%s\" = \"%s\"", (st->first).c_str(), (st->second).c_str());
}
}
if (intTokens) {
for (map<string,int>::iterator it = intTokens->begin(); it != intTokens->end(); it++) {
esyslog("skindesigner: int var \"%s\" = %d", (it->first).c_str(), it->second);
}
}
if (loopTokens) {
for(map < string, vector< map< string, string > > >::iterator it1 = loopTokens->begin(); it1 != loopTokens->end(); it1++) {
int line = 0;
string tokenName = it1->first;
vector< map<string,string> > tokens = it1->second;
esyslog("skindesigner: loop token %s", tokenName.c_str());
for (vector< map<string,string> >::iterator it2 = tokens.begin(); it2 != tokens.end(); it2++) {
esyslog("skindesigner: loop tokens line %d:", line++);
map<string,string> element = *it2;
for (map<string,string>::iterator el = element.begin(); el != element.end(); el++) {
esyslog("skindesigner: name: %s, value: %s", (el->first).c_str(), (el->second).c_str());
}
}
}
}
}
/*****************************************************************
* Private Functions
*****************************************************************/
void cView::DoFill(int num, cTemplateFunction *func) {
tColor col = func->GetColorParameter(ptColor);
Fill(num, col);
}
void cView::DoDrawText(int num, cTemplateFunction *func, int x0, int y0) {
int x = func->GetNumericParameter(ptX);
if (x < 0) x = 0;
x += x0;
int y = func->GetNumericParameter(ptY);
if (y < 0) y = 0;
y += y0;
cPoint pos(x,y);
string fontName = func->GetFontName();
int fontSize = func->GetNumericParameter(ptFontSize);
tColor clr = func->GetColorParameter(ptColor);
tColor clrBack = clrTransparent;
string text = "";
if (!currentlyScrolling) {
text = func->GetText(true);
} else {
text = func->GetText(false);
}
DrawText(num, pos, text.c_str(), clr, clrBack, fontName, fontSize);
}
void cView::DoDrawTextBox(int num, cTemplateFunction *func, int x0, int y0) {
string text = func->GetText(false);
if (text.size() < 3)
return;
int x = func->GetNumericParameter(ptX);
int y = func->GetNumericParameter(ptY);
if (x < 0) x = 0;
x += x0;
if (y < 0) y = 0;
y += y0;
int width = func->GetNumericParameter(ptWidth);
int height = func->GetNumericParameter(ptHeight);
string fontName = func->GetFontName();
int fontSize = func->GetNumericParameter(ptFontSize);
int align = func->GetNumericParameter(ptAlign);
int maxLines = func->GetNumericParameter(ptMaxLines);
tColor clr = func->GetColorParameter(ptColor);
tColor clrBack = clrTransparent;
const cFont *font = fontManager->Font(fontName, fontSize);
if (!font)
return;
cTextWrapper wrapper;
wrapper.Set(text.c_str(), font, width);
int fontHeight = fontManager->Height(fontName, fontSize);
int lines = wrapper.Lines();
int yLine = y;
for (int line=0; line < lines; line++) {
int xLine = x;
if (align == alCenter) {
int textWidth = font->Width(wrapper.GetLine(line));
xLine += (width - textWidth)/2;
} else if (align == alRight) {
int textWidth = font->Width(wrapper.GetLine(line));
xLine += (width - textWidth);
}
cPoint pos(xLine, yLine);
if (maxLines > 0 && line == maxLines-1) {
string lastLine = wrapper.GetLine(line);
if (lines > maxLines) {
lastLine += "...";
}
DrawText(num, pos, lastLine.c_str(), clr, clrBack, fontName, fontSize);
break;
} else if (height > 0 && yLine - y + 2*fontHeight > height) {
DrawText(num, pos, "...", clr, clrBack, fontName, fontSize);
break;
}
DrawText(num, pos, wrapper.GetLine(line), clr, clrBack, fontName, fontSize);
yLine += fontHeight;
}
}
void cView::DoDrawFloatingTextBox(int num, cTemplateFunction *func) {
string text = func->GetText(false);
if (text.size() < 3)
return;
int x = func->GetNumericParameter(ptX);
int y = func->GetNumericParameter(ptY);
if (x < 0) x = 0;
if (y < 0) y = 0;
int width = func->GetNumericParameter(ptWidth);
int height = func->GetNumericParameter(ptHeight);
string fontName = func->GetFontName();
int fontSize = func->GetNumericParameter(ptFontSize);
tColor clr = func->GetColorParameter(ptColor);
tColor clrBack = clrTransparent;
const cFont *font = fontManager->Font(fontName, fontSize);
if (!font)
return;
int floatType = func->GetNumericParameter(ptFloat);
int floatWidth = func->GetNumericParameter(ptFloatWidth);
int floatHeight = func->GetNumericParameter(ptFloatHeight);
cTextWrapper wTextTall;
cTextWrapper wTextFull;
int fontHeight = fontManager->Height(fontName, fontSize);
int linesNarrow = floatHeight / fontHeight;
int widthNarrow = width - floatWidth;
int linesDrawn = 0;
int curY = 0;
bool drawNarrow = true;
splitstring s(text.c_str());
std::vector<std::string> flds = s.split('\n', 1);
if (flds.size() < 1)
return;
std::stringstream sstrTextTall;
std::stringstream sstrTextFull;
for (int i=0; i<flds.size(); i++) {
if (!flds[i].size()) {
//empty line
linesDrawn++;
curY += fontHeight;
if (drawNarrow)
sstrTextTall << "\n";
else
sstrTextFull << "\n";
} else {
cTextWrapper wrapper;
if (drawNarrow) {
wrapper.Set((flds[i].c_str()), font, widthNarrow);
int newLines = wrapper.Lines();
//check if wrapper fits completely into narrow area
if (linesDrawn + newLines < linesNarrow) {
for (int line = 0; line < wrapper.Lines(); line++) {
sstrTextTall << wrapper.GetLine(line) << " ";
}
sstrTextTall << "\n";
linesDrawn += newLines;
} else {
//this wrapper has to be splitted
for (int line = 0; line < wrapper.Lines(); line++) {
if (line + linesDrawn < linesNarrow) {
sstrTextTall << wrapper.GetLine(line) << " ";
} else {
sstrTextFull << wrapper.GetLine(line) << " ";
}
}
sstrTextFull << "\n";
drawNarrow = false;
}
} else {
wrapper.Set((flds[i].c_str()), font, width);
for (int line = 0; line < wrapper.Lines(); line++) {
sstrTextFull << wrapper.GetLine(line) << " ";
}
sstrTextFull << "\n";
}
}
}
//VDRs textwrapper swallows linebreaks at the end, so we have to fix that manually
string textTall = sstrTextTall.str();
size_t posLastCarriageReturn = textTall.find_last_not_of("\n");
int numLinesToAddAtTall = 0;
if (posLastCarriageReturn != string::npos && (posLastCarriageReturn < textTall.size() - 1)) {
numLinesToAddAtTall = textTall.size() - posLastCarriageReturn - 2;
}
wTextTall.Set(textTall.c_str(), font, widthNarrow);
wTextFull.Set(sstrTextFull.str().c_str(), font, width);
int textLinesTall = wTextTall.Lines();
int textLinesFull = wTextFull.Lines();
int textXTall = x;
if (floatType == flTopLeft)
textXTall = x + floatWidth;
int yLine = y;
for (int line=0; line < textLinesTall; line++) {
cPoint pos(textXTall, yLine);
DrawText(num, pos, wTextTall.GetLine(line), clr, clrBack, fontName, fontSize);
yLine += fontHeight;
}
if (numLinesToAddAtTall) {
yLine += numLinesToAddAtTall * fontHeight;
}
for (int line=0; line < textLinesFull; line++) {
cPoint pos(x, yLine);
if (height > 0 && yLine - y + 2*fontHeight > height) {
DrawText(num, pos, "...", clr, clrBack, fontName, fontSize);
break;
}
DrawText(num, pos, wTextFull.GetLine(line), clr, clrBack, fontName, fontSize);
yLine += fontHeight;
}
}
void cView::DoDrawRectangle(int num, cTemplateFunction *func, int x0, int y0) {
int x = func->GetNumericParameter(ptX);
int y = func->GetNumericParameter(ptY);
if (x < 0) x = 0;
x += x0;
if (y < 0) y = 0;
y += y0;
int w = func->GetNumericParameter(ptWidth);
int h = func->GetNumericParameter(ptHeight);
cRect size(x, y, w, h);
tColor clr = func->GetColorParameter(ptColor);
DrawRectangle(num, size, clr);
}
void cView::DoDrawEllipse(int num, cTemplateFunction *func, int x0, int y0) {
int x = func->GetNumericParameter(ptX);
int y = func->GetNumericParameter(ptY);
if (x < 0) x = 0;
x += x0;
if (y < 0) y = 0;
y += y0;
int w = func->GetNumericParameter(ptWidth);
int h = func->GetNumericParameter(ptHeight);
cRect size(x, y, w, h);
tColor clr = func->GetColorParameter(ptColor);
int quadrant = func->GetNumericParameter(ptQuadrant);
DrawEllipse(num, size, clr, quadrant);
}
void cView::DoDrawImage(int num, cTemplateFunction *func, int x0, int y0) {
int x = func->GetNumericParameter(ptX);
int y = func->GetNumericParameter(ptY);
if (x < 0) x = 0;
x += x0;
if (y < 0) y = 0;
y += y0;
cPoint pos(x,y);
int width = func->GetNumericParameter(ptWidth);
int height = func->GetNumericParameter(ptHeight);
string path = func->GetImagePath();
eImageType type = (eImageType)func->GetNumericParameter(ptImageType);
switch (type) {
case itChannelLogo: {
cImage *logo = imgCache->GetLogo(path, width, height);
if (logo) {
DrawImage(num, pos, *logo);
}
break; }
case itSepLogo: {
cImage *sepLogo = imgCache->GetSeparatorLogo(path, width, height);
if (sepLogo) {
DrawImage(num, pos, *sepLogo);
}
break; }
case itSkinPart: {
cImage *skinpart = imgCache->GetSkinpart(path, width, height);
if (skinpart) {
DrawImage(num, pos, *skinpart);
}
break; }
case itIcon: {
cImage *icon = imgCache->GetIcon(type, path, width, height);
if (icon) {
DrawImage(num, pos, *icon);
}
break; }
case itMenuIcon: {
cImage *icon = imgCache->GetIcon(type, path, width, height);
if (icon) {
DrawImage(num, pos, *icon);
}
break; }
case itImage: {
cImageLoader imgLoader;
if (imgLoader.LoadImage(path.c_str(), width, height)) {
DrawImage(num, pos, imgLoader.GetImage());
}
break; }
default:
break;
}
}
/***********************************************************************
* cViewListItem
************************************************************************/
cViewListItem::cViewListItem(cTemplateViewElement *tmplItem) : cView(tmplItem) {
pos = -1;
numTotal = 0;
align = alLeft;
listOrientation = orVertical;
}
cViewListItem::~cViewListItem() {
}
cRect cViewListItem::DrawListItem(map <string,string> *stringTokens, map <string,int> *intTokens) {
cRect posItem;
if (!tmplItem)
return posItem;
if (tmplItem->DebugTokens()) {
DebugTokens("ListItem", stringTokens, intTokens);
}
tmplItem->InitIterator();
cTemplatePixmap *pix = NULL;
int pixCurrent = 0;
while(pix = tmplItem->GetNextPixmap()) {
SetListElementPosition(pix);
if (pixCurrent == 0) {
posItem = pix->GetPixmapSize();
}
if (!PixmapExists(pixCurrent)) {
pix->ParseDynamicParameters(intTokens, true);
} else {
pix->ParseDynamicParameters(intTokens, false);
}
if (!PixmapExists(pixCurrent) && pix->Ready() && pix->DoExecute() && !pix->Scrolling()) {
CreateViewPixmap(pixCurrent, pix);
}
//if pixmap still not valid, skip
if (!pix->Ready() && !pix->Scrolling()) {
pixCurrent++;
continue;
}
//if condition for pixmap set, check if cond is true
if (!pix->DoExecute()) {
pixCurrent++;
continue;
}
pix->ClearDynamicFunctionParameters();
pix->ParseDynamicFunctionParameters(stringTokens, intTokens);
if (!PixmapExists(pixCurrent) && pix->Scrolling()) {
cSize drawportSize;
scrolling = pix->CalculateDrawPortSize(drawportSize);
pix->SetScrollingTextWidth();
if (scrolling) {
CreateScrollingPixmap(pixCurrent, pix, drawportSize);
scrollingPix = pixCurrent;
scrollOrientation = pix->GetNumericParameter(ptOrientation);
scrollMode = pix->GetNumericParameter(ptScrollMode);
scrollDelay = pix->GetNumericParameter(ptDelay);
scrollSpeed = pix->GetNumericParameter(ptScrollSpeed);
} else {
CreateViewPixmap(pixCurrent, pix);
}
}
if (pix->DoDebug()) {
pix->Debug();
}
DrawPixmap(pixCurrent, pix);
pixCurrent++;
}
return posItem;
}
void cViewListItem::ClearListItem(void) {
int pixMax = NumPixmaps();
for (int pixCurrent = 0; pixCurrent < pixMax; pixCurrent++) {
Fill(pixCurrent, clrTransparent);
}
}
void cViewListItem::SetListElementPosition(cTemplatePixmap *pix) {
int itemWidth = pix->GetNumericParameter(ptWidth);
int itemHeight = pix->GetNumericParameter(ptHeight);
int x = 0;
int y = 0;
if (listOrientation == orHorizontal) {
x = container.X();
int totalWidth = numTotal * itemWidth;
if (align == alCenter) {
y += (container.Width() - totalWidth) / 2;
} else if (align == alBottom) {
y += (container.Width() - totalWidth);
}
x += pos * itemWidth;
y = pix->GetNumericParameter(ptY);
} else if (listOrientation == orVertical) {
y = container.Y();
int totalHeight = numTotal * itemHeight;
if (align == alCenter) {
y += (container.Height() - totalHeight) / 2;
} else if (align == alBottom) {
y += (container.Height() - totalHeight);
}
y += pos * itemHeight;
x = pix->GetNumericParameter(ptX);
}
pix->SetX(x);
pix->SetY(y);
}

72
views/view.h Normal file
View File

@@ -0,0 +1,72 @@
#ifndef __VIEW_H
#define __VIEW_H
#include "string"
#include "map"
#include "../libcore/pixmapcontainer.h"
#include "../libtemplate/template.h"
using namespace std;
class cView : public cPixmapContainer {
private:
void Init(void);
void DoFill(int num, cTemplateFunction *func);
void DoDrawText(int num, cTemplateFunction *func, int x0 = 0, int y0 = 0);
void DoDrawTextBox(int num, cTemplateFunction *func, int x0 = 0, int y0 = 0);
void DoDrawFloatingTextBox(int num, cTemplateFunction *func);
void DoDrawRectangle(int num, cTemplateFunction *func, int x0 = 0, int y0 = 0);
void DoDrawEllipse(int num, cTemplateFunction *func, int x0 = 0, int y0 = 0);
void DoDrawImage(int num, cTemplateFunction *func, int x0 = 0, int y0 = 0);
void ActivateScrolling(void);
protected:
cTemplateView *tmplView;
cTemplateViewElement *tmplItem;
cTemplateViewTab *tmplTab;
//scaling window
cRect scalingWindow;
bool tvScaled;
bool viewInit;
//true if view is scrollable in general
bool scrolling;
//true if view is actually starting scrolling
bool currentlyScrolling;
eViewElement veScroll;
int scrollingPix;
int scrollOrientation;
int scrollDelay;
int scrollMode;
int scrollSpeed;
void DrawViewElement(eViewElement ve, map <string,string> *stringTokens = NULL, map <string,int> *intTokens = NULL, map < string, vector< map< string, string > > > *loopTokens = NULL);
void ClearViewElement(eViewElement ve);
bool ViewElementImplemented(eViewElement ve);
void CreateViewPixmap(int num, cTemplatePixmap *pix, cRect *size = NULL);
void CreateScrollingPixmap(int num, cTemplatePixmap *pix, cSize &drawportSize);
void DrawPixmap(int num, cTemplatePixmap *pix, map < string, vector< map< string, string > > > *loopTokens = NULL, bool flushPerLoop = false);
void DrawLoop(int numPixmap, cTemplateFunction *func, map < string, vector< map< string, string > > > *loopTokens);
void DebugTokens(string viewElement, map<string,string> *stringTokens, map<string,int> *intTokens, map < string, vector< map< string, string > > > *loopTokens = NULL);
virtual void Action(void);
public:
cView(cTemplateView *tmplView);
cView(cTemplateViewElement *tmplItem);
cView(cTemplateViewTab *tmplTab);
virtual ~cView();
virtual void Stop(void);
};
class cViewListItem : public cView {
protected:
int pos;
int numTotal;
cRect container;
int align;
int listOrientation;
void SetListElementPosition(cTemplatePixmap *pix);
public:
cViewListItem(cTemplateViewElement *tmplItem);
virtual ~cViewListItem();
cRect DrawListItem(map <string,string> *stringTokens, map <string,int> *intTokens);
void ClearListItem(void);
};
#endif //__VIEW_H