diff options
author | louis <louis.braun@gmx.de> | 2014-09-27 09:25:14 +0200 |
---|---|---|
committer | louis <louis.braun@gmx.de> | 2014-09-27 09:25:14 +0200 |
commit | b0509b5182b6e0d04f05e6b3d5676b0d21f51966 (patch) | |
tree | 22b302342f22843e0815eb5f516c85f1478cbf0b /views/displaymenudetailview.c | |
download | vdr-plugin-skindesigner-0.0.1.tar.gz vdr-plugin-skindesigner-0.0.1.tar.bz2 |
initial commit version 0.0.10.0.1
Diffstat (limited to 'views/displaymenudetailview.c')
-rw-r--r-- | views/displaymenudetailview.c | 929 |
1 files changed, 929 insertions, 0 deletions
diff --git a/views/displaymenudetailview.c b/views/displaymenudetailview.c new file mode 100644 index 0000000..acba9c6 --- /dev/null +++ b/views/displaymenudetailview.c @@ -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; +} |