diff options
author | louis <louis.braun@gmx.de> | 2016-03-13 16:07:21 +0100 |
---|---|---|
committer | louis <louis.braun@gmx.de> | 2016-03-13 16:07:21 +0100 |
commit | 4623e7b345f850ac44cdcacbd0e43e139a4baa6a (patch) | |
tree | 8046f612d0a0821624e7de006021f551ea512d15 | |
parent | d4ef992f8256d324221d15d3bef967eb044a9a86 (diff) | |
download | vdr-plugin-tvguideng-4623e7b345f850ac44cdcacbd0e43e139a4baa6a.tar.gz vdr-plugin-tvguideng-4623e7b345f850ac44cdcacbd0e43e139a4baa6a.tar.bz2 |
added VDR 2.3.1 compatibility
-rw-r--r-- | channelepg.c | 46 | ||||
-rw-r--r-- | channelepg.h | 4 | ||||
-rw-r--r-- | channelgroups.c | 28 | ||||
-rw-r--r-- | channeljump.c | 90 | ||||
-rw-r--r-- | channeljump.h | 50 | ||||
-rw-r--r-- | definitions.h | 1090 | ||||
-rw-r--r-- | detailview.c | 1572 | ||||
-rw-r--r-- | detailview.h | 98 | ||||
-rw-r--r-- | epgelement.c | 104 | ||||
-rw-r--r-- | epgelement.h | 54 | ||||
-rw-r--r-- | epggrid.c | 124 | ||||
-rw-r--r-- | gridelement.c | 112 | ||||
-rw-r--r-- | gridelement.h | 100 | ||||
-rw-r--r-- | recmanager.c | 237 | ||||
-rw-r--r-- | recmanager.h | 10 | ||||
-rw-r--r-- | recmenu.c | 1244 | ||||
-rw-r--r-- | recmenu.h | 130 | ||||
-rw-r--r-- | recmenuitem.c | 3159 | ||||
-rw-r--r-- | recmenuitem.h | 990 | ||||
-rw-r--r-- | recmenus.c | 2336 | ||||
-rw-r--r-- | recmenus.h | 902 | ||||
-rw-r--r-- | recmenuview.c | 1757 | ||||
-rw-r--r-- | recmenuview.h | 92 | ||||
-rw-r--r-- | searchtimer.c | 1181 | ||||
-rw-r--r-- | searchtimer.h | 272 | ||||
-rw-r--r-- | services/remotetimers.h | 6 | ||||
-rw-r--r-- | timemanager.c | 344 | ||||
-rw-r--r-- | timemanager.h | 120 | ||||
-rw-r--r-- | timerconflict.c | 357 | ||||
-rw-r--r-- | timerconflict.h | 74 | ||||
-rw-r--r-- | tvguidengosd.c | 16 |
31 files changed, 8562 insertions, 8137 deletions
diff --git a/channelepg.c b/channelepg.c index bde905d..3ca9173 100644 --- a/channelepg.c +++ b/channelepg.c @@ -8,12 +8,10 @@ cChannelEpg::cChannelEpg(int position, const cChannel *channel, cTimeManager *ti channelsPerPage = (config.displayMode == eHorizontal) ? config.channelsPerPageHorizontal : config.channelsPerPageVertical; SetTimer(); SetSwitchTimer(); - schedulesLock = new cSchedulesLock(false, 100); } cChannelEpg::~cChannelEpg(void) { grids.Clear(); - delete schedulesLock; } void cChannelEpg::ClearGrids(void) { @@ -21,8 +19,19 @@ void cChannelEpg::ClearGrids(void) { } bool cChannelEpg::ReadGrids(void) { - schedules = cSchedules::Schedules(*schedulesLock); + const cSchedule *Schedule = NULL; + +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_SCHEDULES_READ; + const cSchedules* schedules = Schedules; +#else + cSchedulesLock schedulesLock; + const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock); +#endif + if (!schedules) + return false; + Schedule = schedules->GetSchedule(channel); if (!Schedule) { AddDummyGrid(timeManager->GetStart(), timeManager->GetEnd()); @@ -162,7 +171,15 @@ void cChannelEpg::AddNewGridsAtStart(void) { return; } //if not, i have to add new ones to the list - schedules = cSchedules::Schedules(*schedulesLock); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_SCHEDULES_READ; + const cSchedules* schedules = Schedules; +#else + cSchedulesLock schedulesLock; + const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock); +#endif + if (!schedules) + return ; const cSchedule *Schedule = NULL; Schedule = schedules->GetSchedule(channel); if (!Schedule) { @@ -208,7 +225,15 @@ void cChannelEpg::AddNewGridsAtEnd(void) { return; } //if not, i have to add new ones to the list - schedules = cSchedules::Schedules(*schedulesLock); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_SCHEDULES_READ; + const cSchedules* schedules = Schedules; +#else + cSchedulesLock schedulesLock; + const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock); +#endif + if (!schedules) + return ; const cSchedule *Schedule = NULL; Schedule = schedules->GetSchedule(channel); if (!Schedule) { @@ -439,4 +464,13 @@ void cChannelEpg::Debug(void) { for (cGridElement *grid = grids.First(); grid; grid = grids.Next(grid)) { grid->Debug(); } -}
\ No newline at end of file +} + +void cChannelEpg::SetTimer() +{ +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) +#else + hasTimer = channel->HasTimer(); +#endif + +}; diff --git a/channelepg.h b/channelepg.h index 63f24d4..177b104 100644 --- a/channelepg.h +++ b/channelepg.h @@ -23,8 +23,6 @@ private: const cChannel *channel; cList<cGridElement> grids; set<long> deletedElements; - cSchedulesLock *schedulesLock; - const cSchedules *schedules; bool hasTimer; bool hasSwitchTimer; cGridElement *AddEpgGrid(const cEvent *event, cGridElement *after = NULL); @@ -47,7 +45,7 @@ public: void ClearOutdatedStart(void); void ClearOutdatedEnd(void); void SetTimers(void); - void SetTimer(void) { hasTimer = channel->HasTimer(); }; + void SetTimer(void); bool HasTimer(void) { return hasTimer; }; void SetSwitchTimer() {hasSwitchTimer = SwitchTimers.ChannelInSwitchList(channel);}; bool HasSwitchTimer() { return hasSwitchTimer; }; diff --git a/channelgroups.c b/channelgroups.c index 9ea8bfb..ff7efc4 100644 --- a/channelgroups.c +++ b/channelgroups.c @@ -31,12 +31,18 @@ void cChannelgroups::Init(void) { bool setStart = false; int lastChannelNumber = 0; int id = 0; - const cChannel *first = Channels.First(); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* channels = Channels; +#else + const cChannels* channels = &Channels; +#endif + const cChannel *first = channels->First(); if (!first->GroupSep()) { channelGroups.push_back(cChannelGroup(tr("Main Program"), id++)); setStart = true; } - for (const cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel)) { + for (const cChannel *channel = channels->First(); channel; channel = channels->Next(channel)) { if (setStart && (channelGroups.size() > 0)) { channelGroups[channelGroups.size()-1].SetChannelStart(channel->Number()); setStart = false; @@ -82,7 +88,14 @@ void cChannelgroups::Draw(const cChannel *start, const cChannel *stop) { int fields = 1; double offset = 0.0; - for (const cChannel *channel = Channels.Next(start); channel; channel = Channels.Next(channel)) { +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* channels = Channels; +#else + const cChannels* channels = &Channels; +#endif + + for (const cChannel *channel = channels->Next(start); channel; channel = channels->Next(channel)) { if (channel->GroupSep()) continue; if (config.hideLastChannelGroup && IsInLastGroup(channel)) { @@ -200,5 +213,12 @@ int cChannelgroups::GetLastValidChannel(void) { if (config.hideLastChannelGroup && channelGroups.size() > 1) { return channelGroups[channelGroups.size()-2].StopChannel(); } - return Channels.MaxNumber(); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + return Channels->MaxNumber(); +#else + return Channels.MaxNumber(); +#endif + + } diff --git a/channeljump.c b/channeljump.c index 935a129..b149dcf 100644 --- a/channeljump.c +++ b/channeljump.c @@ -1,46 +1,46 @@ -#include <vdr/channels.h>
-#include "channeljump.h"
-
-cChannelJump::cChannelJump(skindesignerapi::cViewElement *channelJump, int lastValidChannel) {
- this->channelJump = channelJump;
- channel = 0;
- maxChannels = lastValidChannel;
- startTime = 0;
- timeout = Setup.ChannelEntryTimeout;
-}
-
-cChannelJump::~cChannelJump(void) {
- channelJump->Clear();
- delete channelJump;
-}
-
-void cChannelJump::Draw(void) {
- channelJump->Clear();
- channelJump->ClearTokens();
- channelJump->AddStringToken((int)eChannelJumpST::channel, *BuildChannelString());
- channelJump->Display();
-}
-
-void cChannelJump::Set(int key) {
- startTime = cTimeMs::Now();
- if (channel == 0) {
- channel = key;
- return;
- }
- int newChannel = channel * 10 + key;
- if (newChannel <= maxChannels)
- channel = newChannel;
-}
-
-cString cChannelJump::BuildChannelString(void) {
- if (channel*10 <= maxChannels)
- return cString::sprintf("%d-", channel);
- else
- return cString::sprintf("%d", channel);
-}
-
- bool cChannelJump::TimeOut(void) {
- if ((int)(cTimeMs::Now() - startTime) > timeout)
- return true;
- return false;
+#include <vdr/channels.h> +#include "channeljump.h" + +cChannelJump::cChannelJump(skindesignerapi::cViewElement *channelJump, int lastValidChannel) { + this->channelJump = channelJump; + channel = 0; + maxChannels = lastValidChannel; + startTime = 0; + timeout = Setup.ChannelEntryTimeout; +} + +cChannelJump::~cChannelJump(void) { + channelJump->Clear(); + delete channelJump; +} + +void cChannelJump::Draw(void) { + channelJump->Clear(); + channelJump->ClearTokens(); + channelJump->AddStringToken((int)eChannelJumpST::channel, *BuildChannelString()); + channelJump->Display(); +} + +void cChannelJump::Set(int key) { + startTime = cTimeMs::Now(); + if (channel == 0) { + channel = key; + return; + } + int newChannel = channel * 10 + key; + if (newChannel <= maxChannels) + channel = newChannel; +} + +cString cChannelJump::BuildChannelString(void) { + if (channel*10 <= maxChannels) + return cString::sprintf("%d-", channel); + else + return cString::sprintf("%d", channel); +} + + bool cChannelJump::TimeOut(void) { + if ((int)(cTimeMs::Now() - startTime) > timeout) + return true; + return false; }
\ No newline at end of file diff --git a/channeljump.h b/channeljump.h index 251482a..e431a9b 100644 --- a/channeljump.h +++ b/channeljump.h @@ -1,26 +1,26 @@ -#ifndef __TVGUIDE_CHANNELJUMP_H
-#define __TVGUIDE_CHANNELJUMP_H
-
-#include <libskindesignerapi/skindesignerosdbase.h>
-#include "definitions.h"
-
-// --- cChannelJump -------------------------------------------------------------
-
-class cChannelJump {
-private:
- skindesignerapi::cViewElement *channelJump;
- int channel;
- int maxChannels;
- int startTime;
- int timeout;
- cString BuildChannelString(void);
-public:
- cChannelJump(skindesignerapi::cViewElement *channelJump, int lastValidChannel);
- virtual ~cChannelJump(void);
- void Set(int key);
- bool TimeOut(void);
- void Draw(void);
- int GetChannel(void) { return channel; };
-};
-
+#ifndef __TVGUIDE_CHANNELJUMP_H +#define __TVGUIDE_CHANNELJUMP_H + +#include <libskindesignerapi/skindesignerosdbase.h> +#include "definitions.h" + +// --- cChannelJump ------------------------------------------------------------- + +class cChannelJump { +private: + skindesignerapi::cViewElement *channelJump; + int channel; + int maxChannels; + int startTime; + int timeout; + cString BuildChannelString(void); +public: + cChannelJump(skindesignerapi::cViewElement *channelJump, int lastValidChannel); + virtual ~cChannelJump(void); + void Set(int key); + bool TimeOut(void); + void Draw(void); + int GetChannel(void) { return channel; }; +}; + #endif //__TVGUIDE_CHANNELJUMP_H
\ No newline at end of file diff --git a/definitions.h b/definitions.h index d2c8119..32a5c45 100644 --- a/definitions.h +++ b/definitions.h @@ -1,546 +1,546 @@ -#ifndef __DEFINITIONS_H
-#define __DEFINITIONS_H
-
-/******************************************************************
-* Menus
-*******************************************************************/
-enum class eViews {
- rootView = 0,
- detailView,
- recMenu,
- recMenu2,
- recMenu3,
- count
-};
-
-/******************************************************************
-* Viewelements
-*******************************************************************/
-enum class eViewElementsRoot {
- backgroundHor = 0,
- backgroundVer,
- headerHor,
- headerVer,
- footerHor,
- footerVer,
- timeHor,
- timeVer,
- dateTimelineHor,
- dateTimelineVer,
- timeIndicatorHor,
- timeIndicatorVer,
- channelJump,
- count
-};
-
-enum class eViewElementsDetail {
- background = 0,
- header,
- footer,
- time,
- count
-};
-
-enum class eViewElementsRecMenu {
- background = 0,
- scrollbar,
- count
-};
-
-/******************************************************************
-* Viewgrids
-*******************************************************************/
-enum class eViewGridsRoot {
- channelsHor = 0,
- channelsVer,
- schedulesHor,
- schedulesVer,
- channelGroupsHor,
- channelGroupsVer,
- timelineHor,
- timelineVer,
- count
-};
-
-enum class eViewGridsRecMenu {
- menu = 0,
- count
-};
-
-/******************************************************************
-* Tokens Rootview Viewelements
-*******************************************************************/
-enum class eHeaderST {
- title = 0,
- shorttext,
- description,
- start,
- stop,
- day,
- date,
- durationminutes,
- channelname,
- channelid,
- posterpath,
- count
-};
-
-enum class eHeaderIT {
- isdummy = 0,
- daynumeric,
- month,
- year,
- running,
- elapsed,
- duration,
- durationhours,
- channelnumber,
- channellogoexists,
- hasposter,
- posterwidth,
- posterheight,
- count
-};
-
-enum class eFooterIT {
- red1 = 0, red2, red3, red4,
- green1, green2, green3, green4,
- yellow1, yellow2, yellow3, yellow4,
- blue1, blue2, blue3, blue4,
- count
-};
-
-enum class eFooterST {
- red = 0,
- green,
- yellow,
- blue,
- count
-};
-
-enum class eTimeST {
- time = 0,
- monthname,
- monthnameshort,
- month,
- dayleadingzero,
- dayname,
- daynameshort,
- count
-};
-
-enum class eTimeIT {
- sec = 0,
- min,
- hour,
- hmins,
- year,
- day,
- count
-};
-
-enum class eDateTimeST {
- weekday = 0,
- date,
- count
-};
-
-enum class eTimeIndicatorIT {
- percenttotal = 0,
- count
-};
-
-enum class eChannelJumpST {
- channel = 0,
- count
-};
-
-/******************************************************************
-* Tokens Rootview Grids
-*******************************************************************/
-enum class eChannelGridST {
- name = 0,
- channelid,
- count
-};
-
-enum class eChannelGridIT {
- number = 0,
- channellogoexists,
- count
-};
-
-enum class eSchedulesGridST {
- title = 0,
- shorttext,
- start,
- stop,
- count
-};
-
-enum class eSchedulesGridIT {
- color = 0,
- dummy,
- timer,
- switchtimer,
- count
-};
-
-enum class eTimelineGridST {
- timestring = 0,
- count
-};
-
-enum class eTimelineGridIT {
- fullhour = 0,
- count
-};
-
-enum class eChannelgroupsGridST {
- group = 0,
- count
-};
-
-enum class eChannelgroupsGridIT {
- color = 0,
- count
-};
-
-/******************************************************************
-* Tokens Detailview ViewElements
-*******************************************************************/
-enum class eScrollbarIT {
- height = 0,
- offset,
- count
-};
-
-enum class eScraperHeaderST {
- posterpath = 0,
- bannerpath,
- count
-};
-
-enum class eScraperHeaderIT {
- ismovie = 0,
- isseries,
- posteravailable,
- posterwidth,
- posterheight,
- banneravailable,
- bannerwidth,
- bannerheight,
- count
-};
-
-enum class eDetailedHeaderST {
- title = eScraperHeaderST::count,
- shorttext,
- start,
- stop,
- day,
- date,
- durationminutes,
- vps,
- channelname,
- channelid,
- epgpicpath,
- count
-};
-
-enum class eDetailedHeaderIT {
- daynumeric = eScraperHeaderIT::count,
- month,
- year,
- running,
- elapsed,
- duration,
- durationhours,
- channelnumber,
- channellogoexists,
- epgpicavailable,
- count
-};
-
-enum class eTabsIT {
- count = 0,
-};
-
-enum class eTabsST {
- currenttab = 0,
- prevtab,
- nexttab,
- count
-};
-
-enum class eTabsLT {
- title = 0,
- current,
- count
-};
-
-enum class eScraperST {
- movietitle = 0,
- movieoriginalTitle,
- movietagline,
- movieoverview,
- moviegenres,
- moviehomepage,
- moviereleasedate,
- moviepopularity,
- movievoteaverage,
- posterpath,
- fanartpath,
- moviecollectionName,
- collectionposterpath,
- collectionfanartpath,
- seriesname,
- seriesoverview,
- seriesfirstaired,
- seriesnetwork,
- seriesgenre,
- seriesrating,
- seriesstatus,
- episodetitle,
- episodefirstaired,
- episodegueststars,
- episodeoverview,
- episoderating,
- episodeimagepath,
- seasonposterpath,
- seriesposter1path,
- seriesposter2path,
- seriesposter3path,
- seriesfanart1path,
- seriesfanart2path,
- seriesfanart3path,
- seriesbanner1path,
- seriesbanner2path,
- seriesbanner3path,
- count
-};
-
-enum class eScraperIT {
- ismovie = 0,
- moviebudget,
- movierevenue,
- movieadult,
- movieruntime,
- isseries,
- posterwidth,
- posterheight,
- fanartwidth,
- fanartheight,
- movieiscollection,
- collectionposterwidth,
- collectionposterheight,
- collectionfanartwidth,
- collectionfanartheight,
- epgpicavailable,
- episodenumber,
- episodeseason,
- episodeimagewidth,
- episodeimageheight,
- seasonposterwidth,
- seasonposterheight,
- seriesposter1width,
- seriesposter1height,
- seriesposter2width,
- seriesposter2height,
- seriesposter3width,
- seriesposter3height,
- seriesfanart1width,
- seriesfanart1height,
- seriesfanart2width,
- seriesfanart2height,
- seriesfanart3width,
- seriesfanart3height,
- seriesbanner1width,
- seriesbanner1height,
- seriesbanner2width,
- seriesbanner2height,
- seriesbanner3width,
- seriesbanner3height,
- count
-};
-
-enum class eScraperLT {
- //actors
- name = 0,
- role,
- thumb,
- thumbwidth,
- thumbheight,
- count
-};
-
-enum class eDetailedEpgST {
- title = eScraperST::count,
- shorttext,
- description,
- start,
- stop,
- day,
- date,
- durationminutes,
- vps,
- channelname,
- channelid,
- epgpic1path,
- epgpic2path,
- epgpic3path,
- count
-};
-
-enum class eDetailedEpgIT {
- daynumeric = eScraperIT::count,
- month,
- year,
- running,
- elapsed,
- duration,
- durationhours,
- channelnumber,
- channellogoexists,
- hasreruns,
- epgpic1avaialble,
- epgpic2avaialble,
- epgpic3avaialble,
- count
-};
-
-enum class eRerunsLT {
- title = 0,
- shorttext,
- date,
- day,
- start,
- stop,
- channelname,
- channelnumber,
- channelid,
- channellogoexists,
- count
-};
-
-/******************************************************************
-* Tokens RecMenu ViewElements
-*******************************************************************/
-enum class eBackgroundRecMenuIT {
- menuwidth = 0,
- menuheight,
- hasscrollbar,
- count
-};
-
-enum class eScrollbarRecMenuIT {
- menuwidth = 0,
- posy,
- totalheight,
- height,
- offset,
- count
-};
-
-enum class eRecMenuIT {
- info = 0,
- lines,
- button,
- buttonyesno,
- yes,
- intselector,
- value,
- boolselector,
- stringselector,
- textinput,
- editmode,
- timeselector,
- dayselector,
- channelselector,
- channelnumber,
- channellogoexisis,
- weekdayselector,
- dayselected,
- day0set,
- day1set,
- day2set,
- day3set,
- day4set,
- day5set,
- day6set,
- directoryselector,
- timerconflictheader,
- overlapstartpercent,
- overlapwidthpercent,
- timerconflict,
- infoactive,
- deleteactive,
- editactive,
- searchactive,
- timerstartpercent,
- timerwidthpercent,
- event,
- hastimer,
- recording,
- recduration,
- searchtimer,
- timeractive,
- activetimers,
- recordingsdone,
- timelineheader,
- timerset,
- channeltransponder,
- timelinetimer,
- timerstart,
- timerwidth,
- favorite,
- count
-};
-
-enum class eRecMenuST {
- line1 = 0,
- line2,
- line3,
- line4,
- value,
- buttontext,
- textyes,
- textno,
- text,
- channelname,
- channelid,
- transponder,
- day0abbr,
- day1abbr,
- day2abbr,
- day3abbr,
- day4abbr,
- day5abbr,
- day6abbr,
- folder,
- conflictstart,
- conflictstop,
- overlapstart,
- overlapstop,
- timertitle,
- starttime,
- stoptime,
- date,
- weekday,
- title,
- shorttext,
- recname,
- recstarttime,
- recdate,
- searchstring,
- timerstart,
- timerstop,
- eventtitle,
- eventshorttext,
- eventstart,
- eventstop,
- favdesc,
- count
-};
-
+#ifndef __DEFINITIONS_H +#define __DEFINITIONS_H + +/****************************************************************** +* Menus +*******************************************************************/ +enum class eViews { + rootView = 0, + detailView, + recMenu, + recMenu2, + recMenu3, + count +}; + +/****************************************************************** +* Viewelements +*******************************************************************/ +enum class eViewElementsRoot { + backgroundHor = 0, + backgroundVer, + headerHor, + headerVer, + footerHor, + footerVer, + timeHor, + timeVer, + dateTimelineHor, + dateTimelineVer, + timeIndicatorHor, + timeIndicatorVer, + channelJump, + count +}; + +enum class eViewElementsDetail { + background = 0, + header, + footer, + time, + count +}; + +enum class eViewElementsRecMenu { + background = 0, + scrollbar, + count +}; + +/****************************************************************** +* Viewgrids +*******************************************************************/ +enum class eViewGridsRoot { + channelsHor = 0, + channelsVer, + schedulesHor, + schedulesVer, + channelGroupsHor, + channelGroupsVer, + timelineHor, + timelineVer, + count +}; + +enum class eViewGridsRecMenu { + menu = 0, + count +}; + +/****************************************************************** +* Tokens Rootview Viewelements +*******************************************************************/ +enum class eHeaderST { + title = 0, + shorttext, + description, + start, + stop, + day, + date, + durationminutes, + channelname, + channelid, + posterpath, + count +}; + +enum class eHeaderIT { + isdummy = 0, + daynumeric, + month, + year, + running, + elapsed, + duration, + durationhours, + channelnumber, + channellogoexists, + hasposter, + posterwidth, + posterheight, + count +}; + +enum class eFooterIT { + red1 = 0, red2, red3, red4, + green1, green2, green3, green4, + yellow1, yellow2, yellow3, yellow4, + blue1, blue2, blue3, blue4, + count +}; + +enum class eFooterST { + red = 0, + green, + yellow, + blue, + count +}; + +enum class eTimeST { + time = 0, + monthname, + monthnameshort, + month, + dayleadingzero, + dayname, + daynameshort, + count +}; + +enum class eTimeIT { + sec = 0, + min, + hour, + hmins, + year, + day, + count +}; + +enum class eDateTimeST { + weekday = 0, + date, + count +}; + +enum class eTimeIndicatorIT { + percenttotal = 0, + count +}; + +enum class eChannelJumpST { + channel = 0, + count +}; + +/****************************************************************** +* Tokens Rootview Grids +*******************************************************************/ +enum class eChannelGridST { + name = 0, + channelid, + count +}; + +enum class eChannelGridIT { + number = 0, + channellogoexists, + count +}; + +enum class eSchedulesGridST { + title = 0, + shorttext, + start, + stop, + count +}; + +enum class eSchedulesGridIT { + color = 0, + dummy, + timer, + switchtimer, + count +}; + +enum class eTimelineGridST { + timestring = 0, + count +}; + +enum class eTimelineGridIT { + fullhour = 0, + count +}; + +enum class eChannelgroupsGridST { + group = 0, + count +}; + +enum class eChannelgroupsGridIT { + color = 0, + count +}; + +/****************************************************************** +* Tokens Detailview ViewElements +*******************************************************************/ +enum class eScrollbarIT { + height = 0, + offset, + count +}; + +enum class eScraperHeaderST { + posterpath = 0, + bannerpath, + count +}; + +enum class eScraperHeaderIT { + ismovie = 0, + isseries, + posteravailable, + posterwidth, + posterheight, + banneravailable, + bannerwidth, + bannerheight, + count +}; + +enum class eDetailedHeaderST { + title = eScraperHeaderST::count, + shorttext, + start, + stop, + day, + date, + durationminutes, + vps, + channelname, + channelid, + epgpicpath, + count +}; + +enum class eDetailedHeaderIT { + daynumeric = eScraperHeaderIT::count, + month, + year, + running, + elapsed, + duration, + durationhours, + channelnumber, + channellogoexists, + epgpicavailable, + count +}; + +enum class eTabsIT { + count = 0, +}; + +enum class eTabsST { + currenttab = 0, + prevtab, + nexttab, + count +}; + +enum class eTabsLT { + title = 0, + current, + count +}; + +enum class eScraperST { + movietitle = 0, + movieoriginalTitle, + movietagline, + movieoverview, + moviegenres, + moviehomepage, + moviereleasedate, + moviepopularity, + movievoteaverage, + posterpath, + fanartpath, + moviecollectionName, + collectionposterpath, + collectionfanartpath, + seriesname, + seriesoverview, + seriesfirstaired, + seriesnetwork, + seriesgenre, + seriesrating, + seriesstatus, + episodetitle, + episodefirstaired, + episodegueststars, + episodeoverview, + episoderating, + episodeimagepath, + seasonposterpath, + seriesposter1path, + seriesposter2path, + seriesposter3path, + seriesfanart1path, + seriesfanart2path, + seriesfanart3path, + seriesbanner1path, + seriesbanner2path, + seriesbanner3path, + count +}; + +enum class eScraperIT { + ismovie = 0, + moviebudget, + movierevenue, + movieadult, + movieruntime, + isseries, + posterwidth, + posterheight, + fanartwidth, + fanartheight, + movieiscollection, + collectionposterwidth, + collectionposterheight, + collectionfanartwidth, + collectionfanartheight, + epgpicavailable, + episodenumber, + episodeseason, + episodeimagewidth, + episodeimageheight, + seasonposterwidth, + seasonposterheight, + seriesposter1width, + seriesposter1height, + seriesposter2width, + seriesposter2height, + seriesposter3width, + seriesposter3height, + seriesfanart1width, + seriesfanart1height, + seriesfanart2width, + seriesfanart2height, + seriesfanart3width, + seriesfanart3height, + seriesbanner1width, + seriesbanner1height, + seriesbanner2width, + seriesbanner2height, + seriesbanner3width, + seriesbanner3height, + count +}; + +enum class eScraperLT { + //actors + name = 0, + role, + thumb, + thumbwidth, + thumbheight, + count +}; + +enum class eDetailedEpgST { + title = eScraperST::count, + shorttext, + description, + start, + stop, + day, + date, + durationminutes, + vps, + channelname, + channelid, + epgpic1path, + epgpic2path, + epgpic3path, + count +}; + +enum class eDetailedEpgIT { + daynumeric = eScraperIT::count, + month, + year, + running, + elapsed, + duration, + durationhours, + channelnumber, + channellogoexists, + hasreruns, + epgpic1avaialble, + epgpic2avaialble, + epgpic3avaialble, + count +}; + +enum class eRerunsLT { + title = 0, + shorttext, + date, + day, + start, + stop, + channelname, + channelnumber, + channelid, + channellogoexists, + count +}; + +/****************************************************************** +* Tokens RecMenu ViewElements +*******************************************************************/ +enum class eBackgroundRecMenuIT { + menuwidth = 0, + menuheight, + hasscrollbar, + count +}; + +enum class eScrollbarRecMenuIT { + menuwidth = 0, + posy, + totalheight, + height, + offset, + count +}; + +enum class eRecMenuIT { + info = 0, + lines, + button, + buttonyesno, + yes, + intselector, + value, + boolselector, + stringselector, + textinput, + editmode, + timeselector, + dayselector, + channelselector, + channelnumber, + channellogoexisis, + weekdayselector, + dayselected, + day0set, + day1set, + day2set, + day3set, + day4set, + day5set, + day6set, + directoryselector, + timerconflictheader, + overlapstartpercent, + overlapwidthpercent, + timerconflict, + infoactive, + deleteactive, + editactive, + searchactive, + timerstartpercent, + timerwidthpercent, + event, + hastimer, + recording, + recduration, + searchtimer, + timeractive, + activetimers, + recordingsdone, + timelineheader, + timerset, + channeltransponder, + timelinetimer, + timerstart, + timerwidth, + favorite, + count +}; + +enum class eRecMenuST { + line1 = 0, + line2, + line3, + line4, + value, + buttontext, + textyes, + textno, + text, + channelname, + channelid, + transponder, + day0abbr, + day1abbr, + day2abbr, + day3abbr, + day4abbr, + day5abbr, + day6abbr, + folder, + conflictstart, + conflictstop, + overlapstart, + overlapstop, + timertitle, + starttime, + stoptime, + date, + weekday, + title, + shorttext, + recname, + recstarttime, + recdate, + searchstring, + timerstart, + timerstop, + eventtitle, + eventshorttext, + eventstart, + eventstop, + favdesc, + count +}; + #endif //__DEFINITIONS_H
\ No newline at end of file diff --git a/detailview.c b/detailview.c index 24c2e79..1dae0b9 100644 --- a/detailview.c +++ b/detailview.c @@ -1,780 +1,794 @@ -#include "helpers.h"
-#include "tvguidengosd.h"
-#include "detailview.h"
-
-cDetailView::cDetailView(skindesignerapi::cOsdView *detailView, const cEvent *event) {
- init = true;
- lastSecond = -1;
- this->detailView = detailView;
- this->event = event;
- back = detailView->GetViewElement((int)eViewElementsDetail::background);
- header = detailView->GetViewElement((int)eViewElementsDetail::header);
- footer = detailView->GetViewElement((int)eViewElementsDetail::footer);
- watch = detailView->GetViewElement((int)eViewElementsDetail::time);
- tabs = detailView->GetViewTabs();
- movie = NULL;
- series = NULL;
-}
-
-cDetailView::~cDetailView() {
- delete back;
- delete header;
- delete footer;
- delete watch;
- delete tabs;
- delete detailView;
- delete movie;
- delete series;
-}
-
-void cDetailView::Draw(void) {
- if (!event) {
- return;
- }
- if (init) {
- DrawBackground();
- DrawHeader();
- DrawFooter();
- Flush();
- SetTabTokens();
- tabs->Init();
- init = false;
- }
- tabs->Display();
-}
-
-void cDetailView::Left(void) {
- tabs->Left();
- tabs->Display();
-}
-
-void cDetailView::Right(void) {
- tabs->Right();
- tabs->Display();
-}
-
-void cDetailView::Up(void) {
- tabs->Up();
- tabs->Display();
-}
-
-void cDetailView::Down(void) {
- tabs->Down();
- tabs->Display();
-}
-
-void cDetailView::DefineTokens(eViewElementsDetail ve, skindesignerapi::cTokenContainer *tk) {
- switch (ve) {
- case eViewElementsDetail::header:
- tk->DefineIntToken("{ismovie}", (int)eScraperHeaderIT::ismovie);
- tk->DefineIntToken("{isseries}", (int)eScraperHeaderIT::isseries);
- tk->DefineIntToken("{posteravailable}", (int)eScraperHeaderIT::posteravailable);
- tk->DefineIntToken("{posterwidth}", (int)eScraperHeaderIT::posterwidth);
- tk->DefineIntToken("{posterheight}", (int)eScraperHeaderIT::posterheight);
- tk->DefineIntToken("{banneravailable}", (int)eScraperHeaderIT::banneravailable);
- tk->DefineIntToken("{bannerwidth}", (int)eScraperHeaderIT::bannerwidth);
- tk->DefineIntToken("{bannerheight}", (int)eScraperHeaderIT::bannerheight);
- tk->DefineIntToken("{daynumeric}", (int)eDetailedHeaderIT::daynumeric);
- tk->DefineIntToken("{month}", (int)eDetailedHeaderIT::month);
- tk->DefineIntToken("{year}", (int)eDetailedHeaderIT::year);
- tk->DefineIntToken("{running}", (int)eDetailedHeaderIT::running);
- tk->DefineIntToken("{elapsed}", (int)eDetailedHeaderIT::elapsed);
- tk->DefineIntToken("{duration}", (int)eDetailedHeaderIT::duration);
- tk->DefineIntToken("{durationhours}", (int)eDetailedHeaderIT::durationhours);
- tk->DefineIntToken("{channelnumber}", (int)eDetailedHeaderIT::channelnumber);
- tk->DefineIntToken("{channellogoexists}", (int)eDetailedHeaderIT::channellogoexists);
- tk->DefineIntToken("{epgpicavailable}", (int)eDetailedHeaderIT::epgpicavailable);
- tk->DefineStringToken("{posterpath}", (int)eScraperHeaderST::posterpath);
- tk->DefineStringToken("{bannerpath}", (int)eScraperHeaderST::bannerpath);
- tk->DefineStringToken("{title}", (int)eDetailedHeaderST::title);
- tk->DefineStringToken("{shorttext}", (int)eDetailedHeaderST::shorttext);
- tk->DefineStringToken("{start}", (int)eDetailedHeaderST::start);
- tk->DefineStringToken("{stop}", (int)eDetailedHeaderST::stop);
- tk->DefineStringToken("{day}", (int)eDetailedHeaderST::day);
- tk->DefineStringToken("{date}", (int)eDetailedHeaderST::date);
- tk->DefineStringToken("{durationminutes}", (int)eDetailedHeaderST::durationminutes);
- tk->DefineStringToken("{vps}", (int)eDetailedHeaderST::vps);
- tk->DefineStringToken("{channelname}", (int)eDetailedHeaderST::channelname);
- tk->DefineStringToken("{channelid}", (int)eDetailedHeaderST::channelid);
- tk->DefineStringToken("{epgpicpath}", (int)eDetailedHeaderST::epgpicpath);
- break;
- case eViewElementsDetail::footer:
- tk->DefineIntToken("{red1}", (int)eFooterIT::red1);
- tk->DefineIntToken("{red2}", (int)eFooterIT::red2);
- tk->DefineIntToken("{red3}", (int)eFooterIT::red3);
- tk->DefineIntToken("{red4}", (int)eFooterIT::red4);
- tk->DefineIntToken("{green1}", (int)eFooterIT::green1);
- tk->DefineIntToken("{green2}", (int)eFooterIT::green2);
- tk->DefineIntToken("{green3}", (int)eFooterIT::green3);
- tk->DefineIntToken("{green4}", (int)eFooterIT::green4);
- tk->DefineIntToken("{yellow1}", (int)eFooterIT::yellow1);
- tk->DefineIntToken("{yellow2}", (int)eFooterIT::yellow2);
- tk->DefineIntToken("{yellow3}", (int)eFooterIT::yellow3);
- tk->DefineIntToken("{yellow4}", (int)eFooterIT::yellow4);
- tk->DefineIntToken("{blue1}", (int)eFooterIT::blue1);
- tk->DefineIntToken("{blue2}", (int)eFooterIT::blue2);
- tk->DefineIntToken("{blue3}", (int)eFooterIT::blue3);
- tk->DefineIntToken("{blue4}", (int)eFooterIT::blue4);
- tk->DefineStringToken("{red}", (int)eFooterST::red);
- tk->DefineStringToken("{green}", (int)eFooterST::green);
- tk->DefineStringToken("{yellow}", (int)eFooterST::yellow);
- tk->DefineStringToken("{blue}", (int)eFooterST::blue);
- break;
- default:
- break;
- }
-}
-
-void cDetailView::DefineTabTokens(skindesignerapi::cTokenContainer *tk) {
- tk->DefineStringToken("{title}", (int)eDetailedEpgST::title);
- tk->DefineStringToken("{shorttext}", (int)eDetailedEpgST::shorttext);
- tk->DefineStringToken("{description}", (int)eDetailedEpgST::description);
- tk->DefineStringToken("{start}", (int)eDetailedEpgST::start);
- tk->DefineStringToken("{stop}", (int)eDetailedEpgST::stop);
- tk->DefineStringToken("{day}", (int)eDetailedEpgST::day);
- tk->DefineStringToken("{date}", (int)eDetailedEpgST::date);
- tk->DefineStringToken("{durationminutes}", (int)eDetailedEpgST::durationminutes);
- tk->DefineStringToken("{vps}", (int)eDetailedEpgST::vps);
- tk->DefineStringToken("{channelname}", (int)eDetailedEpgST::channelname);
- tk->DefineStringToken("{channelid}", (int)eDetailedEpgST::channelid);
- tk->DefineStringToken("{epgpic1path}", (int)eDetailedEpgST::epgpic1path);
- tk->DefineStringToken("{epgpic2path}", (int)eDetailedEpgST::epgpic2path);
- tk->DefineStringToken("{epgpic3path}", (int)eDetailedEpgST::epgpic3path);
- tk->DefineStringToken("{movietitle}", (int)eScraperST::movietitle);
- tk->DefineStringToken("{movieoriginalTitle}", (int)eScraperST::movieoriginalTitle);
- tk->DefineStringToken("{movietagline}", (int)eScraperST::movietagline);
- tk->DefineStringToken("{movieoverview}", (int)eScraperST::movieoverview);
- tk->DefineStringToken("{moviegenres}", (int)eScraperST::moviegenres);
- tk->DefineStringToken("{moviehomepage}", (int)eScraperST::moviehomepage);
- tk->DefineStringToken("{moviereleasedate}", (int)eScraperST::moviereleasedate);
- tk->DefineStringToken("{moviepopularity}", (int)eScraperST::moviepopularity);
- tk->DefineStringToken("{movievoteaverage}", (int)eScraperST::movievoteaverage);
- tk->DefineStringToken("{posterpath}", (int)eScraperST::posterpath);
- tk->DefineStringToken("{fanartpath}", (int)eScraperST::fanartpath);
- tk->DefineStringToken("{moviecollectionName}", (int)eScraperST::moviecollectionName);
- tk->DefineStringToken("{collectionposterpath}", (int)eScraperST::collectionposterpath);
- tk->DefineStringToken("{collectionfanartpath}", (int)eScraperST::collectionfanartpath);
- tk->DefineStringToken("{seriesname}", (int)eScraperST::seriesname);
- tk->DefineStringToken("{seriesoverview}", (int)eScraperST::seriesoverview);
- tk->DefineStringToken("{seriesfirstaired}", (int)eScraperST::seriesfirstaired);
- tk->DefineStringToken("{seriesnetwork}", (int)eScraperST::seriesnetwork);
- tk->DefineStringToken("{seriesgenre}", (int)eScraperST::seriesgenre);
- tk->DefineStringToken("{seriesrating}", (int)eScraperST::seriesrating);
- tk->DefineStringToken("{seriesstatus}", (int)eScraperST::seriesstatus);
- tk->DefineStringToken("{episodetitle}", (int)eScraperST::episodetitle);
- tk->DefineStringToken("{episodefirstaired}", (int)eScraperST::episodefirstaired);
- tk->DefineStringToken("{episodegueststars}", (int)eScraperST::episodegueststars);
- tk->DefineStringToken("{episodeoverview}", (int)eScraperST::episodeoverview);
- tk->DefineStringToken("{episoderating}", (int)eScraperST::episoderating);
- tk->DefineStringToken("{episodeimagepath}", (int)eScraperST::episodeimagepath);
- tk->DefineStringToken("{seasonposterpath}", (int)eScraperST::seasonposterpath);
- tk->DefineStringToken("{seriesposter1path}", (int)eScraperST::seriesposter1path);
- tk->DefineStringToken("{seriesposter2path}", (int)eScraperST::seriesposter2path);
- tk->DefineStringToken("{seriesposter3path}", (int)eScraperST::seriesposter3path);
- tk->DefineStringToken("{seriesfanart1path}", (int)eScraperST::seriesfanart1path);
- tk->DefineStringToken("{seriesfanart2path}", (int)eScraperST::seriesfanart2path);
- tk->DefineStringToken("{seriesfanart3path}", (int)eScraperST::seriesfanart3path);
- tk->DefineStringToken("{seriesbanner1path}", (int)eScraperST::seriesbanner1path);
- tk->DefineStringToken("{seriesbanner2path}", (int)eScraperST::seriesbanner2path);
- tk->DefineStringToken("{seriesbanner3path}", (int)eScraperST::seriesbanner3path);
- tk->DefineIntToken("{daynumeric}", (int)eDetailedEpgIT::daynumeric);
- tk->DefineIntToken("{month}", (int)eDetailedEpgIT::month);
- tk->DefineIntToken("{year}", (int)eDetailedEpgIT::year);
- tk->DefineIntToken("{running}", (int)eDetailedEpgIT::running);
- tk->DefineIntToken("{elapsed}", (int)eDetailedEpgIT::elapsed);
- tk->DefineIntToken("{duration}", (int)eDetailedEpgIT::duration);
- tk->DefineIntToken("{durationhours}", (int)eDetailedEpgIT::durationhours);
- tk->DefineIntToken("{channelnumber}", (int)eDetailedEpgIT::channelnumber);
- tk->DefineIntToken("{channellogoexists}", (int)eDetailedEpgIT::channellogoexists);
- tk->DefineIntToken("{hasreruns}", (int)eDetailedEpgIT::hasreruns);
- tk->DefineIntToken("{epgpic1avaialble}", (int)eDetailedEpgIT::epgpic1avaialble);
- tk->DefineIntToken("{epgpic2avaialble}", (int)eDetailedEpgIT::epgpic2avaialble);
- tk->DefineIntToken("{epgpic3avaialble}", (int)eDetailedEpgIT::epgpic3avaialble);
- tk->DefineIntToken("{ismovie}", (int)eScraperIT::ismovie);
- tk->DefineIntToken("{moviebudget}", (int)eScraperIT::moviebudget);
- tk->DefineIntToken("{movierevenue}", (int)eScraperIT::movierevenue);
- tk->DefineIntToken("{movieadult}", (int)eScraperIT::movieadult);
- tk->DefineIntToken("{movieruntime}", (int)eScraperIT::movieruntime);
- tk->DefineIntToken("{isseries}", (int)eScraperIT::isseries);
- tk->DefineIntToken("{posterwidth}", (int)eScraperIT::posterwidth);
- tk->DefineIntToken("{posterheight}", (int)eScraperIT::posterheight);
- tk->DefineIntToken("{fanartwidth}", (int)eScraperIT::fanartwidth);
- tk->DefineIntToken("{fanartheight}", (int)eScraperIT::fanartheight);
- tk->DefineIntToken("{movieiscollection}", (int)eScraperIT::movieiscollection);
- tk->DefineIntToken("{collectionposterwidth}", (int)eScraperIT::collectionposterwidth);
- tk->DefineIntToken("{collectionposterheight}", (int)eScraperIT::collectionposterheight);
- tk->DefineIntToken("{collectionfanartwidth}", (int)eScraperIT::collectionfanartwidth);
- tk->DefineIntToken("{collectionfanartheight}", (int)eScraperIT::collectionfanartheight);
- tk->DefineIntToken("{epgpicavailable}", (int)eScraperIT::epgpicavailable);
- tk->DefineIntToken("{episodenumber}", (int)eScraperIT::episodenumber);
- tk->DefineIntToken("{episodeseason}", (int)eScraperIT::episodeseason);
- tk->DefineIntToken("{episodeimagewidth}", (int)eScraperIT::episodeimagewidth);
- tk->DefineIntToken("{episodeimageheight}", (int)eScraperIT::episodeimageheight);
- tk->DefineIntToken("{seasonposterwidth}", (int)eScraperIT::seasonposterwidth);
- tk->DefineIntToken("{seasonposterheight}", (int)eScraperIT::seasonposterheight);
- tk->DefineIntToken("{seriesposter1width}", (int)eScraperIT::seriesposter1width);
- tk->DefineIntToken("{seriesposter1height}", (int)eScraperIT::seriesposter1height);
- tk->DefineIntToken("{seriesposter2width}", (int)eScraperIT::seriesposter2width);
- tk->DefineIntToken("{seriesposter2height}", (int)eScraperIT::seriesposter2height);
- tk->DefineIntToken("{seriesposter3width}", (int)eScraperIT::seriesposter3width);
- tk->DefineIntToken("{seriesposter3height}", (int)eScraperIT::seriesposter3height);
- tk->DefineIntToken("{seriesfanart1width}", (int)eScraperIT::seriesfanart1width);
- tk->DefineIntToken("{seriesfanart1height}", (int)eScraperIT::seriesfanart1height);
- tk->DefineIntToken("{seriesfanart2width}", (int)eScraperIT::seriesfanart2width);
- tk->DefineIntToken("{seriesfanart2height}", (int)eScraperIT::seriesfanart2height);
- tk->DefineIntToken("{seriesfanart3width}", (int)eScraperIT::seriesfanart3width);
- tk->DefineIntToken("{seriesfanart3height}", (int)eScraperIT::seriesfanart3height);
- tk->DefineIntToken("{seriesbanner1width}", (int)eScraperIT::seriesbanner1width);
- tk->DefineIntToken("{seriesbanner1height}", (int)eScraperIT::seriesbanner1height);
- tk->DefineIntToken("{seriesbanner2width}", (int)eScraperIT::seriesbanner2width);
- tk->DefineIntToken("{seriesbanner2height}", (int)eScraperIT::seriesbanner2height);
- tk->DefineIntToken("{seriesbanner3width}", (int)eScraperIT::seriesbanner3width);
- tk->DefineIntToken("{seriesbanner3height}", (int)eScraperIT::seriesbanner3height);
- tk->DefineLoopToken("{reruns[title]}", (int)eRerunsLT::title);
- tk->DefineLoopToken("{reruns[shorttext]}", (int)eRerunsLT::shorttext);
- tk->DefineLoopToken("{reruns[date]}", (int)eRerunsLT::date);
- tk->DefineLoopToken("{reruns[day]}", (int)eRerunsLT::day);
- tk->DefineLoopToken("{reruns[start]}", (int)eRerunsLT::start);
- tk->DefineLoopToken("{reruns[stop]}", (int)eRerunsLT::stop);
- tk->DefineLoopToken("{reruns[channelname]}", (int)eRerunsLT::channelname);
- tk->DefineLoopToken("{reruns[channelnumber]}", (int)eRerunsLT::channelnumber);
- tk->DefineLoopToken("{reruns[channelid]}", (int)eRerunsLT::channelid);
- tk->DefineLoopToken("{reruns[channellogoexists]}", (int)eRerunsLT::channellogoexists);
- tk->DefineLoopToken("{actors[name]}", (int)eScraperLT::name);
- tk->DefineLoopToken("{actors[role]}", (int)eScraperLT::role);
- tk->DefineLoopToken("{actors[thumb]}", (int)eScraperLT::thumb);
- tk->DefineLoopToken("{actors[thumbwidth]}", (int)eScraperLT::thumbwidth);
- tk->DefineLoopToken("{actors[thumbheight]}", (int)eScraperLT::thumbheight);
-}
-/********************************************************************
-* Private Functions
-********************************************************************/
-void cDetailView::DrawBackground(void) {
- back->Display();
-}
-
-void cDetailView::DrawHeader(void) {
- if (!event)
- return;
- header->ClearTokens();
- static cPlugin *pScraper = GetScraperPlugin();
- if (pScraper) {
- ScraperGetEventType getType;
- getType.event = event;
- if (!pScraper->Service("GetEventType", &getType)) {
- if (getType.type == tMovie) {
- cMovie movie;
- movie.movieId = getType.movieId;
- pScraper->Service("GetMovie", &movie);
- header->AddIntToken((int)eScraperHeaderIT::banneravailable, true);
- header->AddIntToken((int)eScraperHeaderIT::isseries, false);
- header->AddIntToken((int)eScraperHeaderIT::posteravailable, true);
- header->AddIntToken((int)eScraperHeaderIT::banneravailable, false);
- header->AddStringToken((int)eScraperHeaderST::posterpath, movie.poster.path.c_str());
- header->AddIntToken((int)eScraperHeaderIT::posterwidth, movie.poster.width);
- header->AddIntToken((int)eScraperHeaderIT::posterheight, movie.poster.height);
- } else if (getType.type == tSeries) {
- cSeries series;
- series.seriesId = getType.seriesId;
- series.episodeId = getType.episodeId;
- pScraper->Service("GetSeries", &series);
- header->AddIntToken((int)eScraperHeaderIT::ismovie, false);
- header->AddIntToken((int)eScraperHeaderIT::isseries, true);
- vector<cTvMedia>::iterator poster = series.posters.begin();
- if (poster != series.posters.end()) {
- header->AddIntToken((int)eScraperHeaderIT::posterwidth, (*poster).width);
- header->AddIntToken((int)eScraperHeaderIT::posterheight, (*poster).height);
- header->AddStringToken((int)eScraperHeaderST::posterpath, (*poster).path.c_str());
- header->AddIntToken((int)eScraperHeaderIT::posteravailable, true);
- }
- vector<cTvMedia>::iterator banner = series.banners.begin();
- if (banner != series.banners.end()) {
- header->AddIntToken((int)eScraperHeaderIT::bannerwidth, (*banner).width);
- header->AddIntToken((int)eScraperHeaderIT::bannerheight, (*banner).height);
- header->AddStringToken((int)eScraperHeaderST::bannerpath, (*banner).path.c_str());
- header->AddIntToken((int)eScraperHeaderIT::banneravailable, true);
- }
- }
- }
- }
-
- header->AddStringToken((int)eDetailedHeaderST::title, event->Title());
- header->AddStringToken((int)eDetailedHeaderST::shorttext, event->ShortText());
- header->AddStringToken((int)eDetailedHeaderST::start, *(event->GetTimeString()));
- header->AddStringToken((int)eDetailedHeaderST::stop, *(event->GetEndTimeString()));
-
- time_t startTime = event->StartTime();
- header->AddStringToken((int)eDetailedHeaderST::day, *WeekDayName(startTime));
- header->AddStringToken((int)eDetailedHeaderST::date, *ShortDateString(startTime));
- struct tm * sStartTime = localtime(&startTime);
- header->AddIntToken((int)eDetailedHeaderIT::year, sStartTime->tm_year + 1900);
- header->AddIntToken((int)eDetailedHeaderIT::daynumeric, sStartTime->tm_mday);
- header->AddIntToken((int)eDetailedHeaderIT::month, sStartTime->tm_mon+1);
-
- const cChannel *channel = Channels.GetByChannelID(event->ChannelID());
- if (channel) {
- header->AddStringToken((int)eDetailedHeaderST::channelname, channel->Name());
- header->AddIntToken((int)eDetailedHeaderIT::channelnumber, channel->Number());
- } else {
- header->AddIntToken((int)eDetailedHeaderIT::channelnumber, 0);
- }
- cString channelID = channel->GetChannelID().ToString();
- header->AddStringToken((int)eDetailedHeaderST::channelid, *channelID);
- header->AddIntToken((int)eDetailedHeaderIT::channellogoexists, header->ChannelLogoExists(*channelID));
-
- bool isRunning = false;
- time_t now = time(NULL);
- if ((now >= event->StartTime()) && (now <= event->EndTime()))
- isRunning = true;
- header->AddIntToken((int)eDetailedHeaderIT::running, isRunning);
- if (isRunning) {
- header->AddIntToken((int)eDetailedHeaderIT::elapsed, (now - event->StartTime())/60);
- } else {
- header->AddIntToken((int)eDetailedHeaderIT::elapsed, 0);
- }
- header->AddIntToken((int)eDetailedHeaderIT::duration, event->Duration() / 60);
- header->AddIntToken((int)eDetailedHeaderIT::durationhours, event->Duration() / 3600);
- header->AddStringToken((int)eDetailedHeaderST::durationminutes, *cString::sprintf("%.2d", (event->Duration() / 60)%60));
- if (event->Vps())
- header->AddStringToken((int)eDetailedHeaderST::vps, *event->GetVpsString());
-
- stringstream epgImageName;
- epgImageName << event->EventID();
- string epgImagePath = header->GetEpgImagePath();
-
- bool epgPicAvailable = FileExists(epgImagePath, epgImageName.str(), "jpg");
- if (epgPicAvailable) {
- header->AddIntToken((int)eDetailedHeaderIT::epgpicavailable, true);
- header->AddStringToken((int)eDetailedHeaderST::epgpicpath, *cString::sprintf("%s%s.jpg", epgImagePath.c_str(), epgImageName.str().c_str()));
- } else {
- epgImageName << "_0";
- epgPicAvailable = FileExists(epgImagePath, epgImageName.str(), "jpg");
- if (epgPicAvailable) {
- header->AddIntToken((int)eDetailedHeaderIT::epgpicavailable, true);
- header->AddStringToken((int)eDetailedHeaderST::epgpicpath, *cString::sprintf("%s%s.jpg", epgImagePath.c_str(), epgImageName.str().c_str()));
- }
- }
-
- header->Display();
-}
-
-void cDetailView::DrawFooter(void) {
- string textGreen = "";
- string textYellow = "";
- string textRed = tr("Search & Record");
- string textBlue = tr("Switch");
-
- int colorKeys[4] = { Setup.ColorKey0, Setup.ColorKey1, Setup.ColorKey2, Setup.ColorKey3 };
-
- footer->Clear();
- footer->ClearTokens();
-
- footer->AddStringToken((int)eFooterST::red, textRed.c_str());
- footer->AddStringToken((int)eFooterST::green, textGreen.c_str());
- footer->AddStringToken((int)eFooterST::yellow, textYellow.c_str());
- footer->AddStringToken((int)eFooterST::blue, textBlue.c_str());
-
- for (int button = 0; button < 4; button++) {
- bool isRed = false;
- bool isGreen = false;
- bool isYellow = false;
- bool isBlue = false;
- switch (colorKeys[button]) {
- case 0:
- isRed = true;
- break;
- case 1:
- isGreen = true;
- break;
- case 2:
- isYellow = true;
- break;
- case 3:
- isBlue = true;
- break;
- default:
- break;
- }
- footer->AddIntToken(0 + button, isRed);
- footer->AddIntToken(4 + button, isGreen);
- footer->AddIntToken(8 + button, isYellow);
- footer->AddIntToken(12 + button, isBlue);
- }
-
- footer->Display();
-}
-
-bool cDetailView::DrawTime(void) {
- time_t t = time(0); // get time now
- struct tm * now = localtime(&t);
- int sec = now->tm_sec;
- if (sec == lastSecond)
- return false;
-
- int min = now->tm_min;
- int hour = now->tm_hour;
- int hourMinutes = hour%12 * 5 + min / 12;
-
- char monthname[20];
- char monthshort[10];
- strftime(monthshort, sizeof(monthshort), "%b", now);
- strftime(monthname, sizeof(monthname), "%B", now);
-
- watch->Clear();
- watch->ClearTokens();
- watch->AddIntToken((int)eTimeIT::sec, sec);
- watch->AddIntToken((int)eTimeIT::min, min);
- watch->AddIntToken((int)eTimeIT::hour, hour);
- watch->AddIntToken((int)eTimeIT::hmins, hourMinutes);
- watch->AddIntToken((int)eTimeIT::year, now->tm_year + 1900);
- watch->AddIntToken((int)eTimeIT::day, now->tm_mday);
- watch->AddStringToken((int)eTimeST::time, *TimeString(t));
- watch->AddStringToken((int)eTimeST::monthname, monthname);
- watch->AddStringToken((int)eTimeST::monthnameshort, monthshort);
- watch->AddStringToken((int)eTimeST::month, *cString::sprintf("%02d", now->tm_mon + 1));
- watch->AddStringToken((int)eTimeST::dayleadingzero, *cString::sprintf("%02d", now->tm_mday));
- watch->AddStringToken((int)eTimeST::dayname, *WeekDayNameFull(now->tm_wday));
- watch->AddStringToken((int)eTimeST::daynameshort, *WeekDayName(now->tm_wday));
- watch->Display();
-
- lastSecond = sec;
- return true;
-}
-
-void cDetailView::SetTabTokens(void) {
- tabs->ClearTokens();
- tabs->AddStringToken((int)eDetailedEpgST::title, event->Title());
- tabs->AddStringToken((int)eDetailedEpgST::shorttext, event->ShortText());
- tabs->AddStringToken((int)eDetailedEpgST::description, event->Description());
- tabs->AddStringToken((int)eDetailedEpgST::start, *(event->GetTimeString()));
- tabs->AddStringToken((int)eDetailedEpgST::stop, *(event->GetEndTimeString()));
- time_t startTime = event->StartTime();
- tabs->AddStringToken((int)eDetailedEpgST::day, *WeekDayName(startTime));
- tabs->AddStringToken((int)eDetailedEpgST::date, *ShortDateString(startTime));
- struct tm * sStartTime = localtime(&startTime);
- tabs->AddIntToken((int)eDetailedEpgIT::year, sStartTime->tm_year + 1900);
- tabs->AddIntToken((int)eDetailedEpgIT::daynumeric, sStartTime->tm_mday);
- tabs->AddIntToken((int)eDetailedEpgIT::month, sStartTime->tm_mon+1);
-
- cString channelID = event->ChannelID().ToString();
- tabs->AddStringToken((int)eDetailedEpgST::channelid, *channelID);
- tabs->AddIntToken((int)eDetailedEpgIT::channellogoexists, tabs->ChannelLogoExists(*channelID));
-
- bool isRunning = false;
- time_t now = time(NULL);
- if ((now >= event->StartTime()) && (now <= event->EndTime()))
- isRunning = true;
- tabs->AddIntToken((int)eDetailedEpgIT::running, isRunning);
- if (isRunning) {
- tabs->AddIntToken((int)eDetailedEpgIT::elapsed, (now - event->StartTime())/60);
- } else {
- tabs->AddIntToken((int)eDetailedEpgIT::elapsed, 0);
- }
- tabs->AddIntToken((int)eDetailedEpgIT::duration, event->Duration() / 60);
- tabs->AddIntToken((int)eDetailedEpgIT::durationhours, event->Duration() / 3600);
- tabs->AddStringToken((int)eDetailedEpgST::durationminutes, *cString::sprintf("%.2d", (event->Duration() / 60)%60));
- if (event->Vps())
- tabs->AddStringToken((int)eDetailedEpgST::vps, *event->GetVpsString());
- else
- tabs->AddStringToken((int)eDetailedEpgST::vps, "");
-
-
- bool scrapInfoAvailable = LoadScrapInfo(event);
- int numActors = NumActors();
-
- cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns = LoadReruns();
- int numReruns = NumReruns(reruns);
-
- vector<int> loopInfo;
- loopInfo.push_back(numReruns);
- loopInfo.push_back(numActors);
- tabs->SetLoop(loopInfo);
-
- if (numReruns > 0) {
- tabs->AddIntToken((int)eDetailedEpgIT::hasreruns, 1);
- SetReruns(reruns);
- }
- if (scrapInfoAvailable) {
- SetScraperTokens();
- }
-
- SetEpgPictures(event->EventID());
-}
-
-cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *cDetailView::LoadReruns(void) {
- cPlugin *epgSearchPlugin = cPluginManager::GetPlugin("epgsearch");
- if (!epgSearchPlugin)
- return NULL;
-
- if (isempty(event->Title()))
- return NULL;
-
- Epgsearch_searchresults_v1_0 data;
- data.query = (char*)event->Title();
- data.mode = 0;
- data.channelNr = 0;
- data.useTitle = true;
- data.useSubTitle = true;
- data.useDescription = false;
-
- cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *result = NULL;
- if (epgSearchPlugin->Service("Epgsearch-searchresults-v1.0", &data))
- result = data.pResultList;
- return result;
-}
-
-int cDetailView::NumReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns) {
- if (!reruns || reruns->Count() < 2)
- return 0;
-
- int maxNumReruns = config.rerunAmount;
- int rerunDistance = config.rerunDistance * 3600;
- int rerunMaxChannel = config.rerunMaxChannel;
-
- int i = 0;
- for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = reruns->First(); r && i < maxNumReruns; r = reruns->Next(r)) {
- time_t eventStart = event->StartTime();
- time_t rerunStart = r->event->StartTime();
- cChannel *channel = Channels.GetByChannelID(r->event->ChannelID(), true, true);
- //check for identical event
- if ((event->ChannelID() == r->event->ChannelID()) && (eventStart == rerunStart))
- continue;
- //check for timely distance
- if (rerunDistance > 0)
- if (rerunStart - eventStart < rerunDistance)
- continue;
- //check for maxchannel
- if (rerunMaxChannel > 0)
- if (channel && channel->Number() > rerunMaxChannel)
- continue;
- i++;
- }
- return i;
-}
-
-void cDetailView::SetReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns) {
- if (!reruns || reruns->Count() < 2)
- return;
- int rerunsIndex = tabs->GetLoopIndex("reruns");
-
- int maxNumReruns = config.rerunAmount;
- int rerunDistance = config.rerunDistance * 3600;
- int rerunMaxChannel = config.rerunMaxChannel;
-
- int i = 0;
- for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = reruns->First(); r && i < maxNumReruns; r = reruns->Next(r)) {
- time_t eventStart = event->StartTime();
- time_t rerunStart = r->event->StartTime();
- cChannel *channel = Channels.GetByChannelID(r->event->ChannelID(), true, true);
- //check for identical event
- if ((event->ChannelID() == r->event->ChannelID()) && (eventStart == rerunStart))
- continue;
- //check for timely distance
- if (rerunDistance > 0)
- if (rerunStart - eventStart < rerunDistance)
- continue;
- //check for maxchannel
- if (rerunMaxChannel > 0)
- if (channel && channel->Number() > rerunMaxChannel)
- continue;
- tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::title, r->event->Title());
- tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::shorttext, r->event->ShortText());
- tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::start, *(r->event->GetTimeString()));
- tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::stop, *(r->event->GetEndTimeString()));
- tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::date, *ShortDateString(r->event->StartTime()));
- tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::day, *WeekDayName(r->event->StartTime()));
- cString channelID = r->event->ChannelID().ToString();
- tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelid, *channelID);
- bool logoExists = tabs->ChannelLogoExists(*channelID);
- tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channellogoexists, logoExists ? "1" : "0");
- if (channel) {
- cString channelNumber = cString::sprintf("%d", channel->Number());
- tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelname, channel->ShortName(true));
- tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelnumber, *channelNumber);
- } else {
- tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelname, "");
- tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelnumber, "");
- }
- i++;
- }
-}
-
-bool cDetailView::LoadScrapInfo(const cEvent *event) {
- static cPlugin *pScraper = GetScraperPlugin();
- if (!pScraper || !event) {
- return false;
- }
- delete movie;
- movie = NULL;
- delete series;
- series = NULL;
-
- ScraperGetEventType getType;
- getType.event = event;
- getType.recording = NULL;
- if (!pScraper->Service("GetEventType", &getType)) {
- return false;
- }
- if (getType.type == tMovie) {
- movie = new cMovie();
- movie->movieId = getType.movieId;
- pScraper->Service("GetMovie", movie);
- return true;
- } else if (getType.type == tSeries) {
- series = new cSeries();
- series->seriesId = getType.seriesId;
- series->episodeId = getType.episodeId;
- pScraper->Service("GetSeries", series);
- return true;
- }
- return false;
-}
-
-int cDetailView::NumActors(void) {
- if (series) {
- return series->actors.size();
- } else if (movie) {
- return movie->actors.size();
- }
- return 0;
-}
-
-void cDetailView::SetScraperTokens(void) {
- if (movie) {
- tabs->AddIntToken((int)eScraperIT::ismovie, true);
- tabs->AddIntToken((int)eScraperIT::isseries, false);
-
- tabs->AddStringToken((int)eScraperST::movietitle, movie->title.c_str());
- tabs->AddStringToken((int)eScraperST::movieoriginalTitle, movie->originalTitle.c_str());
- tabs->AddStringToken((int)eScraperST::movietagline, movie->tagline.c_str());
- tabs->AddStringToken((int)eScraperST::movieoverview, movie->overview.c_str());
- tabs->AddStringToken((int)eScraperST::moviegenres, movie->genres.c_str());
- tabs->AddStringToken((int)eScraperST::moviehomepage, movie->homepage.c_str());
- tabs->AddStringToken((int)eScraperST::moviereleasedate, movie->releaseDate.c_str());
- stringstream pop;
- pop << movie->popularity;
- tabs->AddStringToken((int)eScraperST::moviepopularity, pop.str().c_str());
- stringstream vote;
- vote << movie->voteAverage;
- tabs->AddStringToken((int)eScraperST::movievoteaverage, pop.str().c_str());
- tabs->AddStringToken((int)eScraperST::posterpath, movie->poster.path.c_str());
- tabs->AddStringToken((int)eScraperST::fanartpath, movie->fanart.path.c_str());
- tabs->AddStringToken((int)eScraperST::collectionposterpath, movie->collectionPoster.path.c_str());
- tabs->AddStringToken((int)eScraperST::collectionfanartpath, movie->collectionFanart.path.c_str());
-
- tabs->AddIntToken((int)eScraperIT::movieadult, movie->adult);
- tabs->AddIntToken((int)eScraperIT::moviebudget, movie->budget);
- tabs->AddIntToken((int)eScraperIT::movierevenue, movie->revenue);
- tabs->AddIntToken((int)eScraperIT::movieruntime, movie->runtime);
- tabs->AddIntToken((int)eScraperIT::posterwidth, movie->poster.width);
- tabs->AddIntToken((int)eScraperIT::posterheight, movie->poster.height);
- tabs->AddIntToken((int)eScraperIT::fanartwidth, movie->fanart.width);
- tabs->AddIntToken((int)eScraperIT::fanartheight, movie->fanart.height);
- tabs->AddIntToken((int)eScraperIT::collectionposterwidth, movie->collectionPoster.width);
- tabs->AddIntToken((int)eScraperIT::collectionposterheight, movie->collectionPoster.height);
- tabs->AddIntToken((int)eScraperIT::collectionfanartwidth, movie->collectionFanart.width);
- tabs->AddIntToken((int)eScraperIT::collectionfanartheight, movie->collectionFanart.height);
-
- int actorsIndex = tabs->GetLoopIndex("actors");
- int i=0;
- for (vector<cActor>::iterator act = movie->actors.begin(); act != movie->actors.end(); act++) {
- tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::name, (*act).name.c_str());
- tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::role, (*act).role.c_str());
- tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumb, (*act).actorThumb.path.c_str());
- tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumbwidth, *cString::sprintf("%d", (*act).actorThumb.width));
- tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumbheight, *cString::sprintf("%d", (*act).actorThumb.height));
- i++;
- }
- } else if (series) {
- tabs->AddIntToken((int)eScraperIT::ismovie, false);
- tabs->AddIntToken((int)eScraperIT::isseries, true);
- //Series Basics
- tabs->AddStringToken((int)eScraperST::seriesname, series->name.c_str());
- tabs->AddStringToken((int)eScraperST::seriesoverview, series->overview.c_str());
- tabs->AddStringToken((int)eScraperST::seriesfirstaired, series->firstAired.c_str());
- tabs->AddStringToken((int)eScraperST::seriesnetwork, series->network.c_str());
- tabs->AddStringToken((int)eScraperST::seriesgenre, series->genre.c_str());
- stringstream rating;
- rating << series->rating;
- tabs->AddStringToken((int)eScraperST::seriesrating, rating.str().c_str());
- tabs->AddStringToken((int)eScraperST::seriesstatus, series->status.c_str());
- //Episode Information
- tabs->AddIntToken((int)eScraperIT::episodenumber, series->episode.number);
- tabs->AddIntToken((int)eScraperIT::episodeseason, series->episode.season);
- tabs->AddStringToken((int)eScraperST::episodetitle, series->episode.name.c_str());
- tabs->AddStringToken((int)eScraperST::episodefirstaired, series->episode.firstAired.c_str());
- tabs->AddStringToken((int)eScraperST::episodegueststars, series->episode.guestStars.c_str());
- tabs->AddStringToken((int)eScraperST::episodeoverview, series->episode.overview.c_str());
- stringstream eprating;
- eprating << series->episode.rating;
- tabs->AddStringToken((int)eScraperST::episoderating, eprating.str().c_str());
- tabs->AddIntToken((int)eScraperIT::episodeimagewidth, series->episode.episodeImage.width);
- tabs->AddIntToken((int)eScraperIT::episodeimageheight, series->episode.episodeImage.height);
- tabs->AddStringToken((int)eScraperST::episodeimagepath, series->episode.episodeImage.path.c_str());
- //Seasonposter
- tabs->AddIntToken((int)eScraperIT::seasonposterwidth, series->seasonPoster.width);
- tabs->AddIntToken((int)eScraperIT::seasonposterheight, series->seasonPoster.height);
- tabs->AddStringToken((int)eScraperST::seasonposterpath, series->seasonPoster.path.c_str());
-
- //Posters
- int indexInt = (int)eScraperIT::seriesposter1width;
- int indexStr = (int)eScraperST::seriesposter1path;
- for(vector<cTvMedia>::iterator poster = series->posters.begin(); poster != series->posters.end(); poster++) {
- tabs->AddIntToken(indexInt, (*poster).width);
- tabs->AddIntToken(indexInt+1, (*poster).height);
- tabs->AddStringToken(indexStr, (*poster).path.c_str());
- indexInt += 2;
- indexStr++;
- }
- //Banners
- indexInt = (int)eScraperIT::seriesbanner1width;
- indexStr = (int)eScraperST::seriesbanner1path;
- for(vector<cTvMedia>::iterator banner = series->banners.begin(); banner != series->banners.end(); banner++) {
- tabs->AddIntToken(indexInt, (*banner).width);
- tabs->AddIntToken(indexInt+1, (*banner).height);
- tabs->AddStringToken(indexStr, (*banner).path.c_str());
- indexInt += 2;
- indexStr++;
- }
- //Fanarts
- indexInt = (int)eScraperIT::seriesfanart1width;
- indexStr = (int)eScraperST::seriesfanart1path;
- for(vector<cTvMedia>::iterator fanart = series->fanarts.begin(); fanart != series->fanarts.end(); fanart++) {
- tabs->AddIntToken(indexInt, (*fanart).width);
- tabs->AddIntToken(indexInt+1, (*fanart).height);
- tabs->AddStringToken(indexStr, (*fanart).path.c_str());
- indexInt += 2;
- indexStr++;
- }
- //Actors
- int actorsIndex = tabs->GetLoopIndex("actors");
- int i=0;
- for (vector<cActor>::iterator act = series->actors.begin(); act != series->actors.end(); act++) {
- tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::name, (*act).name.c_str());
- tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::role, (*act).role.c_str());
- tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumb, (*act).actorThumb.path.c_str());
- tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumbwidth, *cString::sprintf("%d", (*act).actorThumb.width));
- tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumbheight, *cString::sprintf("%d", (*act).actorThumb.height));
- i++;
- }
- } else {
- tabs->AddIntToken((int)eScraperIT::ismovie, false);
- tabs->AddIntToken((int)eScraperIT::isseries, false);
- }
-}
-
-void cDetailView::SetEpgPictures(int eventId) {
- string epgImagePath = tabs->GetEpgImagePath();
- for (int i=0; i<3; i++) {
- stringstream picName;
- picName << eventId << "_" << i;
- bool epgPicAvailable = FileExists(epgImagePath, picName.str(), "jpg");
- if (epgPicAvailable) {
- tabs->AddIntToken((int)eDetailedEpgIT::epgpic1avaialble + i, true);
- tabs->AddStringToken((int)eDetailedEpgST::epgpic1path + i, *cString::sprintf("%s%s.jpg", epgImagePath.c_str(), picName.str().c_str()));
- } else {
- tabs->AddIntToken((int)eDetailedEpgIT::epgpic1avaialble + i, false);
- tabs->AddStringToken((int)eDetailedEpgST::epgpic1path + i, "");
- }
- }
+#include "helpers.h" +#include "tvguidengosd.h" +#include "detailview.h" + +cDetailView::cDetailView(skindesignerapi::cOsdView *detailView, const cEvent *event) { + init = true; + lastSecond = -1; + this->detailView = detailView; + this->event = event; + back = detailView->GetViewElement((int)eViewElementsDetail::background); + header = detailView->GetViewElement((int)eViewElementsDetail::header); + footer = detailView->GetViewElement((int)eViewElementsDetail::footer); + watch = detailView->GetViewElement((int)eViewElementsDetail::time); + tabs = detailView->GetViewTabs(); + movie = NULL; + series = NULL; +} + +cDetailView::~cDetailView() { + delete back; + delete header; + delete footer; + delete watch; + delete tabs; + delete detailView; + delete movie; + delete series; +} + +void cDetailView::Draw(void) { + if (!event) { + return; + } + if (init) { + DrawBackground(); + DrawHeader(); + DrawFooter(); + Flush(); + SetTabTokens(); + tabs->Init(); + init = false; + } + tabs->Display(); +} + +void cDetailView::Left(void) { + tabs->Left(); + tabs->Display(); +} + +void cDetailView::Right(void) { + tabs->Right(); + tabs->Display(); +} + +void cDetailView::Up(void) { + tabs->Up(); + tabs->Display(); +} + +void cDetailView::Down(void) { + tabs->Down(); + tabs->Display(); +} + +void cDetailView::DefineTokens(eViewElementsDetail ve, skindesignerapi::cTokenContainer *tk) { + switch (ve) { + case eViewElementsDetail::header: + tk->DefineIntToken("{ismovie}", (int)eScraperHeaderIT::ismovie); + tk->DefineIntToken("{isseries}", (int)eScraperHeaderIT::isseries); + tk->DefineIntToken("{posteravailable}", (int)eScraperHeaderIT::posteravailable); + tk->DefineIntToken("{posterwidth}", (int)eScraperHeaderIT::posterwidth); + tk->DefineIntToken("{posterheight}", (int)eScraperHeaderIT::posterheight); + tk->DefineIntToken("{banneravailable}", (int)eScraperHeaderIT::banneravailable); + tk->DefineIntToken("{bannerwidth}", (int)eScraperHeaderIT::bannerwidth); + tk->DefineIntToken("{bannerheight}", (int)eScraperHeaderIT::bannerheight); + tk->DefineIntToken("{daynumeric}", (int)eDetailedHeaderIT::daynumeric); + tk->DefineIntToken("{month}", (int)eDetailedHeaderIT::month); + tk->DefineIntToken("{year}", (int)eDetailedHeaderIT::year); + tk->DefineIntToken("{running}", (int)eDetailedHeaderIT::running); + tk->DefineIntToken("{elapsed}", (int)eDetailedHeaderIT::elapsed); + tk->DefineIntToken("{duration}", (int)eDetailedHeaderIT::duration); + tk->DefineIntToken("{durationhours}", (int)eDetailedHeaderIT::durationhours); + tk->DefineIntToken("{channelnumber}", (int)eDetailedHeaderIT::channelnumber); + tk->DefineIntToken("{channellogoexists}", (int)eDetailedHeaderIT::channellogoexists); + tk->DefineIntToken("{epgpicavailable}", (int)eDetailedHeaderIT::epgpicavailable); + tk->DefineStringToken("{posterpath}", (int)eScraperHeaderST::posterpath); + tk->DefineStringToken("{bannerpath}", (int)eScraperHeaderST::bannerpath); + tk->DefineStringToken("{title}", (int)eDetailedHeaderST::title); + tk->DefineStringToken("{shorttext}", (int)eDetailedHeaderST::shorttext); + tk->DefineStringToken("{start}", (int)eDetailedHeaderST::start); + tk->DefineStringToken("{stop}", (int)eDetailedHeaderST::stop); + tk->DefineStringToken("{day}", (int)eDetailedHeaderST::day); + tk->DefineStringToken("{date}", (int)eDetailedHeaderST::date); + tk->DefineStringToken("{durationminutes}", (int)eDetailedHeaderST::durationminutes); + tk->DefineStringToken("{vps}", (int)eDetailedHeaderST::vps); + tk->DefineStringToken("{channelname}", (int)eDetailedHeaderST::channelname); + tk->DefineStringToken("{channelid}", (int)eDetailedHeaderST::channelid); + tk->DefineStringToken("{epgpicpath}", (int)eDetailedHeaderST::epgpicpath); + break; + case eViewElementsDetail::footer: + tk->DefineIntToken("{red1}", (int)eFooterIT::red1); + tk->DefineIntToken("{red2}", (int)eFooterIT::red2); + tk->DefineIntToken("{red3}", (int)eFooterIT::red3); + tk->DefineIntToken("{red4}", (int)eFooterIT::red4); + tk->DefineIntToken("{green1}", (int)eFooterIT::green1); + tk->DefineIntToken("{green2}", (int)eFooterIT::green2); + tk->DefineIntToken("{green3}", (int)eFooterIT::green3); + tk->DefineIntToken("{green4}", (int)eFooterIT::green4); + tk->DefineIntToken("{yellow1}", (int)eFooterIT::yellow1); + tk->DefineIntToken("{yellow2}", (int)eFooterIT::yellow2); + tk->DefineIntToken("{yellow3}", (int)eFooterIT::yellow3); + tk->DefineIntToken("{yellow4}", (int)eFooterIT::yellow4); + tk->DefineIntToken("{blue1}", (int)eFooterIT::blue1); + tk->DefineIntToken("{blue2}", (int)eFooterIT::blue2); + tk->DefineIntToken("{blue3}", (int)eFooterIT::blue3); + tk->DefineIntToken("{blue4}", (int)eFooterIT::blue4); + tk->DefineStringToken("{red}", (int)eFooterST::red); + tk->DefineStringToken("{green}", (int)eFooterST::green); + tk->DefineStringToken("{yellow}", (int)eFooterST::yellow); + tk->DefineStringToken("{blue}", (int)eFooterST::blue); + break; + default: + break; + } +} + +void cDetailView::DefineTabTokens(skindesignerapi::cTokenContainer *tk) { + tk->DefineStringToken("{title}", (int)eDetailedEpgST::title); + tk->DefineStringToken("{shorttext}", (int)eDetailedEpgST::shorttext); + tk->DefineStringToken("{description}", (int)eDetailedEpgST::description); + tk->DefineStringToken("{start}", (int)eDetailedEpgST::start); + tk->DefineStringToken("{stop}", (int)eDetailedEpgST::stop); + tk->DefineStringToken("{day}", (int)eDetailedEpgST::day); + tk->DefineStringToken("{date}", (int)eDetailedEpgST::date); + tk->DefineStringToken("{durationminutes}", (int)eDetailedEpgST::durationminutes); + tk->DefineStringToken("{vps}", (int)eDetailedEpgST::vps); + tk->DefineStringToken("{channelname}", (int)eDetailedEpgST::channelname); + tk->DefineStringToken("{channelid}", (int)eDetailedEpgST::channelid); + tk->DefineStringToken("{epgpic1path}", (int)eDetailedEpgST::epgpic1path); + tk->DefineStringToken("{epgpic2path}", (int)eDetailedEpgST::epgpic2path); + tk->DefineStringToken("{epgpic3path}", (int)eDetailedEpgST::epgpic3path); + tk->DefineStringToken("{movietitle}", (int)eScraperST::movietitle); + tk->DefineStringToken("{movieoriginalTitle}", (int)eScraperST::movieoriginalTitle); + tk->DefineStringToken("{movietagline}", (int)eScraperST::movietagline); + tk->DefineStringToken("{movieoverview}", (int)eScraperST::movieoverview); + tk->DefineStringToken("{moviegenres}", (int)eScraperST::moviegenres); + tk->DefineStringToken("{moviehomepage}", (int)eScraperST::moviehomepage); + tk->DefineStringToken("{moviereleasedate}", (int)eScraperST::moviereleasedate); + tk->DefineStringToken("{moviepopularity}", (int)eScraperST::moviepopularity); + tk->DefineStringToken("{movievoteaverage}", (int)eScraperST::movievoteaverage); + tk->DefineStringToken("{posterpath}", (int)eScraperST::posterpath); + tk->DefineStringToken("{fanartpath}", (int)eScraperST::fanartpath); + tk->DefineStringToken("{moviecollectionName}", (int)eScraperST::moviecollectionName); + tk->DefineStringToken("{collectionposterpath}", (int)eScraperST::collectionposterpath); + tk->DefineStringToken("{collectionfanartpath}", (int)eScraperST::collectionfanartpath); + tk->DefineStringToken("{seriesname}", (int)eScraperST::seriesname); + tk->DefineStringToken("{seriesoverview}", (int)eScraperST::seriesoverview); + tk->DefineStringToken("{seriesfirstaired}", (int)eScraperST::seriesfirstaired); + tk->DefineStringToken("{seriesnetwork}", (int)eScraperST::seriesnetwork); + tk->DefineStringToken("{seriesgenre}", (int)eScraperST::seriesgenre); + tk->DefineStringToken("{seriesrating}", (int)eScraperST::seriesrating); + tk->DefineStringToken("{seriesstatus}", (int)eScraperST::seriesstatus); + tk->DefineStringToken("{episodetitle}", (int)eScraperST::episodetitle); + tk->DefineStringToken("{episodefirstaired}", (int)eScraperST::episodefirstaired); + tk->DefineStringToken("{episodegueststars}", (int)eScraperST::episodegueststars); + tk->DefineStringToken("{episodeoverview}", (int)eScraperST::episodeoverview); + tk->DefineStringToken("{episoderating}", (int)eScraperST::episoderating); + tk->DefineStringToken("{episodeimagepath}", (int)eScraperST::episodeimagepath); + tk->DefineStringToken("{seasonposterpath}", (int)eScraperST::seasonposterpath); + tk->DefineStringToken("{seriesposter1path}", (int)eScraperST::seriesposter1path); + tk->DefineStringToken("{seriesposter2path}", (int)eScraperST::seriesposter2path); + tk->DefineStringToken("{seriesposter3path}", (int)eScraperST::seriesposter3path); + tk->DefineStringToken("{seriesfanart1path}", (int)eScraperST::seriesfanart1path); + tk->DefineStringToken("{seriesfanart2path}", (int)eScraperST::seriesfanart2path); + tk->DefineStringToken("{seriesfanart3path}", (int)eScraperST::seriesfanart3path); + tk->DefineStringToken("{seriesbanner1path}", (int)eScraperST::seriesbanner1path); + tk->DefineStringToken("{seriesbanner2path}", (int)eScraperST::seriesbanner2path); + tk->DefineStringToken("{seriesbanner3path}", (int)eScraperST::seriesbanner3path); + tk->DefineIntToken("{daynumeric}", (int)eDetailedEpgIT::daynumeric); + tk->DefineIntToken("{month}", (int)eDetailedEpgIT::month); + tk->DefineIntToken("{year}", (int)eDetailedEpgIT::year); + tk->DefineIntToken("{running}", (int)eDetailedEpgIT::running); + tk->DefineIntToken("{elapsed}", (int)eDetailedEpgIT::elapsed); + tk->DefineIntToken("{duration}", (int)eDetailedEpgIT::duration); + tk->DefineIntToken("{durationhours}", (int)eDetailedEpgIT::durationhours); + tk->DefineIntToken("{channelnumber}", (int)eDetailedEpgIT::channelnumber); + tk->DefineIntToken("{channellogoexists}", (int)eDetailedEpgIT::channellogoexists); + tk->DefineIntToken("{hasreruns}", (int)eDetailedEpgIT::hasreruns); + tk->DefineIntToken("{epgpic1avaialble}", (int)eDetailedEpgIT::epgpic1avaialble); + tk->DefineIntToken("{epgpic2avaialble}", (int)eDetailedEpgIT::epgpic2avaialble); + tk->DefineIntToken("{epgpic3avaialble}", (int)eDetailedEpgIT::epgpic3avaialble); + tk->DefineIntToken("{ismovie}", (int)eScraperIT::ismovie); + tk->DefineIntToken("{moviebudget}", (int)eScraperIT::moviebudget); + tk->DefineIntToken("{movierevenue}", (int)eScraperIT::movierevenue); + tk->DefineIntToken("{movieadult}", (int)eScraperIT::movieadult); + tk->DefineIntToken("{movieruntime}", (int)eScraperIT::movieruntime); + tk->DefineIntToken("{isseries}", (int)eScraperIT::isseries); + tk->DefineIntToken("{posterwidth}", (int)eScraperIT::posterwidth); + tk->DefineIntToken("{posterheight}", (int)eScraperIT::posterheight); + tk->DefineIntToken("{fanartwidth}", (int)eScraperIT::fanartwidth); + tk->DefineIntToken("{fanartheight}", (int)eScraperIT::fanartheight); + tk->DefineIntToken("{movieiscollection}", (int)eScraperIT::movieiscollection); + tk->DefineIntToken("{collectionposterwidth}", (int)eScraperIT::collectionposterwidth); + tk->DefineIntToken("{collectionposterheight}", (int)eScraperIT::collectionposterheight); + tk->DefineIntToken("{collectionfanartwidth}", (int)eScraperIT::collectionfanartwidth); + tk->DefineIntToken("{collectionfanartheight}", (int)eScraperIT::collectionfanartheight); + tk->DefineIntToken("{epgpicavailable}", (int)eScraperIT::epgpicavailable); + tk->DefineIntToken("{episodenumber}", (int)eScraperIT::episodenumber); + tk->DefineIntToken("{episodeseason}", (int)eScraperIT::episodeseason); + tk->DefineIntToken("{episodeimagewidth}", (int)eScraperIT::episodeimagewidth); + tk->DefineIntToken("{episodeimageheight}", (int)eScraperIT::episodeimageheight); + tk->DefineIntToken("{seasonposterwidth}", (int)eScraperIT::seasonposterwidth); + tk->DefineIntToken("{seasonposterheight}", (int)eScraperIT::seasonposterheight); + tk->DefineIntToken("{seriesposter1width}", (int)eScraperIT::seriesposter1width); + tk->DefineIntToken("{seriesposter1height}", (int)eScraperIT::seriesposter1height); + tk->DefineIntToken("{seriesposter2width}", (int)eScraperIT::seriesposter2width); + tk->DefineIntToken("{seriesposter2height}", (int)eScraperIT::seriesposter2height); + tk->DefineIntToken("{seriesposter3width}", (int)eScraperIT::seriesposter3width); + tk->DefineIntToken("{seriesposter3height}", (int)eScraperIT::seriesposter3height); + tk->DefineIntToken("{seriesfanart1width}", (int)eScraperIT::seriesfanart1width); + tk->DefineIntToken("{seriesfanart1height}", (int)eScraperIT::seriesfanart1height); + tk->DefineIntToken("{seriesfanart2width}", (int)eScraperIT::seriesfanart2width); + tk->DefineIntToken("{seriesfanart2height}", (int)eScraperIT::seriesfanart2height); + tk->DefineIntToken("{seriesfanart3width}", (int)eScraperIT::seriesfanart3width); + tk->DefineIntToken("{seriesfanart3height}", (int)eScraperIT::seriesfanart3height); + tk->DefineIntToken("{seriesbanner1width}", (int)eScraperIT::seriesbanner1width); + tk->DefineIntToken("{seriesbanner1height}", (int)eScraperIT::seriesbanner1height); + tk->DefineIntToken("{seriesbanner2width}", (int)eScraperIT::seriesbanner2width); + tk->DefineIntToken("{seriesbanner2height}", (int)eScraperIT::seriesbanner2height); + tk->DefineIntToken("{seriesbanner3width}", (int)eScraperIT::seriesbanner3width); + tk->DefineIntToken("{seriesbanner3height}", (int)eScraperIT::seriesbanner3height); + tk->DefineLoopToken("{reruns[title]}", (int)eRerunsLT::title); + tk->DefineLoopToken("{reruns[shorttext]}", (int)eRerunsLT::shorttext); + tk->DefineLoopToken("{reruns[date]}", (int)eRerunsLT::date); + tk->DefineLoopToken("{reruns[day]}", (int)eRerunsLT::day); + tk->DefineLoopToken("{reruns[start]}", (int)eRerunsLT::start); + tk->DefineLoopToken("{reruns[stop]}", (int)eRerunsLT::stop); + tk->DefineLoopToken("{reruns[channelname]}", (int)eRerunsLT::channelname); + tk->DefineLoopToken("{reruns[channelnumber]}", (int)eRerunsLT::channelnumber); + tk->DefineLoopToken("{reruns[channelid]}", (int)eRerunsLT::channelid); + tk->DefineLoopToken("{reruns[channellogoexists]}", (int)eRerunsLT::channellogoexists); + tk->DefineLoopToken("{actors[name]}", (int)eScraperLT::name); + tk->DefineLoopToken("{actors[role]}", (int)eScraperLT::role); + tk->DefineLoopToken("{actors[thumb]}", (int)eScraperLT::thumb); + tk->DefineLoopToken("{actors[thumbwidth]}", (int)eScraperLT::thumbwidth); + tk->DefineLoopToken("{actors[thumbheight]}", (int)eScraperLT::thumbheight); +} +/******************************************************************** +* Private Functions +********************************************************************/ +void cDetailView::DrawBackground(void) { + back->Display(); +} + +void cDetailView::DrawHeader(void) { + if (!event) + return; + header->ClearTokens(); + static cPlugin *pScraper = GetScraperPlugin(); + if (pScraper) { + ScraperGetEventType getType; + getType.event = event; + if (!pScraper->Service("GetEventType", &getType)) { + if (getType.type == tMovie) { + cMovie movie; + movie.movieId = getType.movieId; + pScraper->Service("GetMovie", &movie); + header->AddIntToken((int)eScraperHeaderIT::banneravailable, true); + header->AddIntToken((int)eScraperHeaderIT::isseries, false); + header->AddIntToken((int)eScraperHeaderIT::posteravailable, true); + header->AddIntToken((int)eScraperHeaderIT::banneravailable, false); + header->AddStringToken((int)eScraperHeaderST::posterpath, movie.poster.path.c_str()); + header->AddIntToken((int)eScraperHeaderIT::posterwidth, movie.poster.width); + header->AddIntToken((int)eScraperHeaderIT::posterheight, movie.poster.height); + } else if (getType.type == tSeries) { + cSeries series; + series.seriesId = getType.seriesId; + series.episodeId = getType.episodeId; + pScraper->Service("GetSeries", &series); + header->AddIntToken((int)eScraperHeaderIT::ismovie, false); + header->AddIntToken((int)eScraperHeaderIT::isseries, true); + vector<cTvMedia>::iterator poster = series.posters.begin(); + if (poster != series.posters.end()) { + header->AddIntToken((int)eScraperHeaderIT::posterwidth, (*poster).width); + header->AddIntToken((int)eScraperHeaderIT::posterheight, (*poster).height); + header->AddStringToken((int)eScraperHeaderST::posterpath, (*poster).path.c_str()); + header->AddIntToken((int)eScraperHeaderIT::posteravailable, true); + } + vector<cTvMedia>::iterator banner = series.banners.begin(); + if (banner != series.banners.end()) { + header->AddIntToken((int)eScraperHeaderIT::bannerwidth, (*banner).width); + header->AddIntToken((int)eScraperHeaderIT::bannerheight, (*banner).height); + header->AddStringToken((int)eScraperHeaderST::bannerpath, (*banner).path.c_str()); + header->AddIntToken((int)eScraperHeaderIT::banneravailable, true); + } + } + } + } + + header->AddStringToken((int)eDetailedHeaderST::title, event->Title()); + header->AddStringToken((int)eDetailedHeaderST::shorttext, event->ShortText()); + header->AddStringToken((int)eDetailedHeaderST::start, *(event->GetTimeString())); + header->AddStringToken((int)eDetailedHeaderST::stop, *(event->GetEndTimeString())); + + time_t startTime = event->StartTime(); + header->AddStringToken((int)eDetailedHeaderST::day, *WeekDayName(startTime)); + header->AddStringToken((int)eDetailedHeaderST::date, *ShortDateString(startTime)); + struct tm * sStartTime = localtime(&startTime); + header->AddIntToken((int)eDetailedHeaderIT::year, sStartTime->tm_year + 1900); + header->AddIntToken((int)eDetailedHeaderIT::daynumeric, sStartTime->tm_mday); + header->AddIntToken((int)eDetailedHeaderIT::month, sStartTime->tm_mon+1); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannel *channel = Channels->GetByChannelID(event->ChannelID()); +#else + const cChannel *channel = Channels.GetByChannelID(event->ChannelID()); +#endif + if (channel) { + header->AddStringToken((int)eDetailedHeaderST::channelname, channel->Name()); + header->AddIntToken((int)eDetailedHeaderIT::channelnumber, channel->Number()); + } else { + header->AddIntToken((int)eDetailedHeaderIT::channelnumber, 0); + } + cString channelID = channel->GetChannelID().ToString(); + header->AddStringToken((int)eDetailedHeaderST::channelid, *channelID); + header->AddIntToken((int)eDetailedHeaderIT::channellogoexists, header->ChannelLogoExists(*channelID)); + + bool isRunning = false; + time_t now = time(NULL); + if ((now >= event->StartTime()) && (now <= event->EndTime())) + isRunning = true; + header->AddIntToken((int)eDetailedHeaderIT::running, isRunning); + if (isRunning) { + header->AddIntToken((int)eDetailedHeaderIT::elapsed, (now - event->StartTime())/60); + } else { + header->AddIntToken((int)eDetailedHeaderIT::elapsed, 0); + } + header->AddIntToken((int)eDetailedHeaderIT::duration, event->Duration() / 60); + header->AddIntToken((int)eDetailedHeaderIT::durationhours, event->Duration() / 3600); + header->AddStringToken((int)eDetailedHeaderST::durationminutes, *cString::sprintf("%.2d", (event->Duration() / 60)%60)); + if (event->Vps()) + header->AddStringToken((int)eDetailedHeaderST::vps, *event->GetVpsString()); + + stringstream epgImageName; + epgImageName << event->EventID(); + string epgImagePath = header->GetEpgImagePath(); + + bool epgPicAvailable = FileExists(epgImagePath, epgImageName.str(), "jpg"); + if (epgPicAvailable) { + header->AddIntToken((int)eDetailedHeaderIT::epgpicavailable, true); + header->AddStringToken((int)eDetailedHeaderST::epgpicpath, *cString::sprintf("%s%s.jpg", epgImagePath.c_str(), epgImageName.str().c_str())); + } else { + epgImageName << "_0"; + epgPicAvailable = FileExists(epgImagePath, epgImageName.str(), "jpg"); + if (epgPicAvailable) { + header->AddIntToken((int)eDetailedHeaderIT::epgpicavailable, true); + header->AddStringToken((int)eDetailedHeaderST::epgpicpath, *cString::sprintf("%s%s.jpg", epgImagePath.c_str(), epgImageName.str().c_str())); + } + } + + header->Display(); +} + +void cDetailView::DrawFooter(void) { + string textGreen = ""; + string textYellow = ""; + string textRed = tr("Search & Record"); + string textBlue = tr("Switch"); + + int colorKeys[4] = { Setup.ColorKey0, Setup.ColorKey1, Setup.ColorKey2, Setup.ColorKey3 }; + + footer->Clear(); + footer->ClearTokens(); + + footer->AddStringToken((int)eFooterST::red, textRed.c_str()); + footer->AddStringToken((int)eFooterST::green, textGreen.c_str()); + footer->AddStringToken((int)eFooterST::yellow, textYellow.c_str()); + footer->AddStringToken((int)eFooterST::blue, textBlue.c_str()); + + for (int button = 0; button < 4; button++) { + bool isRed = false; + bool isGreen = false; + bool isYellow = false; + bool isBlue = false; + switch (colorKeys[button]) { + case 0: + isRed = true; + break; + case 1: + isGreen = true; + break; + case 2: + isYellow = true; + break; + case 3: + isBlue = true; + break; + default: + break; + } + footer->AddIntToken(0 + button, isRed); + footer->AddIntToken(4 + button, isGreen); + footer->AddIntToken(8 + button, isYellow); + footer->AddIntToken(12 + button, isBlue); + } + + footer->Display(); +} + +bool cDetailView::DrawTime(void) { + time_t t = time(0); // get time now + struct tm * now = localtime(&t); + int sec = now->tm_sec; + if (sec == lastSecond) + return false; + + int min = now->tm_min; + int hour = now->tm_hour; + int hourMinutes = hour%12 * 5 + min / 12; + + char monthname[20]; + char monthshort[10]; + strftime(monthshort, sizeof(monthshort), "%b", now); + strftime(monthname, sizeof(monthname), "%B", now); + + watch->Clear(); + watch->ClearTokens(); + watch->AddIntToken((int)eTimeIT::sec, sec); + watch->AddIntToken((int)eTimeIT::min, min); + watch->AddIntToken((int)eTimeIT::hour, hour); + watch->AddIntToken((int)eTimeIT::hmins, hourMinutes); + watch->AddIntToken((int)eTimeIT::year, now->tm_year + 1900); + watch->AddIntToken((int)eTimeIT::day, now->tm_mday); + watch->AddStringToken((int)eTimeST::time, *TimeString(t)); + watch->AddStringToken((int)eTimeST::monthname, monthname); + watch->AddStringToken((int)eTimeST::monthnameshort, monthshort); + watch->AddStringToken((int)eTimeST::month, *cString::sprintf("%02d", now->tm_mon + 1)); + watch->AddStringToken((int)eTimeST::dayleadingzero, *cString::sprintf("%02d", now->tm_mday)); + watch->AddStringToken((int)eTimeST::dayname, *WeekDayNameFull(now->tm_wday)); + watch->AddStringToken((int)eTimeST::daynameshort, *WeekDayName(now->tm_wday)); + watch->Display(); + + lastSecond = sec; + return true; +} + +void cDetailView::SetTabTokens(void) { + tabs->ClearTokens(); + tabs->AddStringToken((int)eDetailedEpgST::title, event->Title()); + tabs->AddStringToken((int)eDetailedEpgST::shorttext, event->ShortText()); + tabs->AddStringToken((int)eDetailedEpgST::description, event->Description()); + tabs->AddStringToken((int)eDetailedEpgST::start, *(event->GetTimeString())); + tabs->AddStringToken((int)eDetailedEpgST::stop, *(event->GetEndTimeString())); + time_t startTime = event->StartTime(); + tabs->AddStringToken((int)eDetailedEpgST::day, *WeekDayName(startTime)); + tabs->AddStringToken((int)eDetailedEpgST::date, *ShortDateString(startTime)); + struct tm * sStartTime = localtime(&startTime); + tabs->AddIntToken((int)eDetailedEpgIT::year, sStartTime->tm_year + 1900); + tabs->AddIntToken((int)eDetailedEpgIT::daynumeric, sStartTime->tm_mday); + tabs->AddIntToken((int)eDetailedEpgIT::month, sStartTime->tm_mon+1); + + cString channelID = event->ChannelID().ToString(); + tabs->AddStringToken((int)eDetailedEpgST::channelid, *channelID); + tabs->AddIntToken((int)eDetailedEpgIT::channellogoexists, tabs->ChannelLogoExists(*channelID)); + + bool isRunning = false; + time_t now = time(NULL); + if ((now >= event->StartTime()) && (now <= event->EndTime())) + isRunning = true; + tabs->AddIntToken((int)eDetailedEpgIT::running, isRunning); + if (isRunning) { + tabs->AddIntToken((int)eDetailedEpgIT::elapsed, (now - event->StartTime())/60); + } else { + tabs->AddIntToken((int)eDetailedEpgIT::elapsed, 0); + } + tabs->AddIntToken((int)eDetailedEpgIT::duration, event->Duration() / 60); + tabs->AddIntToken((int)eDetailedEpgIT::durationhours, event->Duration() / 3600); + tabs->AddStringToken((int)eDetailedEpgST::durationminutes, *cString::sprintf("%.2d", (event->Duration() / 60)%60)); + if (event->Vps()) + tabs->AddStringToken((int)eDetailedEpgST::vps, *event->GetVpsString()); + else + tabs->AddStringToken((int)eDetailedEpgST::vps, ""); + + + bool scrapInfoAvailable = LoadScrapInfo(event); + int numActors = NumActors(); + + cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns = LoadReruns(); + int numReruns = NumReruns(reruns); + + vector<int> loopInfo; + loopInfo.push_back(numReruns); + loopInfo.push_back(numActors); + tabs->SetLoop(loopInfo); + + if (numReruns > 0) { + tabs->AddIntToken((int)eDetailedEpgIT::hasreruns, 1); + SetReruns(reruns); + } + if (scrapInfoAvailable) { + SetScraperTokens(); + } + + SetEpgPictures(event->EventID()); +} + +cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *cDetailView::LoadReruns(void) { + cPlugin *epgSearchPlugin = cPluginManager::GetPlugin("epgsearch"); + if (!epgSearchPlugin) + return NULL; + + if (isempty(event->Title())) + return NULL; + + Epgsearch_searchresults_v1_0 data; + data.query = (char*)event->Title(); + data.mode = 0; + data.channelNr = 0; + data.useTitle = true; + data.useSubTitle = true; + data.useDescription = false; + + cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *result = NULL; + if (epgSearchPlugin->Service("Epgsearch-searchresults-v1.0", &data)) + result = data.pResultList; + return result; +} + +int cDetailView::NumReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns) { + if (!reruns || reruns->Count() < 2) + return 0; + + int maxNumReruns = config.rerunAmount; + int rerunDistance = config.rerunDistance * 3600; + int rerunMaxChannel = config.rerunMaxChannel; + + int i = 0; + for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = reruns->First(); r && i < maxNumReruns; r = reruns->Next(r)) { + time_t eventStart = event->StartTime(); + time_t rerunStart = r->event->StartTime(); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannel *channel = Channels->GetByChannelID(r->event->ChannelID(), true, true); +#else + const cChannel *channel = Channels.GetByChannelID(r->event->ChannelID(), true, true); +#endif + //check for identical event + if ((event->ChannelID() == r->event->ChannelID()) && (eventStart == rerunStart)) + continue; + //check for timely distance + if (rerunDistance > 0) + if (rerunStart - eventStart < rerunDistance) + continue; + //check for maxchannel + if (rerunMaxChannel > 0) + if (channel && channel->Number() > rerunMaxChannel) + continue; + i++; + } + return i; +} + +void cDetailView::SetReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns) { + if (!reruns || reruns->Count() < 2) + return; + int rerunsIndex = tabs->GetLoopIndex("reruns"); + + int maxNumReruns = config.rerunAmount; + int rerunDistance = config.rerunDistance * 3600; + int rerunMaxChannel = config.rerunMaxChannel; + + int i = 0; + for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = reruns->First(); r && i < maxNumReruns; r = reruns->Next(r)) { + time_t eventStart = event->StartTime(); + time_t rerunStart = r->event->StartTime(); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannel *channel = Channels->GetByChannelID(r->event->ChannelID(), true, true); +#else + const cChannel *channel = Channels.GetByChannelID(r->event->ChannelID(), true, true); +#endif + //check for identical event + if ((event->ChannelID() == r->event->ChannelID()) && (eventStart == rerunStart)) + continue; + //check for timely distance + if (rerunDistance > 0) + if (rerunStart - eventStart < rerunDistance) + continue; + //check for maxchannel + if (rerunMaxChannel > 0) + if (channel && channel->Number() > rerunMaxChannel) + continue; + tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::title, r->event->Title()); + tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::shorttext, r->event->ShortText()); + tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::start, *(r->event->GetTimeString())); + tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::stop, *(r->event->GetEndTimeString())); + tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::date, *ShortDateString(r->event->StartTime())); + tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::day, *WeekDayName(r->event->StartTime())); + cString channelID = r->event->ChannelID().ToString(); + tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelid, *channelID); + bool logoExists = tabs->ChannelLogoExists(*channelID); + tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channellogoexists, logoExists ? "1" : "0"); + if (channel) { + cString channelNumber = cString::sprintf("%d", channel->Number()); + tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelname, channel->ShortName(true)); + tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelnumber, *channelNumber); + } else { + tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelname, ""); + tabs->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelnumber, ""); + } + i++; + } +} + +bool cDetailView::LoadScrapInfo(const cEvent *event) { + static cPlugin *pScraper = GetScraperPlugin(); + if (!pScraper || !event) { + return false; + } + delete movie; + movie = NULL; + delete series; + series = NULL; + + ScraperGetEventType getType; + getType.event = event; + getType.recording = NULL; + if (!pScraper->Service("GetEventType", &getType)) { + return false; + } + if (getType.type == tMovie) { + movie = new cMovie(); + movie->movieId = getType.movieId; + pScraper->Service("GetMovie", movie); + return true; + } else if (getType.type == tSeries) { + series = new cSeries(); + series->seriesId = getType.seriesId; + series->episodeId = getType.episodeId; + pScraper->Service("GetSeries", series); + return true; + } + return false; +} + +int cDetailView::NumActors(void) { + if (series) { + return series->actors.size(); + } else if (movie) { + return movie->actors.size(); + } + return 0; +} + +void cDetailView::SetScraperTokens(void) { + if (movie) { + tabs->AddIntToken((int)eScraperIT::ismovie, true); + tabs->AddIntToken((int)eScraperIT::isseries, false); + + tabs->AddStringToken((int)eScraperST::movietitle, movie->title.c_str()); + tabs->AddStringToken((int)eScraperST::movieoriginalTitle, movie->originalTitle.c_str()); + tabs->AddStringToken((int)eScraperST::movietagline, movie->tagline.c_str()); + tabs->AddStringToken((int)eScraperST::movieoverview, movie->overview.c_str()); + tabs->AddStringToken((int)eScraperST::moviegenres, movie->genres.c_str()); + tabs->AddStringToken((int)eScraperST::moviehomepage, movie->homepage.c_str()); + tabs->AddStringToken((int)eScraperST::moviereleasedate, movie->releaseDate.c_str()); + stringstream pop; + pop << movie->popularity; + tabs->AddStringToken((int)eScraperST::moviepopularity, pop.str().c_str()); + stringstream vote; + vote << movie->voteAverage; + tabs->AddStringToken((int)eScraperST::movievoteaverage, pop.str().c_str()); + tabs->AddStringToken((int)eScraperST::posterpath, movie->poster.path.c_str()); + tabs->AddStringToken((int)eScraperST::fanartpath, movie->fanart.path.c_str()); + tabs->AddStringToken((int)eScraperST::collectionposterpath, movie->collectionPoster.path.c_str()); + tabs->AddStringToken((int)eScraperST::collectionfanartpath, movie->collectionFanart.path.c_str()); + + tabs->AddIntToken((int)eScraperIT::movieadult, movie->adult); + tabs->AddIntToken((int)eScraperIT::moviebudget, movie->budget); + tabs->AddIntToken((int)eScraperIT::movierevenue, movie->revenue); + tabs->AddIntToken((int)eScraperIT::movieruntime, movie->runtime); + tabs->AddIntToken((int)eScraperIT::posterwidth, movie->poster.width); + tabs->AddIntToken((int)eScraperIT::posterheight, movie->poster.height); + tabs->AddIntToken((int)eScraperIT::fanartwidth, movie->fanart.width); + tabs->AddIntToken((int)eScraperIT::fanartheight, movie->fanart.height); + tabs->AddIntToken((int)eScraperIT::collectionposterwidth, movie->collectionPoster.width); + tabs->AddIntToken((int)eScraperIT::collectionposterheight, movie->collectionPoster.height); + tabs->AddIntToken((int)eScraperIT::collectionfanartwidth, movie->collectionFanart.width); + tabs->AddIntToken((int)eScraperIT::collectionfanartheight, movie->collectionFanart.height); + + int actorsIndex = tabs->GetLoopIndex("actors"); + int i=0; + for (vector<cActor>::iterator act = movie->actors.begin(); act != movie->actors.end(); act++) { + tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::name, (*act).name.c_str()); + tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::role, (*act).role.c_str()); + tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumb, (*act).actorThumb.path.c_str()); + tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumbwidth, *cString::sprintf("%d", (*act).actorThumb.width)); + tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumbheight, *cString::sprintf("%d", (*act).actorThumb.height)); + i++; + } + } else if (series) { + tabs->AddIntToken((int)eScraperIT::ismovie, false); + tabs->AddIntToken((int)eScraperIT::isseries, true); + //Series Basics + tabs->AddStringToken((int)eScraperST::seriesname, series->name.c_str()); + tabs->AddStringToken((int)eScraperST::seriesoverview, series->overview.c_str()); + tabs->AddStringToken((int)eScraperST::seriesfirstaired, series->firstAired.c_str()); + tabs->AddStringToken((int)eScraperST::seriesnetwork, series->network.c_str()); + tabs->AddStringToken((int)eScraperST::seriesgenre, series->genre.c_str()); + stringstream rating; + rating << series->rating; + tabs->AddStringToken((int)eScraperST::seriesrating, rating.str().c_str()); + tabs->AddStringToken((int)eScraperST::seriesstatus, series->status.c_str()); + //Episode Information + tabs->AddIntToken((int)eScraperIT::episodenumber, series->episode.number); + tabs->AddIntToken((int)eScraperIT::episodeseason, series->episode.season); + tabs->AddStringToken((int)eScraperST::episodetitle, series->episode.name.c_str()); + tabs->AddStringToken((int)eScraperST::episodefirstaired, series->episode.firstAired.c_str()); + tabs->AddStringToken((int)eScraperST::episodegueststars, series->episode.guestStars.c_str()); + tabs->AddStringToken((int)eScraperST::episodeoverview, series->episode.overview.c_str()); + stringstream eprating; + eprating << series->episode.rating; + tabs->AddStringToken((int)eScraperST::episoderating, eprating.str().c_str()); + tabs->AddIntToken((int)eScraperIT::episodeimagewidth, series->episode.episodeImage.width); + tabs->AddIntToken((int)eScraperIT::episodeimageheight, series->episode.episodeImage.height); + tabs->AddStringToken((int)eScraperST::episodeimagepath, series->episode.episodeImage.path.c_str()); + //Seasonposter + tabs->AddIntToken((int)eScraperIT::seasonposterwidth, series->seasonPoster.width); + tabs->AddIntToken((int)eScraperIT::seasonposterheight, series->seasonPoster.height); + tabs->AddStringToken((int)eScraperST::seasonposterpath, series->seasonPoster.path.c_str()); + + //Posters + int indexInt = (int)eScraperIT::seriesposter1width; + int indexStr = (int)eScraperST::seriesposter1path; + for(vector<cTvMedia>::iterator poster = series->posters.begin(); poster != series->posters.end(); poster++) { + tabs->AddIntToken(indexInt, (*poster).width); + tabs->AddIntToken(indexInt+1, (*poster).height); + tabs->AddStringToken(indexStr, (*poster).path.c_str()); + indexInt += 2; + indexStr++; + } + //Banners + indexInt = (int)eScraperIT::seriesbanner1width; + indexStr = (int)eScraperST::seriesbanner1path; + for(vector<cTvMedia>::iterator banner = series->banners.begin(); banner != series->banners.end(); banner++) { + tabs->AddIntToken(indexInt, (*banner).width); + tabs->AddIntToken(indexInt+1, (*banner).height); + tabs->AddStringToken(indexStr, (*banner).path.c_str()); + indexInt += 2; + indexStr++; + } + //Fanarts + indexInt = (int)eScraperIT::seriesfanart1width; + indexStr = (int)eScraperST::seriesfanart1path; + for(vector<cTvMedia>::iterator fanart = series->fanarts.begin(); fanart != series->fanarts.end(); fanart++) { + tabs->AddIntToken(indexInt, (*fanart).width); + tabs->AddIntToken(indexInt+1, (*fanart).height); + tabs->AddStringToken(indexStr, (*fanart).path.c_str()); + indexInt += 2; + indexStr++; + } + //Actors + int actorsIndex = tabs->GetLoopIndex("actors"); + int i=0; + for (vector<cActor>::iterator act = series->actors.begin(); act != series->actors.end(); act++) { + tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::name, (*act).name.c_str()); + tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::role, (*act).role.c_str()); + tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumb, (*act).actorThumb.path.c_str()); + tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumbwidth, *cString::sprintf("%d", (*act).actorThumb.width)); + tabs->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumbheight, *cString::sprintf("%d", (*act).actorThumb.height)); + i++; + } + } else { + tabs->AddIntToken((int)eScraperIT::ismovie, false); + tabs->AddIntToken((int)eScraperIT::isseries, false); + } +} + +void cDetailView::SetEpgPictures(int eventId) { + string epgImagePath = tabs->GetEpgImagePath(); + for (int i=0; i<3; i++) { + stringstream picName; + picName << eventId << "_" << i; + bool epgPicAvailable = FileExists(epgImagePath, picName.str(), "jpg"); + if (epgPicAvailable) { + tabs->AddIntToken((int)eDetailedEpgIT::epgpic1avaialble + i, true); + tabs->AddStringToken((int)eDetailedEpgST::epgpic1path + i, *cString::sprintf("%s%s.jpg", epgImagePath.c_str(), picName.str().c_str())); + } else { + tabs->AddIntToken((int)eDetailedEpgIT::epgpic1avaialble + i, false); + tabs->AddStringToken((int)eDetailedEpgST::epgpic1path + i, ""); + } + } }
\ No newline at end of file diff --git a/detailview.h b/detailview.h index 517ec9c..d5174d0 100644 --- a/detailview.h +++ b/detailview.h @@ -1,49 +1,49 @@ -#ifndef __TVGUIDE_DETAILVIEW_H
-#define __TVGUIDE_DETAILVIEW_H
-
-#include "services/scraper2vdr.h"
-#include "services/epgsearch.h"
-#include "config.h"
-#include <libskindesignerapi/skindesignerosdbase.h>
-
-class cDetailView {
-private:
- bool init;
- int lastSecond;
- skindesignerapi::cOsdView *detailView;
- const cEvent *event;
- cMovie *movie;
- cSeries *series;
- skindesignerapi::cViewElement *back;
- skindesignerapi::cViewElement *header;
- skindesignerapi::cViewElement *footer;
- skindesignerapi::cViewElement *watch;
- skindesignerapi::cViewTab *tabs;
- void DrawBackground(void);
- void DrawHeader(void);
- void DrawFooter(void);
- void SetTabTokens(void);
- bool LoadScrapInfo(const cEvent *event);
- int NumActors(void);
- void SetScraperTokens(void);
- cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *LoadReruns(void);
- int NumReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns);
- void SetReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns);
- void SetEpgPictures(int eventId);
-public:
- cDetailView(skindesignerapi::cOsdView *detailView, const cEvent *event);
- virtual ~cDetailView(void);
- void Activate(void) { detailView->Activate(); };
- void Draw(void);
- void Left(void);
- void Right(void);
- void Up(void);
- void Down(void);
- bool DrawTime(void);
- void Flush(void) { detailView->Display(); };
- const cEvent *GetEvent(void) { return event; };
- static void DefineTokens(eViewElementsDetail ve, skindesignerapi::cTokenContainer *tk);
- static void DefineTabTokens(skindesignerapi::cTokenContainer *tk);
-};
-
-#endif //__TVGUIDE_DETAILVIEW_H
+#ifndef __TVGUIDE_DETAILVIEW_H +#define __TVGUIDE_DETAILVIEW_H + +#include "services/scraper2vdr.h" +#include "services/epgsearch.h" +#include "config.h" +#include <libskindesignerapi/skindesignerosdbase.h> + +class cDetailView { +private: + bool init; + int lastSecond; + skindesignerapi::cOsdView *detailView; + const cEvent *event; + cMovie *movie; + cSeries *series; + skindesignerapi::cViewElement *back; + skindesignerapi::cViewElement *header; + skindesignerapi::cViewElement *footer; + skindesignerapi::cViewElement *watch; + skindesignerapi::cViewTab *tabs; + void DrawBackground(void); + void DrawHeader(void); + void DrawFooter(void); + void SetTabTokens(void); + bool LoadScrapInfo(const cEvent *event); + int NumActors(void); + void SetScraperTokens(void); + cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *LoadReruns(void); + int NumReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns); + void SetReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns); + void SetEpgPictures(int eventId); +public: + cDetailView(skindesignerapi::cOsdView *detailView, const cEvent *event); + virtual ~cDetailView(void); + void Activate(void) { detailView->Activate(); }; + void Draw(void); + void Left(void); + void Right(void); + void Up(void); + void Down(void); + bool DrawTime(void); + void Flush(void) { detailView->Display(); }; + const cEvent *GetEvent(void) { return event; }; + static void DefineTokens(eViewElementsDetail ve, skindesignerapi::cTokenContainer *tk); + static void DefineTabTokens(skindesignerapi::cTokenContainer *tk); +}; + +#endif //__TVGUIDE_DETAILVIEW_H diff --git a/epgelement.c b/epgelement.c index 1ef5542..2e1d077 100644 --- a/epgelement.c +++ b/epgelement.c @@ -1,52 +1,52 @@ -#include "switchtimer.h"
-#include "services/remotetimers.h"
-#include "epgelement.h"
-
-cEpgElement::cEpgElement(const cEvent *event, cChannelEpg *owner) : cGridElement(owner) {
- this->event = event;
- hasTimer = false;
- SetTimer();
- hasSwitchTimer = false;
- SetSwitchTimer();
- dummy = false;
-}
-
-cEpgElement::~cEpgElement(void) {
-}
-
-void cEpgElement::SetTimer() {
- if (config.useRemoteTimers && pRemoteTimers) {
- RemoteTimers_Event_v1_0 rt;
- rt.event = event;
- if (pRemoteTimers->Service("RemoteTimers::GetTimerByEvent-v1.0", &rt))
- hasTimer = true;
- else
- hasTimer = false;
- } else if (owner->HasTimer()) {
- hasTimer = event->HasTimer();
- } else {
- hasTimer = false;
- }
-}
-
-void cEpgElement::SetSwitchTimer() {
- if (owner->HasSwitchTimer()) {
- hasSwitchTimer = SwitchTimers.EventInSwitchList(event);
- } else {
- hasSwitchTimer = false;
- }
-}
-
-const char *cEpgElement::Title(void) {
- return event->Title();
-}
-
-const char *cEpgElement::ShortText(void) {
- if (event->ShortText())
- return event->ShortText();
- return "";
-}
-
-void cEpgElement::Debug() {
- esyslog("tvguideng: epgelement %ld: \"%s\" %s - %s, channel %s, timer: %d", id, event->Title(), *(event->GetTimeString()), *(event->GetEndTimeString()), Channel()->Name(), hasTimer);
-}
+#include "switchtimer.h" +#include "services/remotetimers.h" +#include "epgelement.h" + +cEpgElement::cEpgElement(const cEvent *event, cChannelEpg *owner) : cGridElement(owner) { + this->event = event; + hasTimer = false; + SetTimer(); + hasSwitchTimer = false; + SetSwitchTimer(); + dummy = false; +} + +cEpgElement::~cEpgElement(void) { +} + +void cEpgElement::SetTimer() { + if (config.useRemoteTimers && pRemoteTimers) { + RemoteTimers_Event_v1_0 rt; + rt.event = event; + if (pRemoteTimers->Service("RemoteTimers::GetTimerByEvent-v1.0", &rt)) + hasTimer = true; + else + hasTimer = false; + } else if (owner->HasTimer()) { + hasTimer = event->HasTimer(); + } else { + hasTimer = false; + } +} + +void cEpgElement::SetSwitchTimer() { + if (owner->HasSwitchTimer()) { + hasSwitchTimer = SwitchTimers.EventInSwitchList(event); + } else { + hasSwitchTimer = false; + } +} + +const char *cEpgElement::Title(void) { + return event->Title(); +} + +const char *cEpgElement::ShortText(void) { + if (event->ShortText()) + return event->ShortText(); + return ""; +} + +void cEpgElement::Debug() { + esyslog("tvguideng: epgelement %ld: \"%s\" %s - %s, channel %s, timer: %d", id, event->Title(), *(event->GetTimeString()), *(event->GetEndTimeString()), Channel()->Name(), hasTimer); +} diff --git a/epgelement.h b/epgelement.h index 3a7b48d..a503914 100644 --- a/epgelement.h +++ b/epgelement.h @@ -1,28 +1,28 @@ -#ifndef __TVGUIDE_EPGGRID_H
-#define __TVGUIDE_EPGGRID_H
-
-#include <vdr/epg.h>
-#include "gridelement.h"
-#include "channelepg.h"
-
-// --- cEpgGrid -------------------------------------------------------------
-
-class cEpgElement : public cGridElement {
-private:
- const cEvent *event;
- time_t Duration(void) { return event->Duration(); };
-public:
- cEpgElement(const cEvent *event, cChannelEpg *owner);
- virtual ~cEpgElement(void);
- const cEvent *GetEvent(void) {return event;};
- time_t StartTime(void) { return event->StartTime(); };
- time_t EndTime(void) { return event->EndTime(); };
- void SetTimer(void);
- void SetSwitchTimer(void);
- const char *Title(void);
- const char *ShortText(void);
- const cEvent *Event(void) { return event; };
- void Debug(void);
-};
-
+#ifndef __TVGUIDE_EPGGRID_H +#define __TVGUIDE_EPGGRID_H + +#include <vdr/epg.h> +#include "gridelement.h" +#include "channelepg.h" + +// --- cEpgGrid ------------------------------------------------------------- + +class cEpgElement : public cGridElement { +private: + const cEvent *event; + time_t Duration(void) { return event->Duration(); }; +public: + cEpgElement(const cEvent *event, cChannelEpg *owner); + virtual ~cEpgElement(void); + const cEvent *GetEvent(void) {return event;}; + time_t StartTime(void) { return event->StartTime(); }; + time_t EndTime(void) { return event->EndTime(); }; + void SetTimer(void); + void SetSwitchTimer(void); + const char *Title(void); + const char *ShortText(void); + const cEvent *Event(void) { return event; }; + void Debug(void); +}; + #endif //__TVGUIDE_EPGGRID_H
\ No newline at end of file @@ -57,7 +57,14 @@ void cEpgGrid::Init(const cChannel *startChannel) { int numBack = channelsPerPage / 2; int offset = 0; const cChannel *newStartChannel = startChannel; - for (; newStartChannel ; newStartChannel = Channels.Prev(newStartChannel)) { +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* channels = Channels; +#else + const cChannels* channels = &Channels; +#endif + + for (; newStartChannel ; newStartChannel = channels->Prev(newStartChannel)) { if (newStartChannel && !newStartChannel->GroupSep()) { offset++; } @@ -65,7 +72,7 @@ void cEpgGrid::Init(const cChannel *startChannel) { break; } if (!newStartChannel) - newStartChannel = Channels.First(); + newStartChannel = channels->First(); offset--; if (offset < 0) offset = 0; @@ -79,7 +86,15 @@ void cEpgGrid::CreateChannels(const cChannel *startChannel, int activeChannel) { channels.Clear(); if (!startChannel) return; - for (const cChannel *channel = startChannel; channel; channel = Channels.Next(channel)) { + +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* chls = Channels; +#else + cChannels* chls = &Channels; +#endif + + for (const cChannel *channel = startChannel; channel; channel = chls->Next(channel)) { if (config.hideLastChannelGroup && channelGroups->IsInLastGroup(channel)) { break; } @@ -110,7 +125,7 @@ void cEpgGrid::CreateChannels(const cChannel *startChannel, int activeChannel) { int newChannelNumber = 1; if (first) newChannelNumber = first->GetChannelNumber() - numBack; - const cChannel *newStart = Channels.GetByNumber(newChannelNumber); + const cChannel *newStart = chls->GetByNumber(newChannelNumber); CreateChannels(newStart, pos+1); } } @@ -253,7 +268,15 @@ bool cEpgGrid::ChannelForward(void) { return false; //insert new channels at end int numInserted = 0; - for (const cChannel *channel = (const cChannel*)currentChannel->Next(); channel ; channel = Channels.Next(channel)) { + +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* chls = Channels; +#else + const cChannels* chls = &Channels; +#endif + + for (const cChannel *channel = (const cChannel*)currentChannel->Next(); channel ; channel = chls->Next(channel)) { if (channel->GroupSep()) { continue; } @@ -312,7 +335,13 @@ bool cEpgGrid::ChannelBack(void) { return false; //insert new channels at start int numInserted = 0; - for (const cChannel *channel = (const cChannel*)currentChannel->Prev(); channel ; channel = Channels.Prev(channel)) { +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* chls = Channels; +#else + const cChannels* chls = &Channels; +#endif + for (const cChannel *channel = (const cChannel*)currentChannel->Prev(); channel ; channel = chls->Prev(channel)) { if (channel->GroupSep()) { continue; } @@ -352,39 +381,67 @@ bool cEpgGrid::ChannelBack(void) { const cChannel *cEpgGrid::GetNextChannelNumJump(void) { const cChannel *newFirst = SeekChannelForward(channelsPerPage); if (!newFirst) - newFirst = Channels.Last(); + { +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + newFirst = Channels->Last(); +#else + newFirst = Channels.Last(); +#endif + } + return newFirst; } const cChannel *cEpgGrid::GetPrevChannelNumJump(void) { const cChannel *newFirst = SeekChannelBack(channelsPerPage); if (!newFirst) - newFirst = Channels.First(); + { +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + newFirst = Channels->First(); +#else + newFirst = Channels.First(); +#endif + } return newFirst; } const cChannel *cEpgGrid::GetNextChannelGroupJump(void) { - if (!active) { - return Channels.Last(); - } +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* chls = Channels; +#else + cChannels* chls = &Channels; +#endif + + if (!active) + return chls->Last(); + int currentGroup = channelGroups->GetGroup(active->Channel()); int nextChannelNumber = channelGroups->GetNextGroupFirstChannel(currentGroup); - const cChannel *next = Channels.GetByNumber(nextChannelNumber); + const cChannel *next = chls->GetByNumber(nextChannelNumber); if (next) return next; - return Channels.Last(); + return chls->Last(); } const cChannel *cEpgGrid::GetPrevChannelGroupJump(void) { - if (!active) { - return Channels.First(); - } +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* chls = Channels; +#else + cChannels* chls = &Channels; +#endif + if (!active) + return chls->First(); + int currentGroup = channelGroups->GetGroup(active->Channel()); int prevChannelNumber = channelGroups->GetPrevGroupFirstChannel(currentGroup); - const cChannel *prev = Channels.GetByNumber(prevChannelNumber); + const cChannel *prev = chls->GetByNumber(prevChannelNumber); if (prev) return prev; - return Channels.First(); + return chls->First(); } bool cEpgGrid::IsFirstGroup(void) { @@ -715,15 +772,22 @@ const cChannel *cEpgGrid::SeekChannelForward(int num) { return NULL; const cChannel *currentChannel = active->Channel(); const cChannel *destChannel; +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* chls = Channels; +#else + const cChannels* chls = &Channels; +#endif + int found = 0; - for (destChannel = currentChannel; destChannel ; destChannel = Channels.Next(destChannel)) { + for (destChannel = currentChannel; destChannel ; destChannel = chls->Next(destChannel)) { if (destChannel->GroupSep()) { continue; } if (config.hideLastChannelGroup && channelGroups->IsInLastGroup(destChannel)) { - destChannel = Channels.Prev(destChannel); + destChannel = chls->Prev(destChannel); while (destChannel && destChannel->GroupSep()) { - destChannel = Channels.Prev(destChannel); + destChannel = chls->Prev(destChannel); } break; } @@ -732,9 +796,9 @@ const cChannel *cEpgGrid::SeekChannelForward(int num) { found++; } if (!destChannel) - destChannel = Channels.Last(); + destChannel = chls->Last(); while (destChannel && destChannel->GroupSep()) { - destChannel = Channels.Prev(destChannel); + destChannel = chls->Prev(destChannel); } return destChannel; } @@ -745,7 +809,13 @@ const cChannel *cEpgGrid::SeekChannelBack(int num) { const cChannel *currentChannel = active->Channel(); const cChannel *destChannel; int found = 0; - for (destChannel = currentChannel; destChannel ; destChannel = Channels.Prev(destChannel)) { +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* chls = Channels; +#else + const cChannels* chls = &Channels; +#endif + for (destChannel = currentChannel; destChannel ; destChannel = chls->Prev(destChannel)) { if (destChannel->GroupSep()) { continue; } @@ -754,9 +824,9 @@ const cChannel *cEpgGrid::SeekChannelBack(int num) { found++; } if (!destChannel) - destChannel = Channels.First(); + destChannel = chls->First(); while (destChannel && destChannel->GroupSep()) { - destChannel = Channels.Next(destChannel); + destChannel = chls->Next(destChannel); } return destChannel; } @@ -774,4 +844,4 @@ void cEpgGrid::Debug(void) { esyslog("tvguideng: No Active Grid Element"); } esyslog("tvguideng: -----------------------------------------------"); -}
\ No newline at end of file +} diff --git a/gridelement.c b/gridelement.c index fe36128..af18fcd 100644 --- a/gridelement.c +++ b/gridelement.c @@ -1,56 +1,56 @@ -#include "gridelement.h"
-#include "channelepg.h"
-
-long cGridElement::idCounter;
-
-cGridElement::cGridElement(cChannelEpg *owner) {
- id = idCounter;
- idCounter++;
- init = true;
- active = false;
- hasTimer = false;
- hasSwitchTimer = false;
- this->owner = owner;
-}
-
-cGridElement::~cGridElement(void) {
-}
-
-bool cGridElement::Match(time_t t) {
- if ((StartTime() < t) && (EndTime() > t))
- return true;
- else
- return false;
-}
-
-bool cGridElement::IsFirst(void) {
- return owner->IsFirst(this);
-}
-
-int cGridElement::CalcOverlap(cGridElement *neighbor) {
- int overlap = 0;
- if (Intersects(neighbor)) {
- if ((StartTime() <= neighbor->StartTime()) && (EndTime() <= neighbor->EndTime())) {
- overlap = EndTime() - neighbor->StartTime();
- } else if ((StartTime() >= neighbor->StartTime()) && (EndTime() >= neighbor->EndTime())) {
- overlap = neighbor->EndTime() - StartTime();
- } else if ((StartTime() >= neighbor->StartTime()) && (EndTime() <= neighbor->EndTime())) {
- overlap = Duration();
- } else if ((StartTime() <= neighbor->StartTime()) && (EndTime() >= neighbor->EndTime())) {
- overlap = neighbor->EndTime() - neighbor->StartTime();
- }
- }
- return overlap;
-}
-
-bool cGridElement::Intersects(cGridElement *neighbor) {
- return ! ( (neighbor->EndTime() <= StartTime()) || (neighbor->StartTime() >= EndTime()) );
-}
-
-const cChannel *cGridElement::Channel(void) {
- return owner->Channel();
-}
-
-cChannelEpg *cGridElement::Owner(void) {
- return owner;
-}
+#include "gridelement.h" +#include "channelepg.h" + +long cGridElement::idCounter; + +cGridElement::cGridElement(cChannelEpg *owner) { + id = idCounter; + idCounter++; + init = true; + active = false; + hasTimer = false; + hasSwitchTimer = false; + this->owner = owner; +} + +cGridElement::~cGridElement(void) { +} + +bool cGridElement::Match(time_t t) { + if ((StartTime() < t) && (EndTime() > t)) + return true; + else + return false; +} + +bool cGridElement::IsFirst(void) { + return owner->IsFirst(this); +} + +int cGridElement::CalcOverlap(cGridElement *neighbor) { + int overlap = 0; + if (Intersects(neighbor)) { + if ((StartTime() <= neighbor->StartTime()) && (EndTime() <= neighbor->EndTime())) { + overlap = EndTime() - neighbor->StartTime(); + } else if ((StartTime() >= neighbor->StartTime()) && (EndTime() >= neighbor->EndTime())) { + overlap = neighbor->EndTime() - StartTime(); + } else if ((StartTime() >= neighbor->StartTime()) && (EndTime() <= neighbor->EndTime())) { + overlap = Duration(); + } else if ((StartTime() <= neighbor->StartTime()) && (EndTime() >= neighbor->EndTime())) { + overlap = neighbor->EndTime() - neighbor->StartTime(); + } + } + return overlap; +} + +bool cGridElement::Intersects(cGridElement *neighbor) { + return ! ( (neighbor->EndTime() <= StartTime()) || (neighbor->StartTime() >= EndTime()) ); +} + +const cChannel *cGridElement::Channel(void) { + return owner->Channel(); +} + +cChannelEpg *cGridElement::Owner(void) { + return owner; +} diff --git a/gridelement.h b/gridelement.h index 4bd6d08..aa7ccc3 100644 --- a/gridelement.h +++ b/gridelement.h @@ -1,51 +1,51 @@ -#ifndef __TVGUIDE_GRID_H
-#define __TVGUIDE_GRID_H
-
-#include <vdr/tools.h>
-#include <vdr/epg.h>
-
-class cChannelEpg;
-
-class cGridElement : public cListObject {
-protected:
- static long idCounter;
- long id;
- bool init;
- bool active;
- bool hasTimer;
- bool hasSwitchTimer;
- cChannelEpg *owner;
- bool Intersects(cGridElement *neighbor);
- virtual time_t Duration(void) { return 0; };
- bool dummy;
-public:
- cGridElement(cChannelEpg *owner);
- virtual ~cGridElement(void);
- bool IsNew(void) { return init; };
- void Dirty(void) { init = true; };
- void InitFinished(void) { init = false; };
- void SetActive(void) {active = true;};
- void SetInActive(void) {active = false;};
- bool Match(time_t t);
- virtual time_t StartTime(void) { return 0; };
- virtual time_t EndTime(void) { return 0; };
- virtual void SetStartTime(time_t start) {};
- virtual void SetEndTime(time_t end) {};
- int CalcOverlap(cGridElement *neighbor);
- virtual void SetTimer(void) {};
- virtual void SetSwitchTimer(void) {};
- long Id(void) { return id; };
- bool Active(void) { return active; };
- bool HasTimer(void) {return hasTimer;};
- bool HasSwitchTimer(void) {return hasSwitchTimer;};
- bool IsFirst(void);
- bool IsDummy(void) { return dummy; };
- const cChannel *Channel(void);
- virtual const char *Title(void) { return ""; };
- virtual const char *ShortText(void) { return ""; };
- virtual const cEvent *Event(void) { return NULL; };
- cChannelEpg *Owner(void);
- virtual void Debug(void) {};
-};
-
+#ifndef __TVGUIDE_GRID_H +#define __TVGUIDE_GRID_H + +#include <vdr/tools.h> +#include <vdr/epg.h> + +class cChannelEpg; + +class cGridElement : public cListObject { +protected: + static long idCounter; + long id; + bool init; + bool active; + bool hasTimer; + bool hasSwitchTimer; + cChannelEpg *owner; + bool Intersects(cGridElement *neighbor); + virtual time_t Duration(void) { return 0; }; + bool dummy; +public: + cGridElement(cChannelEpg *owner); + virtual ~cGridElement(void); + bool IsNew(void) { return init; }; + void Dirty(void) { init = true; }; + void InitFinished(void) { init = false; }; + void SetActive(void) {active = true;}; + void SetInActive(void) {active = false;}; + bool Match(time_t t); + virtual time_t StartTime(void) { return 0; }; + virtual time_t EndTime(void) { return 0; }; + virtual void SetStartTime(time_t start) {}; + virtual void SetEndTime(time_t end) {}; + int CalcOverlap(cGridElement *neighbor); + virtual void SetTimer(void) {}; + virtual void SetSwitchTimer(void) {}; + long Id(void) { return id; }; + bool Active(void) { return active; }; + bool HasTimer(void) {return hasTimer;}; + bool HasSwitchTimer(void) {return hasSwitchTimer;}; + bool IsFirst(void); + bool IsDummy(void) { return dummy; }; + const cChannel *Channel(void); + virtual const char *Title(void) { return ""; }; + virtual const char *ShortText(void) { return ""; }; + virtual const cEvent *Event(void) { return NULL; }; + cChannelEpg *Owner(void); + virtual void Debug(void) {}; +}; + #endif //__TVGUIDE_GRID_H
\ No newline at end of file diff --git a/recmanager.c b/recmanager.c index fbbf890..047ca18 100644 --- a/recmanager.c +++ b/recmanager.c @@ -6,6 +6,7 @@ #include <algorithm> #include <vdr/menu.h> +#include <vdr/timers.h> #include "recmanager.h" static int CompareRecording(const void *p1, const void *p2) { @@ -51,15 +52,23 @@ bool cRecManager::CheckEventForTimer(const cEvent *event) { return hasTimer; } -cTimer *cRecManager::GetTimerForEvent(const cEvent *event) { - cTimer *timer = NULL; +const cTimer *cRecManager::GetTimerForEvent(const cEvent *event) { + const cTimer *timer = NULL; if (config.useRemoteTimers && pRemoteTimers) { RemoteTimers_GetMatch_v1_0 rtMatch; rtMatch.event = event; pRemoteTimers->Service("RemoteTimers::GetMatch-v1.0", &rtMatch); timer = rtMatch.timer; - } else - timer = Timers.GetMatch(event); + return timer; + } + +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_READ; + timer = Timers->GetMatch(event); +#else + timer = Timers.GetMatch(event); +#endif + return timer; } @@ -74,20 +83,32 @@ cTimer *cRecManager::createTimer(const cEvent *event, std::string path) { } cTimer *cRecManager::createLocalTimer(const cEvent *event, std::string path) { - cTimer *timer = new cTimer(event); - cTimer *t = Timers.GetTimer(timer); + cTimer *timer = new cTimer(event); + +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_WRITE; + cTimers* timers = Timers; +#else + cTimers* timers = &Timers; +#endif + + cTimer* t = timers->GetTimer(timer); + if (t) { t->OnOff(); - t->SetEventFromSchedule(); + + // #TODO ist das richtig? + t->SetEvent(event); // t->SetEventFromSchedule(); + delete timer; timer = t; isyslog("timer %s reactivated", *t->ToDescr()); } else { - Timers.Add(timer); + timers->Add(timer); isyslog("timer %s added (active)", *timer->ToDescr()); } SetTimerPath(timer, event, path); - Timers.SetModified(); + timers->SetModified(); return timer; } @@ -144,7 +165,13 @@ void cRecManager::SetTimerPath(cTimer *timer, const cEvent *event, std::string p } void cRecManager::DeleteTimer(int timerID) { - cTimer *t = Timers.Get(timerID); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_READ; + const cTimer *t = Timers->Get(timerID); +#else + const cTimer *t = Timers.Get(timerID); +#endif + if (!t) return; DeleteTimer(t); @@ -161,21 +188,40 @@ void cRecManager::DeleteTimer(const cEvent *event) { } void cRecManager::DeleteLocalTimer(const cEvent *event) { - cTimer *t = Timers.GetMatch(event); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_READ; + const cTimer *t = Timers->GetMatch(event); +#else + const cTimer *t = Timers.GetMatch(event); +#endif + if (!t) return; DeleteTimer(t); } -void cRecManager::DeleteTimer(cTimer *timer) { - if (timer->Recording()) { - timer->Skip(); - cRecordControls::Process(time(NULL)); - } +void cRecManager::DeleteTimer(const cTimer *timer) { +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_WRITE; + cTimers* timers = Timers; +#else + cTimers* timers = &Timers; +#endif + + cTimer* t = timers->GetTimer((cTimer*)timer); // #TODO dirty cast + + if (t->Recording()) { + t->Skip(); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + cRecordControls::Process(timers, time(NULL)); +#else + cRecordControls::Process(time(NULL)); +#endif + } isyslog("timer %s deleted", *timer->ToDescr()); - Timers.Del(timer, true); - Timers.SetModified(); + timers->Del(t, true); + timers->SetModified(); } void cRecManager::DeleteRemoteTimer(const cEvent *event) { @@ -184,7 +230,7 @@ void cRecManager::DeleteRemoteTimer(const cEvent *event) { pRemoteTimers->Service("RemoteTimers::GetMatch-v1.0", &rtMatch); if (rtMatch.timer) { RemoteTimers_Timer_v1_0 rt; - rt.timer = rtMatch.timer; + rt.timer = (cTimer*)rtMatch.timer; // #TODO - dirty cast isyslog("remotetimer %s deleted", *rt.timer->ToDescr()); if (!pRemoteTimers->Service("RemoteTimers::DelTimer-v1.0", &rt)) isyslog("remotetimer error"); @@ -192,7 +238,7 @@ void cRecManager::DeleteRemoteTimer(const cEvent *event) { } } -void cRecManager::SaveTimer(cTimer *timer, cTimer newTimerSettings) { +void cRecManager::SaveTimer(const cTimer *timer, cTimer newTimerSettings) { if (!timer) return; @@ -204,33 +250,45 @@ void cRecManager::SaveTimer(cTimer *timer, cTimer newTimerSettings) { int stop = newTimerSettings.Stop(); std::string fileName = newTimerSettings.File(); - timer->SetDay(day); - timer->SetStart(start); - timer->SetStop(stop); - timer->SetPriority(prio); - timer->SetLifetime(lifetime); - timer->SetFile(fileName.c_str()); - + // #TODO - very dirty cast from const !! + ((cTimer*)timer)->SetDay(day); + ((cTimer*)timer)->SetStart(start); + ((cTimer*)timer)->SetStop(stop); + ((cTimer*)timer)->SetPriority(prio); + ((cTimer*)timer)->SetLifetime(lifetime); + ((cTimer*)timer)->SetFile(fileName.c_str()); + if (timer->HasFlags(tfActive) && !active) - timer->ClrFlags(tfActive); + ((cTimer*)timer)->ClrFlags(tfActive); else if (!timer->HasFlags(tfActive) && active) - timer->SetFlags(tfActive); + ((cTimer*)timer)->SetFlags(tfActive); - timer->SetEventFromSchedule(); +// #TODO to be implemented timer->SetEventFromSchedule(); if (config.useRemoteTimers && pRemoteTimers) { RemoteTimers_Timer_v1_0 rt; - rt.timer = timer; + rt.timer = (cTimer*)timer; // #TODO - dirty cast if (!pRemoteTimers->Service("RemoteTimers::ModTimer-v1.0", &rt)) rt.timer = NULL; RefreshRemoteTimers(); } else { - Timers.SetModified(); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_WRITE; + Timers->SetModified(); +#else + Timers.SetModified(); +#endif } } bool cRecManager::IsRecorded(const cEvent *event) { - cTimer *timer = Timers.GetMatch(event); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_WRITE; + cTimers* timers = Timers; +#else + cTimers* timers = &Timers; +#endif + cTimer *timer = timers->GetMatch(event); if (!timer) return false; return timer->Recording(); @@ -256,7 +314,7 @@ cTVGuideTimerConflicts *cRecManager::CheckTimerConflict(void) { } void cRecManager::CreateSeriesTimer(cTimer *seriesTimer) { - seriesTimer->SetEventFromSchedule(); +// #TOSO seriesTimer->SetEventFromSchedule(); if (config.useRemoteTimers && pRemoteTimers) { RemoteTimers_Timer_v1_0 rt; rt.timer = seriesTimer; @@ -264,8 +322,15 @@ void cRecManager::CreateSeriesTimer(cTimer *seriesTimer) { isyslog("%s", *rt.errorMsg); RefreshRemoteTimers(); } else { - Timers.Add(seriesTimer); - Timers.SetModified(); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_WRITE; + cTimers* timers = Timers; +#else + cTimers* timers = &Timers; +#endif + + timers->Add(seriesTimer); + timers->SetModified(); } } @@ -312,9 +377,15 @@ const cEvent **cRecManager::PerformSearchTimerSearch(std::string epgSearchString numResults = results.size(); if (numResults > 0) { searchResults = new const cEvent *[numResults]; + +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_SCHEDULES_READ; + const cSchedules* schedules = Schedules; +#else cSchedulesLock schedulesLock; - const cSchedules *schedules; - schedules = cSchedules::Schedules(schedulesLock); + const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock); +#endif + const cEvent *event = NULL; int index=0; for (std::list<std::string>::iterator it=results.begin(); it != results.end(); ++it) { @@ -324,7 +395,15 @@ const cEvent **cRecManager::PerformSearchTimerSearch(std::string epgSearchString int eventID = atoi(flds[1].c_str()); std::string channelID = flds[7]; tChannelID chanID = tChannelID::FromString(channelID.c_str()); - cChannel *channel = Channels.GetByChannelID(chanID); + +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* channels = Channels; +#else + cChannels* channels = &Channels; +#endif + + const cChannel *channel = channels->GetByChannelID(chanID); if (channel) { const cSchedule *Schedule = NULL; Schedule = schedules->GetSchedule(channel); @@ -431,24 +510,30 @@ void cRecManager::DeleteSearchTimer(cTVGuideSearchTimer *searchTimer, bool delTi return; int searchTimerID = searchTimer->GetID(); if (delTimers) { - cTimer *timer = Timers.First(); - while(timer) { +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_WRITE; + cTimers* timers = Timers; +#else + cTimers* timers = &Timers; +#endif + cTimer *timer = timers->First(); + while (timer) { if (!timer->Recording()) { char* searchID = GetAuxValue(timer, "s-id"); if (searchID) { if (searchTimerID == atoi(searchID)) { - cTimer* timerNext = Timers.Next(timer); + cTimer* timerNext = timers->Next(timer); DeleteTimer(timer); timer = timerNext; } else { - timer = Timers.Next(timer); + timer = timers->Next(timer); } free(searchID); } else { - timer = Timers.Next(timer); + timer = timers->Next(timer); } } else { - timer = Timers.Next(timer); + timer = timers->Next(timer); } } } @@ -501,13 +586,20 @@ void cRecManager::DeleteSwitchTimer(const cEvent *event) { } } -cRecording **cRecManager::SearchForRecordings(std::string searchString, int &numResults) { +const cRecording **cRecManager::SearchForRecordings(std::string searchString, int &numResults) { - cRecording **matchingRecordings = NULL; + const cRecording **matchingRecordings = NULL; int num = 0; numResults = 0; + +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_RECORDINGS_READ; + const cRecordings* recordings = Recordings; +#else + const cRecordings* recordings = &Recordings; +#endif - for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { + for (const cRecording *recording = recordings->First(); recording; recording = recordings->Next(recording)) { std::string s1 = recording->Name(); std::string s2 = searchString; if (s1.empty() || s2.empty()) continue; @@ -538,7 +630,7 @@ cRecording **cRecManager::SearchForRecordings(std::string searchString, int &num } if (match) { - matchingRecordings = (cRecording **)realloc(matchingRecordings, (num + 1) * sizeof(cRecording *)); + matchingRecordings = (const cRecording **)realloc(matchingRecordings, (num + 1) * sizeof(cRecording *)); matchingRecordings[num++] = recording; } } @@ -615,17 +707,31 @@ void cRecManager::GetFavorites(std::vector<cTVGuideSearchTimer> *favorites) { const cEvent **cRecManager::WhatsOnNow(bool nowOrNext, int &numResults) { std::vector<const cEvent*> tmpResults; + +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* channels = Channels; +#else + cChannels* channels = &Channels; +#endif + +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_SCHEDULES_READ; + const cSchedules* schedules = Schedules; +#else cSchedulesLock schedulesLock; - const cSchedules *schedules = cSchedules::Schedules(schedulesLock); + const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock); +#endif + const cChannel *startChannel = NULL, *stopChannel = NULL; if (config.favLimitChannels) { - startChannel = Channels.GetByNumber(config.favStartChannel); - stopChannel = Channels.GetByNumber(config.favStopChannel); + startChannel = channels->GetByNumber(config.favStartChannel); + stopChannel = channels->GetByNumber(config.favStopChannel); } if (!startChannel) - startChannel = Channels.First(); + startChannel = channels->First(); - for (const cChannel *channel = startChannel; channel; channel = Channels.Next(channel)) { + for (const cChannel *channel = startChannel; channel; channel = channels->Next(channel)) { if (channel->GroupSep()) continue; const cSchedule *Schedule = schedules->GetSchedule(channel); if (!Schedule) continue; @@ -675,17 +781,30 @@ const cEvent **cRecManager::UserDefinedTime(int userTime, int &numResults) { if (searchTime < now) searchTime += 24*60*60; +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* channels = Channels; +#else + cChannels* channels = &Channels; +#endif + +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_SCHEDULES_READ; + const cSchedules* schedules = Schedules; +#else cSchedulesLock schedulesLock; - const cSchedules *schedules = cSchedules::Schedules(schedulesLock); + const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock); +#endif + const cChannel *startChannel = NULL, *stopChannel = NULL; if (config.favLimitChannels) { - startChannel = Channels.GetByNumber(config.favStartChannel); - stopChannel = Channels.GetByNumber(config.favStopChannel); + startChannel = channels->GetByNumber(config.favStartChannel); + stopChannel = channels->GetByNumber(config.favStopChannel); } if (!startChannel) - startChannel = Channels.First(); + startChannel = channels->First(); - for (const cChannel *channel = startChannel; channel; channel = Channels.Next(channel)) { + for (const cChannel *channel = startChannel; channel; channel = channels->Next(channel)) { if (channel->GroupSep()) continue; const cSchedule *Schedule = schedules->GetSchedule(channel); if (!Schedule) continue; diff --git a/recmanager.h b/recmanager.h index cff14fd..a901049 100644 --- a/recmanager.h +++ b/recmanager.h @@ -29,17 +29,17 @@ public: bool EpgSearchAvailable(void) {return epgSearchAvailable;}; bool RefreshRemoteTimers(void); bool CheckEventForTimer(const cEvent *event); - cTimer *GetTimerForEvent(const cEvent *event); + const cTimer *GetTimerForEvent(const cEvent *event); cTimer *createTimer(const cEvent *event, std::string path = ""); cTimer *createLocalTimer(const cEvent *event, std::string path); cTimer *createRemoteTimer(const cEvent *event, std::string path); void SetTimerPath(cTimer *timer, const cEvent *event, std::string path); - void DeleteTimer(cTimer *timer); + void DeleteTimer(const cTimer *timer); void DeleteTimer(int timerID); void DeleteTimer(const cEvent *event); void DeleteLocalTimer(const cEvent *event); void DeleteRemoteTimer(const cEvent *event); - void SaveTimer(cTimer *timer, cTimer newTimerSettings); + void SaveTimer(const cTimer *timer, cTimer newTimerSettings); bool IsRecorded(const cEvent *event); cTVGuideTimerConflicts *CheckTimerConflict(void); void CreateSeriesTimer(cTimer *seriesTimer); @@ -53,7 +53,7 @@ public: void UpdateSearchTimers(void); bool CreateSwitchTimer(const cEvent *event, cSwitchTimer switchTimer); void DeleteSwitchTimer(const cEvent *event); - cRecording **SearchForRecordings(std::string searchString, int &numResults); + const cRecording **SearchForRecordings(std::string searchString, int &numResults); const cEvent **LoadReruns(const cEvent *event, int &numResults); void GetFavorites(std::vector<cTVGuideSearchTimer> *favorites); const cEvent **WhatsOnNow(bool nowOrNext, int &numResults); @@ -61,4 +61,4 @@ public: virtual ~cRecManager (void); }; -#endif //__TVGUIDE_RECMMANAGER_H
\ No newline at end of file +#endif //__TVGUIDE_RECMMANAGER_H @@ -1,623 +1,623 @@ -#include "recmenu.h"
-#include "tvguidengosd.h"
-
-// --- cRecMenu -------------------------------------------------------------
-
-cRecMenu::cRecMenu() {
- hidden = false;
- menuWidth = 50;
- menuHeight = 0;
- maxMenuHeight = 98;
- recMenuGrid = NULL;
- osdView = NULL;
- scrollBar = NULL;
- back = NULL;
- start = NULL;
- stop = NULL;
- itemCount = 0;
- active = NULL;
- header = NULL;
- footer = NULL;
- scrolling = false;
-}
-
-cRecMenu::~cRecMenu(void) {
- menuItems.Clear();
- if (scrollBar) {
- scrollBar->Clear();
- delete scrollBar;
- scrollBar = NULL;
- }
- if (back) {
- back->Clear();
- delete back;
- back = NULL;
- }
- if (recMenuGrid) {
- recMenuGrid->Clear();
- delete recMenuGrid;
- }
- if (hidden)
- osdView->Activate();
-}
-
-/********************************************************************
-* Public Functions
-********************************************************************/
-
-void cRecMenu::Init(skindesignerapi::cOsdView *osdView) {
- this->osdView = osdView;
- recMenuGrid = osdView->GetViewGrid((int)eViewGridsRecMenu::menu);
- scrollBar = osdView->GetViewElement((int)eViewElementsRecMenu::scrollbar);
- back = osdView->GetViewElement((int)eViewElementsRecMenu::background);
- InitMenuItems();
-}
-
-void cRecMenu::Draw(void) {
- DrawHeader();
- double width = (double)menuWidth / (double)100;
- double x = (double)(100 - menuWidth)/(double)200;
- int totalHeight = GetHeight();
- int yPerc = (100 - totalHeight) / 2;
- if (header)
- yPerc += header->GetHeight();
- double y = (double)yPerc/(double)100;
-
- for (cRecMenuItem *current = start; current; current = menuItems.Next(current)) {
-
- double itemHeight = (double)(current->GetHeight())/(double)100;
- if (current->IsNew()) {
- current->SetTokens(recMenuGrid);
- recMenuGrid->SetGrid(current->Id(), x, y, width, itemHeight);
- } else {
- recMenuGrid->MoveGrid(current->Id(), x, y, width, itemHeight);
- }
- if (current->Active()) {
- recMenuGrid->SetCurrent(current->Id(), true);
- }
- y += itemHeight;
- if (current == stop)
- break;
- }
- DrawFooter();
- recMenuGrid->Display();
-}
-
-eRecMenuState cRecMenu::ProcessKey(eKeys Key) {
- eRecMenuState state = rmsContinue;
- if (!active)
- return state;
-
- state = active->ProcessKey(Key);
- if (state == rmsRefresh) {
- //Refresh current
- active->SetTokens(recMenuGrid);
- active->SetNew();
- Draw();
- } else if (state == rmsNotConsumed) {
- switch (Key & ~k_Repeat) {
- case kUp:
- if (!ScrollUp(false))
- SetLast();
- Draw();
- state = rmsConsumed;
- break;
- case kDown:
- if (!ScrollDown(false))
- SetFirst();
- Draw();
- state = rmsConsumed;
- break;
- case kLeft:
- if (PageUp())
- Draw();
- state = rmsConsumed;
- break;
- case kRight:
- if (PageDown())
- Draw();
- state = rmsConsumed;
- break;
- case kBack:
- state = rmsClose;
- break;
- default:
- break;
- }
- }
- return state;
-}
-
-void cRecMenu::DefineTokens(eViewElementsRecMenu ve, skindesignerapi::cTokenContainer *tk) {
- switch (ve) {
- case eViewElementsRecMenu::background:
- tk->DefineIntToken("{menuwidth}", (int)eBackgroundRecMenuIT::menuwidth);
- tk->DefineIntToken("{menuheight}", (int)eBackgroundRecMenuIT::menuheight);
- tk->DefineIntToken("{hasscrollbar}", (int)eBackgroundRecMenuIT::hasscrollbar);
- break;
- case eViewElementsRecMenu::scrollbar:
- tk->DefineIntToken("{menuwidth}", (int)eScrollbarRecMenuIT::menuwidth);
- tk->DefineIntToken("{posy}", (int)eScrollbarRecMenuIT::posy);
- tk->DefineIntToken("{totalheight}", (int)eScrollbarRecMenuIT::totalheight);
- tk->DefineIntToken("{height}", (int)eScrollbarRecMenuIT::height);
- tk->DefineIntToken("{offset}", (int)eScrollbarRecMenuIT::offset);
- break;
- default:
- break;
- }
-}
-
-void cRecMenu::DefineTokens(eViewGridsRecMenu vg, skindesignerapi::cTokenContainer *tk) {
- tk->DefineIntToken("{info}", (int)eRecMenuIT::info);
- tk->DefineIntToken("{lines}", (int)eRecMenuIT::lines);
- tk->DefineIntToken("{button}", (int)eRecMenuIT::button);
- tk->DefineIntToken("{buttonyesno}", (int)eRecMenuIT::buttonyesno);
- tk->DefineIntToken("{yes}", (int)eRecMenuIT::yes);
- tk->DefineIntToken("{intselector}", (int)eRecMenuIT::intselector);
- tk->DefineIntToken("{intvalue}", (int)eRecMenuIT::value);
- tk->DefineIntToken("{boolselector}", (int)eRecMenuIT::boolselector);
- tk->DefineIntToken("{stringselector}", (int)eRecMenuIT::stringselector);
- tk->DefineIntToken("{textinput}", (int)eRecMenuIT::textinput);
- tk->DefineIntToken("{editmode}", (int)eRecMenuIT::editmode);
- tk->DefineIntToken("{timeselector}", (int)eRecMenuIT::timeselector);
- tk->DefineIntToken("{dayselector}", (int)eRecMenuIT::dayselector);
- tk->DefineIntToken("{channelselector}", (int)eRecMenuIT::channelselector);
- tk->DefineIntToken("{channelnumber}", (int)eRecMenuIT::channelnumber);
- tk->DefineIntToken("{channellogoexisis}", (int)eRecMenuIT::channellogoexisis);
- tk->DefineIntToken("{weekdayselector}", (int)eRecMenuIT::weekdayselector);
- tk->DefineIntToken("{dayselected}", (int)eRecMenuIT::dayselected);
- tk->DefineIntToken("{day0set}", (int)eRecMenuIT::day0set);
- tk->DefineIntToken("{day1set}", (int)eRecMenuIT::day1set);
- tk->DefineIntToken("{day2set}", (int)eRecMenuIT::day2set);
- tk->DefineIntToken("{day3set}", (int)eRecMenuIT::day3set);
- tk->DefineIntToken("{day4set}", (int)eRecMenuIT::day4set);
- tk->DefineIntToken("{day5set}", (int)eRecMenuIT::day5set);
- tk->DefineIntToken("{day6set}", (int)eRecMenuIT::day6set);
- tk->DefineIntToken("{directoryselector}", (int)eRecMenuIT::directoryselector);
- tk->DefineIntToken("{timerconflictheader}", (int)eRecMenuIT::timerconflictheader);
- tk->DefineIntToken("{overlapstartpercent}", (int)eRecMenuIT::overlapstartpercent);
- tk->DefineIntToken("{overlapwidthpercent}", (int)eRecMenuIT::overlapwidthpercent);
- tk->DefineIntToken("{timerconflict}", (int)eRecMenuIT::timerconflict);
- tk->DefineIntToken("{infoactive}", (int)eRecMenuIT::infoactive);
- tk->DefineIntToken("{deleteactive}", (int)eRecMenuIT::deleteactive);
- tk->DefineIntToken("{editactive}", (int)eRecMenuIT::editactive);
- tk->DefineIntToken("{searchactive}", (int)eRecMenuIT::searchactive);
- tk->DefineIntToken("{timerstartpercent}", (int)eRecMenuIT::timerstartpercent);
- tk->DefineIntToken("{timerwidthpercent}", (int)eRecMenuIT::timerwidthpercent);
- tk->DefineIntToken("{event}", (int)eRecMenuIT::event);
- tk->DefineIntToken("{hastimer}", (int)eRecMenuIT::hastimer);
- tk->DefineIntToken("{recording}", (int)eRecMenuIT::recording);
- tk->DefineIntToken("{recduration}", (int)eRecMenuIT::recduration);
- tk->DefineIntToken("{searchtimer}", (int)eRecMenuIT::searchtimer);
- tk->DefineIntToken("{timeractive}", (int)eRecMenuIT::timeractive);
- tk->DefineIntToken("{activetimers}", (int)eRecMenuIT::activetimers);
- tk->DefineIntToken("{recordingsdone}", (int)eRecMenuIT::recordingsdone);
- tk->DefineIntToken("{timelineheader}", (int)eRecMenuIT::timelineheader);
- tk->DefineIntToken("{timerset}", (int)eRecMenuIT::timerset);
- tk->DefineIntToken("{channeltransponder}", (int)eRecMenuIT::channeltransponder);
- tk->DefineIntToken("{timelinetimer}", (int)eRecMenuIT::timelinetimer);
- tk->DefineIntToken("{timerstart}", (int)eRecMenuIT::timerstart);
- tk->DefineIntToken("{timerwidth}", (int)eRecMenuIT::timerwidth);
- tk->DefineIntToken("{favorite}", (int)eRecMenuIT::favorite);
- tk->DefineStringToken("{line1}", (int)eRecMenuST::line1);
- tk->DefineStringToken("{line2}", (int)eRecMenuST::line2);
- tk->DefineStringToken("{line3}", (int)eRecMenuST::line3);
- tk->DefineStringToken("{line4}", (int)eRecMenuST::line4);
- tk->DefineStringToken("{stringvalue}", (int)eRecMenuST::value);
- tk->DefineStringToken("{buttontext}", (int)eRecMenuST::buttontext);
- tk->DefineStringToken("{textyes}", (int)eRecMenuST::textyes);
- tk->DefineStringToken("{textno}", (int)eRecMenuST::textno);
- tk->DefineStringToken("{text}", (int)eRecMenuST::text);
- tk->DefineStringToken("{channelname}", (int)eRecMenuST::channelname);
- tk->DefineStringToken("{channelid}", (int)eRecMenuST::channelid);
- tk->DefineStringToken("{transponder}", (int)eRecMenuST::transponder);
- tk->DefineStringToken("{day0abbr}", (int)eRecMenuST::day0abbr);
- tk->DefineStringToken("{day1abbr}", (int)eRecMenuST::day1abbr);
- tk->DefineStringToken("{day2abbr}", (int)eRecMenuST::day2abbr);
- tk->DefineStringToken("{day3abbr}", (int)eRecMenuST::day3abbr);
- tk->DefineStringToken("{day4abbr}", (int)eRecMenuST::day4abbr);
- tk->DefineStringToken("{day5abbr}", (int)eRecMenuST::day5abbr);
- tk->DefineStringToken("{day6abbr}", (int)eRecMenuST::day6abbr);
- tk->DefineStringToken("{folder}", (int)eRecMenuST::folder);
- tk->DefineStringToken("{conflictstart}", (int)eRecMenuST::conflictstart);
- tk->DefineStringToken("{conflictstop}", (int)eRecMenuST::conflictstop);
- tk->DefineStringToken("{overlapstart}", (int)eRecMenuST::overlapstart);
- tk->DefineStringToken("{overlapstop}", (int)eRecMenuST::overlapstop);
- tk->DefineStringToken("{timertitle}", (int)eRecMenuST::timertitle);
- tk->DefineStringToken("{starttime}", (int)eRecMenuST::starttime);
- tk->DefineStringToken("{stoptime}", (int)eRecMenuST::stoptime);
- tk->DefineStringToken("{date}", (int)eRecMenuST::date);
- tk->DefineStringToken("{weekday}", (int)eRecMenuST::weekday);
- tk->DefineStringToken("{title}", (int)eRecMenuST::title);
- tk->DefineStringToken("{shorttext}", (int)eRecMenuST::shorttext);
- tk->DefineStringToken("{recname}", (int)eRecMenuST::recname);
- tk->DefineStringToken("{recstarttime}", (int)eRecMenuST::recstarttime);
- tk->DefineStringToken("{recdate}", (int)eRecMenuST::recdate);
- tk->DefineStringToken("{searchstring}", (int)eRecMenuST::searchstring);
- tk->DefineStringToken("{timerstart}", (int)eRecMenuST::timerstart);
- tk->DefineStringToken("{timerstop}", (int)eRecMenuST::timerstop);
- tk->DefineStringToken("{eventtitle}", (int)eRecMenuST::eventtitle);
- tk->DefineStringToken("{eventshorttext}", (int)eRecMenuST::eventshorttext);
- tk->DefineStringToken("{eventstart}", (int)eRecMenuST::eventstart);
- tk->DefineStringToken("{eventstop}", (int)eRecMenuST::eventstop);
- tk->DefineStringToken("{favdesc}", (int)eRecMenuST::favdesc);
-}
-
-/********************************************************************
-* Protected Functions
-********************************************************************/
-void cRecMenu::AddMenuItem(cRecMenuItem *item, bool inFront) {
- if (!inFront)
- menuItems.Add(item);
- else
- menuItems.Ins(item);
-}
-
-void cRecMenu::AddHeader(cRecMenuItem *header) {
- this->header = header;
- maxMenuHeight -= header->GetHeight();
-}
-
-void cRecMenu::AddFooter(cRecMenuItem *footer) {
- this->footer = footer;
- maxMenuHeight -= footer->GetHeight();
-}
-
-int cRecMenu::GetNumActive(void) {
- int num = 0;
- for (cRecMenuItem *current = menuItems.First(); current; current = menuItems.Next(current)) {
- if (current == active) {
- return num;
- }
- num++;
- }
- return 0;
-}
-
-bool cRecMenu::ScrollUp(bool retry) {
- if (active == start) {
- bool scrolled = SeekBack(false);
- if (scrolled && scrolling) DrawScrollbar();
- }
- if (footer && active == footer) {
- recMenuGrid->SetCurrent(footer->Id(), false);
- footer->SetInactive();
- active = stop;
- active->SetActive();
- return true;
- }
- cRecMenuItem *prev = (cRecMenuItem*)active->Prev();
- while (prev && !prev->Selectable()) {
- prev = (cRecMenuItem*)prev->Prev();
- }
- if (prev) {
- recMenuGrid->SetCurrent(active->Id(), false);
- active->SetInactive();
- active = prev;
- active->SetActive();
- return true;
- } else {
- SeekBack(false);
- if (!retry)
- ScrollUp(true);
- }
- return false;
-}
-
-bool cRecMenu::ScrollDown(bool retry) {
- if (active == stop || retry) {
- bool scrolled = SeekForward(false);
- if (scrolled && scrolling) DrawScrollbar();
- }
- cRecMenuItem *next = (cRecMenuItem*)active->Next();
- while (next && !next->Selectable()) {
- if (next == stop) {
- return ScrollDown(true);
- }
- next = (cRecMenuItem*)next->Next();
- }
- if (next) {
- recMenuGrid->SetCurrent(active->Id(), false);
- active->SetInactive();
- active = next;
- active->SetActive();
- return true;
- } else {
- SeekForward(false);
- if (!retry)
- return ScrollDown(true);
- }
- if (footer && active != footer) {
- recMenuGrid->SetCurrent(active->Id(), false);
- active->SetInactive();
- active = footer;
- active->SetActive();
- return true;
- }
- return false;
-}
-
-bool cRecMenu::PageUp(void) {
- bool scrolled = SeekBack(true);
- if (scrolled && scrolling) DrawScrollbar();
- if (!scrolled) {
- recMenuGrid->SetCurrent(active->Id(), false);
- active->SetInactive();
- active = start;
- active->SetActive();
- return true;
- }
- if (!active) {
- active = stop;
- active->SetActive();
- }
- return scrolled;
-}
-
-bool cRecMenu::PageDown(void) {
- bool scrolled = SeekForward(true);
- if (scrolled && scrolling) DrawScrollbar();
- if (!scrolled) {
- recMenuGrid->SetCurrent(active->Id(), false);
- active->SetInactive();
- active = stop;
- active->SetActive();
- return true;
- }
- if (!active) {
- active = start;
- active->SetActive();
- }
- return scrolled;
-}
-
-void cRecMenu::ClearMenuItems(bool deleteItems) {
- if (deleteItems) {
- menuItems.Clear();
- active = NULL;
- } else {
- for (cRecMenuItem *current = menuItems.First(); current; current = menuItems.Next(current)) {
- current->SetNew();
- }
- }
- itemCount = 0;
- back->Clear();
- scrollBar->Clear();
- recMenuGrid->Clear();
- if (header)
- header->SetNew();
- if (footer)
- footer->SetNew();
- if (active)
- active->SetInactive();
- active = NULL;
-}
-
-void cRecMenu::InitMenuItems(void) {
- if (menuItems.Count() == 0)
- return;
- scrolling = false;
- menuHeight = 0;
- start = menuItems.First();
- cRecMenuItem *current = start;
- while (current) {
- int itemHeight = current->GetHeight();
- if (menuHeight + itemHeight > maxMenuHeight) {
- scrolling = true;
- break;
- }
- if (current->Active())
- active = current;
- itemCount++;
- stop = current;
- menuHeight += itemHeight;
- current = menuItems.Next(current);
- }
- DrawBackground();
- Flush();
- if (scrolling) {
- DrawScrollbar();
- Flush();
- }
-}
-
-void cRecMenu::InitMenuItemsLast(void) {
- if (menuItems.Count() == 0)
- return;
- scrolling = false;
- menuHeight = 0;
- stop = menuItems.Last();
- active = stop;
- active->SetActive();
- cRecMenuItem *current = stop;
- while (current) {
- int itemHeight = current->GetHeight();
- if (menuHeight + itemHeight > maxMenuHeight) {
- scrolling = true;
- break;
- }
- itemCount++;
- start = current;
- menuHeight += itemHeight;
- current = menuItems.Prev(current);
- }
- DrawBackground();
- Flush();
- if (scrolling) {
- DrawScrollbar();
- Flush();
- }
-}
-
-int cRecMenu::GetHeight(void) {
- int totalHeight = menuHeight;
- if (header)
- totalHeight += header->GetHeight();
- if (footer)
- totalHeight += footer->GetHeight();
- return totalHeight;
-}
-
-/********************************************************************
-* Private Functions
-********************************************************************/
-
-bool cRecMenu::SeekForward(bool page) {
- int jumpStep = 0;
- if (page)
- jumpStep = itemCount;
- else
- jumpStep = itemCount/2;
- int jump = 0;
- cRecMenuItem *next = (cRecMenuItem*)stop->Next();
- while (next && jump < jumpStep) {
- stop = next;
- menuHeight += next->GetHeight();
- next = (cRecMenuItem*)next->Next();
- jump++;
- }
- while (start && menuHeight > maxMenuHeight) {
- if (active == start) {
- active = NULL;
- start->SetInactive();
- }
- menuHeight -= start->GetHeight();
- recMenuGrid->Delete(start->Id());
- start->SetNew();
- start = (cRecMenuItem*)start->Next();
- }
- if (jump > 0)
- return true;
- return false;
-}
-
-bool cRecMenu::SeekBack(bool page) {
- int jumpStep = 0;
- if (page)
- jumpStep = itemCount;
- else
- jumpStep = itemCount/2;
- int jump = 0;
- cRecMenuItem *prev = (cRecMenuItem*)start->Prev();
- while (prev && jump < jumpStep) {
- start = prev;
- menuHeight += prev->GetHeight();
- prev = (cRecMenuItem*)prev->Prev();
- jump++;
- }
- while (stop && menuHeight > maxMenuHeight) {
- if (active == stop) {
- active = NULL;
- stop->SetInactive();
- }
- menuHeight -= stop->GetHeight();
- recMenuGrid->Delete(stop->Id());
- stop->SetNew();
- stop = (cRecMenuItem*)stop->Prev();
- }
- if (jump > 0)
- return true;
- return false;
-}
-
-void cRecMenu::SetFirst(void) {
- if (!scrolling) {
- recMenuGrid->SetCurrent(active->Id(), false);
- active->SetInactive();
- active = start;
- active->SetActive();
- return;
- }
- ClearMenuItems(false);
- menuItems.First()->SetActive();
- InitMenuItems();
-}
-
-void cRecMenu::SetLast(void) {
- if (!scrolling) {
- recMenuGrid->SetCurrent(active->Id(), false);
- active->SetInactive();
- if (footer) {
- active = footer;
- } else {
- active = stop;
- }
- active->SetActive();
- return;
- }
- ClearMenuItems(false);
- InitMenuItemsLast();
-}
-
-void cRecMenu::DrawBackground(void) {
- back->Clear();
- back->ClearTokens();
- back->AddIntToken((int)eBackgroundRecMenuIT::menuwidth, menuWidth + 2);
- back->AddIntToken((int)eBackgroundRecMenuIT::menuheight, GetHeight() + 2);
- back->AddIntToken((int)eBackgroundRecMenuIT::hasscrollbar, scrolling);
- back->Display();
-}
-
-void cRecMenu::DrawScrollbar(void) {
- if (menuItems.Count() == 0)
- return;
- int scrollBarHeight = (double)itemCount / (double)menuItems.Count() * 1000;
- int startPos = 0;
- for (cRecMenuItem *current = menuItems.First(); current; current = menuItems.Next(current)) {
- if (start == current)
- break;
- startPos++;
- }
- int offset = (double)startPos / (double)menuItems.Count() * 1000;
- scrollBar->Clear();
- scrollBar->ClearTokens();
- scrollBar->AddIntToken((int)eScrollbarRecMenuIT::menuwidth, menuWidth + 2);
- int y = (100 - GetHeight())/2;
- if (header)
- y += header->GetHeight();
-
- scrollBar->AddIntToken((int)eScrollbarRecMenuIT::posy, y);
- scrollBar->AddIntToken((int)eScrollbarRecMenuIT::totalheight, menuHeight);
- scrollBar->AddIntToken((int)eScrollbarRecMenuIT::height, scrollBarHeight);
- scrollBar->AddIntToken((int)eScrollbarRecMenuIT::offset, offset);
- scrollBar->Display();
-}
-
-void cRecMenu::DrawHeader(void) {
- if (!header)
- return;
- double width = (double)menuWidth / (double)100;
- double x = (double)(100 - menuWidth)/(double)200;
- int totalHeight = GetHeight();
- double y = (double)((100 - totalHeight) / 2) / (double)100;
-
- if (header->IsNew()) {
- recMenuGrid->ClearTokens();
- header->SetTokens(recMenuGrid);
- recMenuGrid->SetGrid(header->Id(), x, y, width, (double)header->GetHeight()/(double)100);
- }
-}
-
-void cRecMenu::DrawFooter(void) {
- if (!footer)
- return;
- double width = (double)menuWidth / (double)100;
- double x = (double)(100 - menuWidth)/(double)200;
- int totalHeight = GetHeight();
- int totalMenuHeight = menuHeight;
- if (header)
- totalMenuHeight += header->GetHeight();
- double y = (double)((100 - totalHeight) / 2 + totalMenuHeight) / (double)100;
-
- if (footer->IsNew()) {
- recMenuGrid->ClearTokens();
- footer->SetTokens(recMenuGrid);
- recMenuGrid->SetGrid(footer->Id(), x, y, width, (double)footer->GetHeight()/(double)100);
- } else {
- recMenuGrid->MoveGrid(footer->Id(), x, y, width, (double)footer->GetHeight()/(double)100);
- }
- if (footer->Active()) {
- active = footer;
- recMenuGrid->SetCurrent(footer->Id(), true);
- }
+#include "recmenu.h" +#include "tvguidengosd.h" + +// --- cRecMenu ------------------------------------------------------------- + +cRecMenu::cRecMenu() { + hidden = false; + menuWidth = 50; + menuHeight = 0; + maxMenuHeight = 98; + recMenuGrid = NULL; + osdView = NULL; + scrollBar = NULL; + back = NULL; + start = NULL; + stop = NULL; + itemCount = 0; + active = NULL; + header = NULL; + footer = NULL; + scrolling = false; +} + +cRecMenu::~cRecMenu(void) { + menuItems.Clear(); + if (scrollBar) { + scrollBar->Clear(); + delete scrollBar; + scrollBar = NULL; + } + if (back) { + back->Clear(); + delete back; + back = NULL; + } + if (recMenuGrid) { + recMenuGrid->Clear(); + delete recMenuGrid; + } + if (hidden) + osdView->Activate(); +} + +/******************************************************************** +* Public Functions +********************************************************************/ + +void cRecMenu::Init(skindesignerapi::cOsdView *osdView) { + this->osdView = osdView; + recMenuGrid = osdView->GetViewGrid((int)eViewGridsRecMenu::menu); + scrollBar = osdView->GetViewElement((int)eViewElementsRecMenu::scrollbar); + back = osdView->GetViewElement((int)eViewElementsRecMenu::background); + InitMenuItems(); +} + +void cRecMenu::Draw(void) { + DrawHeader(); + double width = (double)menuWidth / (double)100; + double x = (double)(100 - menuWidth)/(double)200; + int totalHeight = GetHeight(); + int yPerc = (100 - totalHeight) / 2; + if (header) + yPerc += header->GetHeight(); + double y = (double)yPerc/(double)100; + + for (cRecMenuItem *current = start; current; current = menuItems.Next(current)) { + + double itemHeight = (double)(current->GetHeight())/(double)100; + if (current->IsNew()) { + current->SetTokens(recMenuGrid); + recMenuGrid->SetGrid(current->Id(), x, y, width, itemHeight); + } else { + recMenuGrid->MoveGrid(current->Id(), x, y, width, itemHeight); + } + if (current->Active()) { + recMenuGrid->SetCurrent(current->Id(), true); + } + y += itemHeight; + if (current == stop) + break; + } + DrawFooter(); + recMenuGrid->Display(); +} + +eRecMenuState cRecMenu::ProcessKey(eKeys Key) { + eRecMenuState state = rmsContinue; + if (!active) + return state; + + state = active->ProcessKey(Key); + if (state == rmsRefresh) { + //Refresh current + active->SetTokens(recMenuGrid); + active->SetNew(); + Draw(); + } else if (state == rmsNotConsumed) { + switch (Key & ~k_Repeat) { + case kUp: + if (!ScrollUp(false)) + SetLast(); + Draw(); + state = rmsConsumed; + break; + case kDown: + if (!ScrollDown(false)) + SetFirst(); + Draw(); + state = rmsConsumed; + break; + case kLeft: + if (PageUp()) + Draw(); + state = rmsConsumed; + break; + case kRight: + if (PageDown()) + Draw(); + state = rmsConsumed; + break; + case kBack: + state = rmsClose; + break; + default: + break; + } + } + return state; +} + +void cRecMenu::DefineTokens(eViewElementsRecMenu ve, skindesignerapi::cTokenContainer *tk) { + switch (ve) { + case eViewElementsRecMenu::background: + tk->DefineIntToken("{menuwidth}", (int)eBackgroundRecMenuIT::menuwidth); + tk->DefineIntToken("{menuheight}", (int)eBackgroundRecMenuIT::menuheight); + tk->DefineIntToken("{hasscrollbar}", (int)eBackgroundRecMenuIT::hasscrollbar); + break; + case eViewElementsRecMenu::scrollbar: + tk->DefineIntToken("{menuwidth}", (int)eScrollbarRecMenuIT::menuwidth); + tk->DefineIntToken("{posy}", (int)eScrollbarRecMenuIT::posy); + tk->DefineIntToken("{totalheight}", (int)eScrollbarRecMenuIT::totalheight); + tk->DefineIntToken("{height}", (int)eScrollbarRecMenuIT::height); + tk->DefineIntToken("{offset}", (int)eScrollbarRecMenuIT::offset); + break; + default: + break; + } +} + +void cRecMenu::DefineTokens(eViewGridsRecMenu vg, skindesignerapi::cTokenContainer *tk) { + tk->DefineIntToken("{info}", (int)eRecMenuIT::info); + tk->DefineIntToken("{lines}", (int)eRecMenuIT::lines); + tk->DefineIntToken("{button}", (int)eRecMenuIT::button); + tk->DefineIntToken("{buttonyesno}", (int)eRecMenuIT::buttonyesno); + tk->DefineIntToken("{yes}", (int)eRecMenuIT::yes); + tk->DefineIntToken("{intselector}", (int)eRecMenuIT::intselector); + tk->DefineIntToken("{intvalue}", (int)eRecMenuIT::value); + tk->DefineIntToken("{boolselector}", (int)eRecMenuIT::boolselector); + tk->DefineIntToken("{stringselector}", (int)eRecMenuIT::stringselector); + tk->DefineIntToken("{textinput}", (int)eRecMenuIT::textinput); + tk->DefineIntToken("{editmode}", (int)eRecMenuIT::editmode); + tk->DefineIntToken("{timeselector}", (int)eRecMenuIT::timeselector); + tk->DefineIntToken("{dayselector}", (int)eRecMenuIT::dayselector); + tk->DefineIntToken("{channelselector}", (int)eRecMenuIT::channelselector); + tk->DefineIntToken("{channelnumber}", (int)eRecMenuIT::channelnumber); + tk->DefineIntToken("{channellogoexisis}", (int)eRecMenuIT::channellogoexisis); + tk->DefineIntToken("{weekdayselector}", (int)eRecMenuIT::weekdayselector); + tk->DefineIntToken("{dayselected}", (int)eRecMenuIT::dayselected); + tk->DefineIntToken("{day0set}", (int)eRecMenuIT::day0set); + tk->DefineIntToken("{day1set}", (int)eRecMenuIT::day1set); + tk->DefineIntToken("{day2set}", (int)eRecMenuIT::day2set); + tk->DefineIntToken("{day3set}", (int)eRecMenuIT::day3set); + tk->DefineIntToken("{day4set}", (int)eRecMenuIT::day4set); + tk->DefineIntToken("{day5set}", (int)eRecMenuIT::day5set); + tk->DefineIntToken("{day6set}", (int)eRecMenuIT::day6set); + tk->DefineIntToken("{directoryselector}", (int)eRecMenuIT::directoryselector); + tk->DefineIntToken("{timerconflictheader}", (int)eRecMenuIT::timerconflictheader); + tk->DefineIntToken("{overlapstartpercent}", (int)eRecMenuIT::overlapstartpercent); + tk->DefineIntToken("{overlapwidthpercent}", (int)eRecMenuIT::overlapwidthpercent); + tk->DefineIntToken("{timerconflict}", (int)eRecMenuIT::timerconflict); + tk->DefineIntToken("{infoactive}", (int)eRecMenuIT::infoactive); + tk->DefineIntToken("{deleteactive}", (int)eRecMenuIT::deleteactive); + tk->DefineIntToken("{editactive}", (int)eRecMenuIT::editactive); + tk->DefineIntToken("{searchactive}", (int)eRecMenuIT::searchactive); + tk->DefineIntToken("{timerstartpercent}", (int)eRecMenuIT::timerstartpercent); + tk->DefineIntToken("{timerwidthpercent}", (int)eRecMenuIT::timerwidthpercent); + tk->DefineIntToken("{event}", (int)eRecMenuIT::event); + tk->DefineIntToken("{hastimer}", (int)eRecMenuIT::hastimer); + tk->DefineIntToken("{recording}", (int)eRecMenuIT::recording); + tk->DefineIntToken("{recduration}", (int)eRecMenuIT::recduration); + tk->DefineIntToken("{searchtimer}", (int)eRecMenuIT::searchtimer); + tk->DefineIntToken("{timeractive}", (int)eRecMenuIT::timeractive); + tk->DefineIntToken("{activetimers}", (int)eRecMenuIT::activetimers); + tk->DefineIntToken("{recordingsdone}", (int)eRecMenuIT::recordingsdone); + tk->DefineIntToken("{timelineheader}", (int)eRecMenuIT::timelineheader); + tk->DefineIntToken("{timerset}", (int)eRecMenuIT::timerset); + tk->DefineIntToken("{channeltransponder}", (int)eRecMenuIT::channeltransponder); + tk->DefineIntToken("{timelinetimer}", (int)eRecMenuIT::timelinetimer); + tk->DefineIntToken("{timerstart}", (int)eRecMenuIT::timerstart); + tk->DefineIntToken("{timerwidth}", (int)eRecMenuIT::timerwidth); + tk->DefineIntToken("{favorite}", (int)eRecMenuIT::favorite); + tk->DefineStringToken("{line1}", (int)eRecMenuST::line1); + tk->DefineStringToken("{line2}", (int)eRecMenuST::line2); + tk->DefineStringToken("{line3}", (int)eRecMenuST::line3); + tk->DefineStringToken("{line4}", (int)eRecMenuST::line4); + tk->DefineStringToken("{stringvalue}", (int)eRecMenuST::value); + tk->DefineStringToken("{buttontext}", (int)eRecMenuST::buttontext); + tk->DefineStringToken("{textyes}", (int)eRecMenuST::textyes); + tk->DefineStringToken("{textno}", (int)eRecMenuST::textno); + tk->DefineStringToken("{text}", (int)eRecMenuST::text); + tk->DefineStringToken("{channelname}", (int)eRecMenuST::channelname); + tk->DefineStringToken("{channelid}", (int)eRecMenuST::channelid); + tk->DefineStringToken("{transponder}", (int)eRecMenuST::transponder); + tk->DefineStringToken("{day0abbr}", (int)eRecMenuST::day0abbr); + tk->DefineStringToken("{day1abbr}", (int)eRecMenuST::day1abbr); + tk->DefineStringToken("{day2abbr}", (int)eRecMenuST::day2abbr); + tk->DefineStringToken("{day3abbr}", (int)eRecMenuST::day3abbr); + tk->DefineStringToken("{day4abbr}", (int)eRecMenuST::day4abbr); + tk->DefineStringToken("{day5abbr}", (int)eRecMenuST::day5abbr); + tk->DefineStringToken("{day6abbr}", (int)eRecMenuST::day6abbr); + tk->DefineStringToken("{folder}", (int)eRecMenuST::folder); + tk->DefineStringToken("{conflictstart}", (int)eRecMenuST::conflictstart); + tk->DefineStringToken("{conflictstop}", (int)eRecMenuST::conflictstop); + tk->DefineStringToken("{overlapstart}", (int)eRecMenuST::overlapstart); + tk->DefineStringToken("{overlapstop}", (int)eRecMenuST::overlapstop); + tk->DefineStringToken("{timertitle}", (int)eRecMenuST::timertitle); + tk->DefineStringToken("{starttime}", (int)eRecMenuST::starttime); + tk->DefineStringToken("{stoptime}", (int)eRecMenuST::stoptime); + tk->DefineStringToken("{date}", (int)eRecMenuST::date); + tk->DefineStringToken("{weekday}", (int)eRecMenuST::weekday); + tk->DefineStringToken("{title}", (int)eRecMenuST::title); + tk->DefineStringToken("{shorttext}", (int)eRecMenuST::shorttext); + tk->DefineStringToken("{recname}", (int)eRecMenuST::recname); + tk->DefineStringToken("{recstarttime}", (int)eRecMenuST::recstarttime); + tk->DefineStringToken("{recdate}", (int)eRecMenuST::recdate); + tk->DefineStringToken("{searchstring}", (int)eRecMenuST::searchstring); + tk->DefineStringToken("{timerstart}", (int)eRecMenuST::timerstart); + tk->DefineStringToken("{timerstop}", (int)eRecMenuST::timerstop); + tk->DefineStringToken("{eventtitle}", (int)eRecMenuST::eventtitle); + tk->DefineStringToken("{eventshorttext}", (int)eRecMenuST::eventshorttext); + tk->DefineStringToken("{eventstart}", (int)eRecMenuST::eventstart); + tk->DefineStringToken("{eventstop}", (int)eRecMenuST::eventstop); + tk->DefineStringToken("{favdesc}", (int)eRecMenuST::favdesc); +} + +/******************************************************************** +* Protected Functions +********************************************************************/ +void cRecMenu::AddMenuItem(cRecMenuItem *item, bool inFront) { + if (!inFront) + menuItems.Add(item); + else + menuItems.Ins(item); +} + +void cRecMenu::AddHeader(cRecMenuItem *header) { + this->header = header; + maxMenuHeight -= header->GetHeight(); +} + +void cRecMenu::AddFooter(cRecMenuItem *footer) { + this->footer = footer; + maxMenuHeight -= footer->GetHeight(); +} + +int cRecMenu::GetNumActive(void) { + int num = 0; + for (cRecMenuItem *current = menuItems.First(); current; current = menuItems.Next(current)) { + if (current == active) { + return num; + } + num++; + } + return 0; +} + +bool cRecMenu::ScrollUp(bool retry) { + if (active == start) { + bool scrolled = SeekBack(false); + if (scrolled && scrolling) DrawScrollbar(); + } + if (footer && active == footer) { + recMenuGrid->SetCurrent(footer->Id(), false); + footer->SetInactive(); + active = stop; + active->SetActive(); + return true; + } + cRecMenuItem *prev = (cRecMenuItem*)active->Prev(); + while (prev && !prev->Selectable()) { + prev = (cRecMenuItem*)prev->Prev(); + } + if (prev) { + recMenuGrid->SetCurrent(active->Id(), false); + active->SetInactive(); + active = prev; + active->SetActive(); + return true; + } else { + SeekBack(false); + if (!retry) + ScrollUp(true); + } + return false; +} + +bool cRecMenu::ScrollDown(bool retry) { + if (active == stop || retry) { + bool scrolled = SeekForward(false); + if (scrolled && scrolling) DrawScrollbar(); + } + cRecMenuItem *next = (cRecMenuItem*)active->Next(); + while (next && !next->Selectable()) { + if (next == stop) { + return ScrollDown(true); + } + next = (cRecMenuItem*)next->Next(); + } + if (next) { + recMenuGrid->SetCurrent(active->Id(), false); + active->SetInactive(); + active = next; + active->SetActive(); + return true; + } else { + SeekForward(false); + if (!retry) + return ScrollDown(true); + } + if (footer && active != footer) { + recMenuGrid->SetCurrent(active->Id(), false); + active->SetInactive(); + active = footer; + active->SetActive(); + return true; + } + return false; +} + +bool cRecMenu::PageUp(void) { + bool scrolled = SeekBack(true); + if (scrolled && scrolling) DrawScrollbar(); + if (!scrolled) { + recMenuGrid->SetCurrent(active->Id(), false); + active->SetInactive(); + active = start; + active->SetActive(); + return true; + } + if (!active) { + active = stop; + active->SetActive(); + } + return scrolled; +} + +bool cRecMenu::PageDown(void) { + bool scrolled = SeekForward(true); + if (scrolled && scrolling) DrawScrollbar(); + if (!scrolled) { + recMenuGrid->SetCurrent(active->Id(), false); + active->SetInactive(); + active = stop; + active->SetActive(); + return true; + } + if (!active) { + active = start; + active->SetActive(); + } + return scrolled; +} + +void cRecMenu::ClearMenuItems(bool deleteItems) { + if (deleteItems) { + menuItems.Clear(); + active = NULL; + } else { + for (cRecMenuItem *current = menuItems.First(); current; current = menuItems.Next(current)) { + current->SetNew(); + } + } + itemCount = 0; + back->Clear(); + scrollBar->Clear(); + recMenuGrid->Clear(); + if (header) + header->SetNew(); + if (footer) + footer->SetNew(); + if (active) + active->SetInactive(); + active = NULL; +} + +void cRecMenu::InitMenuItems(void) { + if (menuItems.Count() == 0) + return; + scrolling = false; + menuHeight = 0; + start = menuItems.First(); + cRecMenuItem *current = start; + while (current) { + int itemHeight = current->GetHeight(); + if (menuHeight + itemHeight > maxMenuHeight) { + scrolling = true; + break; + } + if (current->Active()) + active = current; + itemCount++; + stop = current; + menuHeight += itemHeight; + current = menuItems.Next(current); + } + DrawBackground(); + Flush(); + if (scrolling) { + DrawScrollbar(); + Flush(); + } +} + +void cRecMenu::InitMenuItemsLast(void) { + if (menuItems.Count() == 0) + return; + scrolling = false; + menuHeight = 0; + stop = menuItems.Last(); + active = stop; + active->SetActive(); + cRecMenuItem *current = stop; + while (current) { + int itemHeight = current->GetHeight(); + if (menuHeight + itemHeight > maxMenuHeight) { + scrolling = true; + break; + } + itemCount++; + start = current; + menuHeight += itemHeight; + current = menuItems.Prev(current); + } + DrawBackground(); + Flush(); + if (scrolling) { + DrawScrollbar(); + Flush(); + } +} + +int cRecMenu::GetHeight(void) { + int totalHeight = menuHeight; + if (header) + totalHeight += header->GetHeight(); + if (footer) + totalHeight += footer->GetHeight(); + return totalHeight; +} + +/******************************************************************** +* Private Functions +********************************************************************/ + +bool cRecMenu::SeekForward(bool page) { + int jumpStep = 0; + if (page) + jumpStep = itemCount; + else + jumpStep = itemCount/2; + int jump = 0; + cRecMenuItem *next = (cRecMenuItem*)stop->Next(); + while (next && jump < jumpStep) { + stop = next; + menuHeight += next->GetHeight(); + next = (cRecMenuItem*)next->Next(); + jump++; + } + while (start && menuHeight > maxMenuHeight) { + if (active == start) { + active = NULL; + start->SetInactive(); + } + menuHeight -= start->GetHeight(); + recMenuGrid->Delete(start->Id()); + start->SetNew(); + start = (cRecMenuItem*)start->Next(); + } + if (jump > 0) + return true; + return false; +} + +bool cRecMenu::SeekBack(bool page) { + int jumpStep = 0; + if (page) + jumpStep = itemCount; + else + jumpStep = itemCount/2; + int jump = 0; + cRecMenuItem *prev = (cRecMenuItem*)start->Prev(); + while (prev && jump < jumpStep) { + start = prev; + menuHeight += prev->GetHeight(); + prev = (cRecMenuItem*)prev->Prev(); + jump++; + } + while (stop && menuHeight > maxMenuHeight) { + if (active == stop) { + active = NULL; + stop->SetInactive(); + } + menuHeight -= stop->GetHeight(); + recMenuGrid->Delete(stop->Id()); + stop->SetNew(); + stop = (cRecMenuItem*)stop->Prev(); + } + if (jump > 0) + return true; + return false; +} + +void cRecMenu::SetFirst(void) { + if (!scrolling) { + recMenuGrid->SetCurrent(active->Id(), false); + active->SetInactive(); + active = start; + active->SetActive(); + return; + } + ClearMenuItems(false); + menuItems.First()->SetActive(); + InitMenuItems(); +} + +void cRecMenu::SetLast(void) { + if (!scrolling) { + recMenuGrid->SetCurrent(active->Id(), false); + active->SetInactive(); + if (footer) { + active = footer; + } else { + active = stop; + } + active->SetActive(); + return; + } + ClearMenuItems(false); + InitMenuItemsLast(); +} + +void cRecMenu::DrawBackground(void) { + back->Clear(); + back->ClearTokens(); + back->AddIntToken((int)eBackgroundRecMenuIT::menuwidth, menuWidth + 2); + back->AddIntToken((int)eBackgroundRecMenuIT::menuheight, GetHeight() + 2); + back->AddIntToken((int)eBackgroundRecMenuIT::hasscrollbar, scrolling); + back->Display(); +} + +void cRecMenu::DrawScrollbar(void) { + if (menuItems.Count() == 0) + return; + int scrollBarHeight = (double)itemCount / (double)menuItems.Count() * 1000; + int startPos = 0; + for (cRecMenuItem *current = menuItems.First(); current; current = menuItems.Next(current)) { + if (start == current) + break; + startPos++; + } + int offset = (double)startPos / (double)menuItems.Count() * 1000; + scrollBar->Clear(); + scrollBar->ClearTokens(); + scrollBar->AddIntToken((int)eScrollbarRecMenuIT::menuwidth, menuWidth + 2); + int y = (100 - GetHeight())/2; + if (header) + y += header->GetHeight(); + + scrollBar->AddIntToken((int)eScrollbarRecMenuIT::posy, y); + scrollBar->AddIntToken((int)eScrollbarRecMenuIT::totalheight, menuHeight); + scrollBar->AddIntToken((int)eScrollbarRecMenuIT::height, scrollBarHeight); + scrollBar->AddIntToken((int)eScrollbarRecMenuIT::offset, offset); + scrollBar->Display(); +} + +void cRecMenu::DrawHeader(void) { + if (!header) + return; + double width = (double)menuWidth / (double)100; + double x = (double)(100 - menuWidth)/(double)200; + int totalHeight = GetHeight(); + double y = (double)((100 - totalHeight) / 2) / (double)100; + + if (header->IsNew()) { + recMenuGrid->ClearTokens(); + header->SetTokens(recMenuGrid); + recMenuGrid->SetGrid(header->Id(), x, y, width, (double)header->GetHeight()/(double)100); + } +} + +void cRecMenu::DrawFooter(void) { + if (!footer) + return; + double width = (double)menuWidth / (double)100; + double x = (double)(100 - menuWidth)/(double)200; + int totalHeight = GetHeight(); + int totalMenuHeight = menuHeight; + if (header) + totalMenuHeight += header->GetHeight(); + double y = (double)((100 - totalHeight) / 2 + totalMenuHeight) / (double)100; + + if (footer->IsNew()) { + recMenuGrid->ClearTokens(); + footer->SetTokens(recMenuGrid); + recMenuGrid->SetGrid(footer->Id(), x, y, width, (double)footer->GetHeight()/(double)100); + } else { + recMenuGrid->MoveGrid(footer->Id(), x, y, width, (double)footer->GetHeight()/(double)100); + } + if (footer->Active()) { + active = footer; + recMenuGrid->SetCurrent(footer->Id(), true); + } }
\ No newline at end of file @@ -1,66 +1,66 @@ -#ifndef __TVGUIDE_RECMENU_H
-#define __TVGUIDE_RECMENU_H
-
-#include <list>
-#include <libskindesignerapi/skindesignerosdbase.h>
-#include "definitions.h"
-#include "recmenuitem.h"
-
-// --- cRecMenu -------------------------------------------------------------
-
-class cRecMenu {
-private:
- bool hidden;
- int menuWidth;
- int menuHeight;
- int maxMenuHeight;
- skindesignerapi::cOsdView *osdView;
- skindesignerapi::cViewElement *back;
- skindesignerapi::cViewElement *scrollBar;
- skindesignerapi::cViewGrid *recMenuGrid;
- cList<cRecMenuItem> menuItems;
- cRecMenuItem *start;
- cRecMenuItem *stop;
- int itemCount;
- cRecMenuItem *active;
- cRecMenuItem *header;
- cRecMenuItem *footer;
- bool scrolling;
- bool SeekForward(bool page);
- bool SeekBack(bool page);
- void SetFirst(void);
- void SetLast(void);
- void DrawScrollbar(void);
- void DrawHeader(void);
- void DrawFooter(void);
-protected:
- void SetMenuWidth(int width) { menuWidth = width; };
- void AddMenuItem(cRecMenuItem *item, bool inFront = false);
- void AddHeader(cRecMenuItem *header);
- void AddFooter(cRecMenuItem *footer);
- int GetNumActive(void);
- cRecMenuItem *GetActive(void) { return active; };
- bool ScrollUp(bool retry);
- bool ScrollDown(bool retry);
- bool PageUp(void);
- bool PageDown(void);
- void ClearMenuItems(bool deleteItems);
- void InitMenuItems(void);
- void InitMenuItemsLast(void);
- int GetWidth(void) { return menuWidth; };
- int GetHeight(void);
-public:
- cRecMenu(void);
- virtual ~cRecMenu(void);
- void Init(skindesignerapi::cOsdView *osdView);
- void Activate(void) { osdView->Activate(); };
- void DrawBackground(void);
- void Draw(void);
- void Hide(void) { hidden = true; osdView->Deactivate(true); };
- void Show(void) { hidden = false; osdView->Activate(); };
- void Flush(void) { osdView->Display(); };
- virtual eRecMenuState ProcessKey(eKeys Key);
- static void DefineTokens(eViewElementsRecMenu ve, skindesignerapi::cTokenContainer *tk);
- static void DefineTokens(eViewGridsRecMenu vg, skindesignerapi::cTokenContainer *tk);
-};
+#ifndef __TVGUIDE_RECMENU_H +#define __TVGUIDE_RECMENU_H + +#include <list> +#include <libskindesignerapi/skindesignerosdbase.h> +#include "definitions.h" +#include "recmenuitem.h" + +// --- cRecMenu ------------------------------------------------------------- + +class cRecMenu { +private: + bool hidden; + int menuWidth; + int menuHeight; + int maxMenuHeight; + skindesignerapi::cOsdView *osdView; + skindesignerapi::cViewElement *back; + skindesignerapi::cViewElement *scrollBar; + skindesignerapi::cViewGrid *recMenuGrid; + cList<cRecMenuItem> menuItems; + cRecMenuItem *start; + cRecMenuItem *stop; + int itemCount; + cRecMenuItem *active; + cRecMenuItem *header; + cRecMenuItem *footer; + bool scrolling; + bool SeekForward(bool page); + bool SeekBack(bool page); + void SetFirst(void); + void SetLast(void); + void DrawScrollbar(void); + void DrawHeader(void); + void DrawFooter(void); +protected: + void SetMenuWidth(int width) { menuWidth = width; }; + void AddMenuItem(cRecMenuItem *item, bool inFront = false); + void AddHeader(cRecMenuItem *header); + void AddFooter(cRecMenuItem *footer); + int GetNumActive(void); + cRecMenuItem *GetActive(void) { return active; }; + bool ScrollUp(bool retry); + bool ScrollDown(bool retry); + bool PageUp(void); + bool PageDown(void); + void ClearMenuItems(bool deleteItems); + void InitMenuItems(void); + void InitMenuItemsLast(void); + int GetWidth(void) { return menuWidth; }; + int GetHeight(void); +public: + cRecMenu(void); + virtual ~cRecMenu(void); + void Init(skindesignerapi::cOsdView *osdView); + void Activate(void) { osdView->Activate(); }; + void DrawBackground(void); + void Draw(void); + void Hide(void) { hidden = true; osdView->Deactivate(true); }; + void Show(void) { hidden = false; osdView->Activate(); }; + void Flush(void) { osdView->Display(); }; + virtual eRecMenuState ProcessKey(eKeys Key); + static void DefineTokens(eViewElementsRecMenu ve, skindesignerapi::cTokenContainer *tk); + static void DefineTokens(eViewGridsRecMenu vg, skindesignerapi::cTokenContainer *tk); +}; #endif //__TVGUIDE_RECMENU_H
\ No newline at end of file diff --git a/recmenuitem.c b/recmenuitem.c index 81fa2ed..a0dde60 100644 --- a/recmenuitem.c +++ b/recmenuitem.c @@ -1,1566 +1,1593 @@ -#include "recmenuitem.h"
-#include "recmenus.h"
-#include "config.h"
-#include "helpers.h"
-#include <math.h>
-#include <wctype.h>
-#include <vdr/remote.h>
-
-long cRecMenuItem::idCounter;
-
-// --- cRecMenuItem -------------------------------------------------------------
-
-cRecMenuItem::cRecMenuItem(void) {
- id = idCounter;
- idCounter++;
- init = true;
- active = false;
- selectable = true;
- action = rmsNotConsumed;
- height = 0;
- text = "";
-}
-
-cRecMenuItem::~cRecMenuItem(void) {
-}
-
-bool cRecMenuItem::IsNew(void) {
- if (init) {
- init = false;
- return true;
- }
- return false;
-}
-
-// --- cRecMenuItemInfo -------------------------------------------------------
-
-cRecMenuItemInfo::cRecMenuItemInfo(string line1, int numLines, string line2, string line3, string line4) {
- selectable = false;
- this->numLines = numLines;
- this->line1 = line1;
- this->line2 = line2;
- this->line3 = line3;
- this->line4 = line4;
- if (numLines == 1)
- height = 12;
- else if (numLines == 2)
- height = 16;
- else if (numLines == 3)
- height = 20;
- else if (numLines == 4)
- height = 24;
- this->active = false;
-}
-
-cRecMenuItemInfo::~cRecMenuItemInfo(void) {
-}
-
-void cRecMenuItemInfo::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::info, 1);
- menu->AddIntToken((int)eRecMenuIT::lines, numLines);
- menu->AddStringToken((int)eRecMenuST::line1, line1.c_str());
- menu->AddStringToken((int)eRecMenuST::line2, line2.c_str());
- menu->AddStringToken((int)eRecMenuST::line3, line3.c_str());
- menu->AddStringToken((int)eRecMenuST::line4, line4.c_str());
-}
-
-// --- cRecMenuItemButton -------------------------------------------------------
-
-cRecMenuItemButton::cRecMenuItemButton(string text, eRecMenuState action, bool active) {
- selectable = true;
- height = 8;
- this->text = text;
- this->action = action;
- this->active = active;
-}
-
-cRecMenuItemButton::~cRecMenuItemButton(void) {
-}
-
-void cRecMenuItemButton::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::button, 1);
- menu->AddStringToken((int)eRecMenuST::buttontext, text.c_str());
-}
-
-eRecMenuState cRecMenuItemButton::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kOk:
- return action;
- break;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-// --- cRecMenuItemButtonYesNo -------------------------------------------------------
-cRecMenuItemButtonYesNo::cRecMenuItemButtonYesNo(string textYes,
- string textNo,
- eRecMenuState actionYes,
- eRecMenuState actionNo,
- bool active) {
- height = 8;
- selectable = true;
- this->textYes = textYes;
- this->textNo = textNo;
- this->action = actionYes;
- this->actionNo = actionNo;
- this->active = active;
- yesActive = true;
-}
-
-cRecMenuItemButtonYesNo::~cRecMenuItemButtonYesNo(void) {
-}
-
-void cRecMenuItemButtonYesNo::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::buttonyesno, 1);
- menu->AddIntToken((int)eRecMenuIT::yes, yesActive);
- menu->AddStringToken((int)eRecMenuST::textyes, textYes.c_str());
- menu->AddStringToken((int)eRecMenuST::textno, textNo.c_str());
-}
-
-eRecMenuState cRecMenuItemButtonYesNo::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kLeft:
- if (!yesActive) {
- yesActive = true;
- return rmsRefresh;
- } else
- return rmsNotConsumed;
- break;
- case kRight:
- if (yesActive) {
- yesActive = false;
- return rmsRefresh;
- } else
- return rmsNotConsumed;
- break;
- case kOk:
- if (yesActive)
- return action;
- return actionNo;
- break;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-
-// --- cRecMenuItemInt -------------------------------------------------------
-cRecMenuItemInt::cRecMenuItemInt(string text,
- int initialVal,
- int minVal,
- int maxVal,
- bool active,
- int *callback,
- eRecMenuState action) {
-
- height = 8;
- selectable = true;
- this->text = text;
- this->currentVal = initialVal;
- this->minVal = minVal;
- this->maxVal = maxVal;
- this->active = active;
- this->callback = callback;
- this->action = action;
- fresh = true;
-}
-
-cRecMenuItemInt::~cRecMenuItemInt(void) {
-}
-
-void cRecMenuItemInt::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::intselector, 1);
- menu->AddIntToken((int)eRecMenuIT::value, currentVal);
- menu->AddStringToken((int)eRecMenuST::text, text.c_str());
-}
-
-eRecMenuState cRecMenuItemInt::ProcessKey(eKeys Key) {
- int oldValue = currentVal;
- switch (Key & ~k_Repeat) {
- case kLeft:
- fresh = true;
- if (currentVal > minVal) {
- currentVal--;
- if (callback)
- *callback = currentVal;
- }
- return rmsRefresh;
- break;
- case kRight:
- fresh = true;
- if (currentVal < maxVal) {
- currentVal++;
- if (callback)
- *callback = currentVal;
- }
- return rmsRefresh;
- break;
- case k0 ... k9:
- if (fresh) {
- currentVal = 0;
- fresh = false;
- }
- currentVal = currentVal * 10 + (Key - k0);
- if (!((currentVal >= minVal) && (currentVal <= maxVal)))
- currentVal = oldValue;
- if (callback)
- *callback = currentVal;
- return rmsRefresh;
- break;
- case kOk:
- return action;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-// --- cRecMenuItemBool -------------------------------------------------------
-cRecMenuItemBool::cRecMenuItemBool(string text,
- bool initialVal,
- bool active,
- bool *callback,
- eRecMenuState action) {
- height = 8;
- selectable = true;
- this->text = text;
- this->yes = initialVal;
- this->active = active;
- this->callback = callback;
- this->action = action;
-}
-
-cRecMenuItemBool::~cRecMenuItemBool(void) {
-}
-
-void cRecMenuItemBool::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::boolselector, 1);
- menu->AddIntToken((int)eRecMenuIT::value, yes);
- menu->AddStringToken((int)eRecMenuST::text, text.c_str());
-}
-
-eRecMenuState cRecMenuItemBool::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kLeft:
- case kRight:
- yes = !yes;
- if (callback)
- *callback = yes;
- return rmsRefresh;
- break;
- case kOk:
- return action;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-// --- cRecMenuItemSelect -------------------------------------------------------
-cRecMenuItemSelect::cRecMenuItemSelect(string text,
- vector<string> strings,
- int initialVal,
- bool active,
- int *callback,
- eRecMenuState action) {
- height = 8;
- selectable = true;
- this->text = text;
- this->strings = strings;
- numValues = strings.size();
- if ((initialVal < 0) || (initialVal > numValues-1))
- this->currentVal = 0;
- else
- this->currentVal = initialVal;
- this->active = active;
- this->callback = callback;
- this->action = action;
-}
-
-cRecMenuItemSelect::~cRecMenuItemSelect(void) {
-}
-
-void cRecMenuItemSelect::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::stringselector, 1);
- menu->AddStringToken((int)eRecMenuST::text, text.c_str());
- menu->AddStringToken((int)eRecMenuST::value, strings[currentVal].c_str());
-}
-
-eRecMenuState cRecMenuItemSelect::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kLeft:
- currentVal--;
- if (currentVal<0)
- currentVal = numValues - 1;
- if (callback)
- *callback = currentVal;
- return rmsRefresh;
- break;
- case kRight:
- currentVal = (currentVal+1)%numValues;
- if (callback)
- *callback = currentVal;
- return rmsRefresh;
- break;
- case kOk:
- return action;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-// --- cRecMenuItemText -------------------------------------------------------
-cRecMenuItemText::cRecMenuItemText(string text,
- char *initialVal,
- int length,
- bool active,
- char *callback) {
-
- height = 16;
- selectable = true;
- this->text = text;
- value = initialVal;
- this->active = active;
- this->callback = callback;
- this->length = length;
- allowed = trVDR(FileNameChars);
- pos = -1;
- offset = 0;
- insert = uppercase = false;
- newchar = true;
- lengthUtf8 = 0;
- valueUtf8 = NULL;
- allowedUtf8 = NULL;
- charMapUtf8 = NULL;
- currentCharUtf8 = NULL;
- lastKey = kNone;
- buffer = "";
-}
-
-cRecMenuItemText::~cRecMenuItemText(void) {
- delete[] valueUtf8;
- delete[] allowedUtf8;
- delete[] charMapUtf8;
-}
-
-void cRecMenuItemText::EnterEditMode(void) {
- if (!valueUtf8) {
- valueUtf8 = new uint[length];
- lengthUtf8 = Utf8ToArray(value, valueUtf8, length);
- int l = strlen(allowed) + 1;
- allowedUtf8 = new uint[l];
- Utf8ToArray(allowed, allowedUtf8, l);
- const char *charMap = trVDR("CharMap$ 0\t-.,1#~\\^$[]|()*+?{}/:%@&\tabc2\tdef3\tghi4\tjkl5\tmno6\tpqrs7\ttuv8\twxyz9");
- l = strlen(charMap) + 1;
- charMapUtf8 = new uint[l];
- Utf8ToArray(charMap, charMapUtf8, l);
- currentCharUtf8 = charMapUtf8;
- AdvancePos();
- }
-}
-
-void cRecMenuItemText::LeaveEditMode(bool SaveValue) {
- if (valueUtf8) {
- if (SaveValue) {
- Utf8FromArray(valueUtf8, value, length);
- stripspace(value);
- if (callback) {
- strncpy(callback, value, TEXTINPUTLENGTH);
- }
- }
- lengthUtf8 = 0;
- delete[] valueUtf8;
- valueUtf8 = NULL;
- delete[] allowedUtf8;
- allowedUtf8 = NULL;
- delete[] charMapUtf8;
- charMapUtf8 = NULL;
- pos = -1;
- offset = 0;
- newchar = true;
- }
-}
-
-void cRecMenuItemText::AdvancePos(void) {
- if (pos < length - 2 && pos < lengthUtf8) {
- if (++pos >= lengthUtf8) {
- if (pos >= 2 && valueUtf8[pos - 1] == ' ' && valueUtf8[pos - 2] == ' ')
- pos--; // allow only two blanks at the end
- else {
- valueUtf8[pos] = ' ';
- valueUtf8[pos + 1] = 0;
- lengthUtf8++;
- }
- }
- }
- newchar = true;
- if (!insert && Utf8is(alpha, valueUtf8[pos]))
- uppercase = Utf8is(upper, valueUtf8[pos]);
-}
-
-uint cRecMenuItemText::Inc(uint c, bool Up) {
- uint *p = IsAllowed(c);
- if (!p)
- p = allowedUtf8;
- if (Up) {
- if (!*++p)
- p = allowedUtf8;
- } else if (--p < allowedUtf8) {
- p = allowedUtf8;
- while (*p && *(p + 1))
- p++;
- }
- return *p;
-}
-
-void cRecMenuItemText::Type(uint c) {
- if (insert && lengthUtf8 < length - 1)
- Insert();
- valueUtf8[pos] = c;
- if (pos < length - 2)
- pos++;
- if (pos >= lengthUtf8) {
- valueUtf8[pos] = ' ';
- valueUtf8[pos + 1] = 0;
- lengthUtf8 = pos + 1;
- }
-}
-
-void cRecMenuItemText::Insert(void) {
- memmove(valueUtf8 + pos + 1, valueUtf8 + pos, (lengthUtf8 - pos + 1) * sizeof(*valueUtf8));
- lengthUtf8++;
- valueUtf8[pos] = ' ';
-}
-
-void cRecMenuItemText::Delete(void) {
- memmove(valueUtf8 + pos, valueUtf8 + pos + 1, (lengthUtf8 - pos) * sizeof(*valueUtf8));
- lengthUtf8--;
-}
-
-uint *cRecMenuItemText::IsAllowed(uint c) {
- if (allowedUtf8) {
- for (uint *a = allowedUtf8; *a; a++) {
- if (c == *a)
- return a;
- }
- }
- return NULL;
-}
-
-void cRecMenuItemText::SetText(void) {
- if (InEditMode()) {
- int textAreaWidth = 800;
- if (pos < offset)
- offset = pos;
- int WidthFromOffset = 0;
- int EndPos = lengthUtf8;
- for (int i = offset; i < lengthUtf8; i++) {
- WidthFromOffset += 20;
- if (WidthFromOffset > textAreaWidth) {
- if (pos >= i) {
- do {
- WidthFromOffset -= 20;
- offset++;
- } while (WidthFromOffset > textAreaWidth && offset < pos);
- EndPos = pos + 1;
- } else {
- EndPos = i;
- break;
- }
- }
- }
- char buf[1000];
- char *p = buf;
- if (offset)
- *p++ = '<';
- p += Utf8FromArray(valueUtf8 + offset, p, sizeof(buf) - (p - buf), pos - offset);
- *p++ = '[';
- if (insert && newchar)
- *p++ = ']';
- p += Utf8FromArray(&valueUtf8[pos], p, sizeof(buf) - (p - buf), 1);
- if (!(insert && newchar))
- *p++ = ']';
- p += Utf8FromArray(&valueUtf8[pos + 1], p, sizeof(buf) - (p - buf), EndPos - pos - 1);
- if (EndPos != lengthUtf8)
- *p++ = '>';
- *p = 0;
- buffer = buf;
- } else {
- buffer = "";
- }
-}
-
-void cRecMenuItemText::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::textinput, 1);
- menu->AddIntToken((int)eRecMenuIT::editmode, InEditMode());
- menu->AddStringToken((int)eRecMenuST::text, text.c_str());
- if (buffer.size() > 0) {
- menu->AddStringToken((int)eRecMenuST::value, buffer.c_str());
- } else {
- menu->AddStringToken((int)eRecMenuST::value, value);
- }
-}
-
-eRecMenuState cRecMenuItemText::ProcessKey(eKeys Key) {
- bool consumed = false;
- bool SameKey = NORMALKEY(Key) == lastKey;
-
- if (Key != kNone) {
- lastKey = NORMALKEY(Key);
- } else if (!newchar && k0 <= lastKey && lastKey <= k9 && autoAdvanceTimeout.TimedOut()) {
- AdvancePos();
- newchar = true;
- currentCharUtf8 = NULL;
- SetText();
- return rmsRefresh;
- }
-
- switch ((int)Key) {
- case kRed: // Switch between upper- and lowercase characters
- if (InEditMode()) {
- if (!insert || !newchar) {
- uppercase = !uppercase;
- valueUtf8[pos] = uppercase ? Utf8to(upper, valueUtf8[pos]) : Utf8to(lower, valueUtf8[pos]);
- }
- consumed = true;
- }
- break;
- case kGreen: // Toggle insert/overwrite modes
- if (InEditMode()) {
- insert = !insert;
- newchar = true;
- consumed = true;
- }
- break;
- case kYellow|k_Repeat:
- case kYellow: // Remove the character at the current position; in insert mode it is the character to the right of the cursor
- if (InEditMode()) {
- if (lengthUtf8 > 1) {
- if (!insert || pos < lengthUtf8 - 1)
- Delete();
- else if (insert && pos == lengthUtf8 - 1)
- valueUtf8[pos] = ' '; // in insert mode, deleting the last character replaces it with a blank to keep the cursor position
- // reduce position, if we removed the last character
- if (pos == lengthUtf8)
- pos--;
- } else if (lengthUtf8 == 1)
- valueUtf8[0] = ' '; // This is the last character in the string, replace it with a blank
- if (Utf8is(alpha, valueUtf8[pos]))
- uppercase = Utf8is(upper, valueUtf8[pos]);
- newchar = true;
- consumed = true;
- }
- break;
- case kLeft|k_Repeat:
- case kLeft:
-
- if (pos > 0) {
- if (!insert || newchar)
- pos--;
- newchar = true;
- if (!insert && Utf8is(alpha, valueUtf8[pos]))
- uppercase = Utf8is(upper, valueUtf8[pos]);
- }
- consumed = true;
- break;
- case kRight|k_Repeat:
- case kRight:
- if (InEditMode()) {
- AdvancePos();
- } else {
- EnterEditMode();
- }
- consumed = true;
- break;
- case kUp|k_Repeat:
- case kUp:
- case kDown|k_Repeat:
- case kDown:
- if (InEditMode()) {
- if (insert && newchar) {
- // create a new character in insert mode
- if (lengthUtf8 < length - 1)
- Insert();
- }
- if (uppercase)
- valueUtf8[pos] = Utf8to(upper, Inc(Utf8to(lower, valueUtf8[pos]), NORMALKEY(Key) == kUp));
- else
- valueUtf8[pos] = Inc( valueUtf8[pos], NORMALKEY(Key) == kUp);
- newchar = false;
- consumed = true;
- }
- break;
- case k0|k_Repeat ... k9|k_Repeat:
- case k0 ... k9: {
- if (InEditMode()) {
- if (Setup.NumberKeysForChars) {
- if (!SameKey) {
- if (!newchar)
- AdvancePos();
- currentCharUtf8 = NULL;
- }
- if (!currentCharUtf8 || !*currentCharUtf8 || *currentCharUtf8 == '\t') {
- // find the beginning of the character map entry for Key
- int n = NORMALKEY(Key) - k0;
- currentCharUtf8 = charMapUtf8;
- while (n > 0 && *currentCharUtf8) {
- if (*currentCharUtf8++ == '\t')
- n--;
- }
- // find first allowed character
- while (*currentCharUtf8 && *currentCharUtf8 != '\t' && !IsAllowed(*currentCharUtf8))
- currentCharUtf8++;
- }
- if (*currentCharUtf8 && *currentCharUtf8 != '\t') {
- if (insert && newchar) {
- // create a new character in insert mode
- if (lengthUtf8 < length - 1)
- Insert();
- }
- valueUtf8[pos] = *currentCharUtf8;
- if (uppercase)
- valueUtf8[pos] = Utf8to(upper, valueUtf8[pos]);
- // find next allowed character
- do {
- currentCharUtf8++;
- } while (*currentCharUtf8 && *currentCharUtf8 != '\t' && !IsAllowed(*currentCharUtf8));
- newchar = false;
- autoAdvanceTimeout.Set(AUTO_ADVANCE_TIMEOUT);
- }
- } else {
- Type('0' + NORMALKEY(Key) - k0);
- }
- consumed = true;
- }
- break; }
- case kBack:
- case kOk:
- if (InEditMode()) {
- LeaveEditMode(Key == kOk);
- } else {
- EnterEditMode();
- }
- consumed = true;
- break;
- default:
- if (InEditMode() && BASICKEY(Key) == kKbd) {
- int c = KEYKBD(Key);
- if (c <= 0xFF) {
- if (IsAllowed(Utf8to(lower, c)))
- Type(c);
- else {
- switch (c) {
- case 0x7F: // backspace
- if (pos > 0) {
- pos--;
- ProcessKey(kYellow);
- }
- break;
- default: ;
- }
- }
- } else {
- switch (c) {
- case kfHome: pos = 0; break;
- case kfEnd: pos = lengthUtf8 - 1; break;
- case kfIns: ProcessKey(kGreen);
- case kfDel: ProcessKey(kYellow);
- default: ;
- }
- }
- consumed = true;
- }
- break;
- }
- SetText();
- if (consumed)
- return rmsRefresh;
- return rmsNotConsumed;
-}
-
-// --- cRecMenuItemTime -------------------------------------------------------
-cRecMenuItemTime::cRecMenuItemTime(string text,
- int initialVal,
- bool active,
- int *callback,
- eRecMenuState action) {
- height = 8;
- selectable = true;
- this->text = text;
- this->value = initialVal;
- hh = value / 100;
- mm = value % 100;
- pos = 0;
- fresh = true;
- this->active = active;
- this->callback = callback;
- this->action = action;
-}
-
-cRecMenuItemTime::~cRecMenuItemTime(void) {
-}
-
-void cRecMenuItemTime::SetTokens(skindesignerapi::cViewGrid *menu) {
- char buf[10];
- switch (pos) {
- case 1: snprintf(buf, sizeof(buf), "%01d-:--", hh / 10); break;
- case 2: snprintf(buf, sizeof(buf), "%02d:--", hh); break;
- case 3: snprintf(buf, sizeof(buf), "%02d:%01d-", hh, mm / 10); break;
- default: snprintf(buf, sizeof(buf), "%02d:%02d", hh, mm);
- }
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::timeselector, 1);
- menu->AddStringToken((int)eRecMenuST::text, text.c_str());
- menu->AddStringToken((int)eRecMenuST::value, buf);
-}
-
-eRecMenuState cRecMenuItemTime::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kLeft|k_Repeat:
- case kLeft: {
- if (--mm < 0) {
- mm = 59;
- if (--hh < 0)
- hh = 23;
- }
- fresh = true;
- value = hh * 100 + mm;
- if (callback)
- *callback = value;
- return rmsRefresh;
- break; }
- case kRight|k_Repeat:
- case kRight: {
- if (++mm > 59) {
- mm = 0;
- if (++hh > 23)
- hh = 0;
- }
- fresh = true;
- value = hh * 100 + mm;
- if (callback)
- *callback = value;
- return rmsRefresh;
- break; }
- case k0|k_Repeat ... k9|k_Repeat:
- case k0 ... k9: {
- if (fresh || pos > 3) {
- pos = 0;
- fresh = false;
- }
- int n = Key - k0;
- switch (pos) {
- case 0:
- if (n <= 2) {
- hh = n * 10;
- mm = 0;
- pos++;
- }
- break;
- case 1:
- if (hh + n <= 23) {
- hh += n;
- pos++;
- }
- break;
- case 2:
- if (n <= 5) {
- mm += n * 10;
- pos++;
- }
- break;
- case 3:
- if (mm + n <= 59) {
- mm += n;
- pos++;
- }
- break;
- default: ;
- }
- value = hh * 100 + mm;
- if (callback)
- *callback = value;
- return rmsRefresh;
- break; }
- case kOk:
- return action;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-// --- cRecMenuItemDay -------------------------------------------------------
-cRecMenuItemDay::cRecMenuItemDay(string text,
- time_t initialVal,
- bool active,
- time_t *callback,
- eRecMenuState action) {
-
- height = 8;
- selectable = true;
- this->text = text;
- this->currentVal = cTimer::SetTime(initialVal, 0);
- this->active = active;
- this->callback = callback;
- this->action = action;
-}
-
-cRecMenuItemDay::~cRecMenuItemDay(void) {
-}
-
-void cRecMenuItemDay::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::dayselector, 1);
- menu->AddStringToken((int)eRecMenuST::text, text.c_str());
- menu->AddStringToken((int)eRecMenuST::value, *DateString(currentVal));
-}
-
-eRecMenuState cRecMenuItemDay::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kLeft:
- currentVal -= 60*60*24;
- if (callback)
- *callback = currentVal;
- return rmsRefresh;
- break;
- case kRight:
- currentVal += 60*60*24;
- if (callback)
- *callback = currentVal;
- return rmsRefresh;
- break;
- case kOk:
- return action;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-// --- cRecMenuItemChannelChooser -------------------------------------------------------
-cRecMenuItemChannelChooser::cRecMenuItemChannelChooser(string text,
- cChannel *initialChannel,
- bool active,
- int *callback,
- eRecMenuState action) {
-
- height = 8;
- selectable = true;
- this->text = text;
- this->channel = initialChannel;
- if (initialChannel)
- initialChannelSet = true;
- else
- initialChannelSet = false;
- channelNumber = 0;
- fresh = true;
- this->active = active;
- this->callback = callback;
- this->action = action;
-}
-
-cRecMenuItemChannelChooser::~cRecMenuItemChannelChooser(void) {
-}
-
-void cRecMenuItemChannelChooser::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::channelselector, 1);
- menu->AddStringToken((int)eRecMenuST::text, text.c_str());
- if (channel) {
- menu->AddIntToken((int)eRecMenuIT::channelnumber, channel->Number());
- menu->AddStringToken((int)eRecMenuST::channelname, channel->Name());
- cString channelId = channel->GetChannelID().ToString();
- menu->AddStringToken((int)eRecMenuST::channelid, *channelId);
- menu->AddIntToken((int)eRecMenuIT::channellogoexisis, menu->ChannelLogoExists(*channelId));
- } else {
- menu->AddIntToken((int)eRecMenuIT::channelnumber, 0);
- menu->AddStringToken((int)eRecMenuST::channelname, tr("all Channels"));
- menu->AddStringToken((int)eRecMenuST::channelid, "");
- menu->AddIntToken((int)eRecMenuIT::channellogoexisis, false);
- }
-}
-
-eRecMenuState cRecMenuItemChannelChooser::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kLeft: {
- fresh = true;
- if (!channel)
- return rmsConsumed;
- cChannel *prev = channel;
- cChannel *firstChannel = Channels.First();
- if(firstChannel->GroupSep())
- firstChannel = Channels.Next(firstChannel);
- if (prev == firstChannel) {
- if (!initialChannelSet)
- channel = NULL;
- } else {
- while (prev = Channels.Prev(prev)) {
- if(!prev->GroupSep()) {
- channel = prev;
- break;
- }
- }
- }
- if (callback) {
- if (channel)
- *callback = channel->Number();
- else
- *callback = 0;
- }
- return rmsRefresh;
- break; }
- case kRight: {
- fresh = true;
- if (!channel) {
- channel = Channels.First();
- if(channel->GroupSep())
- channel = Channels.Next(channel);
- } else {
- cChannel *next = channel;
- while (next = Channels.Next(next)) {
- if(!next->GroupSep()) {
- channel = next;
- break;
- }
- }
- }
- if (callback) {
- if (channel)
- *callback = channel->Number();
- else
- *callback = 0;
- }
- return rmsRefresh;
- break; }
- case k0 ... k9: {
- if (fresh) {
- channelNumber = 0;
- fresh = false;
- }
- channelNumber = channelNumber * 10 + (Key - k0);
- cChannel *chanNew = Channels.GetByNumber(channelNumber);
- if (chanNew) {
- channel = chanNew;
- if (callback)
- *callback = channel->Number();
- }
- return rmsRefresh;
- break; }
- case kOk:
- return action;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-// --- cRecMenuItemDayChooser -------------------------------------------------------
-cRecMenuItemDayChooser::cRecMenuItemDayChooser(string text,
- int weekdays,
- bool active,
- int *callback) {
- height = 8;
- selectable = true;
- this->text = text;
- if (weekdays < 1)
- weekdays *= -1;
- this->weekdays = weekdays;
- this->active = active;
- this->callback = callback;
- selectedDay = 0;
-}
-
-cRecMenuItemDayChooser::~cRecMenuItemDayChooser(void) {
-}
-
-void cRecMenuItemDayChooser::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::weekdayselector, 1);
- menu->AddStringToken((int)eRecMenuST::text, text.c_str());
- menu->AddIntToken((int)eRecMenuIT::dayselected, selectedDay);
-
- string days = trVDR("MTWTFSS");
- for (unsigned day=0; day<days.length(); ++day) {
- cString strDay = cString::sprintf("%c", days.at(day));
- menu->AddStringToken((int)eRecMenuST::day0abbr + day, *strDay);
- menu->AddIntToken((int)eRecMenuIT::day0set + day, WeekDaySet(day));
- }
-}
-
-bool cRecMenuItemDayChooser::WeekDaySet(unsigned day) {
- return weekdays & (1 << day);
-}
-
-void cRecMenuItemDayChooser::ToggleDay(void) {
- bool dayActive = WeekDaySet(selectedDay);
- int dayBit = pow(2, selectedDay);
- if (dayActive) {
- weekdays -= dayBit;
- } else {
- weekdays += dayBit;
- }
- if (callback) {
- *callback = weekdays;
- }
-}
-
-eRecMenuState cRecMenuItemDayChooser::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kLeft: {
- selectedDay--;
- if (selectedDay<0)
- selectedDay += 7;
- return rmsRefresh;
- break; }
- case kRight: {
- selectedDay = (selectedDay+1)%7;
- return rmsRefresh;
- break; }
- case kOk:
- ToggleDay();
- return rmsRefresh;
- break;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-// --- cRecMenuItemSelectDirectory -------------------------------------------------------
-cRecMenuItemSelectDirectory::cRecMenuItemSelectDirectory(string text,
- string originalFolder,
- bool active,
- char *callback,
- eRecMenuState action,
- bool isSearchTimer) {
-
- height = 8;
- selectable = true;
- this->text = text;
- this->originalFolder = originalFolder;
- this->active = active;
- this->callback = callback;
- this->action = action;
- folders.push_back(tr("root video folder"));
- if (isSearchTimer && config.instRecFixedFolder.size() > 0)
- folders.push_back(config.instRecFixedFolder);
- ReadRecordingDirectories(&folders, NULL, "");
- numValues = folders.size();
- this->currentVal = GetInitial();
-}
-
-void cRecMenuItemSelectDirectory::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::directoryselector, 1);
- menu->AddStringToken((int)eRecMenuST::text, text.c_str());
- menu->AddStringToken((int)eRecMenuST::folder, folders[currentVal].c_str());
-}
-
-eRecMenuState cRecMenuItemSelectDirectory::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kLeft:
- currentVal--;
- if (currentVal<0)
- currentVal = numValues - 1;
- if (callback) {
- SetCallback();
- }
- return rmsRefresh;
- break;
- case kRight: {
- currentVal = (currentVal+1)%numValues;
- if (callback) {
- SetCallback();
- }
- return rmsRefresh;
- break; }
- case kOk:
- return action;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-void cRecMenuItemSelectDirectory::SetCallback(void) {
- string newFolder = folders[currentVal];
- if (!newFolder.compare(tr("root video folder")))
- newFolder = "";
- strncpy(callback, newFolder.c_str(), TEXTINPUTLENGTH);
-}
-
-int cRecMenuItemSelectDirectory::GetInitial(void) {
- if (originalFolder.size() == 0)
- return 0;
- for (int i=0; i < numValues; i++) {
- if (!folders[i].compare(originalFolder)) {
- return i;
- }
- }
- return 0;
-}
-
-// --- cRecMenuItemTimerConflictHeader -------------------------------------------------------
-cRecMenuItemTimerConflictHeader::cRecMenuItemTimerConflictHeader(time_t conflictStart,
- time_t conflictStop,
- time_t overlapStart,
- time_t overlapStop) {
- height = 10;
- selectable = false;
- active = false;
- this->conflictStart = conflictStart;
- this->conflictStop = conflictStop;
- this->overlapStart = overlapStart;
- this->overlapStop = overlapStop;
-}
-
-cRecMenuItemTimerConflictHeader::~cRecMenuItemTimerConflictHeader(void) {
-}
-
-void cRecMenuItemTimerConflictHeader::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::timerconflictheader, 1);
- menu->AddStringToken((int)eRecMenuST::text, tr("Timer Conflict"));
- menu->AddStringToken((int)eRecMenuST::conflictstart, *TimeString(conflictStart));
- menu->AddStringToken((int)eRecMenuST::conflictstop, *TimeString(conflictStop));
- menu->AddStringToken((int)eRecMenuST::overlapstart, *TimeString(overlapStart));
- menu->AddStringToken((int)eRecMenuST::overlapstop, *TimeString(overlapStop));
-
- int olStart = (double)(overlapStart - conflictStart) / (double)(conflictStop - conflictStart) * 100;
- int olWidth = (double)(overlapStop - overlapStart) / (double)(conflictStop - conflictStart) * 100;
- menu->AddIntToken((int)eRecMenuIT::overlapstartpercent, olStart);
- menu->AddIntToken((int)eRecMenuIT::overlapwidthpercent, olWidth);
-}
-
-// --- cRecMenuItemTimer -------------------------------------------------------
-cRecMenuItemTimer::cRecMenuItemTimer(const cTimer *timer,
- eRecMenuState action1,
- eRecMenuState action2,
- eRecMenuState action3,
- eRecMenuState action4,
- time_t conflictStart,
- time_t conflictStop,
- time_t overlapStart,
- time_t overlapStop,
- bool active) {
- height = 12;
- selectable = true;
- this->timer = timer;
- this->action = action1;
- this->action2 = action2;
- this->action3 = action3;
- this->action4 = action4;
- iconActive = 0;
- this->conflictStart = conflictStart;
- this->conflictStop = conflictStop;
- this->overlapStart = overlapStart;
- this->overlapStop = overlapStop;
- this->active = active;
-}
-
-cRecMenuItemTimer::~cRecMenuItemTimer(void) {
-}
-
-void cRecMenuItemTimer::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::timerconflict, 1);
-
- const cChannel *channel = timer->Channel();
- int channelTransponder = 0;
- const char *channelName = NULL;
- cString channelId = "";
- if (channel) {
- channelTransponder = channel->Transponder();
- channelName = channel->Name() ? channel->Name() : "";
- channelId = channel->GetChannelID().ToString();
- }
- menu->AddIntToken((int)eRecMenuIT::channeltransponder, channelTransponder);
- menu->AddStringToken((int)eRecMenuST::channelname, channelName);
- menu->AddStringToken((int)eRecMenuST::channelid, *channelId);
-
- const cEvent *event = timer->Event();
- string timerTitle = "";
- if (event && event->Title()) {
- timerTitle = event->Title();
- }
- menu->AddStringToken((int)eRecMenuST::timertitle, timerTitle.c_str());
- menu->AddStringToken((int)eRecMenuST::starttime, *TimeString(timer->StartTime()));
- menu->AddStringToken((int)eRecMenuST::stoptime, *TimeString(timer->StopTime()));
- menu->AddStringToken((int)eRecMenuST::date, *ShortDateString(timer->StartTime()));
- menu->AddStringToken((int)eRecMenuST::weekday, *WeekDayName(timer->StartTime()));
-
- menu->AddIntToken((int)eRecMenuIT::infoactive, (iconActive==0)?true:false);
- menu->AddIntToken((int)eRecMenuIT::deleteactive, (iconActive==1)?true:false);
- menu->AddIntToken((int)eRecMenuIT::editactive, (iconActive==2)?true:false);
- menu->AddIntToken((int)eRecMenuIT::searchactive, (iconActive==3)?true:false);
-
-
- int conflictTime = conflictStop - conflictStart;
- int timerStart = (double)(timer->StartTime() - conflictStart) / (double)conflictTime * 100;
- int timerWidth = (double)(timer->StopTime() - timer->StartTime()) / (double)conflictTime * 100;
- int olStart = (double)(overlapStart - conflictStart) / (double)(conflictStop - conflictStart) * 100;
- int olWidth = (double)(overlapStop - overlapStart) / (double)(conflictStop - conflictStart) * 100;
- menu->AddIntToken((int)eRecMenuIT::timerstartpercent, timerStart);
- menu->AddIntToken((int)eRecMenuIT::timerwidthpercent, timerWidth);
- menu->AddIntToken((int)eRecMenuIT::overlapstartpercent, olStart);
- menu->AddIntToken((int)eRecMenuIT::overlapwidthpercent, olWidth);
-}
-
-eRecMenuState cRecMenuItemTimer::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kLeft:
- if (iconActive > 0) {
- iconActive--;
- return rmsRefresh;
- } else
- return rmsNotConsumed;
- break;
- case kRight:
- if (iconActive < 3) {
- iconActive++;
- return rmsRefresh;
- } else
- return rmsNotConsumed;
- break;
- case kOk:
- if (iconActive == 0)
- return action;
- else if (iconActive == 1)
- return action2;
- else if (iconActive == 2)
- return action3;
- else if (iconActive == 3)
- return action4;
- break;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-// --- cRecMenuItemEvent -------------------------------------------------------
-cRecMenuItemEvent::cRecMenuItemEvent(const cEvent *event,
- eRecMenuState action1,
- eRecMenuState action2,
- bool active) {
- height = 8;
- selectable = true;
- this->event = event;
- this->action = action1;
- this->action2 = action2;
- iconActive = 0;
- this->active = active;
-}
-
-cRecMenuItemEvent::~cRecMenuItemEvent(void) {
-}
-
-void cRecMenuItemEvent::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::event, 1);
-
- const cChannel *channel = Channels.GetByChannelID(event->ChannelID());
- const char *channelName = NULL;
- cString channelId = "";
- if (channel) {
- channelName = channel->Name();
- channelId = channel->GetChannelID().ToString();
- menu->AddIntToken((int)eRecMenuIT::channelnumber, channel->Number());
- }
-
- menu->AddStringToken((int)eRecMenuST::channelname, channelName);
- menu->AddStringToken((int)eRecMenuST::channelid, *channelId);
- menu->AddIntToken((int)eRecMenuIT::channellogoexisis, menu->ChannelLogoExists(*channelId));
- menu->AddStringToken((int)eRecMenuST::title, event->Title());
- menu->AddStringToken((int)eRecMenuST::shorttext, event->ShortText());
- menu->AddStringToken((int)eRecMenuST::date, *ShortDateString(event->StartTime()));
- menu->AddStringToken((int)eRecMenuST::weekday, *WeekDayName(event->StartTime()));
- menu->AddStringToken((int)eRecMenuST::starttime, *TimeString(event->StartTime()));
- menu->AddStringToken((int)eRecMenuST::stoptime, *TimeString(event->EndTime()));
- menu->AddIntToken((int)eRecMenuIT::hastimer, event->HasTimer());
-}
-
-eRecMenuState cRecMenuItemEvent::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kOk:
- return action;
- break;
- case kRed:
- if (!event->HasTimer())
- return action2;
- break;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-// --- cRecMenuItemRecording -------------------------------------------------------
-cRecMenuItemRecording::cRecMenuItemRecording(cRecording *recording, bool active) {
- height = 8;
- selectable = true;
- this->recording = recording;
- this->active = active;
-}
-
-void cRecMenuItemRecording::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::recording, 1);
- if (!recording)
- return;
- const cRecordingInfo *recInfo = recording->Info();
- cChannel *channel = NULL;
- if (recInfo)
- channel = Channels.GetByChannelID(recInfo->ChannelID());
- string channelName = tr("unknown channel");
- string channelId = "";
- if (channel && channel->Name()) {
- channelName = channel->Name();
- channelId = *(channel->GetChannelID().ToString());
- menu->AddIntToken((int)eRecMenuIT::channelnumber, channel->Number());
- }
- menu->AddStringToken((int)eRecMenuST::channelname, channelName.c_str());
- menu->AddStringToken((int)eRecMenuST::channelid, channelId.c_str());
- menu->AddIntToken((int)eRecMenuIT::channellogoexisis, menu->ChannelLogoExists(channelId));
-
- string recName = recording->Name() ? recording->Name() : "";
- string recDate = *ShortDateString(recording->Start());
- string recStartTime = *TimeString(recording->Start());
- int recDuration = recording->LengthInSeconds() / 60;
-
- menu->AddStringToken((int)eRecMenuST::recname, recName.c_str());
- menu->AddStringToken((int)eRecMenuST::recdate, recDate.c_str());
- menu->AddStringToken((int)eRecMenuST::recstarttime, recStartTime.c_str());
- menu->AddIntToken((int)eRecMenuIT::recduration, recDuration);
-}
-
-// --- cRecMenuItemSearchTimer -------------------------------------------------------
-cRecMenuItemSearchTimer::cRecMenuItemSearchTimer(cTVGuideSearchTimer timer,
- eRecMenuState action1,
- eRecMenuState action2,
- eRecMenuState action3,
- bool active) {
- height = 8;
- this->timer = timer;
- this->action = action1;
- this->action2 = action2;
- this->action3 = action3;
- selectable = true;
- this->active = active;
- iconActive = 0;
-}
-
-cRecMenuItemSearchTimer::~cRecMenuItemSearchTimer(void) {
-}
-
-void cRecMenuItemSearchTimer::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::searchtimer, 1);
- menu->AddIntToken((int)eRecMenuIT::timeractive, timer.Active());
- menu->AddStringToken((int)eRecMenuST::searchstring, timer.SearchString().c_str());
- menu->AddIntToken((int)eRecMenuIT::activetimers, timer.GetNumTimers());
- menu->AddIntToken((int)eRecMenuIT::recordingsdone, timer.GetNumRecordings());
- menu->AddIntToken((int)eRecMenuIT::searchactive, (iconActive==0)?true:false);
- menu->AddIntToken((int)eRecMenuIT::editactive, (iconActive==1)?true:false);
- menu->AddIntToken((int)eRecMenuIT::deleteactive, (iconActive==2)?true:false);
-}
-
-eRecMenuState cRecMenuItemSearchTimer::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kLeft:
- if (iconActive > 0) {
- iconActive--;
- return rmsRefresh;
- }
- return rmsNotConsumed;
- break;
- case kRight: {
- if (iconActive < 2) {
- iconActive++;
- return rmsRefresh;
- }
- return rmsNotConsumed;
- break; }
- case kOk:
- if (iconActive == 0)
- return action;
- else if (iconActive == 1)
- return action2;
- else if (iconActive == 2)
- return action3;
- break;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-// --- cRecMenuItemTimelineHeader -------------------------------------------------------
-cRecMenuItemTimelineHeader::cRecMenuItemTimelineHeader(time_t day) {
- height = 15;
- timer = NULL;
- this->day = day;
- selectable = false;
- active = false;
-}
-
-cRecMenuItemTimelineHeader::~cRecMenuItemTimelineHeader(void) {
-}
-
-void cRecMenuItemTimelineHeader::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::timelineheader, 1);
- string daydate = *DateString(day);
- menu->AddStringToken((int)eRecMenuST::date, daydate.c_str());
- if (!timer) {
- menu->AddIntToken((int)eRecMenuIT::timerset, false);
- return;
- }
- menu->AddIntToken((int)eRecMenuIT::timerset, true);
-
- const cChannel *channel = timer->Channel();
- const char *channelName = NULL;
- cString channelId = "";
- int channelNumber = 0;
- int transponder = 0;
- if (channel) {
- channelName = channel->Name();
- channelId = channel->GetChannelID().ToString();
- channelNumber = channel->Number();
- transponder = channel->Transponder();
- }
- menu->AddStringToken((int)eRecMenuST::channelname, channelName);
- menu->AddStringToken((int)eRecMenuST::channelid, *channelId);
- menu->AddIntToken((int)eRecMenuIT::channelnumber, channelNumber);
- menu->AddIntToken((int)eRecMenuIT::channeltransponder, transponder);
- menu->AddIntToken((int)eRecMenuIT::channellogoexisis, menu->ChannelLogoExists(*channelId));
-
- menu->AddStringToken((int)eRecMenuST::timerstart, *TimeString(timer->StartTime()));
- menu->AddStringToken((int)eRecMenuST::timerstop, *TimeString(timer->StopTime()));
-
- const cEvent *event = timer->Event();
- const char *eventTitle = NULL;
- const char *eventShortText = "";
- cString eventStart = "";
- cString eventStop = "";
- if (event) {
- eventTitle = event->Title();
- eventShortText = event->ShortText();
- eventStart = event->GetTimeString();
- eventStop = event->GetEndTimeString();
- }
- menu->AddStringToken((int)eRecMenuST::eventtitle, eventTitle);
- menu->AddStringToken((int)eRecMenuST::eventshorttext, eventShortText);
- menu->AddStringToken((int)eRecMenuST::eventstart, *eventStart);
- menu->AddStringToken((int)eRecMenuST::eventstop, *eventStop);
-}
-
-// --- cRecMenuItemTimelineTimer -------------------------------------------------------
-cRecMenuItemTimelineTimer::cRecMenuItemTimelineTimer(cTimer *timer, time_t start, time_t stop, bool active) {
- height = 8;
- this->timer = timer;
- this->start = start;
- this->stop = stop;
- selectable = true;
- this->active = active;
-}
-
-cRecMenuItemTimelineTimer::~cRecMenuItemTimelineTimer(void) {
-}
-
-void cRecMenuItemTimelineTimer::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::timelinetimer, 1);
-
- int secsPerDay = 24*60*60;
- time_t timerStart = timer->StartTime() - start;
- time_t timerStop = timer->StopTime() - start;
- if (timerStart < 0)
- timerStart = 0;
- if (timerStop > secsPerDay)
- timerStop = secsPerDay;
-
- int percentStart = ((double)timerStart / (double)secsPerDay) * 1000;
- int percentWidth = ((double)(timerStop - timerStart) / (double)secsPerDay) * 1000;
- menu->AddIntToken((int)eRecMenuIT::timerstart, percentStart);
- menu->AddIntToken((int)eRecMenuIT::timerwidth, percentWidth);
-}
-
-cTimer *cRecMenuItemTimelineTimer::GetTimer(void) {
- return timer;
-}
-
-eRecMenuState cRecMenuItemTimelineTimer::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kOk:
- return rmsTimelineTimerEdit;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-// --- cRecMenuItemFavorite -------------------------------------------------------
-cRecMenuItemFavorite::cRecMenuItemFavorite(cTVGuideSearchTimer favorite,
- eRecMenuState action1,
- bool active) {
- height = 8;
- this->favorite = favorite;
- this->action = action1;
- selectable = true;
- this->active = active;
-}
-
-void cRecMenuItemFavorite::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::favorite, 1);
- menu->AddStringToken((int)eRecMenuST::favdesc, favorite.SearchString().c_str());
-}
-
-eRecMenuState cRecMenuItemFavorite::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kOk:
- return action;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
-// --- cRecMenuItemFavoriteStatic -------------------------------------------------------
-cRecMenuItemFavoriteStatic::cRecMenuItemFavoriteStatic(string text, eRecMenuState action, bool active) {
- height = 8;
- this->text = text;
- this->action = action;
- selectable = true;
- this->active = active;
-}
-
-void cRecMenuItemFavoriteStatic::SetTokens(skindesignerapi::cViewGrid *menu) {
- menu->ClearTokens();
- menu->AddIntToken((int)eRecMenuIT::favorite, 1);
- menu->AddStringToken((int)eRecMenuST::favdesc, text.c_str());
-}
-
-eRecMenuState cRecMenuItemFavoriteStatic::ProcessKey(eKeys Key) {
- switch (Key & ~k_Repeat) {
- case kOk:
- return action;
- default:
- break;
- }
- return rmsNotConsumed;
-}
-
+#include "recmenuitem.h" +#include "recmenus.h" +#include "config.h" +#include "helpers.h" +#include <math.h> +#include <wctype.h> +#include <vdr/remote.h> + +long cRecMenuItem::idCounter; + +// --- cRecMenuItem ------------------------------------------------------------- + +cRecMenuItem::cRecMenuItem(void) { + id = idCounter; + idCounter++; + init = true; + active = false; + selectable = true; + action = rmsNotConsumed; + height = 0; + text = ""; +} + +cRecMenuItem::~cRecMenuItem(void) { +} + +bool cRecMenuItem::IsNew(void) { + if (init) { + init = false; + return true; + } + return false; +} + +// --- cRecMenuItemInfo ------------------------------------------------------- + +cRecMenuItemInfo::cRecMenuItemInfo(string line1, int numLines, string line2, string line3, string line4) { + selectable = false; + this->numLines = numLines; + this->line1 = line1; + this->line2 = line2; + this->line3 = line3; + this->line4 = line4; + if (numLines == 1) + height = 12; + else if (numLines == 2) + height = 16; + else if (numLines == 3) + height = 20; + else if (numLines == 4) + height = 24; + this->active = false; +} + +cRecMenuItemInfo::~cRecMenuItemInfo(void) { +} + +void cRecMenuItemInfo::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::info, 1); + menu->AddIntToken((int)eRecMenuIT::lines, numLines); + menu->AddStringToken((int)eRecMenuST::line1, line1.c_str()); + menu->AddStringToken((int)eRecMenuST::line2, line2.c_str()); + menu->AddStringToken((int)eRecMenuST::line3, line3.c_str()); + menu->AddStringToken((int)eRecMenuST::line4, line4.c_str()); +} + +// --- cRecMenuItemButton ------------------------------------------------------- + +cRecMenuItemButton::cRecMenuItemButton(string text, eRecMenuState action, bool active) { + selectable = true; + height = 8; + this->text = text; + this->action = action; + this->active = active; +} + +cRecMenuItemButton::~cRecMenuItemButton(void) { +} + +void cRecMenuItemButton::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::button, 1); + menu->AddStringToken((int)eRecMenuST::buttontext, text.c_str()); +} + +eRecMenuState cRecMenuItemButton::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kOk: + return action; + break; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemButtonYesNo ------------------------------------------------------- +cRecMenuItemButtonYesNo::cRecMenuItemButtonYesNo(string textYes, + string textNo, + eRecMenuState actionYes, + eRecMenuState actionNo, + bool active) { + height = 8; + selectable = true; + this->textYes = textYes; + this->textNo = textNo; + this->action = actionYes; + this->actionNo = actionNo; + this->active = active; + yesActive = true; +} + +cRecMenuItemButtonYesNo::~cRecMenuItemButtonYesNo(void) { +} + +void cRecMenuItemButtonYesNo::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::buttonyesno, 1); + menu->AddIntToken((int)eRecMenuIT::yes, yesActive); + menu->AddStringToken((int)eRecMenuST::textyes, textYes.c_str()); + menu->AddStringToken((int)eRecMenuST::textno, textNo.c_str()); +} + +eRecMenuState cRecMenuItemButtonYesNo::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: + if (!yesActive) { + yesActive = true; + return rmsRefresh; + } else + return rmsNotConsumed; + break; + case kRight: + if (yesActive) { + yesActive = false; + return rmsRefresh; + } else + return rmsNotConsumed; + break; + case kOk: + if (yesActive) + return action; + return actionNo; + break; + default: + break; + } + return rmsNotConsumed; +} + + +// --- cRecMenuItemInt ------------------------------------------------------- +cRecMenuItemInt::cRecMenuItemInt(string text, + int initialVal, + int minVal, + int maxVal, + bool active, + int *callback, + eRecMenuState action) { + + height = 8; + selectable = true; + this->text = text; + this->currentVal = initialVal; + this->minVal = minVal; + this->maxVal = maxVal; + this->active = active; + this->callback = callback; + this->action = action; + fresh = true; +} + +cRecMenuItemInt::~cRecMenuItemInt(void) { +} + +void cRecMenuItemInt::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::intselector, 1); + menu->AddIntToken((int)eRecMenuIT::value, currentVal); + menu->AddStringToken((int)eRecMenuST::text, text.c_str()); +} + +eRecMenuState cRecMenuItemInt::ProcessKey(eKeys Key) { + int oldValue = currentVal; + switch (Key & ~k_Repeat) { + case kLeft: + fresh = true; + if (currentVal > minVal) { + currentVal--; + if (callback) + *callback = currentVal; + } + return rmsRefresh; + break; + case kRight: + fresh = true; + if (currentVal < maxVal) { + currentVal++; + if (callback) + *callback = currentVal; + } + return rmsRefresh; + break; + case k0 ... k9: + if (fresh) { + currentVal = 0; + fresh = false; + } + currentVal = currentVal * 10 + (Key - k0); + if (!((currentVal >= minVal) && (currentVal <= maxVal))) + currentVal = oldValue; + if (callback) + *callback = currentVal; + return rmsRefresh; + break; + case kOk: + return action; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemBool ------------------------------------------------------- +cRecMenuItemBool::cRecMenuItemBool(string text, + bool initialVal, + bool active, + bool *callback, + eRecMenuState action) { + height = 8; + selectable = true; + this->text = text; + this->yes = initialVal; + this->active = active; + this->callback = callback; + this->action = action; +} + +cRecMenuItemBool::~cRecMenuItemBool(void) { +} + +void cRecMenuItemBool::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::boolselector, 1); + menu->AddIntToken((int)eRecMenuIT::value, yes); + menu->AddStringToken((int)eRecMenuST::text, text.c_str()); +} + +eRecMenuState cRecMenuItemBool::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: + case kRight: + yes = !yes; + if (callback) + *callback = yes; + return rmsRefresh; + break; + case kOk: + return action; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemSelect ------------------------------------------------------- +cRecMenuItemSelect::cRecMenuItemSelect(string text, + vector<string> strings, + int initialVal, + bool active, + int *callback, + eRecMenuState action) { + height = 8; + selectable = true; + this->text = text; + this->strings = strings; + numValues = strings.size(); + if ((initialVal < 0) || (initialVal > numValues-1)) + this->currentVal = 0; + else + this->currentVal = initialVal; + this->active = active; + this->callback = callback; + this->action = action; +} + +cRecMenuItemSelect::~cRecMenuItemSelect(void) { +} + +void cRecMenuItemSelect::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::stringselector, 1); + menu->AddStringToken((int)eRecMenuST::text, text.c_str()); + menu->AddStringToken((int)eRecMenuST::value, strings[currentVal].c_str()); +} + +eRecMenuState cRecMenuItemSelect::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: + currentVal--; + if (currentVal<0) + currentVal = numValues - 1; + if (callback) + *callback = currentVal; + return rmsRefresh; + break; + case kRight: + currentVal = (currentVal+1)%numValues; + if (callback) + *callback = currentVal; + return rmsRefresh; + break; + case kOk: + return action; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemText ------------------------------------------------------- +cRecMenuItemText::cRecMenuItemText(string text, + char *initialVal, + int length, + bool active, + char *callback) { + + height = 16; + selectable = true; + this->text = text; + value = initialVal; + this->active = active; + this->callback = callback; + this->length = length; + allowed = trVDR(FileNameChars); + pos = -1; + offset = 0; + insert = uppercase = false; + newchar = true; + lengthUtf8 = 0; + valueUtf8 = NULL; + allowedUtf8 = NULL; + charMapUtf8 = NULL; + currentCharUtf8 = NULL; + lastKey = kNone; + buffer = ""; +} + +cRecMenuItemText::~cRecMenuItemText(void) { + delete[] valueUtf8; + delete[] allowedUtf8; + delete[] charMapUtf8; +} + +void cRecMenuItemText::EnterEditMode(void) { + if (!valueUtf8) { + valueUtf8 = new uint[length]; + lengthUtf8 = Utf8ToArray(value, valueUtf8, length); + int l = strlen(allowed) + 1; + allowedUtf8 = new uint[l]; + Utf8ToArray(allowed, allowedUtf8, l); + const char *charMap = trVDR("CharMap$ 0\t-.,1#~\\^$[]|()*+?{}/:%@&\tabc2\tdef3\tghi4\tjkl5\tmno6\tpqrs7\ttuv8\twxyz9"); + l = strlen(charMap) + 1; + charMapUtf8 = new uint[l]; + Utf8ToArray(charMap, charMapUtf8, l); + currentCharUtf8 = charMapUtf8; + AdvancePos(); + } +} + +void cRecMenuItemText::LeaveEditMode(bool SaveValue) { + if (valueUtf8) { + if (SaveValue) { + Utf8FromArray(valueUtf8, value, length); + stripspace(value); + if (callback) { + strncpy(callback, value, TEXTINPUTLENGTH); + } + } + lengthUtf8 = 0; + delete[] valueUtf8; + valueUtf8 = NULL; + delete[] allowedUtf8; + allowedUtf8 = NULL; + delete[] charMapUtf8; + charMapUtf8 = NULL; + pos = -1; + offset = 0; + newchar = true; + } +} + +void cRecMenuItemText::AdvancePos(void) { + if (pos < length - 2 && pos < lengthUtf8) { + if (++pos >= lengthUtf8) { + if (pos >= 2 && valueUtf8[pos - 1] == ' ' && valueUtf8[pos - 2] == ' ') + pos--; // allow only two blanks at the end + else { + valueUtf8[pos] = ' '; + valueUtf8[pos + 1] = 0; + lengthUtf8++; + } + } + } + newchar = true; + if (!insert && Utf8is(alpha, valueUtf8[pos])) + uppercase = Utf8is(upper, valueUtf8[pos]); +} + +uint cRecMenuItemText::Inc(uint c, bool Up) { + uint *p = IsAllowed(c); + if (!p) + p = allowedUtf8; + if (Up) { + if (!*++p) + p = allowedUtf8; + } else if (--p < allowedUtf8) { + p = allowedUtf8; + while (*p && *(p + 1)) + p++; + } + return *p; +} + +void cRecMenuItemText::Type(uint c) { + if (insert && lengthUtf8 < length - 1) + Insert(); + valueUtf8[pos] = c; + if (pos < length - 2) + pos++; + if (pos >= lengthUtf8) { + valueUtf8[pos] = ' '; + valueUtf8[pos + 1] = 0; + lengthUtf8 = pos + 1; + } +} + +void cRecMenuItemText::Insert(void) { + memmove(valueUtf8 + pos + 1, valueUtf8 + pos, (lengthUtf8 - pos + 1) * sizeof(*valueUtf8)); + lengthUtf8++; + valueUtf8[pos] = ' '; +} + +void cRecMenuItemText::Delete(void) { + memmove(valueUtf8 + pos, valueUtf8 + pos + 1, (lengthUtf8 - pos) * sizeof(*valueUtf8)); + lengthUtf8--; +} + +uint *cRecMenuItemText::IsAllowed(uint c) { + if (allowedUtf8) { + for (uint *a = allowedUtf8; *a; a++) { + if (c == *a) + return a; + } + } + return NULL; +} + +void cRecMenuItemText::SetText(void) { + if (InEditMode()) { + int textAreaWidth = 800; + if (pos < offset) + offset = pos; + int WidthFromOffset = 0; + int EndPos = lengthUtf8; + for (int i = offset; i < lengthUtf8; i++) { + WidthFromOffset += 20; + if (WidthFromOffset > textAreaWidth) { + if (pos >= i) { + do { + WidthFromOffset -= 20; + offset++; + } while (WidthFromOffset > textAreaWidth && offset < pos); + EndPos = pos + 1; + } else { + EndPos = i; + break; + } + } + } + char buf[1000]; + char *p = buf; + if (offset) + *p++ = '<'; + p += Utf8FromArray(valueUtf8 + offset, p, sizeof(buf) - (p - buf), pos - offset); + *p++ = '['; + if (insert && newchar) + *p++ = ']'; + p += Utf8FromArray(&valueUtf8[pos], p, sizeof(buf) - (p - buf), 1); + if (!(insert && newchar)) + *p++ = ']'; + p += Utf8FromArray(&valueUtf8[pos + 1], p, sizeof(buf) - (p - buf), EndPos - pos - 1); + if (EndPos != lengthUtf8) + *p++ = '>'; + *p = 0; + buffer = buf; + } else { + buffer = ""; + } +} + +void cRecMenuItemText::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::textinput, 1); + menu->AddIntToken((int)eRecMenuIT::editmode, InEditMode()); + menu->AddStringToken((int)eRecMenuST::text, text.c_str()); + if (buffer.size() > 0) { + menu->AddStringToken((int)eRecMenuST::value, buffer.c_str()); + } else { + menu->AddStringToken((int)eRecMenuST::value, value); + } +} + +eRecMenuState cRecMenuItemText::ProcessKey(eKeys Key) { + bool consumed = false; + bool SameKey = NORMALKEY(Key) == lastKey; + + if (Key != kNone) { + lastKey = NORMALKEY(Key); + } else if (!newchar && k0 <= lastKey && lastKey <= k9 && autoAdvanceTimeout.TimedOut()) { + AdvancePos(); + newchar = true; + currentCharUtf8 = NULL; + SetText(); + return rmsRefresh; + } + + switch ((int)Key) { + case kRed: // Switch between upper- and lowercase characters + if (InEditMode()) { + if (!insert || !newchar) { + uppercase = !uppercase; + valueUtf8[pos] = uppercase ? Utf8to(upper, valueUtf8[pos]) : Utf8to(lower, valueUtf8[pos]); + } + consumed = true; + } + break; + case kGreen: // Toggle insert/overwrite modes + if (InEditMode()) { + insert = !insert; + newchar = true; + consumed = true; + } + break; + case kYellow|k_Repeat: + case kYellow: // Remove the character at the current position; in insert mode it is the character to the right of the cursor + if (InEditMode()) { + if (lengthUtf8 > 1) { + if (!insert || pos < lengthUtf8 - 1) + Delete(); + else if (insert && pos == lengthUtf8 - 1) + valueUtf8[pos] = ' '; // in insert mode, deleting the last character replaces it with a blank to keep the cursor position + // reduce position, if we removed the last character + if (pos == lengthUtf8) + pos--; + } else if (lengthUtf8 == 1) + valueUtf8[0] = ' '; // This is the last character in the string, replace it with a blank + if (Utf8is(alpha, valueUtf8[pos])) + uppercase = Utf8is(upper, valueUtf8[pos]); + newchar = true; + consumed = true; + } + break; + case kLeft|k_Repeat: + case kLeft: + + if (pos > 0) { + if (!insert || newchar) + pos--; + newchar = true; + if (!insert && Utf8is(alpha, valueUtf8[pos])) + uppercase = Utf8is(upper, valueUtf8[pos]); + } + consumed = true; + break; + case kRight|k_Repeat: + case kRight: + if (InEditMode()) { + AdvancePos(); + } else { + EnterEditMode(); + } + consumed = true; + break; + case kUp|k_Repeat: + case kUp: + case kDown|k_Repeat: + case kDown: + if (InEditMode()) { + if (insert && newchar) { + // create a new character in insert mode + if (lengthUtf8 < length - 1) + Insert(); + } + if (uppercase) + valueUtf8[pos] = Utf8to(upper, Inc(Utf8to(lower, valueUtf8[pos]), NORMALKEY(Key) == kUp)); + else + valueUtf8[pos] = Inc( valueUtf8[pos], NORMALKEY(Key) == kUp); + newchar = false; + consumed = true; + } + break; + case k0|k_Repeat ... k9|k_Repeat: + case k0 ... k9: { + if (InEditMode()) { + if (Setup.NumberKeysForChars) { + if (!SameKey) { + if (!newchar) + AdvancePos(); + currentCharUtf8 = NULL; + } + if (!currentCharUtf8 || !*currentCharUtf8 || *currentCharUtf8 == '\t') { + // find the beginning of the character map entry for Key + int n = NORMALKEY(Key) - k0; + currentCharUtf8 = charMapUtf8; + while (n > 0 && *currentCharUtf8) { + if (*currentCharUtf8++ == '\t') + n--; + } + // find first allowed character + while (*currentCharUtf8 && *currentCharUtf8 != '\t' && !IsAllowed(*currentCharUtf8)) + currentCharUtf8++; + } + if (*currentCharUtf8 && *currentCharUtf8 != '\t') { + if (insert && newchar) { + // create a new character in insert mode + if (lengthUtf8 < length - 1) + Insert(); + } + valueUtf8[pos] = *currentCharUtf8; + if (uppercase) + valueUtf8[pos] = Utf8to(upper, valueUtf8[pos]); + // find next allowed character + do { + currentCharUtf8++; + } while (*currentCharUtf8 && *currentCharUtf8 != '\t' && !IsAllowed(*currentCharUtf8)); + newchar = false; + autoAdvanceTimeout.Set(AUTO_ADVANCE_TIMEOUT); + } + } else { + Type('0' + NORMALKEY(Key) - k0); + } + consumed = true; + } + break; } + case kBack: + case kOk: + if (InEditMode()) { + LeaveEditMode(Key == kOk); + } else { + EnterEditMode(); + } + consumed = true; + break; + default: + if (InEditMode() && BASICKEY(Key) == kKbd) { + int c = KEYKBD(Key); + if (c <= 0xFF) { + if (IsAllowed(Utf8to(lower, c))) + Type(c); + else { + switch (c) { + case 0x7F: // backspace + if (pos > 0) { + pos--; + ProcessKey(kYellow); + } + break; + default: ; + } + } + } else { + switch (c) { + case kfHome: pos = 0; break; + case kfEnd: pos = lengthUtf8 - 1; break; + case kfIns: ProcessKey(kGreen); + case kfDel: ProcessKey(kYellow); + default: ; + } + } + consumed = true; + } + break; + } + SetText(); + if (consumed) + return rmsRefresh; + return rmsNotConsumed; +} + +// --- cRecMenuItemTime ------------------------------------------------------- +cRecMenuItemTime::cRecMenuItemTime(string text, + int initialVal, + bool active, + int *callback, + eRecMenuState action) { + height = 8; + selectable = true; + this->text = text; + this->value = initialVal; + hh = value / 100; + mm = value % 100; + pos = 0; + fresh = true; + this->active = active; + this->callback = callback; + this->action = action; +} + +cRecMenuItemTime::~cRecMenuItemTime(void) { +} + +void cRecMenuItemTime::SetTokens(skindesignerapi::cViewGrid *menu) { + char buf[10]; + switch (pos) { + case 1: snprintf(buf, sizeof(buf), "%01d-:--", hh / 10); break; + case 2: snprintf(buf, sizeof(buf), "%02d:--", hh); break; + case 3: snprintf(buf, sizeof(buf), "%02d:%01d-", hh, mm / 10); break; + default: snprintf(buf, sizeof(buf), "%02d:%02d", hh, mm); + } + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::timeselector, 1); + menu->AddStringToken((int)eRecMenuST::text, text.c_str()); + menu->AddStringToken((int)eRecMenuST::value, buf); +} + +eRecMenuState cRecMenuItemTime::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft|k_Repeat: + case kLeft: { + if (--mm < 0) { + mm = 59; + if (--hh < 0) + hh = 23; + } + fresh = true; + value = hh * 100 + mm; + if (callback) + *callback = value; + return rmsRefresh; + break; } + case kRight|k_Repeat: + case kRight: { + if (++mm > 59) { + mm = 0; + if (++hh > 23) + hh = 0; + } + fresh = true; + value = hh * 100 + mm; + if (callback) + *callback = value; + return rmsRefresh; + break; } + case k0|k_Repeat ... k9|k_Repeat: + case k0 ... k9: { + if (fresh || pos > 3) { + pos = 0; + fresh = false; + } + int n = Key - k0; + switch (pos) { + case 0: + if (n <= 2) { + hh = n * 10; + mm = 0; + pos++; + } + break; + case 1: + if (hh + n <= 23) { + hh += n; + pos++; + } + break; + case 2: + if (n <= 5) { + mm += n * 10; + pos++; + } + break; + case 3: + if (mm + n <= 59) { + mm += n; + pos++; + } + break; + default: ; + } + value = hh * 100 + mm; + if (callback) + *callback = value; + return rmsRefresh; + break; } + case kOk: + return action; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemDay ------------------------------------------------------- +cRecMenuItemDay::cRecMenuItemDay(string text, + time_t initialVal, + bool active, + time_t *callback, + eRecMenuState action) { + + height = 8; + selectable = true; + this->text = text; + this->currentVal = cTimer::SetTime(initialVal, 0); + this->active = active; + this->callback = callback; + this->action = action; +} + +cRecMenuItemDay::~cRecMenuItemDay(void) { +} + +void cRecMenuItemDay::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::dayselector, 1); + menu->AddStringToken((int)eRecMenuST::text, text.c_str()); + menu->AddStringToken((int)eRecMenuST::value, *DateString(currentVal)); +} + +eRecMenuState cRecMenuItemDay::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: + currentVal -= 60*60*24; + if (callback) + *callback = currentVal; + return rmsRefresh; + break; + case kRight: + currentVal += 60*60*24; + if (callback) + *callback = currentVal; + return rmsRefresh; + break; + case kOk: + return action; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemChannelChooser ------------------------------------------------------- +cRecMenuItemChannelChooser::cRecMenuItemChannelChooser(string text, + const cChannel *initialChannel, + bool active, + int *callback, + eRecMenuState action) { + + height = 8; + selectable = true; + this->text = text; + this->channel = initialChannel; + if (initialChannel) + initialChannelSet = true; + else + initialChannelSet = false; + channelNumber = 0; + fresh = true; + this->active = active; + this->callback = callback; + this->action = action; +} + +cRecMenuItemChannelChooser::~cRecMenuItemChannelChooser(void) { +} + +void cRecMenuItemChannelChooser::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::channelselector, 1); + menu->AddStringToken((int)eRecMenuST::text, text.c_str()); + if (channel) { + menu->AddIntToken((int)eRecMenuIT::channelnumber, channel->Number()); + menu->AddStringToken((int)eRecMenuST::channelname, channel->Name()); + cString channelId = channel->GetChannelID().ToString(); + menu->AddStringToken((int)eRecMenuST::channelid, *channelId); + menu->AddIntToken((int)eRecMenuIT::channellogoexisis, menu->ChannelLogoExists(*channelId)); + } else { + menu->AddIntToken((int)eRecMenuIT::channelnumber, 0); + menu->AddStringToken((int)eRecMenuST::channelname, tr("all Channels")); + menu->AddStringToken((int)eRecMenuST::channelid, ""); + menu->AddIntToken((int)eRecMenuIT::channellogoexisis, false); + } +} + +eRecMenuState cRecMenuItemChannelChooser::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: { + fresh = true; + if (!channel) + return rmsConsumed; + const cChannel *prev = channel; +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* channels = Channels; +#else + const cChannels* channels = &Channels; +#endif + const cChannel *firstChannel = channels->First(); + if (firstChannel->GroupSep()) + firstChannel = channels->Next(firstChannel); + if (prev == firstChannel) { + if (!initialChannelSet) + channel = NULL; + } else { + while (prev = channels->Prev(prev)) { + if(!prev->GroupSep()) { + channel = prev; + break; + } + } + } + if (callback) { + if (channel) + *callback = channel->Number(); + else + *callback = 0; + } + return rmsRefresh; + break; } + case kRight: { + fresh = true; +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* channels = Channels; +#else + const cChannels* channels = &Channels; +#endif + if (!channel) { + channel = channels->First(); + if(channel->GroupSep()) + channel = channels->Next(channel); + } else { + const cChannel *next = channel; + while (next = channels->Next(next)) { + if(!next->GroupSep()) { + channel = next; + break; + } + } + } + if (callback) { + if (channel) + *callback = channel->Number(); + else + *callback = 0; + } + return rmsRefresh; + break; } + case k0 ... k9: { + if (fresh) { + channelNumber = 0; + fresh = false; + } + channelNumber = channelNumber * 10 + (Key - k0); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannel *chanNew = Channels->GetByNumber(channelNumber); +#else + const cChannel *chanNew = Channels.GetByNumber(channelNumber); +#endif + if (chanNew) { + channel = chanNew; + if (callback) + *callback = channel->Number(); + } + return rmsRefresh; + break; } + case kOk: + return action; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemDayChooser ------------------------------------------------------- +cRecMenuItemDayChooser::cRecMenuItemDayChooser(string text, + int weekdays, + bool active, + int *callback) { + height = 8; + selectable = true; + this->text = text; + if (weekdays < 1) + weekdays *= -1; + this->weekdays = weekdays; + this->active = active; + this->callback = callback; + selectedDay = 0; +} + +cRecMenuItemDayChooser::~cRecMenuItemDayChooser(void) { +} + +void cRecMenuItemDayChooser::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::weekdayselector, 1); + menu->AddStringToken((int)eRecMenuST::text, text.c_str()); + menu->AddIntToken((int)eRecMenuIT::dayselected, selectedDay); + + string days = trVDR("MTWTFSS"); + for (unsigned day=0; day<days.length(); ++day) { + cString strDay = cString::sprintf("%c", days.at(day)); + menu->AddStringToken((int)eRecMenuST::day0abbr + day, *strDay); + menu->AddIntToken((int)eRecMenuIT::day0set + day, WeekDaySet(day)); + } +} + +bool cRecMenuItemDayChooser::WeekDaySet(unsigned day) { + return weekdays & (1 << day); +} + +void cRecMenuItemDayChooser::ToggleDay(void) { + bool dayActive = WeekDaySet(selectedDay); + int dayBit = pow(2, selectedDay); + if (dayActive) { + weekdays -= dayBit; + } else { + weekdays += dayBit; + } + if (callback) { + *callback = weekdays; + } +} + +eRecMenuState cRecMenuItemDayChooser::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: { + selectedDay--; + if (selectedDay<0) + selectedDay += 7; + return rmsRefresh; + break; } + case kRight: { + selectedDay = (selectedDay+1)%7; + return rmsRefresh; + break; } + case kOk: + ToggleDay(); + return rmsRefresh; + break; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemSelectDirectory ------------------------------------------------------- +cRecMenuItemSelectDirectory::cRecMenuItemSelectDirectory(string text, + string originalFolder, + bool active, + char *callback, + eRecMenuState action, + bool isSearchTimer) { + + height = 8; + selectable = true; + this->text = text; + this->originalFolder = originalFolder; + this->active = active; + this->callback = callback; + this->action = action; + folders.push_back(tr("root video folder")); + if (isSearchTimer && config.instRecFixedFolder.size() > 0) + folders.push_back(config.instRecFixedFolder); + ReadRecordingDirectories(&folders, NULL, ""); + numValues = folders.size(); + this->currentVal = GetInitial(); +} + +void cRecMenuItemSelectDirectory::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::directoryselector, 1); + menu->AddStringToken((int)eRecMenuST::text, text.c_str()); + menu->AddStringToken((int)eRecMenuST::folder, folders[currentVal].c_str()); +} + +eRecMenuState cRecMenuItemSelectDirectory::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: + currentVal--; + if (currentVal<0) + currentVal = numValues - 1; + if (callback) { + SetCallback(); + } + return rmsRefresh; + break; + case kRight: { + currentVal = (currentVal+1)%numValues; + if (callback) { + SetCallback(); + } + return rmsRefresh; + break; } + case kOk: + return action; + default: + break; + } + return rmsNotConsumed; +} + +void cRecMenuItemSelectDirectory::SetCallback(void) { + string newFolder = folders[currentVal]; + if (!newFolder.compare(tr("root video folder"))) + newFolder = ""; + strncpy(callback, newFolder.c_str(), TEXTINPUTLENGTH); +} + +int cRecMenuItemSelectDirectory::GetInitial(void) { + if (originalFolder.size() == 0) + return 0; + for (int i=0; i < numValues; i++) { + if (!folders[i].compare(originalFolder)) { + return i; + } + } + return 0; +} + +// --- cRecMenuItemTimerConflictHeader ------------------------------------------------------- +cRecMenuItemTimerConflictHeader::cRecMenuItemTimerConflictHeader(time_t conflictStart, + time_t conflictStop, + time_t overlapStart, + time_t overlapStop) { + height = 10; + selectable = false; + active = false; + this->conflictStart = conflictStart; + this->conflictStop = conflictStop; + this->overlapStart = overlapStart; + this->overlapStop = overlapStop; +} + +cRecMenuItemTimerConflictHeader::~cRecMenuItemTimerConflictHeader(void) { +} + +void cRecMenuItemTimerConflictHeader::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::timerconflictheader, 1); + menu->AddStringToken((int)eRecMenuST::text, tr("Timer Conflict")); + menu->AddStringToken((int)eRecMenuST::conflictstart, *TimeString(conflictStart)); + menu->AddStringToken((int)eRecMenuST::conflictstop, *TimeString(conflictStop)); + menu->AddStringToken((int)eRecMenuST::overlapstart, *TimeString(overlapStart)); + menu->AddStringToken((int)eRecMenuST::overlapstop, *TimeString(overlapStop)); + + int olStart = (double)(overlapStart - conflictStart) / (double)(conflictStop - conflictStart) * 100; + int olWidth = (double)(overlapStop - overlapStart) / (double)(conflictStop - conflictStart) * 100; + menu->AddIntToken((int)eRecMenuIT::overlapstartpercent, olStart); + menu->AddIntToken((int)eRecMenuIT::overlapwidthpercent, olWidth); +} + +// --- cRecMenuItemTimer ------------------------------------------------------- +cRecMenuItemTimer::cRecMenuItemTimer(const cTimer *timer, + eRecMenuState action1, + eRecMenuState action2, + eRecMenuState action3, + eRecMenuState action4, + time_t conflictStart, + time_t conflictStop, + time_t overlapStart, + time_t overlapStop, + bool active) { + height = 12; + selectable = true; + this->timer = timer; + this->action = action1; + this->action2 = action2; + this->action3 = action3; + this->action4 = action4; + iconActive = 0; + this->conflictStart = conflictStart; + this->conflictStop = conflictStop; + this->overlapStart = overlapStart; + this->overlapStop = overlapStop; + this->active = active; +} + +cRecMenuItemTimer::~cRecMenuItemTimer(void) { +} + +void cRecMenuItemTimer::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::timerconflict, 1); + + const cChannel *channel = timer->Channel(); + int channelTransponder = 0; + const char *channelName = NULL; + cString channelId = ""; + if (channel) { + channelTransponder = channel->Transponder(); + channelName = channel->Name() ? channel->Name() : ""; + channelId = channel->GetChannelID().ToString(); + } + menu->AddIntToken((int)eRecMenuIT::channeltransponder, channelTransponder); + menu->AddStringToken((int)eRecMenuST::channelname, channelName); + menu->AddStringToken((int)eRecMenuST::channelid, *channelId); + + const cEvent *event = timer->Event(); + string timerTitle = ""; + if (event && event->Title()) { + timerTitle = event->Title(); + } + menu->AddStringToken((int)eRecMenuST::timertitle, timerTitle.c_str()); + menu->AddStringToken((int)eRecMenuST::starttime, *TimeString(timer->StartTime())); + menu->AddStringToken((int)eRecMenuST::stoptime, *TimeString(timer->StopTime())); + menu->AddStringToken((int)eRecMenuST::date, *ShortDateString(timer->StartTime())); + menu->AddStringToken((int)eRecMenuST::weekday, *WeekDayName(timer->StartTime())); + + menu->AddIntToken((int)eRecMenuIT::infoactive, (iconActive==0)?true:false); + menu->AddIntToken((int)eRecMenuIT::deleteactive, (iconActive==1)?true:false); + menu->AddIntToken((int)eRecMenuIT::editactive, (iconActive==2)?true:false); + menu->AddIntToken((int)eRecMenuIT::searchactive, (iconActive==3)?true:false); + + + int conflictTime = conflictStop - conflictStart; + int timerStart = (double)(timer->StartTime() - conflictStart) / (double)conflictTime * 100; + int timerWidth = (double)(timer->StopTime() - timer->StartTime()) / (double)conflictTime * 100; + int olStart = (double)(overlapStart - conflictStart) / (double)(conflictStop - conflictStart) * 100; + int olWidth = (double)(overlapStop - overlapStart) / (double)(conflictStop - conflictStart) * 100; + menu->AddIntToken((int)eRecMenuIT::timerstartpercent, timerStart); + menu->AddIntToken((int)eRecMenuIT::timerwidthpercent, timerWidth); + menu->AddIntToken((int)eRecMenuIT::overlapstartpercent, olStart); + menu->AddIntToken((int)eRecMenuIT::overlapwidthpercent, olWidth); +} + +eRecMenuState cRecMenuItemTimer::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: + if (iconActive > 0) { + iconActive--; + return rmsRefresh; + } else + return rmsNotConsumed; + break; + case kRight: + if (iconActive < 3) { + iconActive++; + return rmsRefresh; + } else + return rmsNotConsumed; + break; + case kOk: + if (iconActive == 0) + return action; + else if (iconActive == 1) + return action2; + else if (iconActive == 2) + return action3; + else if (iconActive == 3) + return action4; + break; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemEvent ------------------------------------------------------- +cRecMenuItemEvent::cRecMenuItemEvent(const cEvent *event, + eRecMenuState action1, + eRecMenuState action2, + bool active) { + height = 8; + selectable = true; + this->event = event; + this->action = action1; + this->action2 = action2; + iconActive = 0; + this->active = active; +} + +cRecMenuItemEvent::~cRecMenuItemEvent(void) { +} + +void cRecMenuItemEvent::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::event, 1); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannel *channel = Channels->GetByChannelID(event->ChannelID()); +#else + const cChannel *channel = Channels.GetByChannelID(event->ChannelID()); +#endif + const char *channelName = NULL; + cString channelId = ""; + if (channel) { + channelName = channel->Name(); + channelId = channel->GetChannelID().ToString(); + menu->AddIntToken((int)eRecMenuIT::channelnumber, channel->Number()); + } + + menu->AddStringToken((int)eRecMenuST::channelname, channelName); + menu->AddStringToken((int)eRecMenuST::channelid, *channelId); + menu->AddIntToken((int)eRecMenuIT::channellogoexisis, menu->ChannelLogoExists(*channelId)); + menu->AddStringToken((int)eRecMenuST::title, event->Title()); + menu->AddStringToken((int)eRecMenuST::shorttext, event->ShortText()); + menu->AddStringToken((int)eRecMenuST::date, *ShortDateString(event->StartTime())); + menu->AddStringToken((int)eRecMenuST::weekday, *WeekDayName(event->StartTime())); + menu->AddStringToken((int)eRecMenuST::starttime, *TimeString(event->StartTime())); + menu->AddStringToken((int)eRecMenuST::stoptime, *TimeString(event->EndTime())); + menu->AddIntToken((int)eRecMenuIT::hastimer, event->HasTimer()); +} + +eRecMenuState cRecMenuItemEvent::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kOk: + return action; + break; + case kRed: + if (!event->HasTimer()) + return action2; + break; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemRecording ------------------------------------------------------- +cRecMenuItemRecording::cRecMenuItemRecording(const cRecording *recording, bool active) { + height = 8; + selectable = true; + this->recording = recording; + this->active = active; +} + +void cRecMenuItemRecording::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::recording, 1); + if (!recording) + return; + const cRecordingInfo *recInfo = recording->Info(); + const cChannel *channel = NULL; + if (recInfo) { +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + channel = Channels->GetByChannelID(recInfo->ChannelID()); +#else + channel = Channels.GetByChannelID(recInfo->ChannelID()); +#endif + } + string channelName = tr("unknown channel"); + string channelId = ""; + if (channel && channel->Name()) { + channelName = channel->Name(); + channelId = *(channel->GetChannelID().ToString()); + menu->AddIntToken((int)eRecMenuIT::channelnumber, channel->Number()); + } + menu->AddStringToken((int)eRecMenuST::channelname, channelName.c_str()); + menu->AddStringToken((int)eRecMenuST::channelid, channelId.c_str()); + menu->AddIntToken((int)eRecMenuIT::channellogoexisis, menu->ChannelLogoExists(channelId)); + + string recName = recording->Name() ? recording->Name() : ""; + string recDate = *ShortDateString(recording->Start()); + string recStartTime = *TimeString(recording->Start()); + int recDuration = recording->LengthInSeconds() / 60; + + menu->AddStringToken((int)eRecMenuST::recname, recName.c_str()); + menu->AddStringToken((int)eRecMenuST::recdate, recDate.c_str()); + menu->AddStringToken((int)eRecMenuST::recstarttime, recStartTime.c_str()); + menu->AddIntToken((int)eRecMenuIT::recduration, recDuration); +} + +// --- cRecMenuItemSearchTimer ------------------------------------------------------- +cRecMenuItemSearchTimer::cRecMenuItemSearchTimer(cTVGuideSearchTimer timer, + eRecMenuState action1, + eRecMenuState action2, + eRecMenuState action3, + bool active) { + height = 8; + this->timer = timer; + this->action = action1; + this->action2 = action2; + this->action3 = action3; + selectable = true; + this->active = active; + iconActive = 0; +} + +cRecMenuItemSearchTimer::~cRecMenuItemSearchTimer(void) { +} + +void cRecMenuItemSearchTimer::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::searchtimer, 1); + menu->AddIntToken((int)eRecMenuIT::timeractive, timer.Active()); + menu->AddStringToken((int)eRecMenuST::searchstring, timer.SearchString().c_str()); + menu->AddIntToken((int)eRecMenuIT::activetimers, timer.GetNumTimers()); + menu->AddIntToken((int)eRecMenuIT::recordingsdone, timer.GetNumRecordings()); + menu->AddIntToken((int)eRecMenuIT::searchactive, (iconActive==0)?true:false); + menu->AddIntToken((int)eRecMenuIT::editactive, (iconActive==1)?true:false); + menu->AddIntToken((int)eRecMenuIT::deleteactive, (iconActive==2)?true:false); +} + +eRecMenuState cRecMenuItemSearchTimer::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: + if (iconActive > 0) { + iconActive--; + return rmsRefresh; + } + return rmsNotConsumed; + break; + case kRight: { + if (iconActive < 2) { + iconActive++; + return rmsRefresh; + } + return rmsNotConsumed; + break; } + case kOk: + if (iconActive == 0) + return action; + else if (iconActive == 1) + return action2; + else if (iconActive == 2) + return action3; + break; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemTimelineHeader ------------------------------------------------------- +cRecMenuItemTimelineHeader::cRecMenuItemTimelineHeader(time_t day) { + height = 15; + timer = NULL; + this->day = day; + selectable = false; + active = false; +} + +cRecMenuItemTimelineHeader::~cRecMenuItemTimelineHeader(void) { +} + +void cRecMenuItemTimelineHeader::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::timelineheader, 1); + string daydate = *DateString(day); + menu->AddStringToken((int)eRecMenuST::date, daydate.c_str()); + if (!timer) { + menu->AddIntToken((int)eRecMenuIT::timerset, false); + return; + } + menu->AddIntToken((int)eRecMenuIT::timerset, true); + + const cChannel *channel = timer->Channel(); + const char *channelName = NULL; + cString channelId = ""; + int channelNumber = 0; + int transponder = 0; + if (channel) { + channelName = channel->Name(); + channelId = channel->GetChannelID().ToString(); + channelNumber = channel->Number(); + transponder = channel->Transponder(); + } + menu->AddStringToken((int)eRecMenuST::channelname, channelName); + menu->AddStringToken((int)eRecMenuST::channelid, *channelId); + menu->AddIntToken((int)eRecMenuIT::channelnumber, channelNumber); + menu->AddIntToken((int)eRecMenuIT::channeltransponder, transponder); + menu->AddIntToken((int)eRecMenuIT::channellogoexisis, menu->ChannelLogoExists(*channelId)); + + menu->AddStringToken((int)eRecMenuST::timerstart, *TimeString(timer->StartTime())); + menu->AddStringToken((int)eRecMenuST::timerstop, *TimeString(timer->StopTime())); + + const cEvent *event = timer->Event(); + const char *eventTitle = NULL; + const char *eventShortText = ""; + cString eventStart = ""; + cString eventStop = ""; + if (event) { + eventTitle = event->Title(); + eventShortText = event->ShortText(); + eventStart = event->GetTimeString(); + eventStop = event->GetEndTimeString(); + } + menu->AddStringToken((int)eRecMenuST::eventtitle, eventTitle); + menu->AddStringToken((int)eRecMenuST::eventshorttext, eventShortText); + menu->AddStringToken((int)eRecMenuST::eventstart, *eventStart); + menu->AddStringToken((int)eRecMenuST::eventstop, *eventStop); +} + +// --- cRecMenuItemTimelineTimer ------------------------------------------------------- +cRecMenuItemTimelineTimer::cRecMenuItemTimelineTimer(const cTimer *timer, time_t start, time_t stop, bool active) { + height = 8; + this->timer = timer; + this->start = start; + this->stop = stop; + selectable = true; + this->active = active; +} + +cRecMenuItemTimelineTimer::~cRecMenuItemTimelineTimer(void) { +} + +void cRecMenuItemTimelineTimer::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::timelinetimer, 1); + + int secsPerDay = 24*60*60; + time_t timerStart = timer->StartTime() - start; + time_t timerStop = timer->StopTime() - start; + if (timerStart < 0) + timerStart = 0; + if (timerStop > secsPerDay) + timerStop = secsPerDay; + + int percentStart = ((double)timerStart / (double)secsPerDay) * 1000; + int percentWidth = ((double)(timerStop - timerStart) / (double)secsPerDay) * 1000; + menu->AddIntToken((int)eRecMenuIT::timerstart, percentStart); + menu->AddIntToken((int)eRecMenuIT::timerwidth, percentWidth); +} + +const cTimer *cRecMenuItemTimelineTimer::GetTimer(void) { + return timer; +} + +eRecMenuState cRecMenuItemTimelineTimer::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kOk: + return rmsTimelineTimerEdit; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemFavorite ------------------------------------------------------- +cRecMenuItemFavorite::cRecMenuItemFavorite(cTVGuideSearchTimer favorite, + eRecMenuState action1, + bool active) { + height = 8; + this->favorite = favorite; + this->action = action1; + selectable = true; + this->active = active; +} + +void cRecMenuItemFavorite::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::favorite, 1); + menu->AddStringToken((int)eRecMenuST::favdesc, favorite.SearchString().c_str()); +} + +eRecMenuState cRecMenuItemFavorite::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kOk: + return action; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemFavoriteStatic ------------------------------------------------------- +cRecMenuItemFavoriteStatic::cRecMenuItemFavoriteStatic(string text, eRecMenuState action, bool active) { + height = 8; + this->text = text; + this->action = action; + selectable = true; + this->active = active; +} + +void cRecMenuItemFavoriteStatic::SetTokens(skindesignerapi::cViewGrid *menu) { + menu->ClearTokens(); + menu->AddIntToken((int)eRecMenuIT::favorite, 1); + menu->AddStringToken((int)eRecMenuST::favdesc, text.c_str()); +} + +eRecMenuState cRecMenuItemFavoriteStatic::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kOk: + return action; + default: + break; + } + return rmsNotConsumed; +} + diff --git a/recmenuitem.h b/recmenuitem.h index 05818b8..b219b43 100644 --- a/recmenuitem.h +++ b/recmenuitem.h @@ -1,496 +1,496 @@ -#ifndef __TVGUIDE_RECMENUITEM_H
-#define __TVGUIDE_RECMENUITEM_H
-
-#define AUTO_ADVANCE_TIMEOUT 1500
-
-using namespace std;
-
-#include <string>
-#include <sstream>
-#include <vdr/plugin.h>
-#include <vdr/tools.h>
-#include <libskindesignerapi/skindesignerosdbase.h>
-#include "definitions.h"
-#include "searchtimer.h"
-
-enum eRecMenuState {
- rmsConsumed,
- rmsNotConsumed,
- rmsRefresh,
- rmsContinue,
- rmsClose,
- rmsDisabled,
- //INSTANT TIMER
- rmsInstantRecord,
- rmsInstantRecordFolder,
- rmsIgnoreTimerConflict,
- rmsDeleteTimerConflictMenu,
- rmsEditTimerConflictMenu,
- rmsSearchRerunsTimerConflictMenu,
- rmsSaveTimerConflictMenu,
- rmsTimerConflictShowInfo,
- rmsDeleteTimer,
- rmsDeleteTimerConfirmation,
- rmsEditTimer,
- rmsSaveTimer,
- //SEARCH
- rmsSearch,
- rmsSearchWithOptions,
- rmsSearchPerform,
- rmsSearchShowInfo,
- rmsSearchRecord,
- rmsSearchRecordConfirm,
- rmsSearchNothingFoundConfirm,
- //SERIES TIMER
- rmsSeriesTimer,
- rmsSeriesTimerFolder,
- rmsSeriesTimerCreate,
- //SEARCHTIMER
- rmsSearchTimer,
- rmsSearchTimerOptions,
- rmsSearchTimers,
- rmsSearchTimerEdit,
- rmsSearchTimerEditAdvanced,
- rmsSearchTimerTest,
- rmsSearchTimerSave,
- rmsSearchTimerCreateWithTemplate,
- rmsSearchTimerDeleteConfirm,
- rmsSearchTimerDelete,
- rmsSearchTimerDeleteWithTimers,
- rmsSearchTimerRecord,
- //SWITCHTIMER
- rmsSwitchTimer,
- rmsSwitchTimerCreate,
- rmsSwitchTimerDelete,
- //RECORDINGS SEARCH
- rmsRecordingSearch,
- rmsRecordingSearchResult,
- //TIMER CONFLICTS
- rmsTimerConflict,
- rmsTimerConflicts,
- rmsTimerConflictIgnoreReruns,
- rmsTimerConflictRecordRerun,
- //TIMELINE
- rmsTimeline,
- rmsTimelineTimerEdit,
- rmsTimelineTimerSave,
- rmsTimelineTimerDelete,
- //FAVORITES
- rmsFavoritesRecord,
- rmsFavoritesNow,
- rmsFavoritesNext,
- rmsFavoritesUser1,
- rmsFavoritesUser2,
- rmsFavoritesUser3,
- rmsFavoritesUser4,
-};
-
-// --- cRecMenuItem -------------------------------------------------------------
-class cRecMenuItem : public cListObject {
-protected:
- static long idCounter;
- long id;
- bool init;
- bool active;
- bool selectable;
- eRecMenuState action;
- //height of item in percent of screen height
- int height;
- string text;
-public:
- cRecMenuItem(void);
- virtual ~cRecMenuItem(void);
- virtual void SetActive(void) { active = true; }
- virtual void SetInactive(void) { active = false; }
- long Id(void) { return id; };
- bool Selectable(void) { return selectable; }
- bool IsNew(void);
- void SetNew(void) { init = true; };
- bool Active(void) { return active; }
- int GetHeight(void) { return height; };
- string GetText(void) { return text; };
- virtual void SetTokens(skindesignerapi::cViewGrid *menu) {};
- virtual eRecMenuState ProcessKey(eKeys Key) { return rmsNotConsumed; };
-};
-
-// --- cRecMenuItemInfo -------------------------------------------------------
-class cRecMenuItemInfo : public cRecMenuItem {
-private:
- int numLines;
- string line1;
- string line2;
- string line3;
- string line4;
-public:
- cRecMenuItemInfo(string line1, int numLines = 1, string line2 = "", string line3 = "", string line4 = "");
- virtual ~cRecMenuItemInfo(void);
- string GetText(void) { return text; };
- void SetTokens(skindesignerapi::cViewGrid *menu);
-};
-
-// --- cRecMenuItemButton -------------------------------------------------------
-class cRecMenuItemButton : public cRecMenuItem {
-private:
- string text;
-public:
- cRecMenuItemButton(string text, eRecMenuState action, bool active);
- virtual ~cRecMenuItemButton(void);
- string GetText(void) { return text; };
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemButtonYesNo -------------------------------------------------------
-class cRecMenuItemButtonYesNo : public cRecMenuItem {
-private:
- string textYes;
- string textNo;
- eRecMenuState actionNo;
- bool yesActive;
-public:
- cRecMenuItemButtonYesNo(string textYes,
- string textNo,
- eRecMenuState actionYes,
- eRecMenuState actionNo,
- bool active);
- virtual ~cRecMenuItemButtonYesNo(void);
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemInt -------------------------------------------------------
-class cRecMenuItemInt : public cRecMenuItem {
-private:
- int currentVal;
- int *callback;
- int minVal;
- int maxVal;
- bool fresh;
-public:
- cRecMenuItemInt(string text,
- int initialVal,
- int minVal,
- int maxVal,
- bool active = false,
- int *callback = NULL,
- eRecMenuState action = rmsNotConsumed);
- virtual ~cRecMenuItemInt(void);
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemBool -------------------------------------------------------
-class cRecMenuItemBool : public cRecMenuItem {
-private:
- bool yes;
- bool *callback;
-public:
- cRecMenuItemBool(string text,
- bool initialVal,
- bool active = false,
- bool *callback = NULL,
- eRecMenuState action = rmsNotConsumed);
- virtual ~cRecMenuItemBool(void);
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemSelect -------------------------------------------------------
-class cRecMenuItemSelect : public cRecMenuItem {
-private:
- int currentVal;
- int *callback;
- vector<string> strings;
- int numValues;
-public:
- cRecMenuItemSelect(string text,
- vector<string> strings,
- int initialVal,
- bool active = false,
- int *callback = NULL,
- eRecMenuState action = rmsNotConsumed);
- virtual ~cRecMenuItemSelect(void);
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemText -------------------------------------------------------
-class cRecMenuItemText : public cRecMenuItem {
-private:
- char *value;
- string buffer;
- char *callback;
- int length;
- const char *allowed;
- int pos, offset;
- bool insert, newchar, uppercase;
- int lengthUtf8;
- uint *valueUtf8;
- uint *allowedUtf8;
- uint *charMapUtf8;
- uint *currentCharUtf8;
- eKeys lastKey;
- cTimeMs autoAdvanceTimeout;
- uint *IsAllowed(uint c);
- void AdvancePos(void);
- uint Inc(uint c, bool Up);
- void Type(uint c);
- void Insert(void);
- void Delete(void);
- void EnterEditMode(void);
- void LeaveEditMode(bool SaveValue = false);
- bool InEditMode(void) { return valueUtf8 != NULL; };
- void SetText(void);
-public:
- cRecMenuItemText(string title,
- char *initialVal,
- int length,
- bool active = false,
- char *callback = NULL);
- virtual ~cRecMenuItemText(void);
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemTime -------------------------------------------------------
-class cRecMenuItemTime : public cRecMenuItem {
-private:
- int value;
- int *callback;
- int mm;
- int hh;
- int pos;
- bool fresh;
-public:
- cRecMenuItemTime(string text,
- int initialVal,
- bool active = false,
- int *callback = NULL,
- eRecMenuState action = rmsNotConsumed);
- virtual ~cRecMenuItemTime(void);
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemDay -------------------------------------------------------
-class cRecMenuItemDay : public cRecMenuItem {
-private:
- time_t currentVal;
- time_t *callback;
-public:
- cRecMenuItemDay(string text,
- time_t initialVal,
- bool active = false,
- time_t *callback = NULL,
- eRecMenuState action = rmsNotConsumed);
- virtual ~cRecMenuItemDay(void);
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemChannelChooser -------------------------------------------------------
-class cRecMenuItemChannelChooser : public cRecMenuItem {
-private:
- cChannel *channel;
- int channelNumber;
- int *callback;
- bool initialChannelSet;
- bool fresh;
-public:
- cRecMenuItemChannelChooser (string text,
- cChannel *initialChannel,
- bool active = false,
- int *callback = NULL,
- eRecMenuState action = rmsNotConsumed);
- virtual ~cRecMenuItemChannelChooser(void);
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemDayChooser -------------------------------------------------------
-class cRecMenuItemDayChooser : public cRecMenuItem {
-private:
- int weekdays;
- int *callback;
- int selectedDay;
- void ToggleDay(void);
- bool WeekDaySet(unsigned day);
-public:
- cRecMenuItemDayChooser (string text,
- int weekdays,
- bool active = false,
- int *callback = NULL);
- virtual ~cRecMenuItemDayChooser(void);
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemSelectDirectory -------------------------------------------------------
-class cRecMenuItemSelectDirectory : public cRecMenuItem {
-private:
- string text;
- string originalFolder;
- vector<string> folders;
- int currentVal;
- char *callback;
- int numValues;
- void SetCallback(void);
- int GetInitial(void);
-public:
- cRecMenuItemSelectDirectory(string text,
- string originalFolder,
- bool active = false,
- char *callback = NULL,
- eRecMenuState action = rmsNotConsumed,
- bool isSearchTimer = false);
- virtual ~cRecMenuItemSelectDirectory(void) {};
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemTimerConflictHeader -------------------------------------------------------
-class cRecMenuItemTimerConflictHeader: public cRecMenuItem {
-private:
- time_t conflictStart;
- time_t conflictStop;
- time_t overlapStart;
- time_t overlapStop;
-public:
- cRecMenuItemTimerConflictHeader(time_t conflictStart,
- time_t conflictStop,
- time_t overlapStart,
- time_t overlapStop);
- void SetTokens(skindesignerapi::cViewGrid *menu);
- virtual ~cRecMenuItemTimerConflictHeader(void);
-};
-
-// --- cRecMenuItemTimer -------------------------------------------------------
-class cRecMenuItemTimer : public cRecMenuItem {
-private:
- const cTimer *timer;
- eRecMenuState action2;
- eRecMenuState action3;
- eRecMenuState action4;
- int iconActive;
- time_t conflictStart;
- time_t conflictStop;
- time_t overlapStart;
- time_t overlapStop;
-public:
- cRecMenuItemTimer(const cTimer *timer,
- eRecMenuState action1,
- eRecMenuState action2,
- eRecMenuState action3,
- eRecMenuState action4,
- time_t conflictStart,
- time_t conflictStop,
- time_t overlapStart,
- time_t overlapStop,
- bool active);
- virtual ~cRecMenuItemTimer(void);
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemEvent -------------------------------------------------------
-class cRecMenuItemEvent : public cRecMenuItem {
-private:
- const cEvent *event;
- eRecMenuState action2;
- int iconActive;
-public:
- cRecMenuItemEvent(const cEvent *event,
- eRecMenuState action1,
- eRecMenuState action2,
- bool active);
- virtual ~cRecMenuItemEvent(void);
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
- const cEvent *GetEvent(void) { return event; };
-};
-
-// --- cRecMenuItemRecording -------------------------------------------------------
-class cRecMenuItemRecording : public cRecMenuItem {
-private:
- cRecording *recording;
-public:
- cRecMenuItemRecording(cRecording *recording, bool active);
- virtual ~cRecMenuItemRecording(void) {};
- void SetTokens(skindesignerapi::cViewGrid *menu);
-};
-
-// --- cRecMenuItemSearchTimer -------------------------------------------------------
-class cRecMenuItemSearchTimer : public cRecMenuItem {
-private:
- cTVGuideSearchTimer timer;
- eRecMenuState action1;
- eRecMenuState action2;
- eRecMenuState action3;
- int iconActive;
-public:
- cRecMenuItemSearchTimer(cTVGuideSearchTimer timer,
- eRecMenuState action1,
- eRecMenuState action2,
- eRecMenuState action3,
- bool active);
- virtual ~cRecMenuItemSearchTimer(void);
- cTVGuideSearchTimer GetTimer(void) { return timer; };
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemTimelineHeader -------------------------------------------------------
-class cRecMenuItemTimelineHeader : public cRecMenuItem {
-private:
- time_t day;
- cTimer *timer;
-public:
- cRecMenuItemTimelineHeader(time_t day);
- virtual ~cRecMenuItemTimelineHeader(void);
- void SetTokens(skindesignerapi::cViewGrid *menu);
- void SetDay(time_t day) { this->day = day; };
- void SetCurrentTimer(cTimer *timer) { this->timer = timer; };
- void UnsetCurrentTimer(void) { timer = NULL; };
-};
-
-// --- cRecMenuItemTimelineTimer -------------------------------------------------------
-class cRecMenuItemTimelineTimer : public cRecMenuItem {
-private:
- cTimer *timer;
- time_t start;
- time_t stop;
-public:
- cRecMenuItemTimelineTimer(cTimer *timer, time_t start, time_t stop, bool active);
- virtual ~cRecMenuItemTimelineTimer(void);
- void SetTokens(skindesignerapi::cViewGrid *menu);
- cTimer *GetTimer(void);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemFavorite -------------------------------------------------------
-class cRecMenuItemFavorite : public cRecMenuItem {
-private:
- cTVGuideSearchTimer favorite;
- eRecMenuState action1;
-public:
- cRecMenuItemFavorite(cTVGuideSearchTimer favorite,
- eRecMenuState action1,
- bool active);
- virtual ~cRecMenuItemFavorite(void) {};
- void SetTokens(skindesignerapi::cViewGrid *menu);
- cTVGuideSearchTimer GetFavorite(void) { return favorite; };
- eRecMenuState ProcessKey(eKeys Key);
-};
-
-// --- cRecMenuItemFavoriteStatic -------------------------------------------------------
-class cRecMenuItemFavoriteStatic : public cRecMenuItem {
-private:
- string text;
-public:
- cRecMenuItemFavoriteStatic(string text, eRecMenuState action, bool active);
- virtual ~cRecMenuItemFavoriteStatic(void) {};
- void SetTokens(skindesignerapi::cViewGrid *menu);
- eRecMenuState ProcessKey(eKeys Key);
-};
-
+#ifndef __TVGUIDE_RECMENUITEM_H +#define __TVGUIDE_RECMENUITEM_H + +#define AUTO_ADVANCE_TIMEOUT 1500 + +using namespace std; + +#include <string> +#include <sstream> +#include <vdr/plugin.h> +#include <vdr/tools.h> +#include <libskindesignerapi/skindesignerosdbase.h> +#include "definitions.h" +#include "searchtimer.h" + +enum eRecMenuState { + rmsConsumed, + rmsNotConsumed, + rmsRefresh, + rmsContinue, + rmsClose, + rmsDisabled, + //INSTANT TIMER + rmsInstantRecord, + rmsInstantRecordFolder, + rmsIgnoreTimerConflict, + rmsDeleteTimerConflictMenu, + rmsEditTimerConflictMenu, + rmsSearchRerunsTimerConflictMenu, + rmsSaveTimerConflictMenu, + rmsTimerConflictShowInfo, + rmsDeleteTimer, + rmsDeleteTimerConfirmation, + rmsEditTimer, + rmsSaveTimer, + //SEARCH + rmsSearch, + rmsSearchWithOptions, + rmsSearchPerform, + rmsSearchShowInfo, + rmsSearchRecord, + rmsSearchRecordConfirm, + rmsSearchNothingFoundConfirm, + //SERIES TIMER + rmsSeriesTimer, + rmsSeriesTimerFolder, + rmsSeriesTimerCreate, + //SEARCHTIMER + rmsSearchTimer, + rmsSearchTimerOptions, + rmsSearchTimers, + rmsSearchTimerEdit, + rmsSearchTimerEditAdvanced, + rmsSearchTimerTest, + rmsSearchTimerSave, + rmsSearchTimerCreateWithTemplate, + rmsSearchTimerDeleteConfirm, + rmsSearchTimerDelete, + rmsSearchTimerDeleteWithTimers, + rmsSearchTimerRecord, + //SWITCHTIMER + rmsSwitchTimer, + rmsSwitchTimerCreate, + rmsSwitchTimerDelete, + //RECORDINGS SEARCH + rmsRecordingSearch, + rmsRecordingSearchResult, + //TIMER CONFLICTS + rmsTimerConflict, + rmsTimerConflicts, + rmsTimerConflictIgnoreReruns, + rmsTimerConflictRecordRerun, + //TIMELINE + rmsTimeline, + rmsTimelineTimerEdit, + rmsTimelineTimerSave, + rmsTimelineTimerDelete, + //FAVORITES + rmsFavoritesRecord, + rmsFavoritesNow, + rmsFavoritesNext, + rmsFavoritesUser1, + rmsFavoritesUser2, + rmsFavoritesUser3, + rmsFavoritesUser4, +}; + +// --- cRecMenuItem ------------------------------------------------------------- +class cRecMenuItem : public cListObject { +protected: + static long idCounter; + long id; + bool init; + bool active; + bool selectable; + eRecMenuState action; + //height of item in percent of screen height + int height; + string text; +public: + cRecMenuItem(void); + virtual ~cRecMenuItem(void); + virtual void SetActive(void) { active = true; } + virtual void SetInactive(void) { active = false; } + long Id(void) { return id; }; + bool Selectable(void) { return selectable; } + bool IsNew(void); + void SetNew(void) { init = true; }; + bool Active(void) { return active; } + int GetHeight(void) { return height; }; + string GetText(void) { return text; }; + virtual void SetTokens(skindesignerapi::cViewGrid *menu) {}; + virtual eRecMenuState ProcessKey(eKeys Key) { return rmsNotConsumed; }; +}; + +// --- cRecMenuItemInfo ------------------------------------------------------- +class cRecMenuItemInfo : public cRecMenuItem { +private: + int numLines; + string line1; + string line2; + string line3; + string line4; +public: + cRecMenuItemInfo(string line1, int numLines = 1, string line2 = "", string line3 = "", string line4 = ""); + virtual ~cRecMenuItemInfo(void); + string GetText(void) { return text; }; + void SetTokens(skindesignerapi::cViewGrid *menu); +}; + +// --- cRecMenuItemButton ------------------------------------------------------- +class cRecMenuItemButton : public cRecMenuItem { +private: + string text; +public: + cRecMenuItemButton(string text, eRecMenuState action, bool active); + virtual ~cRecMenuItemButton(void); + string GetText(void) { return text; }; + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemButtonYesNo ------------------------------------------------------- +class cRecMenuItemButtonYesNo : public cRecMenuItem { +private: + string textYes; + string textNo; + eRecMenuState actionNo; + bool yesActive; +public: + cRecMenuItemButtonYesNo(string textYes, + string textNo, + eRecMenuState actionYes, + eRecMenuState actionNo, + bool active); + virtual ~cRecMenuItemButtonYesNo(void); + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemInt ------------------------------------------------------- +class cRecMenuItemInt : public cRecMenuItem { +private: + int currentVal; + int *callback; + int minVal; + int maxVal; + bool fresh; +public: + cRecMenuItemInt(string text, + int initialVal, + int minVal, + int maxVal, + bool active = false, + int *callback = NULL, + eRecMenuState action = rmsNotConsumed); + virtual ~cRecMenuItemInt(void); + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemBool ------------------------------------------------------- +class cRecMenuItemBool : public cRecMenuItem { +private: + bool yes; + bool *callback; +public: + cRecMenuItemBool(string text, + bool initialVal, + bool active = false, + bool *callback = NULL, + eRecMenuState action = rmsNotConsumed); + virtual ~cRecMenuItemBool(void); + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemSelect ------------------------------------------------------- +class cRecMenuItemSelect : public cRecMenuItem { +private: + int currentVal; + int *callback; + vector<string> strings; + int numValues; +public: + cRecMenuItemSelect(string text, + vector<string> strings, + int initialVal, + bool active = false, + int *callback = NULL, + eRecMenuState action = rmsNotConsumed); + virtual ~cRecMenuItemSelect(void); + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemText ------------------------------------------------------- +class cRecMenuItemText : public cRecMenuItem { +private: + char *value; + string buffer; + char *callback; + int length; + const char *allowed; + int pos, offset; + bool insert, newchar, uppercase; + int lengthUtf8; + uint *valueUtf8; + uint *allowedUtf8; + uint *charMapUtf8; + uint *currentCharUtf8; + eKeys lastKey; + cTimeMs autoAdvanceTimeout; + uint *IsAllowed(uint c); + void AdvancePos(void); + uint Inc(uint c, bool Up); + void Type(uint c); + void Insert(void); + void Delete(void); + void EnterEditMode(void); + void LeaveEditMode(bool SaveValue = false); + bool InEditMode(void) { return valueUtf8 != NULL; }; + void SetText(void); +public: + cRecMenuItemText(string title, + char *initialVal, + int length, + bool active = false, + char *callback = NULL); + virtual ~cRecMenuItemText(void); + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemTime ------------------------------------------------------- +class cRecMenuItemTime : public cRecMenuItem { +private: + int value; + int *callback; + int mm; + int hh; + int pos; + bool fresh; +public: + cRecMenuItemTime(string text, + int initialVal, + bool active = false, + int *callback = NULL, + eRecMenuState action = rmsNotConsumed); + virtual ~cRecMenuItemTime(void); + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemDay ------------------------------------------------------- +class cRecMenuItemDay : public cRecMenuItem { +private: + time_t currentVal; + time_t *callback; +public: + cRecMenuItemDay(string text, + time_t initialVal, + bool active = false, + time_t *callback = NULL, + eRecMenuState action = rmsNotConsumed); + virtual ~cRecMenuItemDay(void); + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemChannelChooser ------------------------------------------------------- +class cRecMenuItemChannelChooser : public cRecMenuItem { +private: + const cChannel *channel; + int channelNumber; + int *callback; + bool initialChannelSet; + bool fresh; +public: + cRecMenuItemChannelChooser (string text, + const cChannel *initialChannel, + bool active = false, + int *callback = NULL, + eRecMenuState action = rmsNotConsumed); + virtual ~cRecMenuItemChannelChooser(void); + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemDayChooser ------------------------------------------------------- +class cRecMenuItemDayChooser : public cRecMenuItem { +private: + int weekdays; + int *callback; + int selectedDay; + void ToggleDay(void); + bool WeekDaySet(unsigned day); +public: + cRecMenuItemDayChooser (string text, + int weekdays, + bool active = false, + int *callback = NULL); + virtual ~cRecMenuItemDayChooser(void); + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemSelectDirectory ------------------------------------------------------- +class cRecMenuItemSelectDirectory : public cRecMenuItem { +private: + string text; + string originalFolder; + vector<string> folders; + int currentVal; + char *callback; + int numValues; + void SetCallback(void); + int GetInitial(void); +public: + cRecMenuItemSelectDirectory(string text, + string originalFolder, + bool active = false, + char *callback = NULL, + eRecMenuState action = rmsNotConsumed, + bool isSearchTimer = false); + virtual ~cRecMenuItemSelectDirectory(void) {}; + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemTimerConflictHeader ------------------------------------------------------- +class cRecMenuItemTimerConflictHeader: public cRecMenuItem { +private: + time_t conflictStart; + time_t conflictStop; + time_t overlapStart; + time_t overlapStop; +public: + cRecMenuItemTimerConflictHeader(time_t conflictStart, + time_t conflictStop, + time_t overlapStart, + time_t overlapStop); + void SetTokens(skindesignerapi::cViewGrid *menu); + virtual ~cRecMenuItemTimerConflictHeader(void); +}; + +// --- cRecMenuItemTimer ------------------------------------------------------- +class cRecMenuItemTimer : public cRecMenuItem { +private: + const cTimer *timer; + eRecMenuState action2; + eRecMenuState action3; + eRecMenuState action4; + int iconActive; + time_t conflictStart; + time_t conflictStop; + time_t overlapStart; + time_t overlapStop; +public: + cRecMenuItemTimer(const cTimer *timer, + eRecMenuState action1, + eRecMenuState action2, + eRecMenuState action3, + eRecMenuState action4, + time_t conflictStart, + time_t conflictStop, + time_t overlapStart, + time_t overlapStop, + bool active); + virtual ~cRecMenuItemTimer(void); + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemEvent ------------------------------------------------------- +class cRecMenuItemEvent : public cRecMenuItem { +private: + const cEvent *event; + eRecMenuState action2; + int iconActive; +public: + cRecMenuItemEvent(const cEvent *event, + eRecMenuState action1, + eRecMenuState action2, + bool active); + virtual ~cRecMenuItemEvent(void); + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); + const cEvent *GetEvent(void) { return event; }; +}; + +// --- cRecMenuItemRecording ------------------------------------------------------- +class cRecMenuItemRecording : public cRecMenuItem { +private: + const cRecording *recording; +public: + cRecMenuItemRecording(const cRecording *recording, bool active); + virtual ~cRecMenuItemRecording(void) {}; + void SetTokens(skindesignerapi::cViewGrid *menu); +}; + +// --- cRecMenuItemSearchTimer ------------------------------------------------------- +class cRecMenuItemSearchTimer : public cRecMenuItem { +private: + cTVGuideSearchTimer timer; + eRecMenuState action1; + eRecMenuState action2; + eRecMenuState action3; + int iconActive; +public: + cRecMenuItemSearchTimer(cTVGuideSearchTimer timer, + eRecMenuState action1, + eRecMenuState action2, + eRecMenuState action3, + bool active); + virtual ~cRecMenuItemSearchTimer(void); + cTVGuideSearchTimer GetTimer(void) { return timer; }; + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemTimelineHeader ------------------------------------------------------- +class cRecMenuItemTimelineHeader : public cRecMenuItem { +private: + time_t day; + const cTimer *timer; +public: + cRecMenuItemTimelineHeader(time_t day); + virtual ~cRecMenuItemTimelineHeader(void); + void SetTokens(skindesignerapi::cViewGrid *menu); + void SetDay(time_t day) { this->day = day; }; + void SetCurrentTimer(const cTimer *timer) { this->timer = timer; }; + void UnsetCurrentTimer(void) { timer = NULL; }; +}; + +// --- cRecMenuItemTimelineTimer ------------------------------------------------------- +class cRecMenuItemTimelineTimer : public cRecMenuItem { +private: + const cTimer *timer; + time_t start; + time_t stop; +public: + cRecMenuItemTimelineTimer(const cTimer *timer, time_t start, time_t stop, bool active); + virtual ~cRecMenuItemTimelineTimer(void); + void SetTokens(skindesignerapi::cViewGrid *menu); + const cTimer *GetTimer(void); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemFavorite ------------------------------------------------------- +class cRecMenuItemFavorite : public cRecMenuItem { +private: + cTVGuideSearchTimer favorite; + eRecMenuState action1; +public: + cRecMenuItemFavorite(cTVGuideSearchTimer favorite, + eRecMenuState action1, + bool active); + virtual ~cRecMenuItemFavorite(void) {}; + void SetTokens(skindesignerapi::cViewGrid *menu); + cTVGuideSearchTimer GetFavorite(void) { return favorite; }; + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemFavoriteStatic ------------------------------------------------------- +class cRecMenuItemFavoriteStatic : public cRecMenuItem { +private: + string text; +public: + cRecMenuItemFavoriteStatic(string text, eRecMenuState action, bool active); + virtual ~cRecMenuItemFavoriteStatic(void) {}; + void SetTokens(skindesignerapi::cViewGrid *menu); + eRecMenuState ProcessKey(eKeys Key); +}; + #endif //__TVGUIDE_RECMENUITEM_H
\ No newline at end of file @@ -1,1144 +1,1192 @@ -#include <string>
-#include <sstream>
-#include <algorithm>
-#include "config.h"
-#include "services/remotetimers.h"
-#include "helpers.h"
-#include "recmenus.h"
-
-// --- cRecMenuMain ---------------------------------------------------------
-cRecMenuMain::cRecMenuMain(bool epgSearchAvailable, bool timerActive, bool switchTimerActive) {
- SetMenuWidth(50);
- eRecMenuState action = rmsInstantRecord;
- if (!timerActive) {
- if (config.instRecFolderMode == eFolderSelect)
- action = rmsInstantRecordFolder;
- AddMenuItem(new cRecMenuItemButton(tr("Instant Record"), action, true));
- } else {
- AddMenuItem(new cRecMenuItemButton(tr("Delete Timer"), rmsDeleteTimer, true));
- AddMenuItem(new cRecMenuItemButton(tr("Edit Timer"), rmsEditTimer, false));
- }
-
- AddMenuItem(new cRecMenuItemButton(tr("Timer Timeline"), rmsTimeline, false));
-
- if (epgSearchAvailable) {
- AddMenuItem(new cRecMenuItemButton(tr("Create Search Timer"), rmsSearchTimer, false));
- AddMenuItem(new cRecMenuItemButton(tr("Search Timers"), rmsSearchTimers, false));
- }
-
- if (config.instRecFolderMode == eFolderSelect)
- action = rmsSeriesTimerFolder;
- else
- action = rmsSeriesTimer;
- AddMenuItem(new cRecMenuItemButton(tr("Create Series Timer"), action, false));
-
- if (epgSearchAvailable) {
- if (!switchTimerActive) {
- AddMenuItem(new cRecMenuItemButton(tr("Create Switch Timer"), rmsSwitchTimer, false));
- } else {
- AddMenuItem(new cRecMenuItemButton(tr("Delete Switch Timer"), rmsSwitchTimerDelete, false));
- }
- AddMenuItem(new cRecMenuItemButton(tr("Search"), rmsSearch, false));
- }
-
- if (epgSearchAvailable) {
- AddMenuItem(new cRecMenuItemButton(tr("Check for Timer Conflicts"), rmsTimerConflicts, false));
- }
-
- AddMenuItem(new cRecMenuItemButton(tr("Search in Recordings"), rmsRecordingSearch, false));
-};
-
-/******************************************************************************************
-* Instant Timer Menus
-******************************************************************************************/
-
-// --- cRecMenuConfirmTimer ---------------------------------------------------------
-cRecMenuConfirmTimer::cRecMenuConfirmTimer(const cEvent *event) {
- SetMenuWidth(50);
-
- bool eventHasTimer = false;
- if (config.useRemoteTimers && pRemoteTimers) {
- RemoteTimers_GetMatch_v1_0 rtMatch;
- rtMatch.event = event;
- pRemoteTimers->Service("RemoteTimers::GetMatch-v1.0", &rtMatch);
- if (rtMatch.timerMatch == tmFull) {
- eventHasTimer = true;
- }
- } else {
- eventHasTimer = event->HasTimer();
- }
-
- string message;
- if (eventHasTimer) {
- message = tr("Timer created");
- } else {
- message = tr("Timer NOT created");
- }
- cString channelName = Channels.GetByChannelID(event->ChannelID())->Name();
- string datetime = *cString::sprintf("%s %s - %s", *event->GetDateString(), *event->GetTimeString(), *event->GetEndTimeString());
- string eventTitle = event->Title() ? event->Title() : "";
- AddHeader(new cRecMenuItemInfo(message, 4, *channelName, datetime, eventTitle));
- AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true));
-}
-
-// --- cRecMenuAskFolder ---------------------------------------------------------
-cRecMenuAskFolder::cRecMenuAskFolder(const cEvent *event, eRecMenuState nextAction) {
- SetMenuWidth(80);
- this->nextAction = nextAction;
- string message = tr("Set Folder for");
- string eventTitle = event->Title() ? event->Title() : "";
- AddHeader(new cRecMenuItemInfo(message, 2, eventTitle));
- AddMenuItem(new cRecMenuItemButton(tr("root video folder"), nextAction, true));
-
- ReadRecordingDirectories(&folders, NULL, "");
- int numFolders = folders.size();
- for (int i=0; i < numFolders; i++) {
- AddMenuItem(new cRecMenuItemButton(folders[i].c_str(), nextAction, false));
- }
-}
-
-string cRecMenuAskFolder::GetFolder(void) {
- std::string folder = "";
- int folderActive = GetNumActive();
- if (folderActive > 0 && folderActive < (int)folders.size() + 1)
- folder = folders[folderActive - 1];
- return folder;
-}
-
-// --- cRecMenuConfirmDeleteTimer ---------------------------------------------------------
-cRecMenuConfirmDeleteTimer::cRecMenuConfirmDeleteTimer(const cEvent *event) {
- SetMenuWidth(50);
- string message = tr("Timer deleted");
- cString channelName = Channels.GetByChannelID(event->ChannelID())->Name();
- string datetime = *cString::sprintf("%s %s - %s", *event->GetDateString(), *event->GetTimeString(), *event->GetEndTimeString());
- string eventTitle = event->Title() ? event->Title() : "";
-
- AddHeader(new cRecMenuItemInfo(message, 4, *channelName, datetime, eventTitle));
- AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true));
-}
-
-// --- cRecMenuAskDeleteTimer ---------------------------------------------------------
-cRecMenuAskDeleteTimer::cRecMenuAskDeleteTimer(const cEvent *event) {
- SetMenuWidth(50);
- string message = tr("Timer");
- cString channelName = Channels.GetByChannelID(event->ChannelID())->Name();
- string eventTitle = event->Title() ? event->Title() : "";
- string message2 = tr("still recording - really delete?");
-
- AddHeader(new cRecMenuItemInfo(message, 4, *channelName, eventTitle, message2));
- AddMenuItem(new cRecMenuItemButtonYesNo(tr("Yes"), tr("No"), rmsDeleteTimerConfirmation, rmsClose, true));
-}
-
-// --- cRecMenuTimerConflicts ---------------------------------------------------------
-cRecMenuTimerConflicts::cRecMenuTimerConflicts(cTVGuideTimerConflicts *conflicts) {
- SetMenuWidth(80);
- int numConflicts = conflicts->NumConflicts();
-
- string text;
- if (numConflicts == 1) {
- text = *cString::sprintf("%s %s %s", tr("One"), tr("Timer Conflict"), tr("detected"));
- } else {
- text = *cString::sprintf("%d %s %s", conflicts->NumConflicts(), tr("Timer Conflicts"), tr("detected"));
- }
- AddHeader(new cRecMenuItemInfo(text));
-
- for (int i=0; i<numConflicts; i++) {
- cTVGuideTimerConflict *conflict = conflicts->GetConflict(i);
- if (!conflict)
- continue;
- cString dateTime = DayDateTime(conflict->time);
- int numTimers = conflict->timerIDs.size();
- cString textConflict = cString::sprintf("%s: %s (%d %s)", tr("Show conflict"), *dateTime, numTimers, tr("timers involved"));
- bool isActive = (i==0)?true:false;
- AddMenuItem(new cRecMenuItemButton(*textConflict, rmsTimerConflict, isActive));
- }
-
- AddFooter(new cRecMenuItemButton(tr("Ignore Conflicts"), rmsClose, false));
-}
-
-int cRecMenuTimerConflicts::GetTimerConflict(void) {
- return GetNumActive();
-}
-
-// --- cRecMenuTimerConflict ---------------------------------------------------------
-cRecMenuTimerConflict::cRecMenuTimerConflict(cTVGuideTimerConflict *conflict) {
- SetMenuWidth(95);
- this->conflict = conflict;
- AddHeader(new cRecMenuItemTimerConflictHeader(conflict->timeStart,
- conflict->timeStop,
- conflict->overlapStart,
- conflict->overlapStop));
-
- int i=0;
- for(vector<int>::iterator it = conflict->timerIDs.begin(); it != conflict->timerIDs.end(); it++) {
- const cTimer *timer = Timers.Get(*it);
- if (timer) {
- AddMenuItem(new cRecMenuItemTimer(timer,
- rmsTimerConflictShowInfo,
- rmsDeleteTimerConflictMenu,
- rmsEditTimerConflictMenu,
- rmsSearchRerunsTimerConflictMenu,
- conflict->timeStart,
- conflict->timeStop,
- conflict->overlapStart,
- conflict->overlapStop,
- (!i)?true:false));
- i++;
- }
- }
- AddMenuItem(new cRecMenuItemButton(tr("Ignore Conflict"), rmsIgnoreTimerConflict, false));
-}
-
-int cRecMenuTimerConflict::GetTimerConflictIndex(void) {
- return GetNumActive();
-}
-
-// --- cRecMenuNoTimerConflict ---------------------------------------------------------
-cRecMenuNoTimerConflict::cRecMenuNoTimerConflict(void) {
- SetMenuWidth(50);
- string text = tr("No Timer Conflicts found");
- AddHeader(new cRecMenuItemInfo(text));
- AddMenuItem(new cRecMenuItemButton(tr("Close"), rmsClose, true));
-}
-
-// --- cRecMenuRerunResults ---------------------------------------------------------
-cRecMenuRerunResults::cRecMenuRerunResults(const cEvent *original, const cEvent **reruns, int numReruns) {
- this->reruns = reruns;
- this->numReruns = numReruns;
- SetMenuWidth(70);
-
- string message1 = tr("reruns for");
- string message2 = tr("rerun for");
- string message3 = tr("found");
- string line1 = *cString::sprintf("%d %s:", numReruns, (numReruns>1)?(message1.c_str()):(message2.c_str()));
- string line2 = *cString::sprintf("\"%s\" %s", original->Title(), message3.c_str());
-
- AddHeader(new cRecMenuItemInfo(line1, 2, line2));
-
- cRecMenuItem *button = new cRecMenuItemButton(tr("Ignore reruns"), rmsTimerConflictIgnoreReruns, false);
- AddFooter(button);
-
- if (reruns && (numReruns > 0)) {
- for (int i=0; i<numReruns; i++) {
- AddMenuItem(new cRecMenuItemEvent(reruns[i], rmsSearchShowInfo, rmsTimerConflictRecordRerun, (i==0)?true:false));
- }
- }
-}
-
-int cRecMenuRerunResults::GetTotalNumMenuItems(void) {
- return numReruns;
-}
-
-const cEvent *cRecMenuRerunResults::GetEvent(void) {
- cRecMenuItemEvent *activeItem = dynamic_cast<cRecMenuItemEvent*>(GetActive());
- if (activeItem)
- return activeItem->GetEvent();
- return NULL;
-}
-
-// --- cRecMenuNoRerunsFound ---------------------------------------------------------
-cRecMenuNoRerunsFound::cRecMenuNoRerunsFound(string searchString) {
- SetMenuWidth(50);
- string message = tr("No reruns found for Event");
- string eventQuoted = *cString::sprintf("\"%s\"", searchString.c_str());
-
- AddHeader(new cRecMenuItemInfo(message, 2, eventQuoted));
- AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true));
-}
-
-// --- cRecMenuConfirmRerunUsed ---------------------------------------------------------
-cRecMenuConfirmRerunUsed::cRecMenuConfirmRerunUsed(const cEvent *original, const cEvent *replace) {
- SetMenuWidth(70);
- cString channelOrig = Channels.GetByChannelID(original->ChannelID())->Name();
- cString channelReplace = Channels.GetByChannelID(replace->ChannelID())->Name();
- string line1 = *cString::sprintf("%s \"%s\"", tr("Timer for"), original->Title());
- string line2 = *cString::sprintf("%s %s %s", *original->GetDateString(), *original->GetTimeString(), *channelOrig);
- string line3 = *cString::sprintf("%s \"%s\"", tr("replaced by rerun"), replace->Title());
- string line4 = *cString::sprintf("%s %s %s", *replace->GetDateString(), *replace->GetTimeString(), *channelReplace);
-
- AddHeader(new cRecMenuItemInfo(line1, 4, line2, line3, line4));
- AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsTimerConflicts, true));
-}
-
-// --- cRecMenuEditTimer ---------------------------------------------------------
-cRecMenuEditTimer::cRecMenuEditTimer(cTimer *timer, eRecMenuState nextState) {
- SetMenuWidth(70);
- if (!timer)
- return;
- originalTimer = timer;
- string title = "";
- string channelName = "";
- if (timer->Event() && timer->Event()->Title())
- title = timer->Event()->Title();
- if (timer->Channel() && timer->Channel()->Name())
- channelName = timer->Channel()->Name();
- cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(tr("Edit Timer"), 3, title, channelName);
- AddHeader(infoItem);
-
- timerActive = false;
- if (config.useRemoteTimers && pRemoteTimers) {
- RemoteTimers_GetMatch_v1_0 rtMatch;
- rtMatch.event = timer->Event();
- pRemoteTimers->Service("RemoteTimers::GetMatch-v1.0", &rtMatch);
- if (rtMatch.timer) {
- if (rtMatch.timerMatch == tmFull)
- timerActive = true;
- }
- } else
- timerActive = timer->HasFlags(tfActive);
-
- day = timer->Day();
- start = timer->Start();
- stop = timer->Stop();
- prio = timer->Priority();
- lifetime = timer->Lifetime();
- strncpy(folder, GetDirectoryFromTimer(timer->File()).c_str(), TEXTINPUTLENGTH);
-
- AddMenuItem(new cRecMenuItemBool(tr("Timer Active"), timerActive, true, &timerActive));
- AddMenuItem(new cRecMenuItemInt(tr("Priority"), prio, 0, MAXPRIORITY, false, &prio));
- AddMenuItem(new cRecMenuItemInt(tr("Lifetime"), lifetime, 0, MAXLIFETIME, false, &lifetime));
- AddMenuItem(new cRecMenuItemDay(tr("Day"), day, false, &day));
- AddMenuItem(new cRecMenuItemTime(tr("Timer start time"), start, false, &start));
- AddMenuItem(new cRecMenuItemTime(tr("Timer stop time"), stop, false, &stop));
- AddMenuItem(new cRecMenuItemInfo(tr("Timer File"), 2, timer->File() ? timer->File() : ""));
- AddMenuItem(new cRecMenuItemSelectDirectory(tr("New Folder"), string(folder), false, folder));
- if (nextState == rmsTimelineTimerSave) {
- AddMenuItem(new cRecMenuItemButton(tr("Delete Timer"), rmsTimelineTimerDelete, false));
- AddFooter(new cRecMenuItemButtonYesNo(tr("Save"), tr("Cancel"), nextState, rmsTimeline, false));
- } else {
- AddFooter(new cRecMenuItemButtonYesNo(tr("Save"), tr("Cancel"), nextState, rmsClose, false));
- }
-}
-
-cTimer *cRecMenuEditTimer::GetOriginalTimer(void) {
- return originalTimer;
-}
-
-cTimer cRecMenuEditTimer::GetTimer(void) {
- cTimer t;
- if (timerActive)
- t.SetFlags(tfActive);
- else
- t.SetFlags(tfNone);
- t.SetDay(day);
- t.SetStart(start);
- t.SetStop(stop);
- t.SetPriority(prio);
- t.SetLifetime(lifetime);
- string newFolder(folder);
- string newFile = originalTimer->File();
- size_t found = newFile.find_last_of('~');
- if (found != string::npos) {
- string fileName = newFile.substr(found+1);
- if (newFolder.size() > 0)
- newFile = *cString::sprintf("%s~%s", newFolder.c_str(), fileName.c_str());
- else
- newFile = fileName;
- } else {
- if (newFolder.size() > 0)
- newFile = *cString::sprintf("%s~%s", newFolder.c_str(), newFile.c_str());
- }
- std::replace(newFile.begin(), newFile.end(), '/', '~');
- t.SetFile(newFile.c_str());
- return t;
-}
-
-/******************************************************************************************
-* Series Timer Menus
-******************************************************************************************/
-
-// --- cRecMenuSeriesTimer ---------------------------------------------------------
-cRecMenuSeriesTimer::cRecMenuSeriesTimer(cChannel *initialChannel, const cEvent *event, string folder) {
- if (!initialChannel)
- return;
- timerActive = true;
- channel = initialChannel->Number();
- dayOfWeek = 127;
- priority = MAXPRIORITY;
- lifetime = MAXLIFETIME;
- CalculateTimes(event);
- this->folder = folder;
-
- SetMenuWidth(70);
- string line1 = tr("Create Series Timer based on");
- string line2 = *cString::sprintf("\"%s\"", event->Title());
- AddHeader(new cRecMenuItemInfo(line1, 2, line2));
-
- AddMenuItem(new cRecMenuItemBool(tr("Timer Active"), timerActive, false, &timerActive));
- AddMenuItem(new cRecMenuItemChannelChooser(tr("Channel"), initialChannel, false, &channel));
- AddMenuItem(new cRecMenuItemTime(tr("Series Timer start time"), start, false, &start));
- AddMenuItem(new cRecMenuItemTime(tr("Series Timer stop time"), stop, false, &stop));
- AddMenuItem(new cRecMenuItemDayChooser(tr("Days to record"), dayOfWeek, false, &dayOfWeek));
- AddMenuItem(new cRecMenuItemDay(tr("Day to start"), tstart, false, &tstart));
- AddMenuItem(new cRecMenuItemInt(tr("Priority"), priority, 0, MAXPRIORITY, false, &priority));
- AddMenuItem(new cRecMenuItemInt(tr("Lifetime"), lifetime, 0, MAXLIFETIME, false, &lifetime));
-
- AddFooter(new cRecMenuItemButtonYesNo(tr("Create Timer"), tr("Cancel"), rmsSeriesTimerCreate, rmsClose, true));
-}
-
-cTimer *cRecMenuSeriesTimer::GetTimer(void) {
- cChannel *chan = Channels.GetByNumber(channel);
- cTimer *seriesTimer = new cTimer(NULL, NULL, chan);
- cString fileName = "TITLE EPISODE";
- if (folder.size() > 0) {
- std::replace(folder.begin(), folder.end(), '/', '~');
- fileName = cString::sprintf("%s~%s", folder.c_str(), *fileName);
- }
- seriesTimer->SetDay(tstart);
- seriesTimer->SetStart(start);
- seriesTimer->SetStop(stop);
- seriesTimer->SetPriority(priority);
- seriesTimer->SetLifetime(lifetime);
- seriesTimer->SetWeekDays(dayOfWeek);
- seriesTimer->SetFile(*fileName);
- if (timerActive)
- seriesTimer->SetFlags(tfActive);
- else
- seriesTimer->SetFlags(tfNone);
- return seriesTimer;
-}
-
-void cRecMenuSeriesTimer::CalculateTimes(const cEvent *event) {
- tstart = event->StartTime();
- tstart -= Setup.MarginStart * 60;
- time_t tstop = tstart + event->Duration();
- tstop += Setup.MarginStop * 60;
-
- struct tm tm_r;
- struct tm *time = localtime_r(&tstart, &tm_r);
- start = time->tm_hour * 100 + time->tm_min;
- time = localtime_r(&tstop, &tm_r);
- stop = time->tm_hour * 100 + time->tm_min;
- if (stop >= 2400)
- stop -= 2400;
-}
-
-// --- cRecMenuConfirmSeriesTimer ---------------------------------------------------------
-cRecMenuConfirmSeriesTimer::cRecMenuConfirmSeriesTimer(cTimer *seriesTimer) {
- SetMenuWidth(50);
- string line1 = tr("Series Timer created");
- string line2 = "";
- if (seriesTimer) {
- cString days = cTimer::PrintDay(seriesTimer->Day(), seriesTimer->WeekDays(), true);
- line2 = cString::sprintf("%s, %s: %s, %s: %s", *days, tr("Start"), *TimeString(seriesTimer->StartTime()), tr("Stop"), *TimeString(seriesTimer->StopTime()));
- }
- AddHeader(new cRecMenuItemInfo(line1, 2, line2));
- AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true));
-}
-
-/******************************************************************************************
-* SearchTimer Menus
-******************************************************************************************/
-
-// --- cRecMenuSearchTimer ---------------------------------------------------------
-cRecMenuSearchTimer::cRecMenuSearchTimer(const cEvent *event) {
- SetMenuWidth(70);
- string message = tr("Configure Search Timer based on");
- string infoText = *cString::sprintf("\"%s\"", event->Title());
- AddHeader(new cRecMenuItemInfo(message, 2, infoText));
- strncpy(searchString, event->Title(), TEXTINPUTLENGTH);
- AddMenuItem(new cRecMenuItemText(tr("Search Expression:"), searchString, TEXTINPUTLENGTH, false));
- AddFooter(new cRecMenuItemButtonYesNo(tr("Continue"), tr("Cancel"), rmsSearchTimerOptions, rmsClose, true));
-}
-
-// --- cRecMenuSearchTimerTemplates ---------------------------------------------------------
-cRecMenuSearchTimerTemplates::cRecMenuSearchTimerTemplates(cTVGuideSearchTimer searchTimer, vector<TVGuideEPGSearchTemplate> templates) {
- SetMenuWidth(70);
- this->searchTimer = searchTimer;
- this->templates = templates;
- string message = tr("Configure Search Timer for Search String");
- AddHeader(new cRecMenuItemInfo(message, 2, searchTimer.SearchString()));
- AddMenuItem(new cRecMenuItemButton(tr("Manually configure Options"), rmsSearchTimerEdit, true));
-
- numTemplates = templates.size();
- for (int i=0; i<numTemplates; i++) {
- string buttonText = *cString::sprintf("%s \"%s\"", tr("Use Template"), templates[i].name.c_str());
- AddMenuItem(new cRecMenuItemButton(buttonText, rmsSearchTimerCreateWithTemplate, false));
- }
-}
-
-TVGuideEPGSearchTemplate cRecMenuSearchTimerTemplates::GetTemplate(void) {
- TVGuideEPGSearchTemplate templ;
- int tmplActive = GetNumActive() - 1;
- if (tmplActive >= 0 && tmplActive < (int)templates.size())
- templ = templates[tmplActive];
- return templ;
-}
-
-// --- cRecMenuSearchTimers ---------------------------------------------------------
-cRecMenuSearchTimers::cRecMenuSearchTimers(std::vector<cTVGuideSearchTimer> searchTimers) {
- SetMenuWidth(70);
- this->searchTimers = searchTimers;
- numSearchTimers = searchTimers.size();
- string headline;
- if (numSearchTimers > 0) {
- headline = tr("EPGSearch Search Timers");
- } else {
- headline = tr("No Search Timers Configured");
- }
- AddHeader(new cRecMenuItemInfo(headline));
- cRecMenuItem *button = new cRecMenuItemButton(tr("Close"), rmsClose, (!numSearchTimers)?true:false);
- if (numSearchTimers > 0) {
- SetMenuItems();
- AddFooter(button);
- } else {
- AddMenuItem(button);
- }
-}
-
-void cRecMenuSearchTimers::SetMenuItems(void) {
- for (int i = 0; i < numSearchTimers; i++) {
- AddMenuItem(new cRecMenuItemSearchTimer(searchTimers[i], rmsSearchTimerTest, rmsSearchTimerEdit, rmsSearchTimerDeleteConfirm, (i==0)?true:false));
- }
-}
-
-cTVGuideSearchTimer cRecMenuSearchTimers::GetSearchTimer(void) {
- cRecMenuItemSearchTimer *activeItem = dynamic_cast<cRecMenuItemSearchTimer*>(GetActive());
- return activeItem->GetTimer();
-}
-
-// --- cRecMenuSearchTimerEdit ---------------------------------------------------------
-cRecMenuSearchTimerEdit::cRecMenuSearchTimerEdit(cTVGuideSearchTimer searchTimer, bool advancedOptions) {
- this->advancedOptions = advancedOptions;
- this->searchTimer = searchTimer;
- strncpy(searchString, searchTimer.SearchString().c_str(), TEXTINPUTLENGTH);
- timerActive = searchTimer.Active();
- mode = searchTimer.SearchMode();
- useTitle = searchTimer.UseTitle();
- useSubtitle = searchTimer.UseSubtitle();
- useDescription = searchTimer.UseDescription();
- useChannel = searchTimer.UseChannel();
- startChannel = searchTimer.StartChannel();
- stopChannel = searchTimer.StopChannel();
- useTime = searchTimer.UseTime();
- startTime = searchTimer.StartTime();
- stopTime = searchTimer.StopTime();
- useDayOfWeek = searchTimer.UseDayOfWeek();
- dayOfWeek = searchTimer.DayOfWeek();
- priority = searchTimer.Priority();
- lifetime = searchTimer.Lifetime();
- useEpisode = searchTimer.UseEpisode();
- std::string dir = searchTimer.Directory();
- strncpy(directory, dir.c_str(), TEXTINPUTLENGTH);
- marginStart = searchTimer.MarginStart();
- marginStop = searchTimer.MarginStop();
- useVPS = searchTimer.UseVPS();
- avoidRepeats = searchTimer.AvoidRepeats();
- allowedRepeats = searchTimer.AllowedRepeats();
- compareTitle = searchTimer.CompareTitle();
- compareSubtitle = searchTimer.CompareSubtitle();
- compareSummary = searchTimer.CompareSummary();
- useInFavorites = searchTimer.UseInFavorites();
-
- SetMenuWidth(70);
- string infoText;
- if (searchTimer.GetID() > -1) {
- infoText = tr("Configure Search Timer Options");
- } else {
- infoText = tr("Create Search Timer");
- }
- AddHeader(new cRecMenuItemInfo(infoText));
- cRecMenuItemButtonYesNo *footerButton = new cRecMenuItemButtonYesNo(tr("Save Search Timer"), tr("Cancel"), rmsSearchTimerSave, rmsSearchTimers, false);
- AddFooter(footerButton);
- CreateMenuItems();
-}
-
-void cRecMenuSearchTimerEdit::CreateMenuItems(void) {
- AddMenuItem(new cRecMenuItemText(tr("Search String"), searchString, TEXTINPUTLENGTH, true, searchString));
- AddMenuItem(new cRecMenuItemBool(tr("Active"), timerActive, false, &timerActive, rmsSearchTimerSave));
- vector<string> searchModes;
- searchTimer.GetSearchModes(&searchModes);
- esyslog("tvguideng: num search modes %ld", searchModes.size());
- AddMenuItem(new cRecMenuItemSelect(tr("Search Mode"), searchModes, mode, false, &mode, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemBool(tr("Use Title"), useTitle, false, &useTitle, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemBool(tr("Use Subtitle"), useSubtitle, false, &useSubtitle, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemBool(tr("Use Description"), useDescription, false, &useDescription, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemBool(tr("Limit Channels"), useChannel, false, &useChannel, rmsSearchTimerSave));
- if (startChannel == 0)
- startChannel = 1;
- if (stopChannel == 0)
- stopChannel = 1;
- AddMenuItem(new cRecMenuItemChannelChooser(tr("Start Channel"), Channels.GetByNumber(startChannel), false, &startChannel, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemChannelChooser(tr("Stop Channel"), Channels.GetByNumber(stopChannel), false, &stopChannel, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemBool(tr("Use Time"), useTime, false, &useTime, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemTime(tr("Start after"), startTime, false, &startTime, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemTime(tr("Start before"), stopTime, false, &stopTime, rmsSearchTimerSave));
-
- if (!advancedOptions) {
- AddMenuItem(new cRecMenuItemButton(tr("Display advanced Options"), rmsSearchTimerEditAdvanced, false));
- } else {
- AddMenuItem(new cRecMenuItemBool(tr("Limit Days of the Week"), useDayOfWeek, false, &useDayOfWeek, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemDayChooser(tr("Select Days"), dayOfWeek, false, &dayOfWeek));
- AddMenuItem(new cRecMenuItemInt(tr("Priority"), priority, 0, 99, false, &priority, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemInt(tr("Lifetime"), lifetime, 0, 99, false, &lifetime, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemInt(tr("Time margin for start in minutes"), marginStart, 0, 30, false, &marginStart, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemInt(tr("Time margin for stop in minutes"), marginStop, 0, 30, false, &marginStop, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemBool(tr("Series Recording"), useEpisode, false, &useEpisode, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemSelectDirectory(tr("Folder"), string(directory), false, directory, rmsSearchTimerSave, true));
- AddMenuItem(new cRecMenuItemBool(tr("Use VPS"), useVPS, false, &useVPS, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemBool(tr("Avoid Repeats"), avoidRepeats, false, &avoidRepeats, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemInt(tr("Number of allowed repeats"), allowedRepeats, 0, 30, false, &allowedRepeats, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemBool(tr("Compare Title"), compareTitle, false, &compareTitle, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemBool(tr("Compare Subtitle"), compareSubtitle, false, &compareSubtitle, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemBool(tr("Compare Description"), compareSummary, false, &compareSummary, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemBool(tr("Use in Favorites"), useInFavorites, false, &useInFavorites, rmsSearchTimerSave));
- AddMenuItem(new cRecMenuItemButton(tr("Hide advanced Options"), rmsSearchTimerEdit, false));
- }
-
- AddMenuItem(new cRecMenuItemButton(tr("Display Results for Search Timer"), rmsSearchTimerTest, false));
-}
-
-cTVGuideSearchTimer cRecMenuSearchTimerEdit::GetSearchTimer(void) {
- searchTimer.SetSearchString(searchString);
- searchTimer.SetActive(timerActive);
- searchTimer.SetSearchMode(mode);
- searchTimer.SetUseTitle(useTitle);
- searchTimer.SetUseSubtitle(useSubtitle);
- searchTimer.SetUseDesription(useDescription);
- searchTimer.SetUseChannel(useChannel);
- if (useChannel) {
- searchTimer.SetStartChannel(startChannel);
- searchTimer.SetStopChannel(stopChannel);
- }
- searchTimer.SetUseTime(useTime);
- if (useTime) {
- searchTimer.SetStartTime(startTime);
- searchTimer.SetStopTime(stopTime);
- }
- searchTimer.SetUseDayOfWeek(useDayOfWeek);
- if (useDayOfWeek) {
- searchTimer.SetDayOfWeek(dayOfWeek);
- }
- searchTimer.SetPriority(priority);
- searchTimer.SetLifetime(lifetime);
- searchTimer.SetUseEpisode(useEpisode);
- string dir(directory);
- std::replace(dir.begin(), dir.end(), '/', '~');
- searchTimer.SetDirectory(dir);
- searchTimer.SetMarginStart(marginStart);
- searchTimer.SetMarginStop(marginStop);
- searchTimer.SetUseVPS(useVPS);
- searchTimer.SetAvoidRepeats(avoidRepeats);
- if (avoidRepeats) {
- searchTimer.SetAllowedRepeats(allowedRepeats);
- searchTimer.SetCompareTitle(compareTitle);
- searchTimer.SetCompareSubtitle(compareSubtitle);
- searchTimer.SetCompareSummary(compareSummary);
- }
- searchTimer.SetUseInFavorites(useInFavorites);
- return searchTimer;
-}
-
-// --- cRecMenuSearchTimerDeleteConfirm ---------------------------------------------
-cRecMenuSearchTimerDeleteConfirm::cRecMenuSearchTimerDeleteConfirm(cTVGuideSearchTimer searchTimer) {
- SetMenuWidth(70);
- this->searchTimer = searchTimer;
- string line1 = tr("Really delete Search Timer");
- string line2 = *cString::sprintf("\"%s\"?", searchTimer.SearchString().c_str());
- AddHeader(new cRecMenuItemInfo(line1, 2, line2));
- AddMenuItem(new cRecMenuItemButton(tr("Delete only Search Timer"), rmsSearchTimerDelete, true));
- AddMenuItem(new cRecMenuItemButton(tr("Delete Search Timer and created Timers"), rmsSearchTimerDeleteWithTimers, false));
- AddFooter(new cRecMenuItemButton(tr("Cancel"), rmsClose, false));
-}
-
-cTVGuideSearchTimer cRecMenuSearchTimerDeleteConfirm::GetSearchTimer(void) {
- return searchTimer;
-}
-
-// --- cRecMenuSearchTimerCreateConfirm ---------------------------------------------------------
-cRecMenuSearchTimerCreateConfirm::cRecMenuSearchTimerCreateConfirm(bool success) {
- SetMenuWidth(50);
- cRecMenuItemInfo *infoItem = NULL;
- if (success) {
- string line1 = tr("Search Timer sucessfully created");
- string line2 = tr("Search Timer update initialised");
- infoItem = new cRecMenuItemInfo(line1, 2, line2);
- } else {
- string line1 = tr("Search Timer NOT sucessfully created");
- infoItem = new cRecMenuItemInfo(line1);
- }
- AddHeader(infoItem);
- AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true));
-}
-
-// --- cRecMenuSearchTimerTemplatesCreate ---------------------------------------------------------
-cRecMenuSearchTimerTemplatesCreate::cRecMenuSearchTimerTemplatesCreate(TVGuideEPGSearchTemplate templ, cTVGuideSearchTimer searchTimer) {
- SetMenuWidth(70);
- this->templ = templ;
- this->searchTimer = searchTimer;
-
- string line1 = tr("Creating Search Timer");
- string line2 = *cString::sprintf("%s: \"%s\"", tr("Search Term"), searchTimer.SearchString().c_str());
- string line3 = *cString::sprintf("%s \"%s\"", tr("Using Template"), templ.name.c_str());
-
- AddHeader(new cRecMenuItemInfo(line1, 3, line2, line3));
- AddMenuItem(new cRecMenuItemButton(tr("Display Results for Search Timer"), rmsSearchTimerTest, true));
- AddMenuItem(new cRecMenuItemButtonYesNo(tr("Create Search Timer"), tr("Use other Template"), rmsSearchTimerSave, rmsSearchTimerOptions, false));
-}
-
-
-// --- cRecMenuSearchTimerResults ---------------------------------------------------------
-cRecMenuSearchTimerResults::cRecMenuSearchTimerResults(string searchString, const cEvent **searchResults, int numResults, string templateName, eRecMenuState action2) {
- SetMenuWidth(70);
- this->searchResults = searchResults;
- this->action2 = action2;
- this->numResults = numResults;
- string message1 = "", message2 = "", message3 = "";
- if (action2 == rmsFavoritesRecord) {
- message1 = tr("search results for Favorite");
- message2 = tr("search result for Favorite");
- } else {
- message1 = tr("search results for Search Timer");
- message2 = tr("search result for Search Timer");
- message3 = tr("Using Template");
- }
- cRecMenuItem *infoItem = NULL;
- if (templateName.size() > 0) {
- string line1 = *cString::sprintf("%d %s:", numResults, (numResults>1)?(message1.c_str()):(message2.c_str()));
- string line2 = *cString::sprintf("\"%s\"", searchString.c_str());
- string line3 = *cString::sprintf("%s \"%s\"", message3.c_str(), templateName.c_str());
- infoItem = new cRecMenuItemInfo(line1, 3, line2, line3);
- } else {
- string line1 = *cString::sprintf("%d %s:", numResults, (numResults>1)?(message1.c_str()):(message2.c_str()));
- string line2 = *cString::sprintf("\"%s\"", searchString.c_str());
- infoItem = new cRecMenuItemInfo(line1, 2, line2);
- }
- AddHeader(infoItem);
-
- cRecMenuItem *button = new cRecMenuItemButton(tr("Close"), rmsClose, false);
- if (searchResults && (numResults > 0)) {
- for (int i=0; i<numResults; i++) {
- AddMenuItem(new cRecMenuItemEvent(searchResults[i], rmsSearchShowInfo, action2, (i==0)?true:false));
- }
- AddFooter(button);
- } else {
- AddMenuItem(button);
- }
-}
-
-const cEvent *cRecMenuSearchTimerResults::GetEvent(void) {
- const cEvent *ev = NULL;
- if (cRecMenuItemEvent *activeItem = dynamic_cast<cRecMenuItemEvent*>(GetActive()))
- ev = activeItem->GetEvent();
- return ev;
-}
-
-// --- cRecMenuSearchTimerNothingFound ---------------------------------------------------------
-cRecMenuSearchTimerNothingFound::cRecMenuSearchTimerNothingFound(string searchString) {
- SetMenuWidth(50);
- string line1 = tr("Nothing found for Search String");
- string line2 = *cString::sprintf("\"%s\"", searchString.c_str());
- AddHeader(new cRecMenuItemInfo(line1, 2, line2));
- AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true));
-}
-
-/******************************************************************************************
-* SwitchTimer Menus
-******************************************************************************************/
-
-// --- cRecMenuSwitchTimer ---------------------------------------------------------
-cRecMenuSwitchTimer::cRecMenuSwitchTimer(void) {
- SetMenuWidth(60);
- switchMinsBefore = config.switchMinsBefore;
- announceOnly = 0;
-
- AddHeader(new cRecMenuItemInfo(tr("Configure Options for Switchtimer")));
- AddMenuItem(new cRecMenuItemInt(tr("Minutes before switching"), switchMinsBefore, 0, 10, false, &switchMinsBefore));
- vector<string> switchModes;
- switchModes.push_back(tr("switch"));
- switchModes.push_back(tr("announce only"));
- switchModes.push_back(tr("ask for switch"));
- AddMenuItem(new cRecMenuItemSelect(tr("Switch Mode"), switchModes, announceOnly, false, &announceOnly));
-
- AddFooter(new cRecMenuItemButtonYesNo(tr("Create"), tr("Cancel"), rmsSwitchTimerCreate, rmsClose, true));
-}
-
-cSwitchTimer cRecMenuSwitchTimer::GetSwitchTimer(void) {
- cSwitchTimer st;
- st.switchMinsBefore = switchMinsBefore;
- st.announceOnly = announceOnly;
- return st;
-}
-
-// --- cRecMenuSwitchTimerConfirm ---------------------------------------------------------
-cRecMenuSwitchTimerConfirm::cRecMenuSwitchTimerConfirm(bool success) {
- SetMenuWidth(50);
- string message1 = tr("Switch Timer sucessfully created");
- string message2 = tr("Switch Timer NOT sucessfully created");
- string infoText = success?message1:message2;
- AddHeader(new cRecMenuItemInfo(infoText));
- AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true));
-}
-
-// --- cRecMenuSwitchTimerDelete ---------------------------------------------------------
-cRecMenuSwitchTimerDelete::cRecMenuSwitchTimerDelete(void) {
- SetMenuWidth(50);
- AddHeader(new cRecMenuItemInfo(tr("Switch Timer deleted")));
- AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true));
-}
-
-/******************************************************************************************
-* Search Menus
-******************************************************************************************/
-
-// --- cRecMenuSearch ---------------------------------------------------------
-cRecMenuSearch::cRecMenuSearch(string searchString, bool withOptions) {
- SetMenuWidth(60);
- strncpy(this->searchString, searchString.c_str(), TEXTINPUTLENGTH);
- mode = 0;
- channelNr = 0;
- useTitle = true;
- useSubTitle = true;
- useDescription = false;
-
- AddHeader(new cRecMenuItemInfo(tr("Search")));
- AddMenuItem(new cRecMenuItemText(tr("Search Expression:"), this->searchString, TEXTINPUTLENGTH, false, this->searchString));
-
- if (withOptions) {
- vector<string> searchModes;
- cTVGuideSearchTimer searchTimer;
- searchTimer.GetSearchModes(&searchModes);
- AddMenuItem(new cRecMenuItemSelect(tr("Search Mode"), searchModes, 0, false, &mode));
- AddMenuItem(new cRecMenuItemChannelChooser(tr("Channel to Search"), NULL, false, &channelNr));
- AddMenuItem(new cRecMenuItemBool(tr("Search in title"), true, false, &useTitle));
- AddMenuItem(new cRecMenuItemBool(tr("Search in Subtitle"), true, false, &useSubTitle));
- AddMenuItem(new cRecMenuItemBool(tr("Search in Description"), false, false, &useDescription));
- } else {
- AddMenuItem(new cRecMenuItemButton(tr("Show Search Options"), rmsSearchWithOptions, false));
- }
-
- cRecMenuItemButtonYesNo *button = new cRecMenuItemButtonYesNo(tr("Perform Search"), tr("Cancel"), rmsSearchPerform, rmsClose, true);
- AddFooter(button);
-}
-
-Epgsearch_searchresults_v1_0 cRecMenuSearch::GetEPGSearchStruct(void) {
- Epgsearch_searchresults_v1_0 data;
- data.query = searchString;
- data.mode = mode;
- data.channelNr = channelNr;
- data.useTitle = useTitle;
- data.useSubTitle = useSubTitle;
- data.useDescription = useDescription;
- return data;
-}
-
-// --- cRecMenuSearchResults ---------------------------------------------------------
-cRecMenuSearchResults::cRecMenuSearchResults(string searchString, const cEvent **searchResults, int numResults) {
- this->searchResults = searchResults;
- SetMenuWidth(70);
- this->searchString = searchString;
- this->numResults = numResults;
-
- string message = "";
- if (numResults > 1) {
- message = *cString::sprintf("%d %s", numResults, tr("search results for"));
- } else {
- message = *cString::sprintf("%d %s", numResults, tr("search result for"));
- }
- string searchStringQuoted = *cString::sprintf("\"%s\"", searchString.c_str());
- AddHeader(new cRecMenuItemInfo(message, 2, searchStringQuoted));
-
- cRecMenuItem *buttons = new cRecMenuItemButtonYesNo(tr("Adapt Search"), tr("Close"), rmsSearch, rmsClose, false);
- AddFooter(buttons);
- if (searchResults && (numResults > 0)) {
- for (int i=0; i<numResults; i++) {
- AddMenuItem(new cRecMenuItemEvent(searchResults[i], rmsSearchShowInfo, rmsSearchRecord, (i==0)?true:false));
- }
- }
-}
-
-const cEvent *cRecMenuSearchResults::GetEvent(void) {
- cRecMenuItemEvent *activeItem = dynamic_cast<cRecMenuItemEvent*>(GetActive());
- if (activeItem)
- return activeItem->GetEvent();
- return NULL;
-}
-
-// --- cRecMenuSearchNothingFound ---------------------------------------------------------
-cRecMenuSearchNothingFound::cRecMenuSearchNothingFound(string searchString, bool tooShort) {
- SetMenuWidth(50);
- string text;
- if (!tooShort) {
- cString message = tr("Nothing found for Search String");
- text = *cString::sprintf("%s\n\"%s\"",
- *message,
- searchString.c_str());
- } else {
- cString message = tr("Search String has to have at least three letters");
- text = *cString::sprintf("%s\n\"%s\"",
- *message,
- searchString.c_str());
-
- }
- AddHeader(new cRecMenuItemInfo(text));
- AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true));
-}
-
-// --- cRecMenuSearchConfirmTimer ---------------------------------------------------------
-cRecMenuSearchConfirmTimer::cRecMenuSearchConfirmTimer(const cEvent *event) {
- SetMenuWidth(50);
-
- string message = tr("Timer created");
- cString channelName = Channels.GetByChannelID(event->ChannelID())->Name();
- string line3 = *cString::sprintf("%s %s - %s", *event->GetDateString(), *event->GetTimeString(), *event->GetEndTimeString());
- string line4 = event->Title() ? event->Title() : "";
-
- AddHeader(new cRecMenuItemInfo(message, 4, *channelName, line3, line4));
- AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true));
-}
-
-/******************************************************************************************
-* Timeline
-******************************************************************************************/
-
-// --- cRecMenuTimeline ---------------------------------------------------------
-cRecMenuTimeline::cRecMenuTimeline(void) {
- SetMenuWidth(95);
- SetStartStop();
- GetTimersForDay();
-
- timelineHeader = new cRecMenuItemTimelineHeader(timeStart);
- AddHeader(timelineHeader);
-
- timelineFooter = new cRecMenuItemButton(tr("Close"), rmsClose, false);
- AddFooter(timelineFooter);
- SetTimers();
-}
-
-void cRecMenuTimeline::SetHeaderTimer(void) {
- cTimer *currentTimer = NULL;
- cRecMenuItem *currentItem = GetActive();
- if (!currentItem) {
- timelineHeader->UnsetCurrentTimer();
- return;
- }
- if (cRecMenuItemTimelineTimer *myActiveItem = dynamic_cast<cRecMenuItemTimelineTimer*>(currentItem)) {
- currentTimer = myActiveItem->GetTimer();
- }
- timelineHeader->SetCurrentTimer(currentTimer);
- timelineHeader->SetNew();
-}
-
-void cRecMenuTimeline::SetStartStop(void) {
- time_t now = time(0);
- tm *timeStruct = localtime(&now);
- timeStart = now - timeStruct->tm_hour * 3600 - timeStruct->tm_min * 60 - timeStruct->tm_sec;
- today = timeStart;
- timeStop = timeStart + 24*3600 - 1;
-}
-
-void cRecMenuTimeline::GetTimersForDay(void) {
- timersToday.clear();
- for (cTimer *t = Timers.First(); t; t = Timers.Next(t)) {
- if (((t->StartTime() > timeStart) && (t->StartTime() <= timeStop)) || ((t->StopTime() > timeStart) && (t->StopTime() <= timeStop))) {
- timersToday.push_back(t);
- }
- }
- numTimersToday = timersToday.size();
-}
-
-void cRecMenuTimeline::SetTimers(void) {
- if (numTimersToday == 0) {
- AddMenuItem(new cRecMenuItemInfo(tr("No active Timers")));
- timelineFooter->SetActive();
- } else {
- for (int i=0; i<numTimersToday; i++) {
- AddMenuItem(new cRecMenuItemTimelineTimer(timersToday[i], timeStart, timeStop, (i==0)?true:false));
- }
- timelineFooter->SetInactive();
- }
-}
-
-void cRecMenuTimeline::PrevDay(void) {
- if ((timeStart - 3600*24) < today)
- return;
- timeStart -= 3600*24;
- timeStop -= 3600*24;
- ClearMenuItems(true);
- GetTimersForDay();
- SetTimers();
- InitMenuItems();
- SetHeaderTimer();
- timelineHeader->SetDay(timeStart);
- timelineHeader->SetNew();
-}
-
-void cRecMenuTimeline::NextDay(void) {
- timeStart += 3600*24;
- timeStop += 3600*24;
- ClearMenuItems(true);
- GetTimersForDay();
- SetTimers();
- InitMenuItems();
- SetHeaderTimer();
- timelineHeader->SetDay(timeStart);
- timelineHeader->SetNew();
-}
-
-cTimer *cRecMenuTimeline::GetTimer(void) {
- if (cRecMenuItemTimelineTimer *activeItem = dynamic_cast<cRecMenuItemTimelineTimer*>(GetActive()))
- return activeItem->GetTimer();
- return NULL;
-}
-
-
-eRecMenuState cRecMenuTimeline::ProcessKey(eKeys Key) {
- eRecMenuState state = rmsContinue;
- switch (Key & ~k_Repeat) {
- case kLeft:
- PrevDay();
- Draw();
- break;
- state = rmsConsumed;
- case kRight:
- NextDay();
- Draw();
- state = rmsConsumed;
- break;
- case kUp: {
- if (ScrollUp(false)) {
- SetHeaderTimer();
- Draw();
- }
- state = rmsConsumed;
- break; }
- case kDown: {
- if (ScrollDown(false)) {
- SetHeaderTimer();
- Draw();
- }
- state = rmsConsumed;
- break; }
- default:
- break;
- }
- if (state != rmsConsumed) {
- state = cRecMenu::ProcessKey(Key);
- }
- return state;
-}
-
-/******************************************************************************************
-* Recording Search Menus
-******************************************************************************************/
-
-// --- cRecMenuRecordingSearch ---------------------------------------------------------
-cRecMenuRecordingSearch::cRecMenuRecordingSearch(string search) {
- SetMenuWidth(60);
- strncpy(searchString, search.c_str(), TEXTINPUTLENGTH);
- AddHeader(new cRecMenuItemInfo(tr("Search in Recordings")));
- AddMenuItem(new cRecMenuItemText(tr("Search Expression:"), searchString, TEXTINPUTLENGTH, false, searchString));
- AddMenuItem(new cRecMenuItemButtonYesNo(tr("Perform Search"), tr("Cancel"), rmsRecordingSearchResult, rmsClose, true));
-}
-
-// --- cRecMenuRecordingSearchResults ---------------------------------------------------------
-cRecMenuRecordingSearchResults::cRecMenuRecordingSearchResults(string searchString, cRecording **searchResults, int numResults) {
- SetMenuWidth(80);
- this->searchString = searchString;
- this->searchResults = searchResults;
- this->numResults = numResults;
- string line1 = *cString::sprintf("%s %d %s %s:", tr("Found"), numResults, (numResults>1)?tr("recordings"):tr("recording"), tr("for"));
- string line2 = *cString::sprintf("\"%s\"", searchString.c_str());
- AddHeader(new cRecMenuItemInfo(line1, 2, line2));
-
- if (searchResults && (numResults > 0)) {
- for (int i=0; i<numResults; i++) {
- AddMenuItem(new cRecMenuItemRecording(searchResults[i], (i==0)?true:false));
- }
- cRecMenuItem *buttons = new cRecMenuItemButtonYesNo(tr("Adapt Search"), tr("Close"), rmsRecordingSearch, rmsClose, false);
- AddFooter(buttons);
- } else {
- cRecMenuItem *buttons = new cRecMenuItemButtonYesNo(tr("Adapt Search"), tr("Close"), rmsRecordingSearch, rmsClose, true);
- AddMenuItem(buttons);
- }
-}
-
-// --- cRecMenuRecordingSearchNotFound ---------------------------------------------------------
-cRecMenuRecordingSearchNotFound::cRecMenuRecordingSearchNotFound(string searchString) {
- SetMenuWidth(50);
- string line2 = *cString::sprintf("\"%s\"", searchString.c_str());
- AddHeader(new cRecMenuItemInfo(tr("No recordings found for"), 2, line2));
- AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true));
-}
-
-/******************************************************************************************
-* Favorites
-******************************************************************************************/
-
-// --- cRecMenuFavorites ---------------------------------------------------------
-
-cRecMenuFavorites::cRecMenuFavorites(vector<cTVGuideSearchTimer> favorites) {
- SetMenuWidth(70);
- this->favorites = favorites;
-
- CreateFavoritesMenuItems();
-
- string header;
- if (numFavorites > 0) {
- header = tr("Favorites");
- } else {
- header = tr("No Favorites available");
- }
- AddHeader(new cRecMenuItemInfo(header));
- cRecMenuItem *button = new cRecMenuItemButton(tr("Close"), rmsClose, (numFavorites==0)?true:false);
- if (numFavorites != 0)
- AddFooter(button);
- else
- AddMenuItem(button);
-}
-
-void cRecMenuFavorites::CreateFavoritesMenuItems(void) {
- bool active = true;
- if (config.favWhatsOnNow) {
- AddMenuItem(new cRecMenuItemFavoriteStatic(tr("What's on now"), rmsFavoritesNow, active));
- active = false;
- numFavorites++;
- }
- if (config.favWhatsOnNext) {
- AddMenuItem(new cRecMenuItemFavoriteStatic(tr("What's on next"), rmsFavoritesNext, active));
- active = false;
- numFavorites++;
- }
- if (config.favUseTime1) {
- string desc = *cString::sprintf("%s (%s)", config.descUser1.c_str(), NiceTime(config.favTime1).c_str());
- AddMenuItem(new cRecMenuItemFavoriteStatic(desc, rmsFavoritesUser1, active));
- active = false;
- numFavorites++;
- }
- if (config.favUseTime2) {
- string desc = *cString::sprintf("%s (%s)", config.descUser2.c_str(), NiceTime(config.favTime2).c_str());
- AddMenuItem(new cRecMenuItemFavoriteStatic(desc, rmsFavoritesUser2, active));
- active = false;
- numFavorites++;
- }
- if (config.favUseTime3) {
- string desc = *cString::sprintf("%s (%s)", config.descUser3.c_str(), NiceTime(config.favTime3).c_str());
- AddMenuItem(new cRecMenuItemFavoriteStatic(desc, rmsFavoritesUser3, active));
- active = false;
- numFavorites++;
- }
- if (config.favUseTime4) {
- string desc = *cString::sprintf("%s (%s)", config.descUser4.c_str(), NiceTime(config.favTime4).c_str());
- AddMenuItem(new cRecMenuItemFavoriteStatic(desc, rmsFavoritesUser4, active));
- active = false;
- numFavorites++;
- }
-
- int numAdditionalFavs = favorites.size();
- for (int i = 0; i < numAdditionalFavs; i++) {
- AddMenuItem(new cRecMenuItemFavorite(favorites[i], rmsSearchTimerTest, active));
- active = false;
- numFavorites++;
- }
-}
-
-string cRecMenuFavorites::NiceTime(int favTime) {
- int hours = favTime/100;
- int mins = favTime - hours * 100;
- return *cString::sprintf("%02d:%02d", hours, mins);
-}
-
-cTVGuideSearchTimer cRecMenuFavorites::GetFavorite(void) {
- cRecMenuItemFavorite *activeItem = dynamic_cast<cRecMenuItemFavorite*>(GetActive());
- return activeItem->GetFavorite();
-}
+#include <string> +#include <sstream> +#include <algorithm> +#include "config.h" +#include "services/remotetimers.h" +#include "helpers.h" +#include "recmenus.h" + +// --- cRecMenuMain --------------------------------------------------------- +cRecMenuMain::cRecMenuMain(bool epgSearchAvailable, bool timerActive, bool switchTimerActive) { + SetMenuWidth(50); + eRecMenuState action = rmsInstantRecord; + if (!timerActive) { + if (config.instRecFolderMode == eFolderSelect) + action = rmsInstantRecordFolder; + AddMenuItem(new cRecMenuItemButton(tr("Instant Record"), action, true)); + } else { + AddMenuItem(new cRecMenuItemButton(tr("Delete Timer"), rmsDeleteTimer, true)); + AddMenuItem(new cRecMenuItemButton(tr("Edit Timer"), rmsEditTimer, false)); + } + + AddMenuItem(new cRecMenuItemButton(tr("Timer Timeline"), rmsTimeline, false)); + + if (epgSearchAvailable) { + AddMenuItem(new cRecMenuItemButton(tr("Create Search Timer"), rmsSearchTimer, false)); + AddMenuItem(new cRecMenuItemButton(tr("Search Timers"), rmsSearchTimers, false)); + } + + if (config.instRecFolderMode == eFolderSelect) + action = rmsSeriesTimerFolder; + else + action = rmsSeriesTimer; + AddMenuItem(new cRecMenuItemButton(tr("Create Series Timer"), action, false)); + + if (epgSearchAvailable) { + if (!switchTimerActive) { + AddMenuItem(new cRecMenuItemButton(tr("Create Switch Timer"), rmsSwitchTimer, false)); + } else { + AddMenuItem(new cRecMenuItemButton(tr("Delete Switch Timer"), rmsSwitchTimerDelete, false)); + } + AddMenuItem(new cRecMenuItemButton(tr("Search"), rmsSearch, false)); + } + + if (epgSearchAvailable) { + AddMenuItem(new cRecMenuItemButton(tr("Check for Timer Conflicts"), rmsTimerConflicts, false)); + } + + AddMenuItem(new cRecMenuItemButton(tr("Search in Recordings"), rmsRecordingSearch, false)); +}; + +/****************************************************************************************** +* Instant Timer Menus +******************************************************************************************/ + +// --- cRecMenuConfirmTimer --------------------------------------------------------- +cRecMenuConfirmTimer::cRecMenuConfirmTimer(const cEvent *event) { + SetMenuWidth(50); + + bool eventHasTimer = false; + if (config.useRemoteTimers && pRemoteTimers) { + RemoteTimers_GetMatch_v1_0 rtMatch; + rtMatch.event = event; + pRemoteTimers->Service("RemoteTimers::GetMatch-v1.0", &rtMatch); + if (rtMatch.timerMatch == tmFull) { + eventHasTimer = true; + } + } else { + eventHasTimer = event->HasTimer(); + } + + string message; + if (eventHasTimer) { + message = tr("Timer created"); + } else { + message = tr("Timer NOT created"); + } +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + cString channelName = Channels->GetByChannelID(event->ChannelID())->Name(); +#else + cString channelName = Channels.GetByChannelID(event->ChannelID())->Name(); +#endif + string datetime = *cString::sprintf("%s %s - %s", *event->GetDateString(), *event->GetTimeString(), *event->GetEndTimeString()); + string eventTitle = event->Title() ? event->Title() : ""; + AddHeader(new cRecMenuItemInfo(message, 4, *channelName, datetime, eventTitle)); + AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true)); +} + +// --- cRecMenuAskFolder --------------------------------------------------------- +cRecMenuAskFolder::cRecMenuAskFolder(const cEvent *event, eRecMenuState nextAction) { + SetMenuWidth(80); + this->nextAction = nextAction; + string message = tr("Set Folder for"); + string eventTitle = event->Title() ? event->Title() : ""; + AddHeader(new cRecMenuItemInfo(message, 2, eventTitle)); + AddMenuItem(new cRecMenuItemButton(tr("root video folder"), nextAction, true)); + + ReadRecordingDirectories(&folders, NULL, ""); + int numFolders = folders.size(); + for (int i=0; i < numFolders; i++) { + AddMenuItem(new cRecMenuItemButton(folders[i].c_str(), nextAction, false)); + } +} + +string cRecMenuAskFolder::GetFolder(void) { + std::string folder = ""; + int folderActive = GetNumActive(); + if (folderActive > 0 && folderActive < (int)folders.size() + 1) + folder = folders[folderActive - 1]; + return folder; +} + +// --- cRecMenuConfirmDeleteTimer --------------------------------------------------------- +cRecMenuConfirmDeleteTimer::cRecMenuConfirmDeleteTimer(const cEvent *event) { + SetMenuWidth(50); + string message = tr("Timer deleted"); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + cString channelName = Channels->GetByChannelID(event->ChannelID())->Name(); +#else + cString channelName = Channels.GetByChannelID(event->ChannelID())->Name(); +#endif + string datetime = *cString::sprintf("%s %s - %s", *event->GetDateString(), *event->GetTimeString(), *event->GetEndTimeString()); + string eventTitle = event->Title() ? event->Title() : ""; + + AddHeader(new cRecMenuItemInfo(message, 4, *channelName, datetime, eventTitle)); + AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true)); +} + +// --- cRecMenuAskDeleteTimer --------------------------------------------------------- +cRecMenuAskDeleteTimer::cRecMenuAskDeleteTimer(const cEvent *event) { + SetMenuWidth(50); + string message = tr("Timer"); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + cString channelName = Channels->GetByChannelID(event->ChannelID())->Name(); +#else + cString channelName = Channels.GetByChannelID(event->ChannelID())->Name(); +#endif + string eventTitle = event->Title() ? event->Title() : ""; + string message2 = tr("still recording - really delete?"); + + AddHeader(new cRecMenuItemInfo(message, 4, *channelName, eventTitle, message2)); + AddMenuItem(new cRecMenuItemButtonYesNo(tr("Yes"), tr("No"), rmsDeleteTimerConfirmation, rmsClose, true)); +} + +// --- cRecMenuTimerConflicts --------------------------------------------------------- +cRecMenuTimerConflicts::cRecMenuTimerConflicts(cTVGuideTimerConflicts *conflicts) { + SetMenuWidth(80); + int numConflicts = conflicts->NumConflicts(); + + string text; + if (numConflicts == 1) { + text = *cString::sprintf("%s %s %s", tr("One"), tr("Timer Conflict"), tr("detected")); + } else { + text = *cString::sprintf("%d %s %s", conflicts->NumConflicts(), tr("Timer Conflicts"), tr("detected")); + } + AddHeader(new cRecMenuItemInfo(text)); + + for (int i=0; i<numConflicts; i++) { + cTVGuideTimerConflict *conflict = conflicts->GetConflict(i); + if (!conflict) + continue; + cString dateTime = DayDateTime(conflict->time); + int numTimers = conflict->timerIDs.size(); + cString textConflict = cString::sprintf("%s: %s (%d %s)", tr("Show conflict"), *dateTime, numTimers, tr("timers involved")); + bool isActive = (i==0)?true:false; + AddMenuItem(new cRecMenuItemButton(*textConflict, rmsTimerConflict, isActive)); + } + + AddFooter(new cRecMenuItemButton(tr("Ignore Conflicts"), rmsClose, false)); +} + +int cRecMenuTimerConflicts::GetTimerConflict(void) { + return GetNumActive(); +} + +// --- cRecMenuTimerConflict --------------------------------------------------------- +cRecMenuTimerConflict::cRecMenuTimerConflict(cTVGuideTimerConflict *conflict) { + SetMenuWidth(95); + this->conflict = conflict; + AddHeader(new cRecMenuItemTimerConflictHeader(conflict->timeStart, + conflict->timeStop, + conflict->overlapStart, + conflict->overlapStop)); + +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_READ; + const cTimers* timers = Timers; +#else + const cTimers* timers = &Timers; +#endif + int i=0; + for(vector<int>::iterator it = conflict->timerIDs.begin(); it != conflict->timerIDs.end(); it++) { + const cTimer *timer = timers->Get(*it); + if (timer) { + AddMenuItem(new cRecMenuItemTimer(timer, + rmsTimerConflictShowInfo, + rmsDeleteTimerConflictMenu, + rmsEditTimerConflictMenu, + rmsSearchRerunsTimerConflictMenu, + conflict->timeStart, + conflict->timeStop, + conflict->overlapStart, + conflict->overlapStop, + (!i)?true:false)); + i++; + } + } + AddMenuItem(new cRecMenuItemButton(tr("Ignore Conflict"), rmsIgnoreTimerConflict, false)); +} + +int cRecMenuTimerConflict::GetTimerConflictIndex(void) { + return GetNumActive(); +} + +// --- cRecMenuNoTimerConflict --------------------------------------------------------- +cRecMenuNoTimerConflict::cRecMenuNoTimerConflict(void) { + SetMenuWidth(50); + string text = tr("No Timer Conflicts found"); + AddHeader(new cRecMenuItemInfo(text)); + AddMenuItem(new cRecMenuItemButton(tr("Close"), rmsClose, true)); +} + +// --- cRecMenuRerunResults --------------------------------------------------------- +cRecMenuRerunResults::cRecMenuRerunResults(const cEvent *original, const cEvent **reruns, int numReruns) { + this->reruns = reruns; + this->numReruns = numReruns; + SetMenuWidth(70); + + string message1 = tr("reruns for"); + string message2 = tr("rerun for"); + string message3 = tr("found"); + string line1 = *cString::sprintf("%d %s:", numReruns, (numReruns>1)?(message1.c_str()):(message2.c_str())); + string line2 = *cString::sprintf("\"%s\" %s", original->Title(), message3.c_str()); + + AddHeader(new cRecMenuItemInfo(line1, 2, line2)); + + cRecMenuItem *button = new cRecMenuItemButton(tr("Ignore reruns"), rmsTimerConflictIgnoreReruns, false); + AddFooter(button); + + if (reruns && (numReruns > 0)) { + for (int i=0; i<numReruns; i++) { + AddMenuItem(new cRecMenuItemEvent(reruns[i], rmsSearchShowInfo, rmsTimerConflictRecordRerun, (i==0)?true:false)); + } + } +} + +int cRecMenuRerunResults::GetTotalNumMenuItems(void) { + return numReruns; +} + +const cEvent *cRecMenuRerunResults::GetEvent(void) { + cRecMenuItemEvent *activeItem = dynamic_cast<cRecMenuItemEvent*>(GetActive()); + if (activeItem) + return activeItem->GetEvent(); + return NULL; +} + +// --- cRecMenuNoRerunsFound --------------------------------------------------------- +cRecMenuNoRerunsFound::cRecMenuNoRerunsFound(string searchString) { + SetMenuWidth(50); + string message = tr("No reruns found for Event"); + string eventQuoted = *cString::sprintf("\"%s\"", searchString.c_str()); + + AddHeader(new cRecMenuItemInfo(message, 2, eventQuoted)); + AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true)); +} + +// --- cRecMenuConfirmRerunUsed --------------------------------------------------------- +cRecMenuConfirmRerunUsed::cRecMenuConfirmRerunUsed(const cEvent *original, const cEvent *replace) { + SetMenuWidth(70); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + cString channelOrig = Channels->GetByChannelID(original->ChannelID())->Name(); + cString channelReplace = Channels->GetByChannelID(replace->ChannelID())->Name(); +#else + cString channelOrig = Channels.GetByChannelID(original->ChannelID())->Name(); + cString channelReplace = Channels.GetByChannelID(replace->ChannelID())->Name(); +#endif + string line1 = *cString::sprintf("%s \"%s\"", tr("Timer for"), original->Title()); + string line2 = *cString::sprintf("%s %s %s", *original->GetDateString(), *original->GetTimeString(), *channelOrig); + string line3 = *cString::sprintf("%s \"%s\"", tr("replaced by rerun"), replace->Title()); + string line4 = *cString::sprintf("%s %s %s", *replace->GetDateString(), *replace->GetTimeString(), *channelReplace); + + AddHeader(new cRecMenuItemInfo(line1, 4, line2, line3, line4)); + AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsTimerConflicts, true)); +} + +// --- cRecMenuEditTimer --------------------------------------------------------- +cRecMenuEditTimer::cRecMenuEditTimer(const cTimer *timer, eRecMenuState nextState) { + SetMenuWidth(70); + if (!timer) + return; + originalTimer = timer; + string title = ""; + string channelName = ""; + if (timer->Event() && timer->Event()->Title()) + title = timer->Event()->Title(); + if (timer->Channel() && timer->Channel()->Name()) + channelName = timer->Channel()->Name(); + cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(tr("Edit Timer"), 3, title, channelName); + AddHeader(infoItem); + + timerActive = false; + if (config.useRemoteTimers && pRemoteTimers) { + RemoteTimers_GetMatch_v1_0 rtMatch; + rtMatch.event = timer->Event(); + pRemoteTimers->Service("RemoteTimers::GetMatch-v1.0", &rtMatch); + if (rtMatch.timer) { + if (rtMatch.timerMatch == tmFull) + timerActive = true; + } + } else + timerActive = timer->HasFlags(tfActive); + + day = timer->Day(); + start = timer->Start(); + stop = timer->Stop(); + prio = timer->Priority(); + lifetime = timer->Lifetime(); + strncpy(folder, GetDirectoryFromTimer(timer->File()).c_str(), TEXTINPUTLENGTH); + + AddMenuItem(new cRecMenuItemBool(tr("Timer Active"), timerActive, true, &timerActive)); + AddMenuItem(new cRecMenuItemInt(tr("Priority"), prio, 0, MAXPRIORITY, false, &prio)); + AddMenuItem(new cRecMenuItemInt(tr("Lifetime"), lifetime, 0, MAXLIFETIME, false, &lifetime)); + AddMenuItem(new cRecMenuItemDay(tr("Day"), day, false, &day)); + AddMenuItem(new cRecMenuItemTime(tr("Timer start time"), start, false, &start)); + AddMenuItem(new cRecMenuItemTime(tr("Timer stop time"), stop, false, &stop)); + AddMenuItem(new cRecMenuItemInfo(tr("Timer File"), 2, timer->File() ? timer->File() : "")); + AddMenuItem(new cRecMenuItemSelectDirectory(tr("New Folder"), string(folder), false, folder)); + if (nextState == rmsTimelineTimerSave) { + AddMenuItem(new cRecMenuItemButton(tr("Delete Timer"), rmsTimelineTimerDelete, false)); + AddFooter(new cRecMenuItemButtonYesNo(tr("Save"), tr("Cancel"), nextState, rmsTimeline, false)); + } else { + AddFooter(new cRecMenuItemButtonYesNo(tr("Save"), tr("Cancel"), nextState, rmsClose, false)); + } +} + +const cTimer *cRecMenuEditTimer::GetOriginalTimer(void) { + return originalTimer; +} + +cTimer cRecMenuEditTimer::GetTimer(void) { + cTimer t; + if (timerActive) + t.SetFlags(tfActive); + else + t.SetFlags(tfNone); + t.SetDay(day); + t.SetStart(start); + t.SetStop(stop); + t.SetPriority(prio); + t.SetLifetime(lifetime); + string newFolder(folder); + string newFile = originalTimer->File(); + size_t found = newFile.find_last_of('~'); + if (found != string::npos) { + string fileName = newFile.substr(found+1); + if (newFolder.size() > 0) + newFile = *cString::sprintf("%s~%s", newFolder.c_str(), fileName.c_str()); + else + newFile = fileName; + } else { + if (newFolder.size() > 0) + newFile = *cString::sprintf("%s~%s", newFolder.c_str(), newFile.c_str()); + } + std::replace(newFile.begin(), newFile.end(), '/', '~'); + t.SetFile(newFile.c_str()); + return t; +} + +/****************************************************************************************** +* Series Timer Menus +******************************************************************************************/ + +// --- cRecMenuSeriesTimer --------------------------------------------------------- +cRecMenuSeriesTimer::cRecMenuSeriesTimer(const cChannel *initialChannel, const cEvent *event, string folder) { + if (!initialChannel) + return; + timerActive = true; + channel = initialChannel->Number(); + dayOfWeek = 127; + priority = MAXPRIORITY; + lifetime = MAXLIFETIME; + CalculateTimes(event); + this->folder = folder; + + SetMenuWidth(70); + string line1 = tr("Create Series Timer based on"); + string line2 = *cString::sprintf("\"%s\"", event->Title()); + AddHeader(new cRecMenuItemInfo(line1, 2, line2)); + + AddMenuItem(new cRecMenuItemBool(tr("Timer Active"), timerActive, false, &timerActive)); + AddMenuItem(new cRecMenuItemChannelChooser(tr("Channel"), (cChannel*)initialChannel, false, &channel)); + AddMenuItem(new cRecMenuItemTime(tr("Series Timer start time"), start, false, &start)); + AddMenuItem(new cRecMenuItemTime(tr("Series Timer stop time"), stop, false, &stop)); + AddMenuItem(new cRecMenuItemDayChooser(tr("Days to record"), dayOfWeek, false, &dayOfWeek)); + AddMenuItem(new cRecMenuItemDay(tr("Day to start"), tstart, false, &tstart)); + AddMenuItem(new cRecMenuItemInt(tr("Priority"), priority, 0, MAXPRIORITY, false, &priority)); + AddMenuItem(new cRecMenuItemInt(tr("Lifetime"), lifetime, 0, MAXLIFETIME, false, &lifetime)); + + AddFooter(new cRecMenuItemButtonYesNo(tr("Create Timer"), tr("Cancel"), rmsSeriesTimerCreate, rmsClose, true)); +} + +cTimer *cRecMenuSeriesTimer::GetTimer(void) { +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + cTimer *seriesTimer = new cTimer(NULL, NULL, Channels->GetByNumber(channel)); +#else + cTimer *seriesTimer = new cTimer(NULL, NULL, Channels.GetByNumber(channel)); +#endif + cString fileName = "TITLE EPISODE"; + if (folder.size() > 0) { + std::replace(folder.begin(), folder.end(), '/', '~'); + fileName = cString::sprintf("%s~%s", folder.c_str(), *fileName); + } + seriesTimer->SetDay(tstart); + seriesTimer->SetStart(start); + seriesTimer->SetStop(stop); + seriesTimer->SetPriority(priority); + seriesTimer->SetLifetime(lifetime); + seriesTimer->SetWeekDays(dayOfWeek); + seriesTimer->SetFile(*fileName); + if (timerActive) + seriesTimer->SetFlags(tfActive); + else + seriesTimer->SetFlags(tfNone); + return seriesTimer; +} + +void cRecMenuSeriesTimer::CalculateTimes(const cEvent *event) { + tstart = event->StartTime(); + tstart -= Setup.MarginStart * 60; + time_t tstop = tstart + event->Duration(); + tstop += Setup.MarginStop * 60; + + struct tm tm_r; + struct tm *time = localtime_r(&tstart, &tm_r); + start = time->tm_hour * 100 + time->tm_min; + time = localtime_r(&tstop, &tm_r); + stop = time->tm_hour * 100 + time->tm_min; + if (stop >= 2400) + stop -= 2400; +} + +// --- cRecMenuConfirmSeriesTimer --------------------------------------------------------- +cRecMenuConfirmSeriesTimer::cRecMenuConfirmSeriesTimer(cTimer *seriesTimer) { + SetMenuWidth(50); + string line1 = tr("Series Timer created"); + string line2 = ""; + if (seriesTimer) { + cString days = cTimer::PrintDay(seriesTimer->Day(), seriesTimer->WeekDays(), true); + line2 = cString::sprintf("%s, %s: %s, %s: %s", *days, tr("Start"), *TimeString(seriesTimer->StartTime()), tr("Stop"), *TimeString(seriesTimer->StopTime())); + } + AddHeader(new cRecMenuItemInfo(line1, 2, line2)); + AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true)); +} + +/****************************************************************************************** +* SearchTimer Menus +******************************************************************************************/ + +// --- cRecMenuSearchTimer --------------------------------------------------------- +cRecMenuSearchTimer::cRecMenuSearchTimer(const cEvent *event) { + SetMenuWidth(70); + string message = tr("Configure Search Timer based on"); + string infoText = *cString::sprintf("\"%s\"", event->Title()); + AddHeader(new cRecMenuItemInfo(message, 2, infoText)); + strncpy(searchString, event->Title(), TEXTINPUTLENGTH); + AddMenuItem(new cRecMenuItemText(tr("Search Expression:"), searchString, TEXTINPUTLENGTH, false)); + AddFooter(new cRecMenuItemButtonYesNo(tr("Continue"), tr("Cancel"), rmsSearchTimerOptions, rmsClose, true)); +} + +// --- cRecMenuSearchTimerTemplates --------------------------------------------------------- +cRecMenuSearchTimerTemplates::cRecMenuSearchTimerTemplates(cTVGuideSearchTimer searchTimer, vector<TVGuideEPGSearchTemplate> templates) { + SetMenuWidth(70); + this->searchTimer = searchTimer; + this->templates = templates; + string message = tr("Configure Search Timer for Search String"); + AddHeader(new cRecMenuItemInfo(message, 2, searchTimer.SearchString())); + AddMenuItem(new cRecMenuItemButton(tr("Manually configure Options"), rmsSearchTimerEdit, true)); + + numTemplates = templates.size(); + for (int i=0; i<numTemplates; i++) { + string buttonText = *cString::sprintf("%s \"%s\"", tr("Use Template"), templates[i].name.c_str()); + AddMenuItem(new cRecMenuItemButton(buttonText, rmsSearchTimerCreateWithTemplate, false)); + } +} + +TVGuideEPGSearchTemplate cRecMenuSearchTimerTemplates::GetTemplate(void) { + TVGuideEPGSearchTemplate templ; + int tmplActive = GetNumActive() - 1; + if (tmplActive >= 0 && tmplActive < (int)templates.size()) + templ = templates[tmplActive]; + return templ; +} + +// --- cRecMenuSearchTimers --------------------------------------------------------- +cRecMenuSearchTimers::cRecMenuSearchTimers(std::vector<cTVGuideSearchTimer> searchTimers) { + SetMenuWidth(70); + this->searchTimers = searchTimers; + numSearchTimers = searchTimers.size(); + string headline; + if (numSearchTimers > 0) { + headline = tr("EPGSearch Search Timers"); + } else { + headline = tr("No Search Timers Configured"); + } + AddHeader(new cRecMenuItemInfo(headline)); + cRecMenuItem *button = new cRecMenuItemButton(tr("Close"), rmsClose, (!numSearchTimers)?true:false); + if (numSearchTimers > 0) { + SetMenuItems(); + AddFooter(button); + } else { + AddMenuItem(button); + } +} + +void cRecMenuSearchTimers::SetMenuItems(void) { + for (int i = 0; i < numSearchTimers; i++) { + AddMenuItem(new cRecMenuItemSearchTimer(searchTimers[i], rmsSearchTimerTest, rmsSearchTimerEdit, rmsSearchTimerDeleteConfirm, (i==0)?true:false)); + } +} + +cTVGuideSearchTimer cRecMenuSearchTimers::GetSearchTimer(void) { + cRecMenuItemSearchTimer *activeItem = dynamic_cast<cRecMenuItemSearchTimer*>(GetActive()); + return activeItem->GetTimer(); +} + +// --- cRecMenuSearchTimerEdit --------------------------------------------------------- +cRecMenuSearchTimerEdit::cRecMenuSearchTimerEdit(cTVGuideSearchTimer searchTimer, bool advancedOptions) { + this->advancedOptions = advancedOptions; + this->searchTimer = searchTimer; + strncpy(searchString, searchTimer.SearchString().c_str(), TEXTINPUTLENGTH); + timerActive = searchTimer.Active(); + mode = searchTimer.SearchMode(); + useTitle = searchTimer.UseTitle(); + useSubtitle = searchTimer.UseSubtitle(); + useDescription = searchTimer.UseDescription(); + useChannel = searchTimer.UseChannel(); + startChannel = searchTimer.StartChannel(); + stopChannel = searchTimer.StopChannel(); + useTime = searchTimer.UseTime(); + startTime = searchTimer.StartTime(); + stopTime = searchTimer.StopTime(); + useDayOfWeek = searchTimer.UseDayOfWeek(); + dayOfWeek = searchTimer.DayOfWeek(); + priority = searchTimer.Priority(); + lifetime = searchTimer.Lifetime(); + useEpisode = searchTimer.UseEpisode(); + std::string dir = searchTimer.Directory(); + strncpy(directory, dir.c_str(), TEXTINPUTLENGTH); + marginStart = searchTimer.MarginStart(); + marginStop = searchTimer.MarginStop(); + useVPS = searchTimer.UseVPS(); + avoidRepeats = searchTimer.AvoidRepeats(); + allowedRepeats = searchTimer.AllowedRepeats(); + compareTitle = searchTimer.CompareTitle(); + compareSubtitle = searchTimer.CompareSubtitle(); + compareSummary = searchTimer.CompareSummary(); + useInFavorites = searchTimer.UseInFavorites(); + + SetMenuWidth(70); + string infoText; + if (searchTimer.GetID() > -1) { + infoText = tr("Configure Search Timer Options"); + } else { + infoText = tr("Create Search Timer"); + } + AddHeader(new cRecMenuItemInfo(infoText)); + cRecMenuItemButtonYesNo *footerButton = new cRecMenuItemButtonYesNo(tr("Save Search Timer"), tr("Cancel"), rmsSearchTimerSave, rmsSearchTimers, false); + AddFooter(footerButton); + CreateMenuItems(); +} + +void cRecMenuSearchTimerEdit::CreateMenuItems(void) { + AddMenuItem(new cRecMenuItemText(tr("Search String"), searchString, TEXTINPUTLENGTH, true, searchString)); + AddMenuItem(new cRecMenuItemBool(tr("Active"), timerActive, false, &timerActive, rmsSearchTimerSave)); + vector<string> searchModes; + searchTimer.GetSearchModes(&searchModes); + esyslog("tvguideng: num search modes %ld", searchModes.size()); + AddMenuItem(new cRecMenuItemSelect(tr("Search Mode"), searchModes, mode, false, &mode, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemBool(tr("Use Title"), useTitle, false, &useTitle, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemBool(tr("Use Subtitle"), useSubtitle, false, &useSubtitle, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemBool(tr("Use Description"), useDescription, false, &useDescription, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemBool(tr("Limit Channels"), useChannel, false, &useChannel, rmsSearchTimerSave)); + if (startChannel == 0) + startChannel = 1; + if (stopChannel == 0) + stopChannel = 1; +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + AddMenuItem(new cRecMenuItemChannelChooser(tr("Start Channel"), Channels->GetByNumber(startChannel), false, &startChannel, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemChannelChooser(tr("Stop Channel"), Channels->GetByNumber(stopChannel), false, &stopChannel, rmsSearchTimerSave)); +#else + AddMenuItem(new cRecMenuItemChannelChooser(tr("Start Channel"), Channels.GetByNumber(startChannel), false, &startChannel, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemChannelChooser(tr("Stop Channel"), Channels.GetByNumber(stopChannel), false, &stopChannel, rmsSearchTimerSave)); +#endif + AddMenuItem(new cRecMenuItemBool(tr("Use Time"), useTime, false, &useTime, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemTime(tr("Start after"), startTime, false, &startTime, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemTime(tr("Start before"), stopTime, false, &stopTime, rmsSearchTimerSave)); + + if (!advancedOptions) { + AddMenuItem(new cRecMenuItemButton(tr("Display advanced Options"), rmsSearchTimerEditAdvanced, false)); + } else { + AddMenuItem(new cRecMenuItemBool(tr("Limit Days of the Week"), useDayOfWeek, false, &useDayOfWeek, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemDayChooser(tr("Select Days"), dayOfWeek, false, &dayOfWeek)); + AddMenuItem(new cRecMenuItemInt(tr("Priority"), priority, 0, 99, false, &priority, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemInt(tr("Lifetime"), lifetime, 0, 99, false, &lifetime, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemInt(tr("Time margin for start in minutes"), marginStart, 0, 30, false, &marginStart, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemInt(tr("Time margin for stop in minutes"), marginStop, 0, 30, false, &marginStop, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemBool(tr("Series Recording"), useEpisode, false, &useEpisode, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemSelectDirectory(tr("Folder"), string(directory), false, directory, rmsSearchTimerSave, true)); + AddMenuItem(new cRecMenuItemBool(tr("Use VPS"), useVPS, false, &useVPS, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemBool(tr("Avoid Repeats"), avoidRepeats, false, &avoidRepeats, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemInt(tr("Number of allowed repeats"), allowedRepeats, 0, 30, false, &allowedRepeats, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemBool(tr("Compare Title"), compareTitle, false, &compareTitle, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemBool(tr("Compare Subtitle"), compareSubtitle, false, &compareSubtitle, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemBool(tr("Compare Description"), compareSummary, false, &compareSummary, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemBool(tr("Use in Favorites"), useInFavorites, false, &useInFavorites, rmsSearchTimerSave)); + AddMenuItem(new cRecMenuItemButton(tr("Hide advanced Options"), rmsSearchTimerEdit, false)); + } + + AddMenuItem(new cRecMenuItemButton(tr("Display Results for Search Timer"), rmsSearchTimerTest, false)); +} + +cTVGuideSearchTimer cRecMenuSearchTimerEdit::GetSearchTimer(void) { + searchTimer.SetSearchString(searchString); + searchTimer.SetActive(timerActive); + searchTimer.SetSearchMode(mode); + searchTimer.SetUseTitle(useTitle); + searchTimer.SetUseSubtitle(useSubtitle); + searchTimer.SetUseDesription(useDescription); + searchTimer.SetUseChannel(useChannel); + if (useChannel) { + searchTimer.SetStartChannel(startChannel); + searchTimer.SetStopChannel(stopChannel); + } + searchTimer.SetUseTime(useTime); + if (useTime) { + searchTimer.SetStartTime(startTime); + searchTimer.SetStopTime(stopTime); + } + searchTimer.SetUseDayOfWeek(useDayOfWeek); + if (useDayOfWeek) { + searchTimer.SetDayOfWeek(dayOfWeek); + } + searchTimer.SetPriority(priority); + searchTimer.SetLifetime(lifetime); + searchTimer.SetUseEpisode(useEpisode); + string dir(directory); + std::replace(dir.begin(), dir.end(), '/', '~'); + searchTimer.SetDirectory(dir); + searchTimer.SetMarginStart(marginStart); + searchTimer.SetMarginStop(marginStop); + searchTimer.SetUseVPS(useVPS); + searchTimer.SetAvoidRepeats(avoidRepeats); + if (avoidRepeats) { + searchTimer.SetAllowedRepeats(allowedRepeats); + searchTimer.SetCompareTitle(compareTitle); + searchTimer.SetCompareSubtitle(compareSubtitle); + searchTimer.SetCompareSummary(compareSummary); + } + searchTimer.SetUseInFavorites(useInFavorites); + return searchTimer; +} + +// --- cRecMenuSearchTimerDeleteConfirm --------------------------------------------- +cRecMenuSearchTimerDeleteConfirm::cRecMenuSearchTimerDeleteConfirm(cTVGuideSearchTimer searchTimer) { + SetMenuWidth(70); + this->searchTimer = searchTimer; + string line1 = tr("Really delete Search Timer"); + string line2 = *cString::sprintf("\"%s\"?", searchTimer.SearchString().c_str()); + AddHeader(new cRecMenuItemInfo(line1, 2, line2)); + AddMenuItem(new cRecMenuItemButton(tr("Delete only Search Timer"), rmsSearchTimerDelete, true)); + AddMenuItem(new cRecMenuItemButton(tr("Delete Search Timer and created Timers"), rmsSearchTimerDeleteWithTimers, false)); + AddFooter(new cRecMenuItemButton(tr("Cancel"), rmsClose, false)); +} + +cTVGuideSearchTimer cRecMenuSearchTimerDeleteConfirm::GetSearchTimer(void) { + return searchTimer; +} + +// --- cRecMenuSearchTimerCreateConfirm --------------------------------------------------------- +cRecMenuSearchTimerCreateConfirm::cRecMenuSearchTimerCreateConfirm(bool success) { + SetMenuWidth(50); + cRecMenuItemInfo *infoItem = NULL; + if (success) { + string line1 = tr("Search Timer sucessfully created"); + string line2 = tr("Search Timer update initialised"); + infoItem = new cRecMenuItemInfo(line1, 2, line2); + } else { + string line1 = tr("Search Timer NOT sucessfully created"); + infoItem = new cRecMenuItemInfo(line1); + } + AddHeader(infoItem); + AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true)); +} + +// --- cRecMenuSearchTimerTemplatesCreate --------------------------------------------------------- +cRecMenuSearchTimerTemplatesCreate::cRecMenuSearchTimerTemplatesCreate(TVGuideEPGSearchTemplate templ, cTVGuideSearchTimer searchTimer) { + SetMenuWidth(70); + this->templ = templ; + this->searchTimer = searchTimer; + + string line1 = tr("Creating Search Timer"); + string line2 = *cString::sprintf("%s: \"%s\"", tr("Search Term"), searchTimer.SearchString().c_str()); + string line3 = *cString::sprintf("%s \"%s\"", tr("Using Template"), templ.name.c_str()); + + AddHeader(new cRecMenuItemInfo(line1, 3, line2, line3)); + AddMenuItem(new cRecMenuItemButton(tr("Display Results for Search Timer"), rmsSearchTimerTest, true)); + AddMenuItem(new cRecMenuItemButtonYesNo(tr("Create Search Timer"), tr("Use other Template"), rmsSearchTimerSave, rmsSearchTimerOptions, false)); +} + + +// --- cRecMenuSearchTimerResults --------------------------------------------------------- +cRecMenuSearchTimerResults::cRecMenuSearchTimerResults(string searchString, const cEvent **searchResults, int numResults, string templateName, eRecMenuState action2) { + SetMenuWidth(70); + this->searchResults = searchResults; + this->action2 = action2; + this->numResults = numResults; + string message1 = "", message2 = "", message3 = ""; + if (action2 == rmsFavoritesRecord) { + message1 = tr("search results for Favorite"); + message2 = tr("search result for Favorite"); + } else { + message1 = tr("search results for Search Timer"); + message2 = tr("search result for Search Timer"); + message3 = tr("Using Template"); + } + cRecMenuItem *infoItem = NULL; + if (templateName.size() > 0) { + string line1 = *cString::sprintf("%d %s:", numResults, (numResults>1)?(message1.c_str()):(message2.c_str())); + string line2 = *cString::sprintf("\"%s\"", searchString.c_str()); + string line3 = *cString::sprintf("%s \"%s\"", message3.c_str(), templateName.c_str()); + infoItem = new cRecMenuItemInfo(line1, 3, line2, line3); + } else { + string line1 = *cString::sprintf("%d %s:", numResults, (numResults>1)?(message1.c_str()):(message2.c_str())); + string line2 = *cString::sprintf("\"%s\"", searchString.c_str()); + infoItem = new cRecMenuItemInfo(line1, 2, line2); + } + AddHeader(infoItem); + + cRecMenuItem *button = new cRecMenuItemButton(tr("Close"), rmsClose, false); + if (searchResults && (numResults > 0)) { + for (int i=0; i<numResults; i++) { + AddMenuItem(new cRecMenuItemEvent(searchResults[i], rmsSearchShowInfo, action2, (i==0)?true:false)); + } + AddFooter(button); + } else { + AddMenuItem(button); + } +} + +const cEvent *cRecMenuSearchTimerResults::GetEvent(void) { + const cEvent *ev = NULL; + if (cRecMenuItemEvent *activeItem = dynamic_cast<cRecMenuItemEvent*>(GetActive())) + ev = activeItem->GetEvent(); + return ev; +} + +// --- cRecMenuSearchTimerNothingFound --------------------------------------------------------- +cRecMenuSearchTimerNothingFound::cRecMenuSearchTimerNothingFound(string searchString) { + SetMenuWidth(50); + string line1 = tr("Nothing found for Search String"); + string line2 = *cString::sprintf("\"%s\"", searchString.c_str()); + AddHeader(new cRecMenuItemInfo(line1, 2, line2)); + AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true)); +} + +/****************************************************************************************** +* SwitchTimer Menus +******************************************************************************************/ + +// --- cRecMenuSwitchTimer --------------------------------------------------------- +cRecMenuSwitchTimer::cRecMenuSwitchTimer(void) { + SetMenuWidth(60); + switchMinsBefore = config.switchMinsBefore; + announceOnly = 0; + + AddHeader(new cRecMenuItemInfo(tr("Configure Options for Switchtimer"))); + AddMenuItem(new cRecMenuItemInt(tr("Minutes before switching"), switchMinsBefore, 0, 10, false, &switchMinsBefore)); + vector<string> switchModes; + switchModes.push_back(tr("switch")); + switchModes.push_back(tr("announce only")); + switchModes.push_back(tr("ask for switch")); + AddMenuItem(new cRecMenuItemSelect(tr("Switch Mode"), switchModes, announceOnly, false, &announceOnly)); + + AddFooter(new cRecMenuItemButtonYesNo(tr("Create"), tr("Cancel"), rmsSwitchTimerCreate, rmsClose, true)); +} + +cSwitchTimer cRecMenuSwitchTimer::GetSwitchTimer(void) { + cSwitchTimer st; + st.switchMinsBefore = switchMinsBefore; + st.announceOnly = announceOnly; + return st; +} + +// --- cRecMenuSwitchTimerConfirm --------------------------------------------------------- +cRecMenuSwitchTimerConfirm::cRecMenuSwitchTimerConfirm(bool success) { + SetMenuWidth(50); + string message1 = tr("Switch Timer sucessfully created"); + string message2 = tr("Switch Timer NOT sucessfully created"); + string infoText = success?message1:message2; + AddHeader(new cRecMenuItemInfo(infoText)); + AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true)); +} + +// --- cRecMenuSwitchTimerDelete --------------------------------------------------------- +cRecMenuSwitchTimerDelete::cRecMenuSwitchTimerDelete(void) { + SetMenuWidth(50); + AddHeader(new cRecMenuItemInfo(tr("Switch Timer deleted"))); + AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true)); +} + +/****************************************************************************************** +* Search Menus +******************************************************************************************/ + +// --- cRecMenuSearch --------------------------------------------------------- +cRecMenuSearch::cRecMenuSearch(string searchString, bool withOptions) { + SetMenuWidth(60); + strncpy(this->searchString, searchString.c_str(), TEXTINPUTLENGTH); + mode = 0; + channelNr = 0; + useTitle = true; + useSubTitle = true; + useDescription = false; + + AddHeader(new cRecMenuItemInfo(tr("Search"))); + AddMenuItem(new cRecMenuItemText(tr("Search Expression:"), this->searchString, TEXTINPUTLENGTH, false, this->searchString)); + + if (withOptions) { + vector<string> searchModes; + cTVGuideSearchTimer searchTimer; + searchTimer.GetSearchModes(&searchModes); + AddMenuItem(new cRecMenuItemSelect(tr("Search Mode"), searchModes, 0, false, &mode)); + AddMenuItem(new cRecMenuItemChannelChooser(tr("Channel to Search"), NULL, false, &channelNr)); + AddMenuItem(new cRecMenuItemBool(tr("Search in title"), true, false, &useTitle)); + AddMenuItem(new cRecMenuItemBool(tr("Search in Subtitle"), true, false, &useSubTitle)); + AddMenuItem(new cRecMenuItemBool(tr("Search in Description"), false, false, &useDescription)); + } else { + AddMenuItem(new cRecMenuItemButton(tr("Show Search Options"), rmsSearchWithOptions, false)); + } + + cRecMenuItemButtonYesNo *button = new cRecMenuItemButtonYesNo(tr("Perform Search"), tr("Cancel"), rmsSearchPerform, rmsClose, true); + AddFooter(button); +} + +Epgsearch_searchresults_v1_0 cRecMenuSearch::GetEPGSearchStruct(void) { + Epgsearch_searchresults_v1_0 data; + data.query = searchString; + data.mode = mode; + data.channelNr = channelNr; + data.useTitle = useTitle; + data.useSubTitle = useSubTitle; + data.useDescription = useDescription; + return data; +} + +// --- cRecMenuSearchResults --------------------------------------------------------- +cRecMenuSearchResults::cRecMenuSearchResults(string searchString, const cEvent **searchResults, int numResults) { + this->searchResults = searchResults; + SetMenuWidth(70); + this->searchString = searchString; + this->numResults = numResults; + + string message = ""; + if (numResults > 1) { + message = *cString::sprintf("%d %s", numResults, tr("search results for")); + } else { + message = *cString::sprintf("%d %s", numResults, tr("search result for")); + } + string searchStringQuoted = *cString::sprintf("\"%s\"", searchString.c_str()); + AddHeader(new cRecMenuItemInfo(message, 2, searchStringQuoted)); + + cRecMenuItem *buttons = new cRecMenuItemButtonYesNo(tr("Adapt Search"), tr("Close"), rmsSearch, rmsClose, false); + AddFooter(buttons); + if (searchResults && (numResults > 0)) { + for (int i=0; i<numResults; i++) { + AddMenuItem(new cRecMenuItemEvent(searchResults[i], rmsSearchShowInfo, rmsSearchRecord, (i==0)?true:false)); + } + } +} + +const cEvent *cRecMenuSearchResults::GetEvent(void) { + cRecMenuItemEvent *activeItem = dynamic_cast<cRecMenuItemEvent*>(GetActive()); + if (activeItem) + return activeItem->GetEvent(); + return NULL; +} + +// --- cRecMenuSearchNothingFound --------------------------------------------------------- +cRecMenuSearchNothingFound::cRecMenuSearchNothingFound(string searchString, bool tooShort) { + SetMenuWidth(50); + string text; + if (!tooShort) { + cString message = tr("Nothing found for Search String"); + text = *cString::sprintf("%s\n\"%s\"", + *message, + searchString.c_str()); + } else { + cString message = tr("Search String has to have at least three letters"); + text = *cString::sprintf("%s\n\"%s\"", + *message, + searchString.c_str()); + + } + AddHeader(new cRecMenuItemInfo(text)); + AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true)); +} + +// --- cRecMenuSearchConfirmTimer --------------------------------------------------------- +cRecMenuSearchConfirmTimer::cRecMenuSearchConfirmTimer(const cEvent *event) { + SetMenuWidth(50); + + string message = tr("Timer created"); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + cString channelName = Channels->GetByChannelID(event->ChannelID())->Name(); +#else + cString channelName = Channels.GetByChannelID(event->ChannelID())->Name(); +#endif + string line3 = *cString::sprintf("%s %s - %s", *event->GetDateString(), *event->GetTimeString(), *event->GetEndTimeString()); + string line4 = event->Title() ? event->Title() : ""; + + AddHeader(new cRecMenuItemInfo(message, 4, *channelName, line3, line4)); + AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true)); +} + +/****************************************************************************************** +* Timeline +******************************************************************************************/ + +// --- cRecMenuTimeline --------------------------------------------------------- +cRecMenuTimeline::cRecMenuTimeline(void) { + SetMenuWidth(95); + SetStartStop(); + GetTimersForDay(); + + timelineHeader = new cRecMenuItemTimelineHeader(timeStart); + AddHeader(timelineHeader); + + timelineFooter = new cRecMenuItemButton(tr("Close"), rmsClose, false); + AddFooter(timelineFooter); + SetTimers(); +} + +void cRecMenuTimeline::SetHeaderTimer(void) { + const cTimer *currentTimer = NULL; + cRecMenuItem *currentItem = GetActive(); + if (!currentItem) { + timelineHeader->UnsetCurrentTimer(); + return; + } + if (cRecMenuItemTimelineTimer *myActiveItem = dynamic_cast<cRecMenuItemTimelineTimer*>(currentItem)) { + currentTimer = myActiveItem->GetTimer(); + } + timelineHeader->SetCurrentTimer(currentTimer); + timelineHeader->SetNew(); +} + +void cRecMenuTimeline::SetStartStop(void) { + time_t now = time(0); + tm *timeStruct = localtime(&now); + timeStart = now - timeStruct->tm_hour * 3600 - timeStruct->tm_min * 60 - timeStruct->tm_sec; + today = timeStart; + timeStop = timeStart + 24*3600 - 1; +} + +void cRecMenuTimeline::GetTimersForDay(void) { + timersToday.clear(); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_READ; + const cTimers* timers = Timers; +#else + const cTimers* timers = &Timers; +#endif + for (const cTimer *t = timers->First(); t; t = timers->Next(t)) { + if (((t->StartTime() > timeStart) && (t->StartTime() <= timeStop)) || ((t->StopTime() > timeStart) && (t->StopTime() <= timeStop))) { + timersToday.push_back(t); + } + } + numTimersToday = timersToday.size(); +} + +void cRecMenuTimeline::SetTimers(void) { + if (numTimersToday == 0) { + AddMenuItem(new cRecMenuItemInfo(tr("No active Timers"))); + timelineFooter->SetActive(); + } else { + for (int i=0; i<numTimersToday; i++) { + AddMenuItem(new cRecMenuItemTimelineTimer(timersToday[i], timeStart, timeStop, (i==0)?true:false)); + } + timelineFooter->SetInactive(); + } +} + +void cRecMenuTimeline::PrevDay(void) { + if ((timeStart - 3600*24) < today) + return; + timeStart -= 3600*24; + timeStop -= 3600*24; + ClearMenuItems(true); + GetTimersForDay(); + SetTimers(); + InitMenuItems(); + SetHeaderTimer(); + timelineHeader->SetDay(timeStart); + timelineHeader->SetNew(); +} + +void cRecMenuTimeline::NextDay(void) { + timeStart += 3600*24; + timeStop += 3600*24; + ClearMenuItems(true); + GetTimersForDay(); + SetTimers(); + InitMenuItems(); + SetHeaderTimer(); + timelineHeader->SetDay(timeStart); + timelineHeader->SetNew(); +} + +const cTimer *cRecMenuTimeline::GetTimer(void) { + if (cRecMenuItemTimelineTimer *activeItem = dynamic_cast<cRecMenuItemTimelineTimer*>(GetActive())) + return activeItem->GetTimer(); + return NULL; +} + + +eRecMenuState cRecMenuTimeline::ProcessKey(eKeys Key) { + eRecMenuState state = rmsContinue; + switch (Key & ~k_Repeat) { + case kLeft: + PrevDay(); + Draw(); + break; + state = rmsConsumed; + case kRight: + NextDay(); + Draw(); + state = rmsConsumed; + break; + case kUp: { + if (ScrollUp(false)) { + SetHeaderTimer(); + Draw(); + } + state = rmsConsumed; + break; } + case kDown: { + if (ScrollDown(false)) { + SetHeaderTimer(); + Draw(); + } + state = rmsConsumed; + break; } + default: + break; + } + if (state != rmsConsumed) { + state = cRecMenu::ProcessKey(Key); + } + return state; +} + +/****************************************************************************************** +* Recording Search Menus +******************************************************************************************/ + +// --- cRecMenuRecordingSearch --------------------------------------------------------- +cRecMenuRecordingSearch::cRecMenuRecordingSearch(string search) { + SetMenuWidth(60); + strncpy(searchString, search.c_str(), TEXTINPUTLENGTH); + AddHeader(new cRecMenuItemInfo(tr("Search in Recordings"))); + AddMenuItem(new cRecMenuItemText(tr("Search Expression:"), searchString, TEXTINPUTLENGTH, false, searchString)); + AddMenuItem(new cRecMenuItemButtonYesNo(tr("Perform Search"), tr("Cancel"), rmsRecordingSearchResult, rmsClose, true)); +} + +// --- cRecMenuRecordingSearchResults --------------------------------------------------------- +cRecMenuRecordingSearchResults::cRecMenuRecordingSearchResults(string searchString, const cRecording **searchResults, int numResults) { + SetMenuWidth(80); + this->searchString = searchString; + this->searchResults = searchResults; + this->numResults = numResults; + string line1 = *cString::sprintf("%s %d %s %s:", tr("Found"), numResults, (numResults>1)?tr("recordings"):tr("recording"), tr("for")); + string line2 = *cString::sprintf("\"%s\"", searchString.c_str()); + AddHeader(new cRecMenuItemInfo(line1, 2, line2)); + + if (searchResults && (numResults > 0)) { + for (int i=0; i<numResults; i++) { + AddMenuItem(new cRecMenuItemRecording(searchResults[i], (i==0)?true:false)); + } + cRecMenuItem *buttons = new cRecMenuItemButtonYesNo(tr("Adapt Search"), tr("Close"), rmsRecordingSearch, rmsClose, false); + AddFooter(buttons); + } else { + cRecMenuItem *buttons = new cRecMenuItemButtonYesNo(tr("Adapt Search"), tr("Close"), rmsRecordingSearch, rmsClose, true); + AddMenuItem(buttons); + } +} + +// --- cRecMenuRecordingSearchNotFound --------------------------------------------------------- +cRecMenuRecordingSearchNotFound::cRecMenuRecordingSearchNotFound(string searchString) { + SetMenuWidth(50); + string line2 = *cString::sprintf("\"%s\"", searchString.c_str()); + AddHeader(new cRecMenuItemInfo(tr("No recordings found for"), 2, line2)); + AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true)); +} + +/****************************************************************************************** +* Favorites +******************************************************************************************/ + +// --- cRecMenuFavorites --------------------------------------------------------- + +cRecMenuFavorites::cRecMenuFavorites(vector<cTVGuideSearchTimer> favorites) { + SetMenuWidth(70); + this->favorites = favorites; + + CreateFavoritesMenuItems(); + + string header; + if (numFavorites > 0) { + header = tr("Favorites"); + } else { + header = tr("No Favorites available"); + } + AddHeader(new cRecMenuItemInfo(header)); + cRecMenuItem *button = new cRecMenuItemButton(tr("Close"), rmsClose, (numFavorites==0)?true:false); + if (numFavorites != 0) + AddFooter(button); + else + AddMenuItem(button); +} + +void cRecMenuFavorites::CreateFavoritesMenuItems(void) { + bool active = true; + if (config.favWhatsOnNow) { + AddMenuItem(new cRecMenuItemFavoriteStatic(tr("What's on now"), rmsFavoritesNow, active)); + active = false; + numFavorites++; + } + if (config.favWhatsOnNext) { + AddMenuItem(new cRecMenuItemFavoriteStatic(tr("What's on next"), rmsFavoritesNext, active)); + active = false; + numFavorites++; + } + if (config.favUseTime1) { + string desc = *cString::sprintf("%s (%s)", config.descUser1.c_str(), NiceTime(config.favTime1).c_str()); + AddMenuItem(new cRecMenuItemFavoriteStatic(desc, rmsFavoritesUser1, active)); + active = false; + numFavorites++; + } + if (config.favUseTime2) { + string desc = *cString::sprintf("%s (%s)", config.descUser2.c_str(), NiceTime(config.favTime2).c_str()); + AddMenuItem(new cRecMenuItemFavoriteStatic(desc, rmsFavoritesUser2, active)); + active = false; + numFavorites++; + } + if (config.favUseTime3) { + string desc = *cString::sprintf("%s (%s)", config.descUser3.c_str(), NiceTime(config.favTime3).c_str()); + AddMenuItem(new cRecMenuItemFavoriteStatic(desc, rmsFavoritesUser3, active)); + active = false; + numFavorites++; + } + if (config.favUseTime4) { + string desc = *cString::sprintf("%s (%s)", config.descUser4.c_str(), NiceTime(config.favTime4).c_str()); + AddMenuItem(new cRecMenuItemFavoriteStatic(desc, rmsFavoritesUser4, active)); + active = false; + numFavorites++; + } + + int numAdditionalFavs = favorites.size(); + for (int i = 0; i < numAdditionalFavs; i++) { + AddMenuItem(new cRecMenuItemFavorite(favorites[i], rmsSearchTimerTest, active)); + active = false; + numFavorites++; + } +} + +string cRecMenuFavorites::NiceTime(int favTime) { + int hours = favTime/100; + int mins = favTime - hours * 100; + return *cString::sprintf("%02d:%02d", hours, mins); +} + +cTVGuideSearchTimer cRecMenuFavorites::GetFavorite(void) { + cRecMenuItemFavorite *activeItem = dynamic_cast<cRecMenuItemFavorite*>(GetActive()); + return activeItem->GetFavorite(); +} @@ -1,451 +1,451 @@ -#ifndef __TVGUIDE_RECMENUS_H
-#define __TVGUIDE_RECMENUS_H
-
-#define TEXTINPUTLENGTH 256
-
-#include "services/epgsearch.h"
-#include "recmenu.h"
-#include "recmanager.h"
-#include "timerconflict.h"
-#include "switchtimer.h"
-
-// --- cRecMenuMain ---------------------------------------------------------
-class cRecMenuMain : public cRecMenu {
-private:
- int intcallback;
- bool boolcallback;
- int stringselectcallback;
- char searchString[TEXTINPUTLENGTH];
- int timecallback;
- time_t daycallback;
-public:
- cRecMenuMain(bool epgSearchAvailable, bool timerActive, bool switchTimerActive);
- virtual ~cRecMenuMain(void) {};
-};
-
-/******************************************************************************************
-* Instant Timer Menus
-******************************************************************************************/
-
-// --- cRecMenuConfirmTimer ---------------------------------------------------------
-class cRecMenuConfirmTimer: public cRecMenu {
-public:
- cRecMenuConfirmTimer(const cEvent *event);
- virtual ~cRecMenuConfirmTimer(void) {};
-};
-
-// --- cRecMenuAskFolder ---------------------------------------------------------
-class cRecMenuAskFolder: public cRecMenu {
-private:
- vector<string> folders;
- eRecMenuState nextAction;
-public:
- cRecMenuAskFolder(const cEvent *event, eRecMenuState nextAction);
- virtual ~cRecMenuAskFolder(void) {};
- string GetFolder(void);
-};
-
-// --- cRecMenuConfirmDeleteTimer ---------------------------------------------------------
-class cRecMenuConfirmDeleteTimer: public cRecMenu {
-public:
- cRecMenuConfirmDeleteTimer(const cEvent *event);
- virtual ~cRecMenuConfirmDeleteTimer(void) {};
-};
-
-// --- cRecMenuAskDeleteTimer ---------------------------------------------------------
-class cRecMenuAskDeleteTimer: public cRecMenu {
-public:
- cRecMenuAskDeleteTimer(const cEvent *event);
- virtual ~cRecMenuAskDeleteTimer(void) {};
-};
-
-// --- cRecMenuTimerConflicts ---------------------------------------------------------
-class cRecMenuTimerConflicts: public cRecMenu {
-public:
- cRecMenuTimerConflicts(cTVGuideTimerConflicts *conflicts);
- virtual ~cRecMenuTimerConflicts(void) {};
- int GetTimerConflict(void);
-};
-
-// --- cRecMenuTimerConflict ---------------------------------------------------------
-class cRecMenuTimerConflict: public cRecMenu {
-private:
- cTVGuideTimerConflict *conflict;
-public:
- cRecMenuTimerConflict(cTVGuideTimerConflict *conflict);
- virtual ~cRecMenuTimerConflict(void) {};
- int GetTimerConflictIndex(void);
-};
-
-// --- cRecMenuNoTimerConflict ---------------------------------------------------------
-class cRecMenuNoTimerConflict: public cRecMenu {
-public:
- cRecMenuNoTimerConflict(void);
- virtual ~cRecMenuNoTimerConflict(void) {};
-};
-
-// --- cRecMenuRerunResults ---------------------------------------------------------
-class cRecMenuRerunResults: public cRecMenu {
-private:
- const cEvent **reruns;
- int numReruns;
-public:
- cRecMenuRerunResults(const cEvent *original, const cEvent **reruns, int numReruns);
- int GetTotalNumMenuItems(void);
- virtual ~cRecMenuRerunResults(void) {
- delete[] reruns;
- };
- const cEvent *GetEvent(void);
-};
-
-// --- cRecMenuNoRerunsFound ---------------------------------------------------------
-class cRecMenuNoRerunsFound: public cRecMenu {
-public:
- cRecMenuNoRerunsFound(string searchString);
- virtual ~cRecMenuNoRerunsFound(void) {};
-};
-
-// --- cRecMenuConfirmRerunUsed ---------------------------------------------------------
-class cRecMenuConfirmRerunUsed: public cRecMenu {
-public:
- cRecMenuConfirmRerunUsed(const cEvent *original, const cEvent *replace);
- virtual ~cRecMenuConfirmRerunUsed(void) {};
-};
-
-// --- cRecMenuEditTimer ---------------------------------------------------------
-class cRecMenuEditTimer: public cRecMenu {
-private:
- cTimer *originalTimer;
- bool timerActive;
- time_t day;
- int start;
- int stop;
- int prio;
- int lifetime;
- char folder[TEXTINPUTLENGTH];
-public:
- cRecMenuEditTimer(cTimer *timer, eRecMenuState nextState);
- virtual ~cRecMenuEditTimer(void) {};
- cTimer GetTimer(void);
- cTimer *GetOriginalTimer(void);
-};
-
-/******************************************************************************************
-* Series Timer Menus
-******************************************************************************************/
-
-// --- cRecMenuSeriesTimer ---------------------------------------------------------
-class cRecMenuSeriesTimer: public cRecMenu {
- string folder;
- bool timerActive;
- int channel;
- time_t tstart;
- int start;
- int stop;
- int dayOfWeek;
- int priority;
- int lifetime;
- void CalculateTimes(const cEvent *event);
-public:
- cRecMenuSeriesTimer(cChannel *initialChannel, const cEvent *event, string folder);
- virtual ~cRecMenuSeriesTimer(void) {};
- cTimer *GetTimer(void);
-};
-
-// --- cRecMenuConfirmSeriesTimer ---------------------------------------------------------
-class cRecMenuConfirmSeriesTimer: public cRecMenu {
-public:
- cRecMenuConfirmSeriesTimer(cTimer *seriesTimer);
- virtual ~cRecMenuConfirmSeriesTimer(void) {};
-};
-
-/******************************************************************************************
-* SearchTimer Menus
-******************************************************************************************/
-
-// --- cRecMenuSearchTimer ---------------------------------------------------------
-class cRecMenuSearchTimer: public cRecMenu {
-private:
- char searchString[TEXTINPUTLENGTH];
-public:
- cRecMenuSearchTimer(const cEvent *event);
- virtual ~cRecMenuSearchTimer(void) {};
- string GetSearchString(void) { return searchString; };
-};
-
-// --- cRecMenuSearchTimerTemplates ---------------------------------------------------------
-class cRecMenuSearchTimerTemplates: public cRecMenu {
-private:
- int numTemplates;
- cTVGuideSearchTimer searchTimer;
- vector<TVGuideEPGSearchTemplate> templates;
-public:
- cRecMenuSearchTimerTemplates(cTVGuideSearchTimer searchTimer, vector<TVGuideEPGSearchTemplate> templates);
- virtual ~cRecMenuSearchTimerTemplates(void) {};
- cTVGuideSearchTimer GetSearchTimer(void) { return searchTimer; };
- TVGuideEPGSearchTemplate GetTemplate(void);
-};
-
-// --- cRecMenuSearchTimers ---------------------------------------------------------
-class cRecMenuSearchTimers: public cRecMenu {
-private:
- int numSearchTimers;
- vector<cTVGuideSearchTimer> searchTimers;
- void SetMenuItems(void);
-public:
- cRecMenuSearchTimers(vector<cTVGuideSearchTimer> searchTimers);
- virtual ~cRecMenuSearchTimers(void) {};
- cTVGuideSearchTimer GetSearchTimer(void);
-};
-
-// --- cRecMenuSearchTimerEdit ---------------------------------------------------------
-class cRecMenuSearchTimerEdit: public cRecMenu {
-private:
- bool advancedOptions;
- cTVGuideSearchTimer searchTimer;
- char searchString[TEXTINPUTLENGTH];
- bool timerActive;
- int mode;
- bool useTitle;
- bool useSubtitle;
- bool useDescription;
- bool useChannel;
- int startChannel;
- int stopChannel;
- bool useTime;
- int startTime;
- int stopTime;
- bool useDayOfWeek;
- int dayOfWeek;
- int priority;
- int lifetime;
- bool useEpisode;
- char directory[TEXTINPUTLENGTH];
- int marginStart;
- int marginStop;
- bool useVPS;
- bool avoidRepeats;
- int allowedRepeats;
- bool compareTitle;
- bool compareSubtitle;
- bool compareSummary;
- bool useInFavorites;
- void CreateMenuItems(void);
-public:
- cRecMenuSearchTimerEdit(cTVGuideSearchTimer searchTimer, bool advancedOptions);
- virtual ~cRecMenuSearchTimerEdit(void) {};
- cTVGuideSearchTimer GetSearchTimer(void);
-};
-
-// --- cRecMenuSearchTimerDeleteConfirm ---------------------------------------------
-class cRecMenuSearchTimerDeleteConfirm: public cRecMenu {
-private:
- cTVGuideSearchTimer searchTimer;
-public:
- cRecMenuSearchTimerDeleteConfirm(cTVGuideSearchTimer searchTimer);
- virtual ~cRecMenuSearchTimerDeleteConfirm(void) {};
- cTVGuideSearchTimer GetSearchTimer(void);
-};
-
-// --- cRecMenuSearchTimerCreateConfirm ---------------------------------------------------------
-class cRecMenuSearchTimerCreateConfirm: public cRecMenu {
-private:
-public:
- cRecMenuSearchTimerCreateConfirm(bool success);
- virtual ~cRecMenuSearchTimerCreateConfirm(void) {};
-};
-
-// --- cRecMenuSearchTimerTemplatesCreate ---------------------------------------------------------
-class cRecMenuSearchTimerTemplatesCreate: public cRecMenu {
-private:
- TVGuideEPGSearchTemplate templ;
- cTVGuideSearchTimer searchTimer;
-public:
- cRecMenuSearchTimerTemplatesCreate(TVGuideEPGSearchTemplate templ, cTVGuideSearchTimer searchTimer);
- virtual ~cRecMenuSearchTimerTemplatesCreate(void) {};
- cTVGuideSearchTimer GetSearchTimer(void) { return searchTimer; };
- TVGuideEPGSearchTemplate GetTemplate(void) { return templ; };
-};
-
-// --- cRecMenuSearchTimerResults ---------------------------------------------------------
-class cRecMenuSearchTimerResults: public cRecMenu {
-private:
- const cEvent **searchResults;
- int numResults;
- eRecMenuState action2;
-public:
- cRecMenuSearchTimerResults(string searchString, const cEvent **searchResults, int numResults, string templateName = "", eRecMenuState action2 = rmsDisabled);
- virtual ~cRecMenuSearchTimerResults(void) {
- delete[] searchResults;
- };
- const cEvent *GetEvent(void);
-};
-
-// --- cRecMenuSearchTimerNothingFound ---------------------------------------------------------
-class cRecMenuSearchTimerNothingFound: public cRecMenu {
-public:
- cRecMenuSearchTimerNothingFound(string searchString);
- virtual ~cRecMenuSearchTimerNothingFound(void) {};
-};
-
-/******************************************************************************************
-* SwitchTimer Menus
-******************************************************************************************/
-
-// --- cRecMenuSwitchTimer ---------------------------------------------------------
-class cRecMenuSwitchTimer: public cRecMenu {
-private:
- int switchMinsBefore;
- int announceOnly;
-public:
- cRecMenuSwitchTimer(void);
- virtual ~cRecMenuSwitchTimer(void) {};
- cSwitchTimer GetSwitchTimer(void);
-};
-
-// --- cRecMenuSwitchTimerConfirm ---------------------------------------------------------
-class cRecMenuSwitchTimerConfirm: public cRecMenu {
-private:
-public:
- cRecMenuSwitchTimerConfirm(bool success);
- virtual ~cRecMenuSwitchTimerConfirm(void) {};
-};
-
-// --- cRecMenuSwitchTimerDelete ---------------------------------------------------------
-class cRecMenuSwitchTimerDelete: public cRecMenu {
-private:
-public:
- cRecMenuSwitchTimerDelete(void);
- virtual ~cRecMenuSwitchTimerDelete(void) {};
-};
-
-/******************************************************************************************
-* Search Menus
-******************************************************************************************/
-
-// --- cRecMenuSearch ---------------------------------------------------------
-class cRecMenuSearch: public cRecMenu {
-private:
- char searchString[TEXTINPUTLENGTH];
- int mode;
- int channelNr;
- bool useTitle;
- bool useSubTitle;
- bool useDescription;
-public:
- cRecMenuSearch(string searchString, bool withOptions);
- virtual ~cRecMenuSearch(void) {};
- string GetSearchString(void) { return searchString; };
- Epgsearch_searchresults_v1_0 GetEPGSearchStruct(void);
-};
-
-// --- cRecMenuSearchResults ---------------------------------------------------------
-class cRecMenuSearchResults: public cRecMenu {
-private:
- string searchString;
- const cEvent **searchResults;
- int numResults;
-public:
- cRecMenuSearchResults(string searchString, const cEvent **searchResults, int numResults);
- virtual ~cRecMenuSearchResults(void) {
- delete[] searchResults;
- };
- string GetSearchString(void) { return searchString; };
- const cEvent *GetEvent(void);
-};
-
-// --- cRecMenuSearchNothingFound ---------------------------------------------------------
-class cRecMenuSearchNothingFound: public cRecMenu {
-public:
- cRecMenuSearchNothingFound(string searchString, bool tooShort = false);
- virtual ~cRecMenuSearchNothingFound(void) {};
-};
-
-// --- cRecMenuSearchConfirmTimer ---------------------------------------------------------
-class cRecMenuSearchConfirmTimer: public cRecMenu {
-public:
- cRecMenuSearchConfirmTimer(const cEvent *event);
- virtual ~cRecMenuSearchConfirmTimer(void) {};
-};
-
-/******************************************************************************************
-* Timeline
-******************************************************************************************/
-
-// --- cRecMenuTimeline ---------------------------------------------------------
-class cRecMenuTimeline: public cRecMenu {
-private:
- vector<cTimer*> timersToday;
- int numTimersToday;
- time_t today;
- time_t timeStart;
- time_t timeStop;
- cRecMenuItemTimelineHeader *timelineHeader;
- cRecMenuItem *timelineFooter;
- void SetStartStop(void);
- void GetTimersForDay(void);
- void SetTimers(void);
- void PrevDay(void);
- void NextDay(void);
- void ClearMenu(void);
-public:
- cRecMenuTimeline(void);
- virtual ~cRecMenuTimeline(void) {};
- eRecMenuState ProcessKey(eKeys Key);
- void SetHeaderTimer(void);
- cTimer *GetTimer(void);
-};
-
-/******************************************************************************************
-* Recording Search Menus
-******************************************************************************************/
-
-// --- cRecMenuRecordingSearch ---------------------------------------------------------
-class cRecMenuRecordingSearch: public cRecMenu {
-private:
- char searchString[TEXTINPUTLENGTH];
-public:
- cRecMenuRecordingSearch(string search);
- virtual ~cRecMenuRecordingSearch(void) {};
- string GetSearchString(void) { return searchString; };
-};
-
-// --- cRecMenuRecordingSearchResults ---------------------------------------------------------
-class cRecMenuRecordingSearchResults: public cRecMenu {
-private:
- string searchString;
- cRecording **searchResults;
- int numResults;
-public:
- cRecMenuRecordingSearchResults(string searchString, cRecording **searchResults, int numResults);
- virtual ~cRecMenuRecordingSearchResults(void) {
- delete[] searchResults;
- };
- string GetSearchString(void) { return searchString; };
-};
-
-// --- cRecMenuRecordingSearchNotFound ---------------------------------------------------------
-class cRecMenuRecordingSearchNotFound: public cRecMenu {
-public:
- cRecMenuRecordingSearchNotFound(string searchString);
- virtual ~cRecMenuRecordingSearchNotFound(void) {};
-};
-
-/******************************************************************************************
-* Favorites
-******************************************************************************************/
-
-// --- cRecMenuFavorites ---------------------------------------------------------
-class cRecMenuFavorites: public cRecMenu {
-private:
- vector<cTVGuideSearchTimer> favorites;
- int numFavorites;
- void CreateFavoritesMenuItems(void);
- string NiceTime(int favTime);
-public:
- cRecMenuFavorites(vector<cTVGuideSearchTimer> favorites);
- virtual ~cRecMenuFavorites(void) {};
- cTVGuideSearchTimer GetFavorite(void);
-};
-
-#endif //__TVGUIDE_RECMENUS_H
\ No newline at end of file +#ifndef __TVGUIDE_RECMENUS_H +#define __TVGUIDE_RECMENUS_H + +#define TEXTINPUTLENGTH 256 + +#include "services/epgsearch.h" +#include "recmenu.h" +#include "recmanager.h" +#include "timerconflict.h" +#include "switchtimer.h" + +// --- cRecMenuMain --------------------------------------------------------- +class cRecMenuMain : public cRecMenu { +private: + int intcallback; + bool boolcallback; + int stringselectcallback; + char searchString[TEXTINPUTLENGTH]; + int timecallback; + time_t daycallback; +public: + cRecMenuMain(bool epgSearchAvailable, bool timerActive, bool switchTimerActive); + virtual ~cRecMenuMain(void) {}; +}; + +/****************************************************************************************** +* Instant Timer Menus +******************************************************************************************/ + +// --- cRecMenuConfirmTimer --------------------------------------------------------- +class cRecMenuConfirmTimer: public cRecMenu { +public: + cRecMenuConfirmTimer(const cEvent *event); + virtual ~cRecMenuConfirmTimer(void) {}; +}; + +// --- cRecMenuAskFolder --------------------------------------------------------- +class cRecMenuAskFolder: public cRecMenu { +private: + vector<string> folders; + eRecMenuState nextAction; +public: + cRecMenuAskFolder(const cEvent *event, eRecMenuState nextAction); + virtual ~cRecMenuAskFolder(void) {}; + string GetFolder(void); +}; + +// --- cRecMenuConfirmDeleteTimer --------------------------------------------------------- +class cRecMenuConfirmDeleteTimer: public cRecMenu { +public: + cRecMenuConfirmDeleteTimer(const cEvent *event); + virtual ~cRecMenuConfirmDeleteTimer(void) {}; +}; + +// --- cRecMenuAskDeleteTimer --------------------------------------------------------- +class cRecMenuAskDeleteTimer: public cRecMenu { +public: + cRecMenuAskDeleteTimer(const cEvent *event); + virtual ~cRecMenuAskDeleteTimer(void) {}; +}; + +// --- cRecMenuTimerConflicts --------------------------------------------------------- +class cRecMenuTimerConflicts: public cRecMenu { +public: + cRecMenuTimerConflicts(cTVGuideTimerConflicts *conflicts); + virtual ~cRecMenuTimerConflicts(void) {}; + int GetTimerConflict(void); +}; + +// --- cRecMenuTimerConflict --------------------------------------------------------- +class cRecMenuTimerConflict: public cRecMenu { +private: + cTVGuideTimerConflict *conflict; +public: + cRecMenuTimerConflict(cTVGuideTimerConflict *conflict); + virtual ~cRecMenuTimerConflict(void) {}; + int GetTimerConflictIndex(void); +}; + +// --- cRecMenuNoTimerConflict --------------------------------------------------------- +class cRecMenuNoTimerConflict: public cRecMenu { +public: + cRecMenuNoTimerConflict(void); + virtual ~cRecMenuNoTimerConflict(void) {}; +}; + +// --- cRecMenuRerunResults --------------------------------------------------------- +class cRecMenuRerunResults: public cRecMenu { +private: + const cEvent **reruns; + int numReruns; +public: + cRecMenuRerunResults(const cEvent *original, const cEvent **reruns, int numReruns); + int GetTotalNumMenuItems(void); + virtual ~cRecMenuRerunResults(void) { + delete[] reruns; + }; + const cEvent *GetEvent(void); +}; + +// --- cRecMenuNoRerunsFound --------------------------------------------------------- +class cRecMenuNoRerunsFound: public cRecMenu { +public: + cRecMenuNoRerunsFound(string searchString); + virtual ~cRecMenuNoRerunsFound(void) {}; +}; + +// --- cRecMenuConfirmRerunUsed --------------------------------------------------------- +class cRecMenuConfirmRerunUsed: public cRecMenu { +public: + cRecMenuConfirmRerunUsed(const cEvent *original, const cEvent *replace); + virtual ~cRecMenuConfirmRerunUsed(void) {}; +}; + +// --- cRecMenuEditTimer --------------------------------------------------------- +class cRecMenuEditTimer: public cRecMenu { +private: + const cTimer *originalTimer; + bool timerActive; + time_t day; + int start; + int stop; + int prio; + int lifetime; + char folder[TEXTINPUTLENGTH]; +public: + cRecMenuEditTimer(const cTimer *timer, eRecMenuState nextState); + virtual ~cRecMenuEditTimer(void) {}; + cTimer GetTimer(void); + const cTimer *GetOriginalTimer(void); +}; + +/****************************************************************************************** +* Series Timer Menus +******************************************************************************************/ + +// --- cRecMenuSeriesTimer --------------------------------------------------------- +class cRecMenuSeriesTimer: public cRecMenu { + string folder; + bool timerActive; + int channel; + time_t tstart; + int start; + int stop; + int dayOfWeek; + int priority; + int lifetime; + void CalculateTimes(const cEvent *event); +public: + cRecMenuSeriesTimer(const cChannel *initialChannel, const cEvent *event, string folder); + virtual ~cRecMenuSeriesTimer(void) {}; + cTimer *GetTimer(void); +}; + +// --- cRecMenuConfirmSeriesTimer --------------------------------------------------------- +class cRecMenuConfirmSeriesTimer: public cRecMenu { +public: + cRecMenuConfirmSeriesTimer(cTimer *seriesTimer); + virtual ~cRecMenuConfirmSeriesTimer(void) {}; +}; + +/****************************************************************************************** +* SearchTimer Menus +******************************************************************************************/ + +// --- cRecMenuSearchTimer --------------------------------------------------------- +class cRecMenuSearchTimer: public cRecMenu { +private: + char searchString[TEXTINPUTLENGTH]; +public: + cRecMenuSearchTimer(const cEvent *event); + virtual ~cRecMenuSearchTimer(void) {}; + string GetSearchString(void) { return searchString; }; +}; + +// --- cRecMenuSearchTimerTemplates --------------------------------------------------------- +class cRecMenuSearchTimerTemplates: public cRecMenu { +private: + int numTemplates; + cTVGuideSearchTimer searchTimer; + vector<TVGuideEPGSearchTemplate> templates; +public: + cRecMenuSearchTimerTemplates(cTVGuideSearchTimer searchTimer, vector<TVGuideEPGSearchTemplate> templates); + virtual ~cRecMenuSearchTimerTemplates(void) {}; + cTVGuideSearchTimer GetSearchTimer(void) { return searchTimer; }; + TVGuideEPGSearchTemplate GetTemplate(void); +}; + +// --- cRecMenuSearchTimers --------------------------------------------------------- +class cRecMenuSearchTimers: public cRecMenu { +private: + int numSearchTimers; + vector<cTVGuideSearchTimer> searchTimers; + void SetMenuItems(void); +public: + cRecMenuSearchTimers(vector<cTVGuideSearchTimer> searchTimers); + virtual ~cRecMenuSearchTimers(void) {}; + cTVGuideSearchTimer GetSearchTimer(void); +}; + +// --- cRecMenuSearchTimerEdit --------------------------------------------------------- +class cRecMenuSearchTimerEdit: public cRecMenu { +private: + bool advancedOptions; + cTVGuideSearchTimer searchTimer; + char searchString[TEXTINPUTLENGTH]; + bool timerActive; + int mode; + bool useTitle; + bool useSubtitle; + bool useDescription; + bool useChannel; + int startChannel; + int stopChannel; + bool useTime; + int startTime; + int stopTime; + bool useDayOfWeek; + int dayOfWeek; + int priority; + int lifetime; + bool useEpisode; + char directory[TEXTINPUTLENGTH]; + int marginStart; + int marginStop; + bool useVPS; + bool avoidRepeats; + int allowedRepeats; + bool compareTitle; + bool compareSubtitle; + bool compareSummary; + bool useInFavorites; + void CreateMenuItems(void); +public: + cRecMenuSearchTimerEdit(cTVGuideSearchTimer searchTimer, bool advancedOptions); + virtual ~cRecMenuSearchTimerEdit(void) {}; + cTVGuideSearchTimer GetSearchTimer(void); +}; + +// --- cRecMenuSearchTimerDeleteConfirm --------------------------------------------- +class cRecMenuSearchTimerDeleteConfirm: public cRecMenu { +private: + cTVGuideSearchTimer searchTimer; +public: + cRecMenuSearchTimerDeleteConfirm(cTVGuideSearchTimer searchTimer); + virtual ~cRecMenuSearchTimerDeleteConfirm(void) {}; + cTVGuideSearchTimer GetSearchTimer(void); +}; + +// --- cRecMenuSearchTimerCreateConfirm --------------------------------------------------------- +class cRecMenuSearchTimerCreateConfirm: public cRecMenu { +private: +public: + cRecMenuSearchTimerCreateConfirm(bool success); + virtual ~cRecMenuSearchTimerCreateConfirm(void) {}; +}; + +// --- cRecMenuSearchTimerTemplatesCreate --------------------------------------------------------- +class cRecMenuSearchTimerTemplatesCreate: public cRecMenu { +private: + TVGuideEPGSearchTemplate templ; + cTVGuideSearchTimer searchTimer; +public: + cRecMenuSearchTimerTemplatesCreate(TVGuideEPGSearchTemplate templ, cTVGuideSearchTimer searchTimer); + virtual ~cRecMenuSearchTimerTemplatesCreate(void) {}; + cTVGuideSearchTimer GetSearchTimer(void) { return searchTimer; }; + TVGuideEPGSearchTemplate GetTemplate(void) { return templ; }; +}; + +// --- cRecMenuSearchTimerResults --------------------------------------------------------- +class cRecMenuSearchTimerResults: public cRecMenu { +private: + const cEvent **searchResults; + int numResults; + eRecMenuState action2; +public: + cRecMenuSearchTimerResults(string searchString, const cEvent **searchResults, int numResults, string templateName = "", eRecMenuState action2 = rmsDisabled); + virtual ~cRecMenuSearchTimerResults(void) { + delete[] searchResults; + }; + const cEvent *GetEvent(void); +}; + +// --- cRecMenuSearchTimerNothingFound --------------------------------------------------------- +class cRecMenuSearchTimerNothingFound: public cRecMenu { +public: + cRecMenuSearchTimerNothingFound(string searchString); + virtual ~cRecMenuSearchTimerNothingFound(void) {}; +}; + +/****************************************************************************************** +* SwitchTimer Menus +******************************************************************************************/ + +// --- cRecMenuSwitchTimer --------------------------------------------------------- +class cRecMenuSwitchTimer: public cRecMenu { +private: + int switchMinsBefore; + int announceOnly; +public: + cRecMenuSwitchTimer(void); + virtual ~cRecMenuSwitchTimer(void) {}; + cSwitchTimer GetSwitchTimer(void); +}; + +// --- cRecMenuSwitchTimerConfirm --------------------------------------------------------- +class cRecMenuSwitchTimerConfirm: public cRecMenu { +private: +public: + cRecMenuSwitchTimerConfirm(bool success); + virtual ~cRecMenuSwitchTimerConfirm(void) {}; +}; + +// --- cRecMenuSwitchTimerDelete --------------------------------------------------------- +class cRecMenuSwitchTimerDelete: public cRecMenu { +private: +public: + cRecMenuSwitchTimerDelete(void); + virtual ~cRecMenuSwitchTimerDelete(void) {}; +}; + +/****************************************************************************************** +* Search Menus +******************************************************************************************/ + +// --- cRecMenuSearch --------------------------------------------------------- +class cRecMenuSearch: public cRecMenu { +private: + char searchString[TEXTINPUTLENGTH]; + int mode; + int channelNr; + bool useTitle; + bool useSubTitle; + bool useDescription; +public: + cRecMenuSearch(string searchString, bool withOptions); + virtual ~cRecMenuSearch(void) {}; + string GetSearchString(void) { return searchString; }; + Epgsearch_searchresults_v1_0 GetEPGSearchStruct(void); +}; + +// --- cRecMenuSearchResults --------------------------------------------------------- +class cRecMenuSearchResults: public cRecMenu { +private: + string searchString; + const cEvent **searchResults; + int numResults; +public: + cRecMenuSearchResults(string searchString, const cEvent **searchResults, int numResults); + virtual ~cRecMenuSearchResults(void) { + delete[] searchResults; + }; + string GetSearchString(void) { return searchString; }; + const cEvent *GetEvent(void); +}; + +// --- cRecMenuSearchNothingFound --------------------------------------------------------- +class cRecMenuSearchNothingFound: public cRecMenu { +public: + cRecMenuSearchNothingFound(string searchString, bool tooShort = false); + virtual ~cRecMenuSearchNothingFound(void) {}; +}; + +// --- cRecMenuSearchConfirmTimer --------------------------------------------------------- +class cRecMenuSearchConfirmTimer: public cRecMenu { +public: + cRecMenuSearchConfirmTimer(const cEvent *event); + virtual ~cRecMenuSearchConfirmTimer(void) {}; +}; + +/****************************************************************************************** +* Timeline +******************************************************************************************/ + +// --- cRecMenuTimeline --------------------------------------------------------- +class cRecMenuTimeline: public cRecMenu { +private: + vector<const cTimer*> timersToday; + int numTimersToday; + time_t today; + time_t timeStart; + time_t timeStop; + cRecMenuItemTimelineHeader *timelineHeader; + cRecMenuItem *timelineFooter; + void SetStartStop(void); + void GetTimersForDay(void); + void SetTimers(void); + void PrevDay(void); + void NextDay(void); + void ClearMenu(void); +public: + cRecMenuTimeline(void); + virtual ~cRecMenuTimeline(void) {}; + eRecMenuState ProcessKey(eKeys Key); + void SetHeaderTimer(void); + const cTimer *GetTimer(void); +}; + +/****************************************************************************************** +* Recording Search Menus +******************************************************************************************/ + +// --- cRecMenuRecordingSearch --------------------------------------------------------- +class cRecMenuRecordingSearch: public cRecMenu { +private: + char searchString[TEXTINPUTLENGTH]; +public: + cRecMenuRecordingSearch(string search); + virtual ~cRecMenuRecordingSearch(void) {}; + string GetSearchString(void) { return searchString; }; +}; + +// --- cRecMenuRecordingSearchResults --------------------------------------------------------- +class cRecMenuRecordingSearchResults: public cRecMenu { +private: + string searchString; + const cRecording **searchResults; + int numResults; +public: + cRecMenuRecordingSearchResults(string searchString, const cRecording **searchResults, int numResults); + virtual ~cRecMenuRecordingSearchResults(void) { + delete[] searchResults; + }; + string GetSearchString(void) { return searchString; }; +}; + +// --- cRecMenuRecordingSearchNotFound --------------------------------------------------------- +class cRecMenuRecordingSearchNotFound: public cRecMenu { +public: + cRecMenuRecordingSearchNotFound(string searchString); + virtual ~cRecMenuRecordingSearchNotFound(void) {}; +}; + +/****************************************************************************************** +* Favorites +******************************************************************************************/ + +// --- cRecMenuFavorites --------------------------------------------------------- +class cRecMenuFavorites: public cRecMenu { +private: + vector<cTVGuideSearchTimer> favorites; + int numFavorites; + void CreateFavoritesMenuItems(void); + string NiceTime(int favTime); +public: + cRecMenuFavorites(vector<cTVGuideSearchTimer> favorites); + virtual ~cRecMenuFavorites(void) {}; + cTVGuideSearchTimer GetFavorite(void); +}; + +#endif //__TVGUIDE_RECMENUS_H diff --git a/recmenuview.c b/recmenuview.c index a4c8ceb..67c4ac4 100644 --- a/recmenuview.c +++ b/recmenuview.c @@ -1,860 +1,897 @@ -#include "tvguidengosd.h"
-#include "recmenuview.h"
-
-cRecMenuView::cRecMenuView(void) {
- active = false;
- recMenuView = NULL;
- recMenuViewBuffer = NULL;
- recMenuViewBuffer2 = NULL;
- event = NULL;
- displayEvent = NULL;
- activeMenu = NULL;
- activeMenuBuffer = NULL;
- activeMenuBuffer2 = NULL;
- recManager = new cRecManager();
- recManager->SetEPGSearchPlugin();
- timerConflicts = NULL;
-}
-
-cRecMenuView::~cRecMenuView() {
- if (activeMenu)
- delete activeMenu;
- if (activeMenuBuffer)
- delete activeMenuBuffer;
- if (activeMenuBuffer2)
- delete activeMenuBuffer2;
- if (recMenuView)
- delete recMenuView;
- if (recMenuViewBuffer)
- delete recMenuViewBuffer;
- if (recMenuViewBuffer2)
- delete recMenuViewBuffer2;
-}
-
-void cRecMenuView::Init(skindesignerapi::cOsdView *recMenuView, skindesignerapi::cOsdView *recMenuViewBuffer, skindesignerapi::cOsdView *recMenuViewBuffer2) {
- active = true;
- this->recMenuView = recMenuView;
- this->recMenuViewBuffer = recMenuViewBuffer;
- this->recMenuViewBuffer2 = recMenuViewBuffer2;
-}
-
-void cRecMenuView::DisplayRecMenu(const cEvent *event) {
- if (!event) {
- return;
- }
- this->event = event;
- activeMenu = new cRecMenuMain(recManager->EpgSearchAvailable(), recManager->CheckEventForTimer(event), SwitchTimers.EventInSwitchList(event));
- DisplayMenu();
-}
-
-void cRecMenuView::DisplayFavorites(void) {
- vector<cTVGuideSearchTimer> favorites;
- recManager->GetFavorites(&favorites);
- activeMenu = new cRecMenuFavorites(favorites);
- DisplayMenu();
-}
-
-void cRecMenuView::DisplayRecSearch(const cEvent *e) {
- activeMenu = new cRecMenuRecordingSearch(e->Title() ? e->Title() : "");
- DisplayMenu();
-}
-
-void cRecMenuView::DisplaySearchEPG(const cEvent *e) {
- activeMenu = new cRecMenuSearch(e->Title() ? e->Title() : "", false);
- DisplayMenu();
-}
-
-void cRecMenuView::Close(void) {
- if (activeMenu) {
- delete activeMenu;
- activeMenu = NULL;
- }
- if (activeMenuBuffer) {
- delete activeMenuBuffer;
- activeMenuBuffer = NULL;
- }
- if (activeMenuBuffer2) {
- delete activeMenuBuffer2;
- activeMenuBuffer2 = NULL;
- }
- delete recMenuView;
- recMenuView = NULL;
- delete recMenuViewBuffer;
- recMenuViewBuffer = NULL;
- delete recMenuViewBuffer2;
- recMenuViewBuffer2 = NULL;
- active = false;
-}
-
-void cRecMenuView::Hide(bool full) {
- if (recMenuViewBuffer) {
- recMenuViewBuffer->Deactivate(true);
- if (full)
- recMenuView->Deactivate(true);
- } else
- recMenuView->Deactivate(true);
-}
-
-void cRecMenuView::Activate(bool full) {
- if (recMenuViewBuffer) {
- recMenuViewBuffer->Activate();
- if (full)
- recMenuView->Activate();
- } else
- recMenuView->Activate();
-}
-
-eOSState cRecMenuView::ProcessKey(eKeys Key) {
- eOSState state = osContinue;
- eRecMenuState nextState = rmsContinue;
- if (!activeMenu)
- return state;
- nextState = activeMenu->ProcessKey(Key);
- if ((nextState == rmsClose) || ((nextState == rmsNotConsumed)&&(Key == kBack))) {
- if (activeMenuBuffer2) {
- delete activeMenu;
- activeMenu = activeMenuBuffer2;
- activeMenuBuffer2 = NULL;
- activeMenu->Show();
- return osContinue;
- } else if (activeMenuBuffer) {
- delete activeMenu;
- activeMenu = activeMenuBuffer;
- activeMenuBuffer = NULL;
- activeMenu->Show();
- return osContinue;
- } else {
- Close();
- return osEnd;
- }
- }
- state = StateMachine(nextState);
- if (activeMenu)
- activeMenu->Flush();
- return state;
-}
-
-void cRecMenuView::DisplayMenu(bool buffer, bool buffer2) {
- if (!activeMenu)
- return;
- if (buffer) {
- activeMenu->Init(recMenuViewBuffer);
- } else if (buffer2) {
- activeMenu->Init(recMenuViewBuffer2);
- } else {
- activeMenu->Init(recMenuView);
- }
- if (cRecMenuTimeline *timeline = dynamic_cast<cRecMenuTimeline*>(activeMenu)) {
- timeline->SetHeaderTimer();
- }
- activeMenu->Draw();
-}
-
-void cRecMenuView::DisplaySearchTimerList(void) {
- delete activeMenu;
- vector<cTVGuideSearchTimer> searchTimers;
- recManager->GetSearchTimers(&searchTimers);
- activeMenu = new cRecMenuSearchTimers(searchTimers);
- DisplayMenu();
-}
-
-bool cRecMenuView::DisplayTimerConflict(cTimer *timer) {
- int timerID = 0;
- for (cTimer *t = Timers.First(); t; t = Timers.Next(t)) {
- if (t == timer)
- return DisplayTimerConflict(timerID);
- timerID++;
- }
- return false;
-}
-
-bool cRecMenuView::DisplayTimerConflict(int timerID) {
- if (timerConflicts)
- delete timerConflicts;
- timerConflicts = recManager->CheckTimerConflict();
- if (!timerConflicts)
- return false;
- int showTimerConflict = timerConflicts->GetCorrespondingConflict(timerID);
- if (showTimerConflict > -1) {
- timerConflicts->SetCurrentConflict(showTimerConflict);
- cTVGuideTimerConflict *conflict = timerConflicts->GetCurrentConflict();
- if (!conflict)
- return false;
- activeMenu = new cRecMenuTimerConflict(conflict);
- DisplayMenu();
- return true;
- }
- return false;
-}
-
-void cRecMenuView::DisplayFavoriteResults(string header, const cEvent **result, int numResults) {
- if (numResults) {
- activeMenuBuffer = activeMenu;
- activeMenuBuffer->Hide();
- activeMenu = new cRecMenuSearchTimerResults(header, result, numResults, "", rmsFavoritesRecord);
- } else {
- activeMenuBuffer = activeMenu;
- activeMenuBuffer->Hide();
- activeMenu = new cRecMenuSearchTimerNothingFound(header);
- }
- DisplayMenu(true);
-}
-
-eOSState cRecMenuView::StateMachine(eRecMenuState nextState) {
- eOSState state = osContinue;
- switch (nextState) {
-/***************************************************************************************
-* INSTANT RECORDING
-****************************************************************************************/
- case rmsInstantRecord: {
- //caller: main menu or folder chooser
- //Creating timer for active Event, if no conflict, confirm and exit
- string recFolder = "";
- if (cRecMenuAskFolder *menu = dynamic_cast<cRecMenuAskFolder*>(activeMenu)) {
- recFolder = menu->GetFolder();
- }
- delete activeMenu;
- cTimer *timer = recManager->createTimer(event, recFolder);
- if (!DisplayTimerConflict(timer)) {
- activeMenu = new cRecMenuConfirmTimer(event);
- DisplayMenu();
- }
- break; }
- case rmsInstantRecordFolder: {
- //caller: main menu
- //Asking for Folder
- delete activeMenu;
- activeMenu = new cRecMenuAskFolder(event, rmsInstantRecord);
- DisplayMenu();
- break; }
- case rmsDeleteTimer: {
- //caller: main menu
- //delete timer for active event
- delete activeMenu;
- if (recManager->IsRecorded(event)) {
- activeMenu = new cRecMenuAskDeleteTimer(event);
- } else {
- recManager->DeleteTimer(event);
- activeMenu = new cRecMenuConfirmDeleteTimer(event);
- }
- DisplayMenu();
- break; }
- case rmsDeleteTimerConfirmation: {
- //delete running timer for active event
- recManager->DeleteTimer(event);
- delete activeMenu;
- activeMenu = new cRecMenuConfirmDeleteTimer(event);
- DisplayMenu();
- break; }
- case rmsEditTimer: {
- //edit timer for active event
- cTimer *timer = recManager->GetTimerForEvent(event);
- if (timer) {
- delete activeMenu;
- activeMenu = new cRecMenuEditTimer(timer, rmsSaveTimer);
- DisplayMenu();
- }
- break; }
- case rmsSaveTimer: {
- //caller: cRecMenuEditTimer
- //save timer for active event
- cTimer timerModified;
- cTimer *originalTimer;
- if (cRecMenuEditTimer *menu = dynamic_cast<cRecMenuEditTimer*>(activeMenu)) {
- timerModified = menu->GetTimer();
- originalTimer = menu->GetOriginalTimer();
- } else break;
- recManager->SaveTimer(originalTimer, timerModified);
- Close();
- state = osEnd;
- break; }
- case rmsIgnoreTimerConflict:
- //caller: cRecMenuTimerConflict
- //Confirming created Timer
- delete activeMenu;
- activeMenu = new cRecMenuConfirmTimer(event);
- DisplayMenu();
- break;
- case rmsTimerConflictShowInfo: {
- //caller: cRecMenuTimerConflict
- int timerIndex;
- if (cRecMenuTimerConflict *menu = dynamic_cast<cRecMenuTimerConflict*>(activeMenu)) {
- timerIndex = menu->GetTimerConflictIndex();
- } else break;
- int timerID = timerConflicts->GetCurrentConflictTimerID(timerIndex);
- cTimer *t = Timers.Get(timerID);
- if (t) {
- displayEvent = t->Event();
- if (displayEvent) {
- state = osUser1;
- }
- }
- break; }
- case rmsDeleteTimerConflictMenu: {
- //caller: cRecMenuTimerConflict
- //delete timer out of current timer conflict
- int timerIndex;
- if (cRecMenuTimerConflict *menu = dynamic_cast<cRecMenuTimerConflict*>(activeMenu)) {
- timerIndex = menu->GetTimerConflictIndex();
- } else break;
- int timerID = timerConflicts->GetCurrentConflictTimerID(timerIndex);
- recManager->DeleteTimer(timerID);
- delete activeMenu;
- if (!DisplayTimerConflict(timerID)) {
- activeMenu = new cRecMenuConfirmTimer(event);
- DisplayMenu();
- }
- break; }
- case rmsEditTimerConflictMenu: {
- //caller: cRecMenuTimerConflict
- //edit timer out of current timer conflict
- int timerIndex;
- if (cRecMenuTimerConflict *menu = dynamic_cast<cRecMenuTimerConflict*>(activeMenu)) {
- timerIndex = menu->GetTimerConflictIndex();
- } else break;
- int timerID = timerConflicts->GetCurrentConflictTimerID(timerIndex);
- cTimer *timer = Timers.Get(timerID);
- if (timer) {
- delete activeMenu;
- activeMenu = new cRecMenuEditTimer(timer, rmsSaveTimerConflictMenu);
- DisplayMenu();
- }
- break; }
- case rmsSaveTimerConflictMenu: {
- //caller: cRecMenuEditTimer
- //save timer from current timer conflict
- cTimer timerModified;
- cTimer *originalTimer;
- if (cRecMenuEditTimer *menu = dynamic_cast<cRecMenuEditTimer*>(activeMenu)) {
- timerModified = menu->GetTimer();
- originalTimer = menu->GetOriginalTimer();
- } else break;
- recManager->SaveTimer(originalTimer, timerModified);
- delete activeMenu;
- if (!DisplayTimerConflict(originalTimer)) {
- activeMenu = new cRecMenuConfirmTimer(event);
- DisplayMenu();
- }
- break; }
-/***************************************************************************************
-* SERIES TIMER
-****************************************************************************************/
- case rmsSeriesTimer: {
- //caller: main menu oder folder chooser
- string recFolder = "";
- if (cRecMenuAskFolder *menu = dynamic_cast<cRecMenuAskFolder*>(activeMenu)) {
- recFolder = menu->GetFolder();
- }
- delete activeMenu;
- cChannel *channel = Channels.GetByChannelID(event->ChannelID());
- activeMenu = new cRecMenuSeriesTimer(channel, event, recFolder);
- DisplayMenu();
- break; }
- case rmsSeriesTimerFolder:
- //caller: main menu
- //Asking for Folder
- delete activeMenu;
- activeMenu = new cRecMenuAskFolder(event, rmsSeriesTimer);
- DisplayMenu();
- break;
- case rmsSeriesTimerCreate: {
- //caller: cRecMenuSeriesTimer
- cTimer *seriesTimer;
- if (cRecMenuSeriesTimer *menu = dynamic_cast<cRecMenuSeriesTimer*>(activeMenu)) {
- seriesTimer = menu->GetTimer();
- } else break;
- recManager->CreateSeriesTimer(seriesTimer);
- delete activeMenu;
- activeMenu = new cRecMenuConfirmSeriesTimer(seriesTimer);
- DisplayMenu();
- break; }
-/**********************************************************************************************
- * SWITCH TIMER
- ***********************************************************************************************/
- case rmsSwitchTimer:
- delete activeMenu;
- activeMenu = new cRecMenuSwitchTimer();
- DisplayMenu();
- break;
- case rmsSwitchTimerCreate: {
- cSwitchTimer switchTimer;
- if (cRecMenuSwitchTimer *menu = dynamic_cast<cRecMenuSwitchTimer*>(activeMenu)) {
- switchTimer = menu->GetSwitchTimer();
- } else break;
- bool success = recManager->CreateSwitchTimer(event, switchTimer);
- delete activeMenu;
- activeMenu = new cRecMenuSwitchTimerConfirm(success);
- DisplayMenu();
- break; }
- case rmsSwitchTimerDelete:
- recManager->DeleteSwitchTimer(event);
- delete activeMenu;
- activeMenu = new cRecMenuSwitchTimerDelete();
- DisplayMenu();
- break;
-/**********************************************************************************************
- * SEARCH TIMER
- ***********************************************************************************************/
- case rmsSearchTimer:
- //Caller: main menu
- //set search String for search timer
- delete activeMenu;
- activeMenu = new cRecMenuSearchTimer(event);
- DisplayMenu();
- break;
- case rmsSearchTimerOptions: {
- //Caller: cRecMenuSearchTimer, cRecMenuSearchTimerTemplates
- //Choose to set options manually or by template
- string searchString;
- cTVGuideSearchTimer searchTimer;
- bool reload = false;
- if (cRecMenuSearchTimer *menu = dynamic_cast<cRecMenuSearchTimer*>(activeMenu)) {
- searchString = menu->GetSearchString();
- } else if (cRecMenuSearchTimerTemplatesCreate *menu = dynamic_cast<cRecMenuSearchTimerTemplatesCreate*>(activeMenu)) {
- searchTimer = menu->GetSearchTimer();
- reload = true;
- } else break;
- delete activeMenu;
- if (searchString.size() < 4) {
- activeMenu = new cRecMenuSearchTimer(event);
- } else {
- if (!reload) {
- searchTimer.SetSearchString(searchString);
- }
- vector<TVGuideEPGSearchTemplate> epgSearchTemplates;
- recManager->ReadEPGSearchTemplates(&epgSearchTemplates);
- if (epgSearchTemplates.size() > 0) {
- activeMenu = new cRecMenuSearchTimerTemplates(searchTimer, epgSearchTemplates);
- } else {
- activeMenu = new cRecMenuSearchTimerEdit(searchTimer, false);
- }
- }
- DisplayMenu();
- break; }
- case rmsSearchTimers: {
- //caller: main menu
- DisplaySearchTimerList();
- break; }
- case rmsSearchTimerEdit:
- case rmsSearchTimerEditAdvanced: {
- //caller: cRecMenuSearchTimers, cRecMenuSearchTimerEdit, cRecMenuSearchTimerTemplates
- cTVGuideSearchTimer searchTimer;
- bool advancedOptions = false;
- if (cRecMenuSearchTimers *menu = dynamic_cast<cRecMenuSearchTimers*>(activeMenu)) {
- searchTimer = menu->GetSearchTimer();
- } else if (cRecMenuSearchTimerEdit *menu = dynamic_cast<cRecMenuSearchTimerEdit*>(activeMenu)) {
- searchTimer = menu->GetSearchTimer();
- advancedOptions = (nextState == rmsSearchTimerEditAdvanced)?true:false;
- } else if (cRecMenuSearchTimerTemplates *menu = dynamic_cast<cRecMenuSearchTimerTemplates*>(activeMenu)) {
- searchTimer = menu->GetSearchTimer();
- } else break;
- delete activeMenu;
- activeMenu = new cRecMenuSearchTimerEdit(searchTimer, advancedOptions);
- DisplayMenu();
- break; }
- case rmsSearchTimerTest: {
- //caller: cRecMenuSearchTimerEdit, cRecMenuSearchTimerTemplatesCreate, cRecMenuSearchTimers, cRecMenuFavorites
- //show results of currently choosen search timer
- cTVGuideSearchTimer searchTimer;
- eRecMenuState recState = rmsDisabled;
- if (cRecMenuSearchTimerEdit *menu = dynamic_cast<cRecMenuSearchTimerEdit*>(activeMenu)) {
- searchTimer = menu->GetSearchTimer();
- recState = rmsSearchTimerRecord;
- } else if (cRecMenuSearchTimers *menu = dynamic_cast<cRecMenuSearchTimers*>(activeMenu)) {
- searchTimer = menu->GetSearchTimer();
- recState = rmsSearchTimerRecord;
- } else if (cRecMenuSearchTimerTemplatesCreate *menu = dynamic_cast<cRecMenuSearchTimerTemplatesCreate*>(activeMenu)) {
- searchTimer = menu->GetSearchTimer();
- TVGuideEPGSearchTemplate tmpl = menu->GetTemplate();
- searchTimer.SetTemplate(tmpl.templValue);
- searchTimer.Parse(true);
- } else if (cRecMenuFavorites *menu = dynamic_cast<cRecMenuFavorites*>(activeMenu)) {
- searchTimer = menu->GetFavorite();
- recState = rmsFavoritesRecord;
- }
- else break;
- int numSearchResults = 0;
- string searchString = searchTimer.BuildSearchString();
- const cEvent **searchResult = recManager->PerformSearchTimerSearch(searchString, numSearchResults);
- if (numSearchResults) {
- activeMenuBuffer = activeMenu;
- activeMenuBuffer->Hide();
- activeMenu = new cRecMenuSearchTimerResults(searchTimer.SearchString(), searchResult, numSearchResults, "", recState);
- } else {
- activeMenuBuffer = activeMenu;
- activeMenuBuffer->Hide();
- activeMenu = new cRecMenuSearchTimerNothingFound(searchTimer.SearchString());
- }
- DisplayMenu(true);
- break; }
- case rmsSearchTimerSave: {
- //caller: cRecMenuSearchTimerEdit, cRecMenuSearchTimerTemplatesCreate
- //create new or modify existing search timer
- cTVGuideSearchTimer searchTimer;
- if (cRecMenuSearchTimerEdit *menu = dynamic_cast<cRecMenuSearchTimerEdit*>(activeMenu)) {
- searchTimer = menu->GetSearchTimer();
- } else if (cRecMenuSearchTimerTemplatesCreate *menu = dynamic_cast<cRecMenuSearchTimerTemplatesCreate*>(activeMenu)) {
- searchTimer = menu->GetSearchTimer();
- TVGuideEPGSearchTemplate tmpl = menu->GetTemplate();
- searchTimer.SetTemplate(tmpl.templValue);
- searchTimer.Parse(true);
- } else break;
- bool success = recManager->SaveSearchTimer(&searchTimer);
- recManager->UpdateSearchTimers();
- if (searchTimer.GetID() >= 0) {
- //Timer modified, show list
- DisplaySearchTimerList();
- } else {
- //new timer, confirm
- delete activeMenu;
- activeMenu = new cRecMenuSearchTimerCreateConfirm(success);
- DisplayMenu();
- }
- break; }
- case rmsSearchTimerCreateWithTemplate: {
- //caller: cRecMenuSearchTimerTemplates
- //create new search timer from template
- TVGuideEPGSearchTemplate templ;
- cTVGuideSearchTimer searchTimer;
- if (cRecMenuSearchTimerTemplates *menu = dynamic_cast<cRecMenuSearchTimerTemplates*>(activeMenu)) {
- templ = menu->GetTemplate();
- searchTimer = menu->GetSearchTimer();
- } else break;
- delete activeMenu;
- activeMenu = new cRecMenuSearchTimerTemplatesCreate(templ, searchTimer);
- DisplayMenu();
- break; }
- case rmsSearchTimerDeleteConfirm: {
- //caller: cRecMenuSearchTimers
- //Ask for confirmation and if timers created by this search timer should alo be deleted
- cTVGuideSearchTimer searchTimer;
- if (cRecMenuSearchTimers *menu = dynamic_cast<cRecMenuSearchTimers*>(activeMenu)) {
- searchTimer = menu->GetSearchTimer();
- } else break;
- activeMenuBuffer = activeMenu;
- activeMenuBuffer->Hide();
- activeMenu = new cRecMenuSearchTimerDeleteConfirm(searchTimer);
- DisplayMenu(true);
- break; }
- case rmsSearchTimerDelete:
- case rmsSearchTimerDeleteWithTimers: {
- //caller: cRecMenuSearchTimerDeleteConfirm
- //actually delete searchtimer
- cTVGuideSearchTimer searchTimer;
- if (cRecMenuSearchTimerDeleteConfirm *menu = dynamic_cast<cRecMenuSearchTimerDeleteConfirm*>(activeMenu)) {
- searchTimer = menu->GetSearchTimer();
- } else break;
- bool delTimers = (nextState==rmsSearchTimerDeleteWithTimers)?true:false;
- recManager->DeleteSearchTimer(&searchTimer, delTimers);
- delete activeMenuBuffer;
- activeMenuBuffer = NULL;
- DisplaySearchTimerList();
- break; }
- case rmsSearchTimerRecord: {
- //caller: cRecMenuSearchTimerResults
- const cEvent *ev = NULL;
- if (cRecMenuSearchTimerResults *menu = dynamic_cast<cRecMenuSearchTimerResults*>(activeMenu)) {
- ev = menu->GetEvent();
- } else break;
- if (!ev)
- break;
- recManager->createTimer(ev, "");
- activeMenuBuffer2 = activeMenu;
- activeMenuBuffer2->Hide();
- activeMenu = new cRecMenuSearchConfirmTimer(ev);
- DisplayMenu(false, true);
- break; }
-/**********************************************************************************************
-* SEARCH
-***********************************************************************************************/
- case rmsSearch:
- case rmsSearchWithOptions: {
- //caller: main menu, cRecMenuSearch, cRecMenuSearchResults
- bool withOptions = false;
- string searchString = event->Title();
- if (cRecMenuSearch *menu = dynamic_cast<cRecMenuSearch*>(activeMenu)) {
- withOptions = true;
- searchString = menu->GetSearchString();
- } else if (cRecMenuSearchResults *menu = dynamic_cast<cRecMenuSearchResults*>(activeMenu)) {
- searchString = menu->GetSearchString();
- }
- delete activeMenu;
- activeMenu = new cRecMenuSearch(searchString, withOptions);
- DisplayMenu();
- break; }
- case rmsSearchPerform: {
- //caller: cRecMenuSearch
- bool useBuffer = false;
- Epgsearch_searchresults_v1_0 epgSearchData;
- if (cRecMenuSearch *menu = dynamic_cast<cRecMenuSearch*>(activeMenu)) {
- epgSearchData = menu->GetEPGSearchStruct();
- } else break;
- string searchString = epgSearchData.query;
- if (searchString.size() < 3) {
- activeMenu->Hide();
- activeMenuBuffer = activeMenu;
- useBuffer = true;
- activeMenu = new cRecMenuSearchNothingFound(searchString, true);
- } else {
- int numSearchResults = 0;
- const cEvent **searchResult = recManager->PerformSearch(epgSearchData, numSearchResults);
- if (searchResult) {
- delete activeMenu;
- activeMenu = new cRecMenuSearchResults(searchString, searchResult, numSearchResults);
- } else {
- activeMenu->Hide();
- activeMenuBuffer = activeMenu;
- useBuffer = true;
- activeMenu = new cRecMenuSearchNothingFound(searchString);
- }
- }
- DisplayMenu(useBuffer);
- break; }
- case rmsSearchShowInfo: {
- //caller: cRecMenuSearchResults, cRecMenuSearchTimerResults, cRecMenuRerunResults
- if (cRecMenuSearchResults *menu = dynamic_cast<cRecMenuSearchResults*>(activeMenu)) {
- displayEvent = menu->GetEvent();
- } else if (cRecMenuSearchTimerResults *menu = dynamic_cast<cRecMenuSearchTimerResults*>(activeMenu)) {
- displayEvent = menu->GetEvent();
- } else if (cRecMenuRerunResults *menu = dynamic_cast<cRecMenuRerunResults*>(activeMenu)) {
- displayEvent = menu->GetEvent();
- } else break;
- if (displayEvent) {
- state = osUser1;
- }
- break;}
- case rmsSearchRecord: {
- //caller: cRecMenuSearchResults
- const cEvent *ev = NULL;
- if (cRecMenuSearchResults *menu = dynamic_cast<cRecMenuSearchResults*>(activeMenu)) {
- ev = menu->GetEvent();
- } else break;
- if (!ev)
- break;
- recManager->createTimer(ev, "");
- activeMenuBuffer = activeMenu;
- activeMenuBuffer->Hide();
- activeMenu = new cRecMenuSearchConfirmTimer(ev);
- DisplayMenu(true);
- break;}
-/**********************************************************************************************
- * CHECK FOR TIMER CONFLICTS
- ***********************************************************************************************/
- case rmsTimerConflicts: {
- //caller: main menu
- //Show timer conflict
- if (timerConflicts) {
- delete timerConflicts;
- }
- timerConflicts = recManager->CheckTimerConflict();
- delete activeMenu;
- int numConflicts = timerConflicts->NumConflicts();
- if (numConflicts > 0) {
- activeMenu = new cRecMenuTimerConflicts(timerConflicts);
- } else {
- activeMenu = new cRecMenuNoTimerConflict();
- }
- DisplayMenu();
- break; }
- case rmsTimerConflict: {
- //caller: cRecMenuTimerConflicts
- //Show timer conflict
- if (!timerConflicts)
- break;
- int timerConflict;
- if (cRecMenuTimerConflicts *menu = dynamic_cast<cRecMenuTimerConflicts*>(activeMenu)) {
- timerConflict = menu->GetTimerConflict();
- } else break;
- timerConflicts->SetCurrentConflict(timerConflict);
- delete activeMenu;
- activeMenu = new cRecMenuTimerConflict(timerConflicts->GetCurrentConflict());
- DisplayMenu();
- break; }
- case rmsSearchRerunsTimerConflictMenu: {
- //caller: cRecMenuTimerConflict
- //Show reruns for timer from timer conflict
- if (!timerConflicts)
- break;
- int timerConflict;
- if (cRecMenuTimerConflict *menu = dynamic_cast<cRecMenuTimerConflict*>(activeMenu)) {
- timerConflict = menu->GetTimerConflictIndex();
- } else break;
- int timerID = timerConflicts->GetCurrentConflictTimerID(timerConflict);
- cTimer *timer = Timers.Get(timerID);
- if (timer) {
- const cEvent *event = timer->Event();
- if (event) {
- int numReruns = 0;
- const cEvent **reruns = recManager->LoadReruns(event, numReruns);
- if (reruns && (numReruns > 0)) {
- activeMenuBuffer = activeMenu;
- activeMenuBuffer->Hide();
- activeMenu = new cRecMenuRerunResults(event, reruns, numReruns);
- } else {
- activeMenuBuffer = activeMenu;
- activeMenuBuffer->Hide();
- activeMenu = new cRecMenuNoRerunsFound((event->Title())?event->Title():"");
- }
- DisplayMenu(true);
- }
- }
- break; }
- case rmsTimerConflictRecordRerun: {
- //caller: cRecMenuRerunResults
- //buffer: cRecMenuTimerConflict
- if (!activeMenuBuffer)
- break;
- if (!timerConflicts)
- break;
- const cEvent *replace;
- int originalConflictIndex;
- if (cRecMenuRerunResults *menu = dynamic_cast<cRecMenuRerunResults*>(activeMenu)) {
- replace = menu->GetEvent();
- } else break;
- if (cRecMenuTimerConflict *menu = dynamic_cast<cRecMenuTimerConflict*>(activeMenuBuffer)) {
- originalConflictIndex = menu->GetTimerConflictIndex();
- } else break;
- int originalTimerID = timerConflicts->GetCurrentConflictTimerID(originalConflictIndex);
- cTimer *timerOriginal = Timers.Get(originalTimerID);
- if (replace && timerOriginal) {
- recManager->DeleteTimer(timerOriginal->Event());
- recManager->createTimer(replace);
- activeMenuBuffer->Show();
- delete activeMenuBuffer;
- activeMenuBuffer = NULL;
- delete activeMenu;
- activeMenu = new cRecMenuConfirmRerunUsed(timerOriginal->Event(), replace);
- DisplayMenu();
- }
- break; }
- /**********************************************************************************************
- * TIMELINE
- ***********************************************************************************************/
- case rmsTimeline: {
- delete activeMenu;
- activeMenu = new cRecMenuTimeline();
- DisplayMenu();
- break; }
- case rmsTimelineTimerEdit: {
- cTimer *timer;
- if (cRecMenuTimeline *menu = dynamic_cast<cRecMenuTimeline*>(activeMenu)) {
- timer = menu->GetTimer();
- } else break;
- if (timer) {
- delete activeMenu;
- activeMenu = new cRecMenuEditTimer(timer, rmsTimelineTimerSave);
- DisplayMenu();
- }
- break;}
- case rmsTimelineTimerSave: {
- cTimer timerModified;
- cTimer *originalTimer;
- if (cRecMenuEditTimer *menu = dynamic_cast<cRecMenuEditTimer*>(activeMenu)) {
- timerModified = menu->GetTimer();
- originalTimer = menu->GetOriginalTimer();
- } else break;
- recManager->SaveTimer(originalTimer, timerModified);
- delete activeMenu;
- activeMenu = new cRecMenuTimeline();
- DisplayMenu();
- break; }
- case rmsTimelineTimerDelete: {
- cTimer *timer;
- if (cRecMenuEditTimer *menu = dynamic_cast<cRecMenuEditTimer*>(activeMenu)) {
- timer = menu->GetOriginalTimer();
- } else break;
- recManager->DeleteTimer(timer);
- delete activeMenu;
- activeMenu = new cRecMenuTimeline();
- DisplayMenu();
- break; }
- default:
- break;
-/**********************************************************************************************
- * RECORDINGS SEARCH
- ***********************************************************************************************/
- case rmsRecordingSearch: {
- //caller: main menu or rmsRecordingSearchResult
- string searchString = event->Title();
- if (cRecMenuRecordingSearchResults *menu = dynamic_cast<cRecMenuRecordingSearchResults*>(activeMenu)) {
- searchString = menu->GetSearchString();
- };
- delete activeMenu;
- activeMenu = new cRecMenuRecordingSearch(searchString);
- DisplayMenu();
- break; }
- case rmsRecordingSearchResult: {
- //caller: cRecMenuRecordingSearch
- string searchString;
- if (cRecMenuRecordingSearch *menu = dynamic_cast<cRecMenuRecordingSearch*>(activeMenu)) {
- searchString = menu->GetSearchString();
- } else break;
- delete activeMenu;
- if (searchString.size() < 4) {
- activeMenu = new cRecMenuRecordingSearch(searchString);
- } else {
- int numSearchResults = 0;
- cRecording **searchResult = recManager->SearchForRecordings(searchString, numSearchResults);
- if (numSearchResults == 0) {
- activeMenu = new cRecMenuRecordingSearchNotFound(searchString);
- } else {
- activeMenu = new cRecMenuRecordingSearchResults(searchString, searchResult, numSearchResults);
- }
- }
- DisplayMenu();
- break; }
- /**********************************************************************************************
- * FAVORITES
- *********************************************************************************************/
- case rmsFavoritesRecord: {
- //caller: cRecMenuSearchTimerResults
- const cEvent *ev = NULL;
- if (cRecMenuSearchTimerResults *menu = dynamic_cast<cRecMenuSearchTimerResults*>(activeMenu)) {
- ev = menu->GetEvent();
- } else break;
- if (!ev)
- break;
- recManager->createTimer(ev, "");
- activeMenuBuffer2 = activeMenu;
- activeMenuBuffer2->Hide();
- activeMenu = new cRecMenuSearchConfirmTimer(ev);
- DisplayMenu(false, true);
- break;}
- case rmsFavoritesNow:
- case rmsFavoritesNext: {
- int numResults = 0;
- bool nowOrNext;
- string header;
- if (nextState == rmsFavoritesNow) {
- nowOrNext = true;
- header = tr("What's on now");
- } else {
- nowOrNext = false;
- header = tr("What's on next");
- }
- const cEvent **result = recManager->WhatsOnNow(nowOrNext, numResults);
- DisplayFavoriteResults(header, result, numResults);
- break; }
- case rmsFavoritesUser1: {
- int numResults = 0;
- const cEvent **result = recManager->UserDefinedTime(1, numResults);
- DisplayFavoriteResults(config.descUser1, result, numResults);
- break; }
- case rmsFavoritesUser2: {
- int numResults = 0;
- const cEvent **result = recManager->UserDefinedTime(2, numResults);
- DisplayFavoriteResults(config.descUser2, result, numResults);
- break; }
- case rmsFavoritesUser3: {
- int numResults = 0;
- const cEvent **result = recManager->UserDefinedTime(3, numResults);
- DisplayFavoriteResults(config.descUser3, result, numResults);
- break; }
- case rmsFavoritesUser4: {
- int numResults = 0;
- const cEvent **result = recManager->UserDefinedTime(4, numResults);
- DisplayFavoriteResults(config.descUser4, result, numResults);
- break; }
- }
- return state;
-}
+#include "tvguidengosd.h" +#include "recmenuview.h" + +cRecMenuView::cRecMenuView(void) { + active = false; + recMenuView = NULL; + recMenuViewBuffer = NULL; + recMenuViewBuffer2 = NULL; + event = NULL; + displayEvent = NULL; + activeMenu = NULL; + activeMenuBuffer = NULL; + activeMenuBuffer2 = NULL; + recManager = new cRecManager(); + recManager->SetEPGSearchPlugin(); + timerConflicts = NULL; +} + +cRecMenuView::~cRecMenuView() { + if (activeMenu) + delete activeMenu; + if (activeMenuBuffer) + delete activeMenuBuffer; + if (activeMenuBuffer2) + delete activeMenuBuffer2; + if (recMenuView) + delete recMenuView; + if (recMenuViewBuffer) + delete recMenuViewBuffer; + if (recMenuViewBuffer2) + delete recMenuViewBuffer2; +} + +void cRecMenuView::Init(skindesignerapi::cOsdView *recMenuView, skindesignerapi::cOsdView *recMenuViewBuffer, skindesignerapi::cOsdView *recMenuViewBuffer2) { + active = true; + this->recMenuView = recMenuView; + this->recMenuViewBuffer = recMenuViewBuffer; + this->recMenuViewBuffer2 = recMenuViewBuffer2; +} + +void cRecMenuView::DisplayRecMenu(const cEvent *event) { + if (!event) { + return; + } + this->event = event; + activeMenu = new cRecMenuMain(recManager->EpgSearchAvailable(), recManager->CheckEventForTimer(event), SwitchTimers.EventInSwitchList(event)); + DisplayMenu(); +} + +void cRecMenuView::DisplayFavorites(void) { + vector<cTVGuideSearchTimer> favorites; + recManager->GetFavorites(&favorites); + activeMenu = new cRecMenuFavorites(favorites); + DisplayMenu(); +} + +void cRecMenuView::DisplayRecSearch(const cEvent *e) { + activeMenu = new cRecMenuRecordingSearch(e->Title() ? e->Title() : ""); + DisplayMenu(); +} + +void cRecMenuView::DisplaySearchEPG(const cEvent *e) { + activeMenu = new cRecMenuSearch(e->Title() ? e->Title() : "", false); + DisplayMenu(); +} + +void cRecMenuView::Close(void) { + if (activeMenu) { + delete activeMenu; + activeMenu = NULL; + } + if (activeMenuBuffer) { + delete activeMenuBuffer; + activeMenuBuffer = NULL; + } + if (activeMenuBuffer2) { + delete activeMenuBuffer2; + activeMenuBuffer2 = NULL; + } + delete recMenuView; + recMenuView = NULL; + delete recMenuViewBuffer; + recMenuViewBuffer = NULL; + delete recMenuViewBuffer2; + recMenuViewBuffer2 = NULL; + active = false; +} + +void cRecMenuView::Hide(bool full) { + if (recMenuViewBuffer) { + recMenuViewBuffer->Deactivate(true); + if (full) + recMenuView->Deactivate(true); + } else + recMenuView->Deactivate(true); +} + +void cRecMenuView::Activate(bool full) { + if (recMenuViewBuffer) { + recMenuViewBuffer->Activate(); + if (full) + recMenuView->Activate(); + } else + recMenuView->Activate(); +} + +eOSState cRecMenuView::ProcessKey(eKeys Key) { + eOSState state = osContinue; + eRecMenuState nextState = rmsContinue; + if (!activeMenu) + return state; + nextState = activeMenu->ProcessKey(Key); + if ((nextState == rmsClose) || ((nextState == rmsNotConsumed)&&(Key == kBack))) { + if (activeMenuBuffer2) { + delete activeMenu; + activeMenu = activeMenuBuffer2; + activeMenuBuffer2 = NULL; + activeMenu->Show(); + return osContinue; + } else if (activeMenuBuffer) { + delete activeMenu; + activeMenu = activeMenuBuffer; + activeMenuBuffer = NULL; + activeMenu->Show(); + return osContinue; + } else { + Close(); + return osEnd; + } + } + state = StateMachine(nextState); + if (activeMenu) + activeMenu->Flush(); + return state; +} + +void cRecMenuView::DisplayMenu(bool buffer, bool buffer2) { + if (!activeMenu) + return; + if (buffer) { + activeMenu->Init(recMenuViewBuffer); + } else if (buffer2) { + activeMenu->Init(recMenuViewBuffer2); + } else { + activeMenu->Init(recMenuView); + } + if (cRecMenuTimeline *timeline = dynamic_cast<cRecMenuTimeline*>(activeMenu)) { + timeline->SetHeaderTimer(); + } + activeMenu->Draw(); +} + +void cRecMenuView::DisplaySearchTimerList(void) { + delete activeMenu; + vector<cTVGuideSearchTimer> searchTimers; + recManager->GetSearchTimers(&searchTimers); + activeMenu = new cRecMenuSearchTimers(searchTimers); + DisplayMenu(); +} + +bool cRecMenuView::DisplayTimerConflict(const cTimer *timer) { + int timerID = 0; +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_READ; + const cTimers* timers = Timers; +#else + const cTimers* timers = &Timers; +#endif + for (const cTimer *t = timers->First(); t; t = timers->Next(t)) { + if (t == timer) + return DisplayTimerConflict(timerID); + timerID++; + } + return false; +} + +bool cRecMenuView::DisplayTimerConflict(int timerID) { + if (timerConflicts) + delete timerConflicts; + timerConflicts = recManager->CheckTimerConflict(); + if (!timerConflicts) + return false; + int showTimerConflict = timerConflicts->GetCorrespondingConflict(timerID); + if (showTimerConflict > -1) { + timerConflicts->SetCurrentConflict(showTimerConflict); + cTVGuideTimerConflict *conflict = timerConflicts->GetCurrentConflict(); + if (!conflict) + return false; + activeMenu = new cRecMenuTimerConflict(conflict); + DisplayMenu(); + return true; + } + return false; +} + +void cRecMenuView::DisplayFavoriteResults(string header, const cEvent **result, int numResults) { + if (numResults) { + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuSearchTimerResults(header, result, numResults, "", rmsFavoritesRecord); + } else { + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuSearchTimerNothingFound(header); + } + DisplayMenu(true); +} + +eOSState cRecMenuView::StateMachine(eRecMenuState nextState) { + eOSState state = osContinue; + switch (nextState) { +/*************************************************************************************** +* INSTANT RECORDING +****************************************************************************************/ + case rmsInstantRecord: { + //caller: main menu or folder chooser + //Creating timer for active Event, if no conflict, confirm and exit + string recFolder = ""; + if (cRecMenuAskFolder *menu = dynamic_cast<cRecMenuAskFolder*>(activeMenu)) { + recFolder = menu->GetFolder(); + } + delete activeMenu; + cTimer *timer = recManager->createTimer(event, recFolder); + if (!DisplayTimerConflict(timer)) { + activeMenu = new cRecMenuConfirmTimer(event); + DisplayMenu(); + } + break; } + case rmsInstantRecordFolder: { + //caller: main menu + //Asking for Folder + delete activeMenu; + activeMenu = new cRecMenuAskFolder(event, rmsInstantRecord); + DisplayMenu(); + break; } + case rmsDeleteTimer: { + //caller: main menu + //delete timer for active event + delete activeMenu; + if (recManager->IsRecorded(event)) { + activeMenu = new cRecMenuAskDeleteTimer(event); + } else { + recManager->DeleteTimer(event); + activeMenu = new cRecMenuConfirmDeleteTimer(event); + } + DisplayMenu(); + break; } + case rmsDeleteTimerConfirmation: { + //delete running timer for active event + recManager->DeleteTimer(event); + delete activeMenu; + activeMenu = new cRecMenuConfirmDeleteTimer(event); + DisplayMenu(); + break; } + case rmsEditTimer: { + //edit timer for active event + const cTimer *timer = recManager->GetTimerForEvent(event); + if (timer) { + delete activeMenu; + activeMenu = new cRecMenuEditTimer(timer, rmsSaveTimer); + DisplayMenu(); + } + break; } + case rmsSaveTimer: { + //caller: cRecMenuEditTimer + //save timer for active event + cTimer timerModified; + const cTimer *originalTimer; + if (cRecMenuEditTimer *menu = dynamic_cast<cRecMenuEditTimer*>(activeMenu)) { + timerModified = menu->GetTimer(); + originalTimer = menu->GetOriginalTimer(); + } else break; + recManager->SaveTimer(originalTimer, timerModified); + Close(); + state = osEnd; + break; } + case rmsIgnoreTimerConflict: + //caller: cRecMenuTimerConflict + //Confirming created Timer + delete activeMenu; + activeMenu = new cRecMenuConfirmTimer(event); + DisplayMenu(); + break; + case rmsTimerConflictShowInfo: { + //caller: cRecMenuTimerConflict + int timerIndex; + if (cRecMenuTimerConflict *menu = dynamic_cast<cRecMenuTimerConflict*>(activeMenu)) { + timerIndex = menu->GetTimerConflictIndex(); + } else break; + int timerID = timerConflicts->GetCurrentConflictTimerID(timerIndex); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_READ; + const cTimers* timers = Timers; +#else + const cTimers* timers = &Timers; +#endif + const cTimer *t = timers->Get(timerID); + if (t) { + displayEvent = t->Event(); + if (displayEvent) { + state = osUser1; + } + } + break; } + case rmsDeleteTimerConflictMenu: { + //caller: cRecMenuTimerConflict + //delete timer out of current timer conflict + int timerIndex; + if (cRecMenuTimerConflict *menu = dynamic_cast<cRecMenuTimerConflict*>(activeMenu)) { + timerIndex = menu->GetTimerConflictIndex(); + } else break; + int timerID = timerConflicts->GetCurrentConflictTimerID(timerIndex); + recManager->DeleteTimer(timerID); + delete activeMenu; + if (!DisplayTimerConflict(timerID)) { + activeMenu = new cRecMenuConfirmTimer(event); + DisplayMenu(); + } + break; } + case rmsEditTimerConflictMenu: { + //caller: cRecMenuTimerConflict + //edit timer out of current timer conflict + int timerIndex; + if (cRecMenuTimerConflict *menu = dynamic_cast<cRecMenuTimerConflict*>(activeMenu)) { + timerIndex = menu->GetTimerConflictIndex(); + } else break; + int timerID = timerConflicts->GetCurrentConflictTimerID(timerIndex); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_READ; + const cTimers* timers = Timers; +#else + const cTimers* timers = &Timers; +#endif + const cTimer *timer = timers->Get(timerID); + if (timer) { + delete activeMenu; + activeMenu = new cRecMenuEditTimer(timer, rmsSaveTimerConflictMenu); + DisplayMenu(); + } + break; } + case rmsSaveTimerConflictMenu: { + //caller: cRecMenuEditTimer + //save timer from current timer conflict + cTimer timerModified; + const cTimer *originalTimer; + if (cRecMenuEditTimer *menu = dynamic_cast<cRecMenuEditTimer*>(activeMenu)) { + timerModified = menu->GetTimer(); + originalTimer = menu->GetOriginalTimer(); + } else break; + recManager->SaveTimer(originalTimer, timerModified); + delete activeMenu; + if (!DisplayTimerConflict(originalTimer)) { + activeMenu = new cRecMenuConfirmTimer(event); + DisplayMenu(); + } + break; } +/*************************************************************************************** +* SERIES TIMER +****************************************************************************************/ + case rmsSeriesTimer: { + //caller: main menu oder folder chooser + string recFolder = ""; + if (cRecMenuAskFolder *menu = dynamic_cast<cRecMenuAskFolder*>(activeMenu)) { + recFolder = menu->GetFolder(); + } + delete activeMenu; +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* channels = Channels; +#else + cChannels* channels = &Channels; +#endif + + const cChannel *channel = channels->GetByChannelID(event->ChannelID()); + activeMenu = new cRecMenuSeriesTimer(channel, event, recFolder); + DisplayMenu(); + break; } + case rmsSeriesTimerFolder: + //caller: main menu + //Asking for Folder + delete activeMenu; + activeMenu = new cRecMenuAskFolder(event, rmsSeriesTimer); + DisplayMenu(); + break; + case rmsSeriesTimerCreate: { + //caller: cRecMenuSeriesTimer + cTimer *seriesTimer; + if (cRecMenuSeriesTimer *menu = dynamic_cast<cRecMenuSeriesTimer*>(activeMenu)) { + seriesTimer = menu->GetTimer(); + } else break; + recManager->CreateSeriesTimer(seriesTimer); + delete activeMenu; + activeMenu = new cRecMenuConfirmSeriesTimer(seriesTimer); + DisplayMenu(); + break; } +/********************************************************************************************** + * SWITCH TIMER + ***********************************************************************************************/ + case rmsSwitchTimer: + delete activeMenu; + activeMenu = new cRecMenuSwitchTimer(); + DisplayMenu(); + break; + case rmsSwitchTimerCreate: { + cSwitchTimer switchTimer; + if (cRecMenuSwitchTimer *menu = dynamic_cast<cRecMenuSwitchTimer*>(activeMenu)) { + switchTimer = menu->GetSwitchTimer(); + } else break; + bool success = recManager->CreateSwitchTimer(event, switchTimer); + delete activeMenu; + activeMenu = new cRecMenuSwitchTimerConfirm(success); + DisplayMenu(); + break; } + case rmsSwitchTimerDelete: + recManager->DeleteSwitchTimer(event); + delete activeMenu; + activeMenu = new cRecMenuSwitchTimerDelete(); + DisplayMenu(); + break; +/********************************************************************************************** + * SEARCH TIMER + ***********************************************************************************************/ + case rmsSearchTimer: + //Caller: main menu + //set search String for search timer + delete activeMenu; + activeMenu = new cRecMenuSearchTimer(event); + DisplayMenu(); + break; + case rmsSearchTimerOptions: { + //Caller: cRecMenuSearchTimer, cRecMenuSearchTimerTemplates + //Choose to set options manually or by template + string searchString; + cTVGuideSearchTimer searchTimer; + bool reload = false; + if (cRecMenuSearchTimer *menu = dynamic_cast<cRecMenuSearchTimer*>(activeMenu)) { + searchString = menu->GetSearchString(); + } else if (cRecMenuSearchTimerTemplatesCreate *menu = dynamic_cast<cRecMenuSearchTimerTemplatesCreate*>(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + reload = true; + } else break; + delete activeMenu; + if (searchString.size() < 4) { + activeMenu = new cRecMenuSearchTimer(event); + } else { + if (!reload) { + searchTimer.SetSearchString(searchString); + } + vector<TVGuideEPGSearchTemplate> epgSearchTemplates; + recManager->ReadEPGSearchTemplates(&epgSearchTemplates); + if (epgSearchTemplates.size() > 0) { + activeMenu = new cRecMenuSearchTimerTemplates(searchTimer, epgSearchTemplates); + } else { + activeMenu = new cRecMenuSearchTimerEdit(searchTimer, false); + } + } + DisplayMenu(); + break; } + case rmsSearchTimers: { + //caller: main menu + DisplaySearchTimerList(); + break; } + case rmsSearchTimerEdit: + case rmsSearchTimerEditAdvanced: { + //caller: cRecMenuSearchTimers, cRecMenuSearchTimerEdit, cRecMenuSearchTimerTemplates + cTVGuideSearchTimer searchTimer; + bool advancedOptions = false; + if (cRecMenuSearchTimers *menu = dynamic_cast<cRecMenuSearchTimers*>(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + } else if (cRecMenuSearchTimerEdit *menu = dynamic_cast<cRecMenuSearchTimerEdit*>(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + advancedOptions = (nextState == rmsSearchTimerEditAdvanced)?true:false; + } else if (cRecMenuSearchTimerTemplates *menu = dynamic_cast<cRecMenuSearchTimerTemplates*>(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + } else break; + delete activeMenu; + activeMenu = new cRecMenuSearchTimerEdit(searchTimer, advancedOptions); + DisplayMenu(); + break; } + case rmsSearchTimerTest: { + //caller: cRecMenuSearchTimerEdit, cRecMenuSearchTimerTemplatesCreate, cRecMenuSearchTimers, cRecMenuFavorites + //show results of currently choosen search timer + cTVGuideSearchTimer searchTimer; + eRecMenuState recState = rmsDisabled; + if (cRecMenuSearchTimerEdit *menu = dynamic_cast<cRecMenuSearchTimerEdit*>(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + recState = rmsSearchTimerRecord; + } else if (cRecMenuSearchTimers *menu = dynamic_cast<cRecMenuSearchTimers*>(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + recState = rmsSearchTimerRecord; + } else if (cRecMenuSearchTimerTemplatesCreate *menu = dynamic_cast<cRecMenuSearchTimerTemplatesCreate*>(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + TVGuideEPGSearchTemplate tmpl = menu->GetTemplate(); + searchTimer.SetTemplate(tmpl.templValue); + searchTimer.Parse(true); + } else if (cRecMenuFavorites *menu = dynamic_cast<cRecMenuFavorites*>(activeMenu)) { + searchTimer = menu->GetFavorite(); + recState = rmsFavoritesRecord; + } + else break; + int numSearchResults = 0; + string searchString = searchTimer.BuildSearchString(); + const cEvent **searchResult = recManager->PerformSearchTimerSearch(searchString, numSearchResults); + if (numSearchResults) { + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuSearchTimerResults(searchTimer.SearchString(), searchResult, numSearchResults, "", recState); + } else { + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuSearchTimerNothingFound(searchTimer.SearchString()); + } + DisplayMenu(true); + break; } + case rmsSearchTimerSave: { + //caller: cRecMenuSearchTimerEdit, cRecMenuSearchTimerTemplatesCreate + //create new or modify existing search timer + cTVGuideSearchTimer searchTimer; + if (cRecMenuSearchTimerEdit *menu = dynamic_cast<cRecMenuSearchTimerEdit*>(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + } else if (cRecMenuSearchTimerTemplatesCreate *menu = dynamic_cast<cRecMenuSearchTimerTemplatesCreate*>(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + TVGuideEPGSearchTemplate tmpl = menu->GetTemplate(); + searchTimer.SetTemplate(tmpl.templValue); + searchTimer.Parse(true); + } else break; + bool success = recManager->SaveSearchTimer(&searchTimer); + recManager->UpdateSearchTimers(); + if (searchTimer.GetID() >= 0) { + //Timer modified, show list + DisplaySearchTimerList(); + } else { + //new timer, confirm + delete activeMenu; + activeMenu = new cRecMenuSearchTimerCreateConfirm(success); + DisplayMenu(); + } + break; } + case rmsSearchTimerCreateWithTemplate: { + //caller: cRecMenuSearchTimerTemplates + //create new search timer from template + TVGuideEPGSearchTemplate templ; + cTVGuideSearchTimer searchTimer; + if (cRecMenuSearchTimerTemplates *menu = dynamic_cast<cRecMenuSearchTimerTemplates*>(activeMenu)) { + templ = menu->GetTemplate(); + searchTimer = menu->GetSearchTimer(); + } else break; + delete activeMenu; + activeMenu = new cRecMenuSearchTimerTemplatesCreate(templ, searchTimer); + DisplayMenu(); + break; } + case rmsSearchTimerDeleteConfirm: { + //caller: cRecMenuSearchTimers + //Ask for confirmation and if timers created by this search timer should alo be deleted + cTVGuideSearchTimer searchTimer; + if (cRecMenuSearchTimers *menu = dynamic_cast<cRecMenuSearchTimers*>(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + } else break; + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuSearchTimerDeleteConfirm(searchTimer); + DisplayMenu(true); + break; } + case rmsSearchTimerDelete: + case rmsSearchTimerDeleteWithTimers: { + //caller: cRecMenuSearchTimerDeleteConfirm + //actually delete searchtimer + cTVGuideSearchTimer searchTimer; + if (cRecMenuSearchTimerDeleteConfirm *menu = dynamic_cast<cRecMenuSearchTimerDeleteConfirm*>(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + } else break; + bool delTimers = (nextState==rmsSearchTimerDeleteWithTimers)?true:false; + recManager->DeleteSearchTimer(&searchTimer, delTimers); + delete activeMenuBuffer; + activeMenuBuffer = NULL; + DisplaySearchTimerList(); + break; } + case rmsSearchTimerRecord: { + //caller: cRecMenuSearchTimerResults + const cEvent *ev = NULL; + if (cRecMenuSearchTimerResults *menu = dynamic_cast<cRecMenuSearchTimerResults*>(activeMenu)) { + ev = menu->GetEvent(); + } else break; + if (!ev) + break; + recManager->createTimer(ev, ""); + activeMenuBuffer2 = activeMenu; + activeMenuBuffer2->Hide(); + activeMenu = new cRecMenuSearchConfirmTimer(ev); + DisplayMenu(false, true); + break; } +/********************************************************************************************** +* SEARCH +***********************************************************************************************/ + case rmsSearch: + case rmsSearchWithOptions: { + //caller: main menu, cRecMenuSearch, cRecMenuSearchResults + bool withOptions = false; + string searchString = event->Title(); + if (cRecMenuSearch *menu = dynamic_cast<cRecMenuSearch*>(activeMenu)) { + withOptions = true; + searchString = menu->GetSearchString(); + } else if (cRecMenuSearchResults *menu = dynamic_cast<cRecMenuSearchResults*>(activeMenu)) { + searchString = menu->GetSearchString(); + } + delete activeMenu; + activeMenu = new cRecMenuSearch(searchString, withOptions); + DisplayMenu(); + break; } + case rmsSearchPerform: { + //caller: cRecMenuSearch + bool useBuffer = false; + Epgsearch_searchresults_v1_0 epgSearchData; + if (cRecMenuSearch *menu = dynamic_cast<cRecMenuSearch*>(activeMenu)) { + epgSearchData = menu->GetEPGSearchStruct(); + } else break; + string searchString = epgSearchData.query; + if (searchString.size() < 3) { + activeMenu->Hide(); + activeMenuBuffer = activeMenu; + useBuffer = true; + activeMenu = new cRecMenuSearchNothingFound(searchString, true); + } else { + int numSearchResults = 0; + const cEvent **searchResult = recManager->PerformSearch(epgSearchData, numSearchResults); + if (searchResult) { + delete activeMenu; + activeMenu = new cRecMenuSearchResults(searchString, searchResult, numSearchResults); + } else { + activeMenu->Hide(); + activeMenuBuffer = activeMenu; + useBuffer = true; + activeMenu = new cRecMenuSearchNothingFound(searchString); + } + } + DisplayMenu(useBuffer); + break; } + case rmsSearchShowInfo: { + //caller: cRecMenuSearchResults, cRecMenuSearchTimerResults, cRecMenuRerunResults + if (cRecMenuSearchResults *menu = dynamic_cast<cRecMenuSearchResults*>(activeMenu)) { + displayEvent = menu->GetEvent(); + } else if (cRecMenuSearchTimerResults *menu = dynamic_cast<cRecMenuSearchTimerResults*>(activeMenu)) { + displayEvent = menu->GetEvent(); + } else if (cRecMenuRerunResults *menu = dynamic_cast<cRecMenuRerunResults*>(activeMenu)) { + displayEvent = menu->GetEvent(); + } else break; + if (displayEvent) { + state = osUser1; + } + break;} + case rmsSearchRecord: { + //caller: cRecMenuSearchResults + const cEvent *ev = NULL; + if (cRecMenuSearchResults *menu = dynamic_cast<cRecMenuSearchResults*>(activeMenu)) { + ev = menu->GetEvent(); + } else break; + if (!ev) + break; + recManager->createTimer(ev, ""); + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuSearchConfirmTimer(ev); + DisplayMenu(true); + break;} +/********************************************************************************************** + * CHECK FOR TIMER CONFLICTS + ***********************************************************************************************/ + case rmsTimerConflicts: { + //caller: main menu + //Show timer conflict + if (timerConflicts) { + delete timerConflicts; + } + timerConflicts = recManager->CheckTimerConflict(); + delete activeMenu; + int numConflicts = timerConflicts->NumConflicts(); + if (numConflicts > 0) { + activeMenu = new cRecMenuTimerConflicts(timerConflicts); + } else { + activeMenu = new cRecMenuNoTimerConflict(); + } + DisplayMenu(); + break; } + case rmsTimerConflict: { + //caller: cRecMenuTimerConflicts + //Show timer conflict + if (!timerConflicts) + break; + int timerConflict; + if (cRecMenuTimerConflicts *menu = dynamic_cast<cRecMenuTimerConflicts*>(activeMenu)) { + timerConflict = menu->GetTimerConflict(); + } else break; + timerConflicts->SetCurrentConflict(timerConflict); + delete activeMenu; + activeMenu = new cRecMenuTimerConflict(timerConflicts->GetCurrentConflict()); + DisplayMenu(); + break; } + case rmsSearchRerunsTimerConflictMenu: { + //caller: cRecMenuTimerConflict + //Show reruns for timer from timer conflict + if (!timerConflicts) + break; + int timerConflict; + if (cRecMenuTimerConflict *menu = dynamic_cast<cRecMenuTimerConflict*>(activeMenu)) { + timerConflict = menu->GetTimerConflictIndex(); + } else break; + int timerID = timerConflicts->GetCurrentConflictTimerID(timerConflict); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_READ; + const cTimers* timers = Timers; +#else + const cTimers* timers = &Timers; +#endif + const cTimer *timer = timers->Get(timerID); + if (timer) { + const cEvent *event = timer->Event(); + if (event) { + int numReruns = 0; + const cEvent **reruns = recManager->LoadReruns(event, numReruns); + if (reruns && (numReruns > 0)) { + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuRerunResults(event, reruns, numReruns); + } else { + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuNoRerunsFound((event->Title())?event->Title():""); + } + DisplayMenu(true); + } + } + break; } + case rmsTimerConflictRecordRerun: { + //caller: cRecMenuRerunResults + //buffer: cRecMenuTimerConflict + if (!activeMenuBuffer) + break; + if (!timerConflicts) + break; + const cEvent *replace; + int originalConflictIndex; + if (cRecMenuRerunResults *menu = dynamic_cast<cRecMenuRerunResults*>(activeMenu)) { + replace = menu->GetEvent(); + } else break; + if (cRecMenuTimerConflict *menu = dynamic_cast<cRecMenuTimerConflict*>(activeMenuBuffer)) { + originalConflictIndex = menu->GetTimerConflictIndex(); + } else break; + int originalTimerID = timerConflicts->GetCurrentConflictTimerID(originalConflictIndex); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_READ; + const cTimers* timers = Timers; +#else + const cTimers* timers = &Timers; +#endif + const cTimer *timerOriginal = timers->Get(originalTimerID); + if (replace && timerOriginal) { + recManager->DeleteTimer(timerOriginal->Event()); + recManager->createTimer(replace); + activeMenuBuffer->Show(); + delete activeMenuBuffer; + activeMenuBuffer = NULL; + delete activeMenu; + activeMenu = new cRecMenuConfirmRerunUsed(timerOriginal->Event(), replace); + DisplayMenu(); + } + break; } + /********************************************************************************************** + * TIMELINE + ***********************************************************************************************/ + case rmsTimeline: { + delete activeMenu; + activeMenu = new cRecMenuTimeline(); + DisplayMenu(); + break; } + case rmsTimelineTimerEdit: { + const cTimer *timer; + if (cRecMenuTimeline *menu = dynamic_cast<cRecMenuTimeline*>(activeMenu)) { + timer = menu->GetTimer(); + } else break; + if (timer) { + delete activeMenu; + activeMenu = new cRecMenuEditTimer(timer, rmsTimelineTimerSave); + DisplayMenu(); + } + break;} + case rmsTimelineTimerSave: { + cTimer timerModified; + const cTimer *originalTimer; + if (cRecMenuEditTimer *menu = dynamic_cast<cRecMenuEditTimer*>(activeMenu)) { + timerModified = menu->GetTimer(); + originalTimer = menu->GetOriginalTimer(); + } else break; + recManager->SaveTimer(originalTimer, timerModified); + delete activeMenu; + activeMenu = new cRecMenuTimeline(); + DisplayMenu(); + break; } + case rmsTimelineTimerDelete: { + const cTimer *timer; + if (cRecMenuEditTimer *menu = dynamic_cast<cRecMenuEditTimer*>(activeMenu)) { + timer = menu->GetOriginalTimer(); + } else break; + recManager->DeleteTimer(timer); + delete activeMenu; + activeMenu = new cRecMenuTimeline(); + DisplayMenu(); + break; } + default: + break; +/********************************************************************************************** + * RECORDINGS SEARCH + ***********************************************************************************************/ + case rmsRecordingSearch: { + //caller: main menu or rmsRecordingSearchResult + string searchString = event->Title(); + if (cRecMenuRecordingSearchResults *menu = dynamic_cast<cRecMenuRecordingSearchResults*>(activeMenu)) { + searchString = menu->GetSearchString(); + }; + delete activeMenu; + activeMenu = new cRecMenuRecordingSearch(searchString); + DisplayMenu(); + break; } + case rmsRecordingSearchResult: { + //caller: cRecMenuRecordingSearch + string searchString; + if (cRecMenuRecordingSearch *menu = dynamic_cast<cRecMenuRecordingSearch*>(activeMenu)) { + searchString = menu->GetSearchString(); + } else break; + delete activeMenu; + if (searchString.size() < 4) { + activeMenu = new cRecMenuRecordingSearch(searchString); + } else { + int numSearchResults = 0; + const cRecording **searchResult = recManager->SearchForRecordings(searchString, numSearchResults); + if (numSearchResults == 0) { + activeMenu = new cRecMenuRecordingSearchNotFound(searchString); + } else { + activeMenu = new cRecMenuRecordingSearchResults(searchString, searchResult, numSearchResults); + } + } + DisplayMenu(); + break; } + /********************************************************************************************** + * FAVORITES + *********************************************************************************************/ + case rmsFavoritesRecord: { + //caller: cRecMenuSearchTimerResults + const cEvent *ev = NULL; + if (cRecMenuSearchTimerResults *menu = dynamic_cast<cRecMenuSearchTimerResults*>(activeMenu)) { + ev = menu->GetEvent(); + } else break; + if (!ev) + break; + recManager->createTimer(ev, ""); + activeMenuBuffer2 = activeMenu; + activeMenuBuffer2->Hide(); + activeMenu = new cRecMenuSearchConfirmTimer(ev); + DisplayMenu(false, true); + break;} + case rmsFavoritesNow: + case rmsFavoritesNext: { + int numResults = 0; + bool nowOrNext; + string header; + if (nextState == rmsFavoritesNow) { + nowOrNext = true; + header = tr("What's on now"); + } else { + nowOrNext = false; + header = tr("What's on next"); + } + const cEvent **result = recManager->WhatsOnNow(nowOrNext, numResults); + DisplayFavoriteResults(header, result, numResults); + break; } + case rmsFavoritesUser1: { + int numResults = 0; + const cEvent **result = recManager->UserDefinedTime(1, numResults); + DisplayFavoriteResults(config.descUser1, result, numResults); + break; } + case rmsFavoritesUser2: { + int numResults = 0; + const cEvent **result = recManager->UserDefinedTime(2, numResults); + DisplayFavoriteResults(config.descUser2, result, numResults); + break; } + case rmsFavoritesUser3: { + int numResults = 0; + const cEvent **result = recManager->UserDefinedTime(3, numResults); + DisplayFavoriteResults(config.descUser3, result, numResults); + break; } + case rmsFavoritesUser4: { + int numResults = 0; + const cEvent **result = recManager->UserDefinedTime(4, numResults); + DisplayFavoriteResults(config.descUser4, result, numResults); + break; } + } + return state; +} diff --git a/recmenuview.h b/recmenuview.h index 6f1d03a..718379e 100644 --- a/recmenuview.h +++ b/recmenuview.h @@ -1,46 +1,46 @@ -#ifndef __TVGUIDE_RECMENUVIEW_H
-#define __TVGUIDE_RECMENUVIEW_H
-
-#include "config.h"
-#include <libskindesignerapi/skindesignerosdbase.h>
-#include "recmanager.h"
-#include "recmenus.h"
-
-class cRecMenuView {
-private:
- bool active;
- skindesignerapi::cOsdView *recMenuView;
- skindesignerapi::cOsdView *recMenuViewBuffer;
- skindesignerapi::cOsdView *recMenuViewBuffer2;
- const cEvent *event;
- const cEvent *displayEvent;
- cRecManager *recManager;
- cRecMenu *activeMenu;
- cRecMenu *activeMenuBuffer;
- cRecMenu *activeMenuBuffer2;
- cTVGuideTimerConflicts *timerConflicts;
- void DrawBackground(int menuWidth, int menuHeight, bool scrolling);
- void DisplayMenu(bool buffer = false, bool buffer2 = false);
- void DisplaySearchTimerList(void);
- bool DisplayTimerConflict(cTimer *timer);
- bool DisplayTimerConflict(int timerID);
- void DisplayFavoriteResults(string header, const cEvent **result, int numResults);
- eOSState StateMachine(eRecMenuState nextState);
-public:
- cRecMenuView(void);
- virtual ~cRecMenuView(void);
- void Init(skindesignerapi::cOsdView *recMenuView, skindesignerapi::cOsdView *recMenuViewBuffer, skindesignerapi::cOsdView *recMenuViewBuffer2);
- void DisplayRecMenu(const cEvent *event);
- void DisplayFavorites(void);
- void DisplayRecSearch(const cEvent *e);
- void DisplaySearchEPG(const cEvent *e);
- void Close(void);
- void Hide(bool full = false);
- void Activate(bool full = false);
- eOSState ProcessKey(eKeys Key);
- void Flush(void) { activeMenu->Flush(); };
- const cEvent *GetEvent(void) { return displayEvent; };
- bool Active(void) { return active; };
-};
-
-#endif //__TVGUIDE_RECMENUVIEW_H
+#ifndef __TVGUIDE_RECMENUVIEW_H +#define __TVGUIDE_RECMENUVIEW_H + +#include "config.h" +#include <libskindesignerapi/skindesignerosdbase.h> +#include "recmanager.h" +#include "recmenus.h" + +class cRecMenuView { +private: + bool active; + skindesignerapi::cOsdView *recMenuView; + skindesignerapi::cOsdView *recMenuViewBuffer; + skindesignerapi::cOsdView *recMenuViewBuffer2; + const cEvent *event; + const cEvent *displayEvent; + cRecManager *recManager; + cRecMenu *activeMenu; + cRecMenu *activeMenuBuffer; + cRecMenu *activeMenuBuffer2; + cTVGuideTimerConflicts *timerConflicts; + void DrawBackground(int menuWidth, int menuHeight, bool scrolling); + void DisplayMenu(bool buffer = false, bool buffer2 = false); + void DisplaySearchTimerList(void); + bool DisplayTimerConflict(const cTimer *timer); + bool DisplayTimerConflict(int timerID); + void DisplayFavoriteResults(string header, const cEvent **result, int numResults); + eOSState StateMachine(eRecMenuState nextState); +public: + cRecMenuView(void); + virtual ~cRecMenuView(void); + void Init(skindesignerapi::cOsdView *recMenuView, skindesignerapi::cOsdView *recMenuViewBuffer, skindesignerapi::cOsdView *recMenuViewBuffer2); + void DisplayRecMenu(const cEvent *event); + void DisplayFavorites(void); + void DisplayRecSearch(const cEvent *e); + void DisplaySearchEPG(const cEvent *e); + void Close(void); + void Hide(bool full = false); + void Activate(bool full = false); + eOSState ProcessKey(eKeys Key); + void Flush(void) { activeMenu->Flush(); }; + const cEvent *GetEvent(void) { return displayEvent; }; + bool Active(void) { return active; }; +}; + +#endif //__TVGUIDE_RECMENUVIEW_H diff --git a/searchtimer.c b/searchtimer.c index fe78f6c..22d1313 100644 --- a/searchtimer.c +++ b/searchtimer.c @@ -1,570 +1,611 @@ -#include <string>
-#include <vector>
-#include <sstream>
-#include <algorithm>
-#include <vdr/channels.h>
-#include <vdr/device.h>
-#include "helpers.h"
-#include "searchtimer.h"
-
-// -- cTVGuideSearchTimer -----------------------------------------------------------------
-cTVGuideSearchTimer::cTVGuideSearchTimer(void) {
- strTimer = "";
- ID = -1;
- searchString = "";
- useTime = false;
- startTime = 0000;
- stopTime = 2359;
- useChannel = false;
- channelMin = Channels.GetByNumber(cDevice::CurrentChannel());
- channelMax = Channels.GetByNumber(cDevice::CurrentChannel());
- channelGroup = "";
- useCase = false;
- mode = 0;
- useTitle = true;
- useSubtitle = true;
- useDescription = true;
- useDuration = false;
- minDuration = 0;
- maxDuration = 2359;
- useAsSearchTimer = true;
- useDayOfWeek = false;
- dayOfWeek = 0;
- directory = "";
- useEpisode = 0;
- priority = 99;
- lifetime = 99;
- marginStart = 5;
- marginStop = 5;
- useVPS = false;
- action = 0;
- useExtEPGInfo = 0;
- extEPGInfoValues = "";
- avoidRepeats = 1;
- allowedRepeats = 1;
- compareTitle = 1;
- compareSubtitle = 2;
- compareSummary = 1;
- catvaluesAvoidRepeat = 0;
- repeatsWithinDays = 0;
- delAfterDays = 0;
- recordingsKeep = 0;
- switchMinsBefore = 0;
- pauseOnNrRecordings = 0;
- blacklistMode = 0;
- blacklists = "";
- fuzzyTolerance = 0;
- useInFavorites = 0;
- menuTemplate = 0;
- delMode = 0;
- delAfterCountRecs = 0;
- delAfterDaysOfFirstRec = 0;
- useAsSearchTimerFrom = 0;
- useAsSearchTimerTil = 0;
- ignoreMissingEPGCats = 0;
- unmuteSoundOnSwitch = 0;
- compareSummaryMatchInPercent = 0;
- contentsFilter = "";
- compareDate = 0;
-}
-
-cTVGuideSearchTimer::~cTVGuideSearchTimer(void) {
-}
-
-bool cTVGuideSearchTimer::operator < (const cTVGuideSearchTimer& other) const {
- std::string searchStringOther = other.SearchString();
- searchStringOther = StrToLowerCase(searchStringOther);
- std::string thisSearchString = StrToLowerCase(searchString);
- int comp = thisSearchString.compare(searchStringOther);
- if (comp < 0)
- return true;
- return false;
-}
-
-
-void cTVGuideSearchTimer::SetTemplate(std::string tmpl) {
- std::stringstream searchTimerString;
- searchTimerString << "0:";
- searchTimerString << tmpl;
- strTimer = searchTimerString.str();
-}
-
-int cTVGuideSearchTimer::DayOfWeek(void) {
- int vdrDayOfWeek = 0;
- if (dayOfWeek >= 0) {
- vdrDayOfWeek = pow(2, (dayOfWeek+6)%7);
- } else if (dayOfWeek < 0) {
- int absDayOfWeek = abs(dayOfWeek);
- for (int i=0; i < 7; i++) {
- if (absDayOfWeek & (1 << i)) {
- vdrDayOfWeek += pow(2, (i+6)%7);
- }
- }
- }
- return vdrDayOfWeek;
-}
-
-void cTVGuideSearchTimer::SetDayOfWeek(int VDRDayOfWeek) {
- int epgSearchDayOfWeek = 0;
- for (int i=0; i < 7; i++) {
- if (VDRDayOfWeek & (1 << i)) {
- epgSearchDayOfWeek += pow(2, (i+1)%7);
- }
- }
- this->dayOfWeek = epgSearchDayOfWeek * (-1);
-}
-
-/*
- 0 - unique search timer id
- 1 - the search term
- 2 - use time? 0/1
- 3 - start time in HHMM
- 4 - stop time in HHMM
- 5 - use channel? 0 = no, 1 = Interval, 2 = Channel group, 3 = FTA only
- 6 - if 'use channel' = 1 then channel id[|channel id] in VDR format,
- one entry or min/max entry separated with |, if 'use channel' = 2
- then the channel group name
- 7 - match case? 0/1
- 8 - search mode:
- 0 - the whole term must appear as substring
- 1 - all single terms (delimiters are blank,',', ';', '|' or '~')
- must exist as substrings.
- 2 - at least one term (delimiters are blank, ',', ';', '|' or '~')
- must exist as substring.
- 3 - matches exactly
- 4 - regular expression
- 9 - use title? 0/1
- 10 - use subtitle? 0/1
- 11 - use description? 0/1
- 12 - use duration? 0/1
- 13 - min duration in hhmm
- 14 - max duration in hhmm
- 15 - use as search timer? 0/1
- 16 - use day of week? 0/1
- 17 - day of week (0 = Sunday, 1 = Monday...;
- -1 Sunday, -2 Monday, -4 Tuesday, ...; -7 Sun, Mon, Tue)
- 18 - use series recording? 0/1
- 19 - directory for recording
- 20 - priority of recording
- 21 - lifetime of recording
- 22 - time margin for start in minutes
- 23 - time margin for stop in minutes
- 24 - use VPS? 0/1
- 25 - action:
- 0 = create a timer
- 1 = announce only via OSD (no timer)
- 2 = switch only (no timer)
- 3 = announce via OSD and switch (no timer)
- 4 = announce via mail
- 26 - use extended EPG info? 0/1
- 27 - extended EPG info values. This entry has the following format
- (delimiter is '|' for each category, '#' separates id and value):
- 1 - the id of the extended EPG info category as specified in
- epgsearchcats.conf
- 2 - the value of the extended EPG info category
- (a ':' will be translated to "!^colon^!", e.g. in "16:9")
- 28 - avoid repeats? 0/1
- 29 - allowed repeats
- 30 - compare title when testing for a repeat? 0/1
- 31 - compare subtitle when testing for a repeat? 0/1/2
- 0 - no
- 1 - yes
- 2 - yes, if present
- 32 - compare description when testing for a repeat? 0/1
- 33 - compare extended EPG info when testing for a repeat?
- This entry is a bit field of the category IDs.
- 34 - accepts repeats only within x days
- 35 - delete a recording automatically after x days
- 36 - but keep this number of recordings anyway
- 37 - minutes before switch (if action = 2)
- 38 - pause if x recordings already exist
- 39 - blacklist usage mode (0 none, 1 selection, 2 all)
- 40 - selected blacklist IDs separated with '|'
- 41 - fuzzy tolerance value for fuzzy searching
- 42 - use this search in favorites menu (0 no, 1 yes)
- 43 - id of a menu search template
- 44 - auto deletion mode (0 don't delete search timer, 1 delete after given
- count of recordings, 2 delete after given days after first recording)
- 45 - count of recordings after which to delete the search timer
- 46 - count of days after the first recording after which to delete the search
- timer
- 47 - first day where the search timer is active (see parameter 16)
- 48 - last day where the search timer is active (see parameter 16)
- 49 - ignore missing EPG categories? 0/1
- 50 - unmute sound if off when used as switch timer
- 51 - percentage of match when comparing the summary of two events (with 'avoid repeats')
- 52 - HEX representation of the content descriptors, each descriptor ID is represented with 2 chars
- 53 - compare date when testing for a repeat? (0=no, 1=same day, 2=same week, 3=same month)
-*/
-bool cTVGuideSearchTimer::Parse(bool readTemplate) {
- splitstring s(strTimer.c_str());
- std::vector<std::string> values = s.split(':', 1);
- int numValues = values.size();
- if (numValues < 12)
- return false;
- for (int value = 0; value < numValues; value++) {
- switch (value) {
- case 0:
- if (!readTemplate)
- ID = atoi(values[value].c_str());
- break;
- case 1:
- if (!readTemplate) {
- std::string searchStringMasked = values[value];
- std::replace(searchStringMasked.begin(), searchStringMasked.end(), '|', ':');
- searchString = searchStringMasked;
- }
- break;
- case 2:
- useTime = atoi(values[value].c_str());
- break;
- case 3:
- if (useTime) {
- startTime = atoi(values[value].c_str());
- }
- break;
- case 4:
- if (useTime) {
- stopTime = atoi(values[value].c_str());
- }
- break;
- case 5:
- useChannel = atoi(values[value].c_str());
- break;
- case 6:
- if (useChannel == 0) {
- channelMin = NULL;
- channelMax = NULL;
- } else if (useChannel == 1) {
- char *channelMinbuffer = NULL;
- char *channelMaxbuffer = NULL;
- int channels = sscanf(values[value].c_str(), "%m[^|]|%m[^|]", &channelMinbuffer, &channelMaxbuffer);
- channelMin = Channels.GetByChannelID(tChannelID::FromString(channelMinbuffer), true, true);
- if (!channelMin) {
- channelMin = channelMax = NULL;
- useChannel = 0;
- }
- if (channels == 1)
- channelMax = channelMin;
- else {
- channelMax = Channels.GetByChannelID(tChannelID::FromString(channelMaxbuffer), true, true);
- if (!channelMax) {
- channelMin = channelMax = NULL;
- useChannel = 0;
- }
- }
- free(channelMinbuffer);
- free(channelMaxbuffer);
- } else if (useChannel == 2) {
- channelGroup = values[value];
- }
- break;
- case 7:
- useCase = atoi(values[value].c_str());
- break;
- case 8:
- mode = atoi(values[value].c_str());
- break;
- case 9:
- useTitle = atoi(values[value].c_str());
- break;
- case 10:
- useSubtitle = atoi(values[value].c_str());
- break;
- case 11:
- useDescription = atoi(values[value].c_str());
- break;
- case 12:
- useDuration = atoi(values[value].c_str());
- break;
- case 13:
- minDuration = atoi(values[value].c_str());
- break;
- case 14:
- maxDuration = atoi(values[value].c_str());
- break;
- case 15:
- useAsSearchTimer = atoi(values[value].c_str());
- break;
- case 16:
- useDayOfWeek = atoi(values[value].c_str());
- break;
- case 17:
- dayOfWeek = atoi(values[value].c_str());
- break;
- case 18:
- useEpisode = atoi(values[value].c_str());
- break;
- case 19:
- directory = values[value];
- break;
- case 20:
- priority = atoi(values[value].c_str());
- break;
- case 21:
- lifetime = atoi(values[value].c_str());
- break;
- case 22:
- marginStart = atoi(values[value].c_str());
- break;
- case 23:
- marginStop = atoi(values[value].c_str());
- break;
- case 24:
- useVPS = atoi(values[value].c_str());
- break;
- case 25:
- action = atoi(values[value].c_str());
- break;
- case 26:
- useExtEPGInfo = atoi(values[value].c_str());
- break;
- case 27:
- extEPGInfoValues = values[value];
- break;
- case 28:
- avoidRepeats = atoi(values[value].c_str());
- break;
- case 29:
- allowedRepeats = atoi(values[value].c_str());
- break;
- case 30:
- compareTitle = atoi(values[value].c_str());
- break;
- case 31:
- compareSubtitle = atoi(values[value].c_str());
- break;
- case 32:
- compareSummary = atoi(values[value].c_str());
- break;
- case 33:
- catvaluesAvoidRepeat = atol(values[value].c_str());
- break;
- case 34:
- repeatsWithinDays = atoi(values[value].c_str());
- break;
- case 35:
- delAfterDays = atoi(values[value].c_str());
- break;
- case 36:
- recordingsKeep = atoi(values[value].c_str());
- break;
- case 37:
- switchMinsBefore = atoi(values[value].c_str());
- break;
- case 38:
- pauseOnNrRecordings = atoi(values[value].c_str());
- break;
- case 39:
- blacklistMode = atoi(values[value].c_str());
- break;
- case 40:
- blacklists = values[value];
- break;
- case 41:
- fuzzyTolerance = atoi(values[value].c_str());
- break;
- case 42:
- useInFavorites = atoi(values[value].c_str());
- break;
- case 43:
- menuTemplate = atoi(values[value].c_str());
- break;
- case 44:
- delMode = atoi(values[value].c_str());
- break;
- case 45:
- delAfterCountRecs = atoi(values[value].c_str());
- break;
- case 46:
- delAfterDaysOfFirstRec = atoi(values[value].c_str());
- break;
- case 47:
- useAsSearchTimerFrom = atol(values[value].c_str());
- break;
- case 48:
- useAsSearchTimerTil = atol(values[value].c_str());
- break;
- case 49:
- ignoreMissingEPGCats = atoi(values[value].c_str());
- break;
- case 50:
- unmuteSoundOnSwitch = atoi(values[value].c_str());
- break;
- case 51:
- compareSummaryMatchInPercent = atoi(values[value].c_str());
- break;
- case 52:
- contentsFilter = values[value];
- break;
- case 53:
- compareDate = atoi(values[value].c_str());
- break;
- default:
- break;
- }
- }
- return true;
-}
-
-std::string cTVGuideSearchTimer::BuildSearchString(void) {
- std::stringstream search;
- // 0 - 2
- if (ID > -1)
- search << ID << ":";
- else
- search << ":";
- std::string searchStringMasked = searchString;
- std::replace(searchStringMasked.begin(), searchStringMasked.end(), ':', '|');
- search << searchStringMasked << ":";
- search << useTime << ":";
-
- // 3 - 6
- if (useTime) {
- search << *cString::sprintf("%04d", startTime) << ":";
- search << *cString::sprintf("%04d", stopTime) << ":";
- } else {
- search << "::";
- }
-
- search << useChannel << ":";
- if (useChannel == 1) {
- if (channelMin && channelMax) {
- if (channelMin->Number() < channelMax->Number())
- search << std::string(channelMin->GetChannelID().ToString()) << "|" << std::string(channelMax->GetChannelID().ToString()) << ":";
- else
- search << std::string(channelMin->GetChannelID().ToString()) << ":";
- } else {
- search << "0:";
- }
- } else if (useChannel == 2) {
- search << channelGroup << ":";
- } else {
- search << "0:";
- }
- // 7 - 14
- search << useCase << ":";
- search << mode << ":";
- search << useTitle << ":";
- search << useSubtitle << ":";
- search << useDescription << ":";
- search << useDuration << ":";
- if (useDuration) {
- search << *cString::sprintf("%04d", minDuration) << ":";
- search << *cString::sprintf("%04d", maxDuration) << ":";
- } else {
- search << "::";
- }
- //15 - 53
- search << useAsSearchTimer << ":";
- search << useDayOfWeek << ":";
- search << dayOfWeek << ":";
- search << useEpisode << ":";
- search << directory << ":";
- search << priority << ":";
- search << lifetime << ":";
- search << marginStart << ":";
- search << marginStop << ":";
- search << useVPS << ":";
- search << action << ":";
- search << useExtEPGInfo << ":";
- search << extEPGInfoValues << ":";
- search << avoidRepeats << ":";
- search << allowedRepeats << ":";
- search << compareTitle << ":";
- search << compareSubtitle << ":";
- search << compareSummary << ":";
- search << catvaluesAvoidRepeat << ":";
- search << repeatsWithinDays << ":";
- search << delAfterDays << ":";
- search << recordingsKeep << ":";
- search << switchMinsBefore << ":";
- search << pauseOnNrRecordings << ":";
- search << blacklistMode << ":";
- search << blacklists << ":";
- search << fuzzyTolerance << ":";
- search << useInFavorites << ":";
- search << menuTemplate << ":";
- search << delMode << ":";
- search << delAfterCountRecs << ":";
- search << delAfterDaysOfFirstRec << ":";
- search << useAsSearchTimerFrom << ":";
- search << useAsSearchTimerTil << ":";
- search << ignoreMissingEPGCats << ":";
- search << unmuteSoundOnSwitch << ":";
- search << compareSummaryMatchInPercent << ":";
- search << contentsFilter << ":";
- search << compareDate;
-
- strTimer = search.str();
- return strTimer;
-}
-
-bool cTVGuideSearchTimer::Active(void) {
- if (useAsSearchTimer)
- return true;
- return false;
-}
-
-
-int cTVGuideSearchTimer::GetNumTimers(void) {
- int numTimers = 0;
- if (ID < 0)
- return numTimers;
- for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) {
- char* searchID = GetAuxValue(timer, "s-id");
- if (!searchID) continue;
- if (ID == atoi(searchID))
- numTimers++;
- free(searchID);
- }
- return numTimers;
-}
-
-int cTVGuideSearchTimer::GetNumRecordings(void) {
- int numRecordings = 0;
- if (ID < 0)
- return numRecordings;
- for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) {
- if (recording->IsEdited())
- continue;
- if (!recording->Info())
- continue;
- char* searchID = GetAuxValue(recording, "s-id");
- if (!searchID) continue;
- if (ID == atoi(searchID))
- numRecordings++;
- free(searchID);
- }
- return numRecordings;
-}
-
-void cTVGuideSearchTimer::GetSearchModes(std::vector<std::string> *searchModes) {
- searchModes->push_back(tr("whole term must appear"));
- searchModes->push_back(tr("all terms must exist"));
- searchModes->push_back(tr("one term must exist"));
- searchModes->push_back(tr("exact match"));
- searchModes->push_back(tr("regular expression"));
-}
-
-
-void cTVGuideSearchTimer::Dump(void) {
- esyslog("tvguide searchtimer: strTimer: %s", strTimer.c_str());
- esyslog("tvguide searchtimer: ID: %d", ID);
- esyslog("tvguide searchtimer: searchString: %s", searchString.c_str());
- esyslog("tvguide searchtimer: useTime: %d", useTime);
- esyslog("tvguide searchtimer: startTime: %d", startTime);
- esyslog("tvguide searchtimer: stopTime: %d", stopTime);
- esyslog("tvguide searchtimer: useChannel: %d", useChannel);
- if (channelMin)
- esyslog("tvguide searchtimer: channelMin: %s", channelMin->Name());
- if (channelMax)
- esyslog("tvguide searchtimer: channelMax: %s", channelMax->Name());
- esyslog("tvguide searchtimer: channelGroup: %s", channelGroup.c_str());
- esyslog("tvguide searchtimer: useCase: %d", useCase);
- esyslog("tvguide searchtimer: mode: %d", mode);
- esyslog("tvguide searchtimer: useTitle: %d", useTitle);
- esyslog("tvguide searchtimer: useSubtitle: %d", useSubtitle);
- esyslog("tvguide searchtimer: useDescription: %d", useDescription);
-}
-
+#include <string> +#include <vector> +#include <sstream> +#include <algorithm> +#include <vdr/channels.h> +#include <vdr/device.h> +#include "helpers.h" +#include "searchtimer.h" + +// -- cTVGuideSearchTimer ----------------------------------------------------------------- +cTVGuideSearchTimer::cTVGuideSearchTimer(void) { + strTimer = ""; + ID = -1; + searchString = ""; + useTime = false; + startTime = 0000; + stopTime = 2359; + useChannel = false; +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + channelMin = Channels->GetByNumber(cDevice::CurrentChannel()); + channelMax = Channels->GetByNumber(cDevice::CurrentChannel()); +#else + channelMin = Channels.GetByNumber(cDevice::CurrentChannel()); + channelMax = Channels.GetByNumber(cDevice::CurrentChannel()); +#endif + channelGroup = ""; + useCase = false; + mode = 0; + useTitle = true; + useSubtitle = true; + useDescription = true; + useDuration = false; + minDuration = 0; + maxDuration = 2359; + useAsSearchTimer = true; + useDayOfWeek = false; + dayOfWeek = 0; + directory = ""; + useEpisode = 0; + priority = 99; + lifetime = 99; + marginStart = 5; + marginStop = 5; + useVPS = false; + action = 0; + useExtEPGInfo = 0; + extEPGInfoValues = ""; + avoidRepeats = 1; + allowedRepeats = 1; + compareTitle = 1; + compareSubtitle = 2; + compareSummary = 1; + catvaluesAvoidRepeat = 0; + repeatsWithinDays = 0; + delAfterDays = 0; + recordingsKeep = 0; + switchMinsBefore = 0; + pauseOnNrRecordings = 0; + blacklistMode = 0; + blacklists = ""; + fuzzyTolerance = 0; + useInFavorites = 0; + menuTemplate = 0; + delMode = 0; + delAfterCountRecs = 0; + delAfterDaysOfFirstRec = 0; + useAsSearchTimerFrom = 0; + useAsSearchTimerTil = 0; + ignoreMissingEPGCats = 0; + unmuteSoundOnSwitch = 0; + compareSummaryMatchInPercent = 0; + contentsFilter = ""; + compareDate = 0; +} + +cTVGuideSearchTimer::~cTVGuideSearchTimer(void) { +} + +bool cTVGuideSearchTimer::operator < (const cTVGuideSearchTimer& other) const { + std::string searchStringOther = other.SearchString(); + searchStringOther = StrToLowerCase(searchStringOther); + std::string thisSearchString = StrToLowerCase(searchString); + int comp = thisSearchString.compare(searchStringOther); + if (comp < 0) + return true; + return false; +} + + +void cTVGuideSearchTimer::SetTemplate(std::string tmpl) { + std::stringstream searchTimerString; + searchTimerString << "0:"; + searchTimerString << tmpl; + strTimer = searchTimerString.str(); +} + +int cTVGuideSearchTimer::DayOfWeek(void) { + int vdrDayOfWeek = 0; + if (dayOfWeek >= 0) { + vdrDayOfWeek = pow(2, (dayOfWeek+6)%7); + } else if (dayOfWeek < 0) { + int absDayOfWeek = abs(dayOfWeek); + for (int i=0; i < 7; i++) { + if (absDayOfWeek & (1 << i)) { + vdrDayOfWeek += pow(2, (i+6)%7); + } + } + } + return vdrDayOfWeek; +} + +void cTVGuideSearchTimer::SetDayOfWeek(int VDRDayOfWeek) { + int epgSearchDayOfWeek = 0; + for (int i=0; i < 7; i++) { + if (VDRDayOfWeek & (1 << i)) { + epgSearchDayOfWeek += pow(2, (i+1)%7); + } + } + this->dayOfWeek = epgSearchDayOfWeek * (-1); +} + +/* + 0 - unique search timer id + 1 - the search term + 2 - use time? 0/1 + 3 - start time in HHMM + 4 - stop time in HHMM + 5 - use channel? 0 = no, 1 = Interval, 2 = Channel group, 3 = FTA only + 6 - if 'use channel' = 1 then channel id[|channel id] in VDR format, + one entry or min/max entry separated with |, if 'use channel' = 2 + then the channel group name + 7 - match case? 0/1 + 8 - search mode: + 0 - the whole term must appear as substring + 1 - all single terms (delimiters are blank,',', ';', '|' or '~') + must exist as substrings. + 2 - at least one term (delimiters are blank, ',', ';', '|' or '~') + must exist as substring. + 3 - matches exactly + 4 - regular expression + 9 - use title? 0/1 + 10 - use subtitle? 0/1 + 11 - use description? 0/1 + 12 - use duration? 0/1 + 13 - min duration in hhmm + 14 - max duration in hhmm + 15 - use as search timer? 0/1 + 16 - use day of week? 0/1 + 17 - day of week (0 = Sunday, 1 = Monday...; + -1 Sunday, -2 Monday, -4 Tuesday, ...; -7 Sun, Mon, Tue) + 18 - use series recording? 0/1 + 19 - directory for recording + 20 - priority of recording + 21 - lifetime of recording + 22 - time margin for start in minutes + 23 - time margin for stop in minutes + 24 - use VPS? 0/1 + 25 - action: + 0 = create a timer + 1 = announce only via OSD (no timer) + 2 = switch only (no timer) + 3 = announce via OSD and switch (no timer) + 4 = announce via mail + 26 - use extended EPG info? 0/1 + 27 - extended EPG info values. This entry has the following format + (delimiter is '|' for each category, '#' separates id and value): + 1 - the id of the extended EPG info category as specified in + epgsearchcats.conf + 2 - the value of the extended EPG info category + (a ':' will be translated to "!^colon^!", e.g. in "16:9") + 28 - avoid repeats? 0/1 + 29 - allowed repeats + 30 - compare title when testing for a repeat? 0/1 + 31 - compare subtitle when testing for a repeat? 0/1/2 + 0 - no + 1 - yes + 2 - yes, if present + 32 - compare description when testing for a repeat? 0/1 + 33 - compare extended EPG info when testing for a repeat? + This entry is a bit field of the category IDs. + 34 - accepts repeats only within x days + 35 - delete a recording automatically after x days + 36 - but keep this number of recordings anyway + 37 - minutes before switch (if action = 2) + 38 - pause if x recordings already exist + 39 - blacklist usage mode (0 none, 1 selection, 2 all) + 40 - selected blacklist IDs separated with '|' + 41 - fuzzy tolerance value for fuzzy searching + 42 - use this search in favorites menu (0 no, 1 yes) + 43 - id of a menu search template + 44 - auto deletion mode (0 don't delete search timer, 1 delete after given + count of recordings, 2 delete after given days after first recording) + 45 - count of recordings after which to delete the search timer + 46 - count of days after the first recording after which to delete the search + timer + 47 - first day where the search timer is active (see parameter 16) + 48 - last day where the search timer is active (see parameter 16) + 49 - ignore missing EPG categories? 0/1 + 50 - unmute sound if off when used as switch timer + 51 - percentage of match when comparing the summary of two events (with 'avoid repeats') + 52 - HEX representation of the content descriptors, each descriptor ID is represented with 2 chars + 53 - compare date when testing for a repeat? (0=no, 1=same day, 2=same week, 3=same month) +*/ +bool cTVGuideSearchTimer::Parse(bool readTemplate) { + splitstring s(strTimer.c_str()); + std::vector<std::string> values = s.split(':', 1); + int numValues = values.size(); + if (numValues < 12) + return false; + for (int value = 0; value < numValues; value++) { + switch (value) { + case 0: + if (!readTemplate) + ID = atoi(values[value].c_str()); + break; + case 1: + if (!readTemplate) { + std::string searchStringMasked = values[value]; + std::replace(searchStringMasked.begin(), searchStringMasked.end(), '|', ':'); + searchString = searchStringMasked; + } + break; + case 2: + useTime = atoi(values[value].c_str()); + break; + case 3: + if (useTime) { + startTime = atoi(values[value].c_str()); + } + break; + case 4: + if (useTime) { + stopTime = atoi(values[value].c_str()); + } + break; + case 5: + useChannel = atoi(values[value].c_str()); + break; + case 6: + if (useChannel == 0) { + channelMin = NULL; + channelMax = NULL; + } else if (useChannel == 1) { + char *channelMinbuffer = NULL; + char *channelMaxbuffer = NULL; + int channels = sscanf(values[value].c_str(), "%m[^|]|%m[^|]", &channelMinbuffer, &channelMaxbuffer); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* channelsP = Channels; +#else + cChannels* channelsP = &Channels; +#endif + channelMin = channelsP->GetByChannelID(tChannelID::FromString(channelMinbuffer), true, true); + if (!channelMin) { + channelMin = channelMax = NULL; + useChannel = 0; + } + if (channels == 1) + channelMax = channelMin; + else { + channelMax = channelsP->GetByChannelID(tChannelID::FromString(channelMaxbuffer), true, true); + if (!channelMax) { + channelMin = channelMax = NULL; + useChannel = 0; + } + } + free(channelMinbuffer); + free(channelMaxbuffer); + } else if (useChannel == 2) { + channelGroup = values[value]; + } + break; + case 7: + useCase = atoi(values[value].c_str()); + break; + case 8: + mode = atoi(values[value].c_str()); + break; + case 9: + useTitle = atoi(values[value].c_str()); + break; + case 10: + useSubtitle = atoi(values[value].c_str()); + break; + case 11: + useDescription = atoi(values[value].c_str()); + break; + case 12: + useDuration = atoi(values[value].c_str()); + break; + case 13: + minDuration = atoi(values[value].c_str()); + break; + case 14: + maxDuration = atoi(values[value].c_str()); + break; + case 15: + useAsSearchTimer = atoi(values[value].c_str()); + break; + case 16: + useDayOfWeek = atoi(values[value].c_str()); + break; + case 17: + dayOfWeek = atoi(values[value].c_str()); + break; + case 18: + useEpisode = atoi(values[value].c_str()); + break; + case 19: + directory = values[value]; + break; + case 20: + priority = atoi(values[value].c_str()); + break; + case 21: + lifetime = atoi(values[value].c_str()); + break; + case 22: + marginStart = atoi(values[value].c_str()); + break; + case 23: + marginStop = atoi(values[value].c_str()); + break; + case 24: + useVPS = atoi(values[value].c_str()); + break; + case 25: + action = atoi(values[value].c_str()); + break; + case 26: + useExtEPGInfo = atoi(values[value].c_str()); + break; + case 27: + extEPGInfoValues = values[value]; + break; + case 28: + avoidRepeats = atoi(values[value].c_str()); + break; + case 29: + allowedRepeats = atoi(values[value].c_str()); + break; + case 30: + compareTitle = atoi(values[value].c_str()); + break; + case 31: + compareSubtitle = atoi(values[value].c_str()); + break; + case 32: + compareSummary = atoi(values[value].c_str()); + break; + case 33: + catvaluesAvoidRepeat = atol(values[value].c_str()); + break; + case 34: + repeatsWithinDays = atoi(values[value].c_str()); + break; + case 35: + delAfterDays = atoi(values[value].c_str()); + break; + case 36: + recordingsKeep = atoi(values[value].c_str()); + break; + case 37: + switchMinsBefore = atoi(values[value].c_str()); + break; + case 38: + pauseOnNrRecordings = atoi(values[value].c_str()); + break; + case 39: + blacklistMode = atoi(values[value].c_str()); + break; + case 40: + blacklists = values[value]; + break; + case 41: + fuzzyTolerance = atoi(values[value].c_str()); + break; + case 42: + useInFavorites = atoi(values[value].c_str()); + break; + case 43: + menuTemplate = atoi(values[value].c_str()); + break; + case 44: + delMode = atoi(values[value].c_str()); + break; + case 45: + delAfterCountRecs = atoi(values[value].c_str()); + break; + case 46: + delAfterDaysOfFirstRec = atoi(values[value].c_str()); + break; + case 47: + useAsSearchTimerFrom = atol(values[value].c_str()); + break; + case 48: + useAsSearchTimerTil = atol(values[value].c_str()); + break; + case 49: + ignoreMissingEPGCats = atoi(values[value].c_str()); + break; + case 50: + unmuteSoundOnSwitch = atoi(values[value].c_str()); + break; + case 51: + compareSummaryMatchInPercent = atoi(values[value].c_str()); + break; + case 52: + contentsFilter = values[value]; + break; + case 53: + compareDate = atoi(values[value].c_str()); + break; + default: + break; + } + } + return true; +} + +std::string cTVGuideSearchTimer::BuildSearchString(void) { + std::stringstream search; + // 0 - 2 + if (ID > -1) + search << ID << ":"; + else + search << ":"; + std::string searchStringMasked = searchString; + std::replace(searchStringMasked.begin(), searchStringMasked.end(), ':', '|'); + search << searchStringMasked << ":"; + search << useTime << ":"; + + // 3 - 6 + if (useTime) { + search << *cString::sprintf("%04d", startTime) << ":"; + search << *cString::sprintf("%04d", stopTime) << ":"; + } else { + search << "::"; + } + + search << useChannel << ":"; + if (useChannel == 1) { + if (channelMin && channelMax) { + if (channelMin->Number() < channelMax->Number()) + search << std::string(channelMin->GetChannelID().ToString()) << "|" << std::string(channelMax->GetChannelID().ToString()) << ":"; + else + search << std::string(channelMin->GetChannelID().ToString()) << ":"; + } else { + search << "0:"; + } + } else if (useChannel == 2) { + search << channelGroup << ":"; + } else { + search << "0:"; + } + // 7 - 14 + search << useCase << ":"; + search << mode << ":"; + search << useTitle << ":"; + search << useSubtitle << ":"; + search << useDescription << ":"; + search << useDuration << ":"; + if (useDuration) { + search << *cString::sprintf("%04d", minDuration) << ":"; + search << *cString::sprintf("%04d", maxDuration) << ":"; + } else { + search << "::"; + } + //15 - 53 + search << useAsSearchTimer << ":"; + search << useDayOfWeek << ":"; + search << dayOfWeek << ":"; + search << useEpisode << ":"; + search << directory << ":"; + search << priority << ":"; + search << lifetime << ":"; + search << marginStart << ":"; + search << marginStop << ":"; + search << useVPS << ":"; + search << action << ":"; + search << useExtEPGInfo << ":"; + search << extEPGInfoValues << ":"; + search << avoidRepeats << ":"; + search << allowedRepeats << ":"; + search << compareTitle << ":"; + search << compareSubtitle << ":"; + search << compareSummary << ":"; + search << catvaluesAvoidRepeat << ":"; + search << repeatsWithinDays << ":"; + search << delAfterDays << ":"; + search << recordingsKeep << ":"; + search << switchMinsBefore << ":"; + search << pauseOnNrRecordings << ":"; + search << blacklistMode << ":"; + search << blacklists << ":"; + search << fuzzyTolerance << ":"; + search << useInFavorites << ":"; + search << menuTemplate << ":"; + search << delMode << ":"; + search << delAfterCountRecs << ":"; + search << delAfterDaysOfFirstRec << ":"; + search << useAsSearchTimerFrom << ":"; + search << useAsSearchTimerTil << ":"; + search << ignoreMissingEPGCats << ":"; + search << unmuteSoundOnSwitch << ":"; + search << compareSummaryMatchInPercent << ":"; + search << contentsFilter << ":"; + search << compareDate; + + strTimer = search.str(); + return strTimer; +} + +bool cTVGuideSearchTimer::Active(void) { + if (useAsSearchTimer) + return true; + return false; +} + +void cTVGuideSearchTimer::SetStartChannel(int startChannel) { +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + channelMin = Channels->GetByNumber(startChannel); +#else + channelMin = Channels.GetByNumber(startChannel); +#endif +} + +void cTVGuideSearchTimer::SetStopChannel(int stopChannel) { +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + channelMax = Channels->GetByNumber(stopChannel); +#else + channelMax = Channels.GetByNumber(stopChannel); +#endif +} + +int cTVGuideSearchTimer::GetNumTimers(void) { + int numTimers = 0; + if (ID < 0) + return numTimers; +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_READ; + const cTimers* timers = Timers; +#else + const cTimers* timers = &Timers; +#endif + for (const cTimer *timer = timers->First(); timer; timer = timers->Next(timer)) { + char* searchID = GetAuxValue(timer, "s-id"); + if (!searchID) continue; + if (ID == atoi(searchID)) + numTimers++; + free(searchID); + } + return numTimers; +} + +int cTVGuideSearchTimer::GetNumRecordings(void) { + int numRecordings = 0; + if (ID < 0) + return numRecordings; +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_RECORDINGS_READ; + const cRecordings* recordings = Recordings; +#else + cRecordings* recordings = &Recordings; +#endif + for (const cRecording *recording = recordings->First(); recording; recording = recordings->Next(recording)) { + if (recording->IsEdited()) + continue; + if (!recording->Info()) + continue; + char* searchID = GetAuxValue(recording, "s-id"); + if (!searchID) continue; + if (ID == atoi(searchID)) + numRecordings++; + free(searchID); + } + return numRecordings; +} + +void cTVGuideSearchTimer::GetSearchModes(std::vector<std::string> *searchModes) { + searchModes->push_back(tr("whole term must appear")); + searchModes->push_back(tr("all terms must exist")); + searchModes->push_back(tr("one term must exist")); + searchModes->push_back(tr("exact match")); + searchModes->push_back(tr("regular expression")); +} + + +void cTVGuideSearchTimer::Dump(void) { + esyslog("tvguide searchtimer: strTimer: %s", strTimer.c_str()); + esyslog("tvguide searchtimer: ID: %d", ID); + esyslog("tvguide searchtimer: searchString: %s", searchString.c_str()); + esyslog("tvguide searchtimer: useTime: %d", useTime); + esyslog("tvguide searchtimer: startTime: %d", startTime); + esyslog("tvguide searchtimer: stopTime: %d", stopTime); + esyslog("tvguide searchtimer: useChannel: %d", useChannel); + if (channelMin) + esyslog("tvguide searchtimer: channelMin: %s", channelMin->Name()); + if (channelMax) + esyslog("tvguide searchtimer: channelMax: %s", channelMax->Name()); + esyslog("tvguide searchtimer: channelGroup: %s", channelGroup.c_str()); + esyslog("tvguide searchtimer: useCase: %d", useCase); + esyslog("tvguide searchtimer: mode: %d", mode); + esyslog("tvguide searchtimer: useTitle: %d", useTitle); + esyslog("tvguide searchtimer: useSubtitle: %d", useSubtitle); + esyslog("tvguide searchtimer: useDescription: %d", useDescription); +} + diff --git a/searchtimer.h b/searchtimer.h index f797ebd..d0e944c 100644 --- a/searchtimer.h +++ b/searchtimer.h @@ -1,136 +1,136 @@ -#ifndef __TVGUIDE_SEARCHTIMER_H
-#define __TVGUIDE_SEARCHTIMER_H
-
-
-class cTVGuideSearchTimer {
-private:
- std::string strTimer;
- int ID;
- std::string searchString;
- int useTime;
- int startTime;
- int stopTime;
- int useChannel;
- cChannel *channelMin;
- cChannel *channelMax;
- std::string channelGroup;
- int useCase;
- int mode;
- int useTitle;
- int useSubtitle;
- int useDescription;
- int useDuration;
- int minDuration;
- int maxDuration;
- int useAsSearchTimer;
- int useDayOfWeek;
- int dayOfWeek;
- int useEpisode;
- std::string directory;
- int priority;
- int lifetime;
- int marginStart;
- int marginStop;
- int useVPS;
- int action;
- int useExtEPGInfo;
- std::string extEPGInfoValues;
- int avoidRepeats;
- int allowedRepeats;
- int compareTitle;
- int compareSubtitle;
- int compareSummary;
- unsigned long catvaluesAvoidRepeat;
- int repeatsWithinDays;
- int delAfterDays;
- int recordingsKeep;
- int switchMinsBefore;
- int pauseOnNrRecordings;
- int blacklistMode;
- std::string blacklists;
- int fuzzyTolerance;
- int useInFavorites;
- int menuTemplate;
- int delMode;
- int delAfterCountRecs;
- int delAfterDaysOfFirstRec;
- int useAsSearchTimerFrom;
- int useAsSearchTimerTil;
- int ignoreMissingEPGCats;
- int unmuteSoundOnSwitch;
- int compareSummaryMatchInPercent;
- std::string contentsFilter;
- int compareDate;
-public:
- cTVGuideSearchTimer(void);
- virtual ~cTVGuideSearchTimer(void);
- bool operator < (const cTVGuideSearchTimer& other) const;
- void SetEPGSearchString(std::string strTimer) { this->strTimer = strTimer; };
- void SetTemplate(std::string tmpl);
- bool Parse(bool readTemplate = false);
- std::string BuildSearchString(void);
- int GetID(void) { return ID; };
- //GETTER
- std::string SearchString(void) const { return searchString; };
- bool Active(void);
- bool UseTitle(void) { return useTitle; };
- bool UseSubtitle(void) { return useSubtitle; };
- bool UseDescription(void) { return useDescription; };
- int SearchMode(void) { return mode; };
- bool UseChannel(void) { return useChannel; };
- int StartChannel(void) { return (channelMin)?channelMin->Number():0; };
- int StopChannel(void) { return (channelMax)?channelMax->Number():0; };
- bool UseTime(void) { return useTime; };
- int StartTime(void) { return startTime; };
- int StopTime(void) { return stopTime; };
- bool UseDayOfWeek(void) { return useDayOfWeek; };
- int DayOfWeek(void);
- int UseEpisode(void) { return useEpisode; };
- std::string Directory(void) { return directory; };
- int Priority(void) { return priority; };
- int Lifetime(void) { return lifetime; };
- int MarginStart(void) { return marginStart; };
- int MarginStop(void) { return marginStop; };
- bool UseVPS(void) { return useVPS; };
- bool AvoidRepeats(void) { return avoidRepeats; };
- int AllowedRepeats(void) { return allowedRepeats; };
- bool CompareTitle(void) { return compareTitle; };
- bool CompareSubtitle(void) { return compareSubtitle; };
- bool CompareSummary(void) { return compareSummary; };
- bool UseInFavorites(void) { return useInFavorites; };
- //SETTER
- void SetSearchString(std::string searchString) { this->searchString = searchString; };
- void SetActive(bool active) { useAsSearchTimer = active; };
- void SetSearchMode(int searchMode) { mode = searchMode; };
- void SetUseTitle(bool useTitle) { this->useTitle = useTitle; };
- void SetUseSubtitle(bool useSubtitle) { this->useSubtitle = useSubtitle; };
- void SetUseDesription(bool useDescription) { this->useDescription = useDescription; };
- void SetUseChannel(bool useChannel) { this->useChannel = useChannel; };
- void SetStartChannel(int startChannel) { channelMin = Channels.GetByNumber(startChannel); };
- void SetStopChannel(int stopChannel) { channelMax = Channels.GetByNumber(stopChannel); };
- void SetUseTime(bool useTime) { this->useTime = useTime; };
- void SetStartTime(int startTime) { this->startTime = startTime; };
- void SetStopTime(int stopTime) { this->stopTime = stopTime; };
- void SetUseDayOfWeek(bool useDayOfWeek) { this->useDayOfWeek = useDayOfWeek; };
- void SetDayOfWeek(int VDRDayOfWeek);
- void SetUseEpisode(int useEpisode) { this->useEpisode = useEpisode; };
- void SetDirectory(std::string directory) { this-> directory = directory; };
- void SetPriority(int priority) { this->priority = priority; };
- void SetLifetime(int lifetime) { this->lifetime = lifetime; };
- void SetMarginStart(int marginStart) { this->marginStart = marginStart; };
- void SetMarginStop(int marginStop) { this->marginStop = marginStop; };
- void SetUseVPS(bool useVPS) { this->useVPS = useVPS; };
- void SetAvoidRepeats(bool avoidRepeats) { this->avoidRepeats = avoidRepeats; };
- void SetAllowedRepeats(int allowedRepeats) { this->allowedRepeats = allowedRepeats; };
- void SetCompareTitle(bool compareTitle) { this->compareTitle = compareTitle; };
- void SetCompareSubtitle(bool compareSubtitle) { this->compareSubtitle = compareSubtitle; };
- void SetCompareSummary(bool compareSummary) { this->compareSummary = compareSummary; };
- void SetUseInFavorites(bool useInFavorites) { this->useInFavorites = useInFavorites; };
- //COMMON
- int GetNumTimers(void);
- int GetNumRecordings(void);
- void GetSearchModes(std::vector<std::string> *searchModes);
- void Dump(void);
-};
-
-#endif //__TVGUIDE_SEARCHTIMER_H
+#ifndef __TVGUIDE_SEARCHTIMER_H +#define __TVGUIDE_SEARCHTIMER_H + + +class cTVGuideSearchTimer { +private: + std::string strTimer; + int ID; + std::string searchString; + int useTime; + int startTime; + int stopTime; + int useChannel; + const cChannel *channelMin; + const cChannel *channelMax; + std::string channelGroup; + int useCase; + int mode; + int useTitle; + int useSubtitle; + int useDescription; + int useDuration; + int minDuration; + int maxDuration; + int useAsSearchTimer; + int useDayOfWeek; + int dayOfWeek; + int useEpisode; + std::string directory; + int priority; + int lifetime; + int marginStart; + int marginStop; + int useVPS; + int action; + int useExtEPGInfo; + std::string extEPGInfoValues; + int avoidRepeats; + int allowedRepeats; + int compareTitle; + int compareSubtitle; + int compareSummary; + unsigned long catvaluesAvoidRepeat; + int repeatsWithinDays; + int delAfterDays; + int recordingsKeep; + int switchMinsBefore; + int pauseOnNrRecordings; + int blacklistMode; + std::string blacklists; + int fuzzyTolerance; + int useInFavorites; + int menuTemplate; + int delMode; + int delAfterCountRecs; + int delAfterDaysOfFirstRec; + int useAsSearchTimerFrom; + int useAsSearchTimerTil; + int ignoreMissingEPGCats; + int unmuteSoundOnSwitch; + int compareSummaryMatchInPercent; + std::string contentsFilter; + int compareDate; +public: + cTVGuideSearchTimer(void); + virtual ~cTVGuideSearchTimer(void); + bool operator < (const cTVGuideSearchTimer& other) const; + void SetEPGSearchString(std::string strTimer) { this->strTimer = strTimer; }; + void SetTemplate(std::string tmpl); + bool Parse(bool readTemplate = false); + std::string BuildSearchString(void); + int GetID(void) { return ID; }; + //GETTER + std::string SearchString(void) const { return searchString; }; + bool Active(void); + bool UseTitle(void) { return useTitle; }; + bool UseSubtitle(void) { return useSubtitle; }; + bool UseDescription(void) { return useDescription; }; + int SearchMode(void) { return mode; }; + bool UseChannel(void) { return useChannel; }; + int StartChannel(void) { return (channelMin)?channelMin->Number():0; }; + int StopChannel(void) { return (channelMax)?channelMax->Number():0; }; + bool UseTime(void) { return useTime; }; + int StartTime(void) { return startTime; }; + int StopTime(void) { return stopTime; }; + bool UseDayOfWeek(void) { return useDayOfWeek; }; + int DayOfWeek(void); + int UseEpisode(void) { return useEpisode; }; + std::string Directory(void) { return directory; }; + int Priority(void) { return priority; }; + int Lifetime(void) { return lifetime; }; + int MarginStart(void) { return marginStart; }; + int MarginStop(void) { return marginStop; }; + bool UseVPS(void) { return useVPS; }; + bool AvoidRepeats(void) { return avoidRepeats; }; + int AllowedRepeats(void) { return allowedRepeats; }; + bool CompareTitle(void) { return compareTitle; }; + bool CompareSubtitle(void) { return compareSubtitle; }; + bool CompareSummary(void) { return compareSummary; }; + bool UseInFavorites(void) { return useInFavorites; }; + //SETTER + void SetSearchString(std::string searchString) { this->searchString = searchString; }; + void SetActive(bool active) { useAsSearchTimer = active; }; + void SetSearchMode(int searchMode) { mode = searchMode; }; + void SetUseTitle(bool useTitle) { this->useTitle = useTitle; }; + void SetUseSubtitle(bool useSubtitle) { this->useSubtitle = useSubtitle; }; + void SetUseDesription(bool useDescription) { this->useDescription = useDescription; }; + void SetUseChannel(bool useChannel) { this->useChannel = useChannel; }; + void SetStartChannel(int startChannel); + void SetStopChannel(int stopChannel); + void SetUseTime(bool useTime) { this->useTime = useTime; }; + void SetStartTime(int startTime) { this->startTime = startTime; }; + void SetStopTime(int stopTime) { this->stopTime = stopTime; }; + void SetUseDayOfWeek(bool useDayOfWeek) { this->useDayOfWeek = useDayOfWeek; }; + void SetDayOfWeek(int VDRDayOfWeek); + void SetUseEpisode(int useEpisode) { this->useEpisode = useEpisode; }; + void SetDirectory(std::string directory) { this-> directory = directory; }; + void SetPriority(int priority) { this->priority = priority; }; + void SetLifetime(int lifetime) { this->lifetime = lifetime; }; + void SetMarginStart(int marginStart) { this->marginStart = marginStart; }; + void SetMarginStop(int marginStop) { this->marginStop = marginStop; }; + void SetUseVPS(bool useVPS) { this->useVPS = useVPS; }; + void SetAvoidRepeats(bool avoidRepeats) { this->avoidRepeats = avoidRepeats; }; + void SetAllowedRepeats(int allowedRepeats) { this->allowedRepeats = allowedRepeats; }; + void SetCompareTitle(bool compareTitle) { this->compareTitle = compareTitle; }; + void SetCompareSubtitle(bool compareSubtitle) { this->compareSubtitle = compareSubtitle; }; + void SetCompareSummary(bool compareSummary) { this->compareSummary = compareSummary; }; + void SetUseInFavorites(bool useInFavorites) { this->useInFavorites = useInFavorites; }; + //COMMON + int GetNumTimers(void); + int GetNumRecordings(void); + void GetSearchModes(std::vector<std::string> *searchModes); + void Dump(void); +}; + +#endif //__TVGUIDE_SEARCHTIMER_H diff --git a/services/remotetimers.h b/services/remotetimers.h index cd86b7a..3a01388 100644 --- a/services/remotetimers.h +++ b/services/remotetimers.h @@ -9,7 +9,7 @@ struct RemoteTimers_Event_v1_0 { //in const cEvent *event; //out - cTimer *timer; + const cTimer *timer; cString errorMsg; }; @@ -17,7 +17,7 @@ struct RemoteTimers_GetMatch_v1_0 { //in const cEvent *event; //out - cTimer *timer; + const cTimer *timer; int timerMatch; int timerType; bool isRemote; @@ -30,4 +30,4 @@ struct RemoteTimers_Timer_v1_0 { cString errorMsg; }; -#endif //REMOTETIMERSERVICES_INC
\ No newline at end of file +#endif //REMOTETIMERSERVICES_INC diff --git a/timemanager.c b/timemanager.c index f6a0dd3..bb056cc 100644 --- a/timemanager.c +++ b/timemanager.c @@ -1,173 +1,173 @@ -#include <time.h>
-#include <vdr/tools.h>
-#include "config.h"
-#include "timemanager.h"
-
-cTimeManager::cTimeManager(void) {
- displayHours = config.displayHours;
- displaySeconds = displayHours * 3600;
- timeFormat = e24Hours;
-}
-
-cTimeManager::~cTimeManager(void) {
-}
-
-cString cTimeManager::PrintTime(time_t displayTime) {
- struct tm *ts;
- ts = localtime(&displayTime);
- cString strTime = cString::sprintf("%d.%d-%d:%d.%d", ts->tm_mday, ts->tm_mon+1, ts->tm_hour, ts->tm_min, ts->tm_sec);
- return strTime;
-}
-
-
-void cTimeManager::Now() {
- t = time(0);
- tStart = t;
- tStart = GetRounded();
- tEnd = tStart + displaySeconds;
-}
-
-void cTimeManager::AddMinutes(int step) {
- tStart += step*60;
- tEnd += step*60;
-}
-
-bool cTimeManager::DelMinutes(int step) {
- if ((tStart - step*60)+30*60 < t) {
- return true;
- }
- tStart -= step*60;
- tEnd -= step*60;
- return false;
-}
-
-void cTimeManager::SetTime(time_t newTime) {
- tStart = newTime;
- tEnd = tStart + displaySeconds;
-}
-
-time_t cTimeManager::GetPrevPrimetime(time_t current) {
- tm *st = localtime(¤t);
- if (st->tm_hour < 21) {
- current -= 24 * 60* 60;
- st = localtime(¤t);
- }
- st->tm_hour = 20;
- st->tm_min = 0;
- time_t primeTime = mktime(st);
- return primeTime;
-}
-
-time_t cTimeManager::GetNextPrimetime(time_t current){
- tm *st = localtime(¤t);
- if (st->tm_hour > 19) {
- current += 24 * 60* 60;
- st = localtime(¤t);
- }
- st->tm_hour = 20;
- st->tm_min = 0;
- time_t primeTime = mktime(st);
- return primeTime;
-}
-
-bool cTimeManager::TooFarInPast(time_t current) {
- if (current < t) {
- return true;
- }
- return false;
-}
-
-cString cTimeManager::GetCurrentTime() {
- char buf[25];
- t = time(0);
- tm *st = localtime(&t);
- if (timeFormat == e12Hours) {
- strftime(buf, sizeof(buf), "%I:%M %p", st);
- } else if (timeFormat == e24Hours)
- strftime(buf, sizeof(buf), "%H:%M", st);
- return buf;
-
-}
-
-cString cTimeManager::GetDate() {
- char text[6];
- tm *st = localtime(&tStart);
- snprintf(text, sizeof(text), "%d.%d", st->tm_mday, st->tm_mon+1);
- return text;
-}
-
-cString cTimeManager::GetWeekday() {
- return WeekDayName(tStart);
-}
-
-bool cTimeManager::IsStart(int activeStart) {
- if (tStart <= t && activeStart <= t)
- return true;
- return false;
-}
-
-time_t cTimeManager::GetRounded() {
- tm *rounded = localtime ( &tStart );
- rounded->tm_sec = 0;
- if (rounded->tm_min > 29)
- rounded->tm_min = 30;
- else
- rounded->tm_min = 0;
- return mktime(rounded);
-}
-
-bool cTimeManager::NowVisible(void) {
- if (t > tStart)
- return true;
- return false;
-}
-
-void cTimeManager::Debug() {
- esyslog("tvguideng: now %s, tStart: %s, tEnd: %s", *TimeString(t), *TimeString(tStart), *TimeString(tEnd));
-}
-
-// --- cTimeInterval -------------------------------------------------------------
-
-cTimeInterval::cTimeInterval(time_t start, time_t stop) {
- this->start = start;
- this->stop = stop;
-}
-
-cTimeInterval::~cTimeInterval(void) {
-}
-
-cTimeInterval *cTimeInterval::Intersect(cTimeInterval *interval) {
- time_t startIntersect, stopIntersect;
-
- if ((stop <= interval->Start()) || (interval->Stop() <= start)) {
- return NULL;
- }
-
- if (start <= interval->Start()) {
- startIntersect = interval->Start();
- } else {
- startIntersect = start;
- }
- if (stop <= interval->Stop()) {
- stopIntersect = stop;
- } else {
- stopIntersect = interval->Stop();
- }
- return new cTimeInterval(startIntersect, stopIntersect);
-}
-
-cTimeInterval *cTimeInterval::Union(cTimeInterval *interval) {
- time_t startUnion, stopUnion;
-
- if (start <= interval->Start()) {
- startUnion = start;
- } else {
- startUnion = interval->Start();
- }
- if (stop <= interval->Stop()) {
- stopUnion = interval->Stop();
- } else {
- stopUnion = stop;
- }
- return new cTimeInterval(startUnion, stopUnion);
+#include <time.h> +#include <vdr/tools.h> +#include "config.h" +#include "timemanager.h" + +cTimeManager::cTimeManager(void) { + displayHours = config.displayHours; + displaySeconds = displayHours * 3600; + timeFormat = e24Hours; +} + +cTimeManager::~cTimeManager(void) { +} + +cString cTimeManager::PrintTime(time_t displayTime) { + struct tm *ts; + ts = localtime(&displayTime); + cString strTime = cString::sprintf("%d.%d-%d:%d.%d", ts->tm_mday, ts->tm_mon+1, ts->tm_hour, ts->tm_min, ts->tm_sec); + return strTime; +} + + +void cTimeManager::Now() { + t = time(0); + tStart = t; + tStart = GetRounded(); + tEnd = tStart + displaySeconds; +} + +void cTimeManager::AddMinutes(int step) { + tStart += step*60; + tEnd += step*60; +} + +bool cTimeManager::DelMinutes(int step) { + if ((tStart - step*60)+30*60 < t) { + return true; + } + tStart -= step*60; + tEnd -= step*60; + return false; +} + +void cTimeManager::SetTime(time_t newTime) { + tStart = newTime; + tEnd = tStart + displaySeconds; +} + +time_t cTimeManager::GetPrevPrimetime(time_t current) { + tm *st = localtime(¤t); + if (st->tm_hour < 21) { + current -= 24 * 60* 60; + st = localtime(¤t); + } + st->tm_hour = 20; + st->tm_min = 0; + time_t primeTime = mktime(st); + return primeTime; +} + +time_t cTimeManager::GetNextPrimetime(time_t current){ + tm *st = localtime(¤t); + if (st->tm_hour > 19) { + current += 24 * 60* 60; + st = localtime(¤t); + } + st->tm_hour = 20; + st->tm_min = 0; + time_t primeTime = mktime(st); + return primeTime; +} + +bool cTimeManager::TooFarInPast(time_t current) { + if (current < t) { + return true; + } + return false; +} + +cString cTimeManager::GetCurrentTime() { + char buf[25]; + t = time(0); + tm *st = localtime(&t); + if (timeFormat == e12Hours) { + strftime(buf, sizeof(buf), "%I:%M %p", st); + } else if (timeFormat == e24Hours) + strftime(buf, sizeof(buf), "%H:%M", st); + return buf; + +} + +cString cTimeManager::GetDate() { + char text[6]; + tm *st = localtime(&tStart); + snprintf(text, sizeof(text), "%d.%d", st->tm_mday, st->tm_mon+1); + return text; +} + +cString cTimeManager::GetWeekday() { + return WeekDayName(tStart); +} + +bool cTimeManager::IsStart(int activeStart) { + if (tStart <= t && activeStart <= t) + return true; + return false; +} + +time_t cTimeManager::GetRounded() { + tm *rounded = localtime ( &tStart ); + rounded->tm_sec = 0; + if (rounded->tm_min > 29) + rounded->tm_min = 30; + else + rounded->tm_min = 0; + return mktime(rounded); +} + +bool cTimeManager::NowVisible(void) { + if (t > tStart) + return true; + return false; +} + +void cTimeManager::Debug() { + esyslog("tvguideng: now %s, tStart: %s, tEnd: %s", *TimeString(t), *TimeString(tStart), *TimeString(tEnd)); +} + +// --- cTimeInterval ------------------------------------------------------------- + +cTimeInterval::cTimeInterval(time_t start, time_t stop) { + this->start = start; + this->stop = stop; +} + +cTimeInterval::~cTimeInterval(void) { +} + +cTimeInterval *cTimeInterval::Intersect(cTimeInterval *interval) { + time_t startIntersect, stopIntersect; + + if ((stop <= interval->Start()) || (interval->Stop() <= start)) { + return NULL; + } + + if (start <= interval->Start()) { + startIntersect = interval->Start(); + } else { + startIntersect = start; + } + if (stop <= interval->Stop()) { + stopIntersect = stop; + } else { + stopIntersect = interval->Stop(); + } + return new cTimeInterval(startIntersect, stopIntersect); +} + +cTimeInterval *cTimeInterval::Union(cTimeInterval *interval) { + time_t startUnion, stopUnion; + + if (start <= interval->Start()) { + startUnion = start; + } else { + startUnion = interval->Start(); + } + if (stop <= interval->Stop()) { + stopUnion = interval->Stop(); + } else { + stopUnion = stop; + } + return new cTimeInterval(startUnion, stopUnion); }
\ No newline at end of file diff --git a/timemanager.h b/timemanager.h index fb6b5b2..3a70365 100644 --- a/timemanager.h +++ b/timemanager.h @@ -1,61 +1,61 @@ -#ifndef __TVGUIDE_TIMEMANAGER_H
-#define __TVGUIDE_TIMEMANAGER_H
-
-#include <vdr/tools.h>
-
-enum eTimeFormat {
- e12Hours,
- e24Hours
-};
-
-// --- cTimeManager -------------------------------------------------------------
-
-class cTimeManager {
- private:
- time_t t;
- time_t tStart;
- time_t tEnd;
- int displayHours;
- int displaySeconds;
- eTimeFormat timeFormat;
- public:
- cTimeManager(void);
- virtual ~cTimeManager(void);
- static cString PrintTime(time_t displayTime);
- void Now();
- time_t GetNow() { return t; };
- void AddMinutes(int step);
- bool DelMinutes(int step);
- void SetTime(time_t newTime);
- time_t Get() {return t;};
- time_t GetStart() {return tStart;};
- time_t GetEnd() {return tEnd;};
- cString GetCurrentTime();
- cString GetDate();
- cString GetWeekday();
- time_t GetPrevPrimetime(time_t current);
- time_t GetNextPrimetime(time_t current);
- bool TooFarInPast(time_t current);
- bool IsStart(int activeStart);
- time_t GetRounded();
- bool NowVisible(void);
- int GetDisplaySeconds(void) {return displaySeconds; };
- void Debug();
-};
-
-// --- cTimeInterval -------------------------------------------------------------
-
-class cTimeInterval {
- private:
- time_t start;
- time_t stop;
- public:
- cTimeInterval(time_t start, time_t stop);
- virtual ~cTimeInterval(void);
- time_t Start(void) { return start; };
- time_t Stop(void) { return stop; };
- cTimeInterval *Intersect(cTimeInterval *interval);
- cTimeInterval *Union(cTimeInterval *interval);
-};
-
+#ifndef __TVGUIDE_TIMEMANAGER_H +#define __TVGUIDE_TIMEMANAGER_H + +#include <vdr/tools.h> + +enum eTimeFormat { + e12Hours, + e24Hours +}; + +// --- cTimeManager ------------------------------------------------------------- + +class cTimeManager { + private: + time_t t; + time_t tStart; + time_t tEnd; + int displayHours; + int displaySeconds; + eTimeFormat timeFormat; + public: + cTimeManager(void); + virtual ~cTimeManager(void); + static cString PrintTime(time_t displayTime); + void Now(); + time_t GetNow() { return t; }; + void AddMinutes(int step); + bool DelMinutes(int step); + void SetTime(time_t newTime); + time_t Get() {return t;}; + time_t GetStart() {return tStart;}; + time_t GetEnd() {return tEnd;}; + cString GetCurrentTime(); + cString GetDate(); + cString GetWeekday(); + time_t GetPrevPrimetime(time_t current); + time_t GetNextPrimetime(time_t current); + bool TooFarInPast(time_t current); + bool IsStart(int activeStart); + time_t GetRounded(); + bool NowVisible(void); + int GetDisplaySeconds(void) {return displaySeconds; }; + void Debug(); +}; + +// --- cTimeInterval ------------------------------------------------------------- + +class cTimeInterval { + private: + time_t start; + time_t stop; + public: + cTimeInterval(time_t start, time_t stop); + virtual ~cTimeInterval(void); + time_t Start(void) { return start; }; + time_t Stop(void) { return stop; }; + cTimeInterval *Intersect(cTimeInterval *interval); + cTimeInterval *Union(cTimeInterval *interval); +}; + #endif //__TVGUIDE_TIMEMANAGER_H
\ No newline at end of file diff --git a/timerconflict.c b/timerconflict.c index a89dc2c..9ac6a7d 100644 --- a/timerconflict.c +++ b/timerconflict.c @@ -1,175 +1,182 @@ -#include <string>
-#include <vector>
-#include <vdr/timers.h>
-#include "helpers.h"
-#include "timemanager.h"
-#include "timerconflict.h"
-
-cTVGuideTimerConflict::cTVGuideTimerConflict(void) {
- time = 0;
- timeStart = 0;
- timeStop = 0;
- overlapStart = 0;
- overlapStop = 0;
- percentPossible = 0;
- timerID = 0;
-}
-
-cTVGuideTimerConflict::~cTVGuideTimerConflict(void) {
-
-}
-
-bool cTVGuideTimerConflict::timerInvolved(int involvedID) {
- int numConflicts = timerIDs.size();
- for (int i=0; i<numConflicts; i++) {
- if (timerIDs[i] == involvedID)
- return true;
- }
- return false;
-}
-
-// --- cTVGuideTimerConflicts------------------------------------
-
-cTVGuideTimerConflicts::cTVGuideTimerConflicts(void) {
- numConflicts = 0;
- currentConflict = -1;
-}
-
-cTVGuideTimerConflicts::~cTVGuideTimerConflicts(void) {
- for(std::vector<cTVGuideTimerConflict*>::const_iterator it = conflicts.begin(); it != conflicts.end(); it++) {
- cTVGuideTimerConflict *conf = *it;
- delete conf;
- }
- conflicts.clear();
-}
-
-void cTVGuideTimerConflicts::AddConflict(std::string epgSearchConflictLine) {
- /* TIMERCONFLICT FORMAT:
- The result list looks like this for example when we have 2 timer conflicts at one time:
- 1190232780:152|30|50#152#45:45|10|50#152#45
- '1190232780' is the time of the conflict in seconds since 1970-01-01.
- It's followed by list of timers that have a conflict at this time:
- '152|30|50#1 int editTimer(cTimer *timer, bool active, int prio, int start, int stop);
- 52#45' is the description of the first conflicting timer. Here:
- '152' is VDR's timer id of this timer as returned from VDR's LSTT command
- '30' is the percentage of recording that would be done (0...100)
- '50#152#45' is the list of concurrent timers at this conflict
- '45|10|50#152#45' describes the next conflict
- */
- cTVGuideTimerConflict *conflict = new cTVGuideTimerConflict();
- splitstring s(epgSearchConflictLine.c_str());
- std::vector<std::string> flds = s.split(':');
- if (flds.size() < 2)
- return;
- conflict->time = atoi(flds[0].c_str());
- splitstring s2(flds[1].c_str());
- std::vector<std::string> flds2 = s2.split('|');
- if (flds2.size() < 3)
- return;
- conflict->timerID = atoi(flds2[0].c_str());
- conflict->percentPossible = atoi(flds2[1].c_str());
- splitstring s3(flds2[2].c_str());
- std::vector<std::string> flds3 = s3.split('#');
- std::vector<int> timerIDs;
- for (int k = 0; k < (int)flds3.size(); k++) {
- timerIDs.push_back(atoi(flds3[k].c_str()) - 1);
- }
- conflict->timerIDs = timerIDs;
- conflicts.push_back(conflict);
-}
-
-void cTVGuideTimerConflicts::CalculateConflicts(void) {
- numConflicts = conflicts.size();
- for (int i=0; i < numConflicts; i++) {
- cTimeInterval *unionSet = NULL;
- int numTimers = conflicts[i]->timerIDs.size();
- for (int j=0; j < numTimers; j++) {
- const cTimer *timer = Timers.Get(conflicts[i]->timerIDs[j]);
- if (timer) {
- if (!unionSet) {
- unionSet = new cTimeInterval(timer->StartTime(), timer->StopTime());
- } else {
- cTimeInterval *timerInterval = new cTimeInterval(timer->StartTime(), timer->StopTime());
- cTimeInterval *newUnion = unionSet->Union(timerInterval);
- delete unionSet;
- delete timerInterval;
- unionSet = newUnion;
- }
- }
- }
- conflicts[i]->timeStart = unionSet->Start();
- conflicts[i]->timeStop = unionSet->Stop();
- delete unionSet;
-
- cTimeInterval *intersect = NULL;
- for (int j=0; j < numTimers; j++) {
- const cTimer *timer = Timers.Get(conflicts[i]->timerIDs[j]);
- if (timer) {
- if (!intersect) {
- intersect = new cTimeInterval(timer->StartTime(), timer->StopTime());
- } else {
- cTimeInterval *timerInterval = new cTimeInterval(timer->StartTime(), timer->StopTime());
- cTimeInterval *newIntersect = intersect->Intersect(timerInterval);
- if (newIntersect) {
- delete intersect;
- intersect = newIntersect;
- }
- delete timerInterval;
- }
- }
- }
- conflicts[i]->overlapStart = intersect->Start();
- conflicts[i]->overlapStop = intersect->Stop();
- delete intersect;
- }
-}
-
-cTVGuideTimerConflict *cTVGuideTimerConflicts::GetCurrentConflict(void) {
- if (currentConflict < 0)
- return NULL;
- if (currentConflict > (numConflicts-1))
- return NULL;
- return conflicts[currentConflict];
-}
-
-int cTVGuideTimerConflicts::GetCurrentConflictTimerID(int timerIndex) {
- if (currentConflict < 0)
- return -1;
- if (currentConflict > (numConflicts-1))
- return -1;
- int numTimersInConflict = conflicts[currentConflict]->timerIDs.size();
- if (timerIndex > (numTimersInConflict - 1))
- return -1;
- return conflicts[currentConflict]->timerIDs[timerIndex];
-}
-
-int cTVGuideTimerConflicts::GetCorrespondingConflict(int timerID) {
- int conflictIndex = -1;
- if (numConflicts > 0) {
- for (int i=0; i<numConflicts; i++) {
- if (conflicts[i]->timerInvolved(timerID)) {
- conflictIndex = i;
- break;
- }
- }
- }
- return conflictIndex;
-}
-
-cTVGuideTimerConflict *cTVGuideTimerConflicts::GetConflict(int conflictIndex) {
- if (conflictIndex < 0)
- return NULL;
- if (conflictIndex > (numConflicts-1))
- return NULL;
- return conflicts[conflictIndex];
-}
-
-std::vector<cTVGuideTimerConflict*> cTVGuideTimerConflicts::GetConflictsBetween(time_t start, time_t stop) {
- std::vector<cTVGuideTimerConflict*> conflictsFound;
- for (int i=0; i < numConflicts; i++) {
- if ((conflicts[i]->timeStart > start) && (conflicts[i]->timeStart < stop)||
- (conflicts[i]->timeStop > start) && (conflicts[i]->timeStop < stop))
- conflictsFound.push_back(conflicts[i]);
- }
- return conflictsFound;
-}
\ No newline at end of file +#include <string> +#include <vector> +#include <vdr/timers.h> +#include "helpers.h" +#include "timemanager.h" +#include "timerconflict.h" + +cTVGuideTimerConflict::cTVGuideTimerConflict(void) { + time = 0; + timeStart = 0; + timeStop = 0; + overlapStart = 0; + overlapStop = 0; + percentPossible = 0; + timerID = 0; +} + +cTVGuideTimerConflict::~cTVGuideTimerConflict(void) { + +} + +bool cTVGuideTimerConflict::timerInvolved(int involvedID) { + int numConflicts = timerIDs.size(); + for (int i=0; i<numConflicts; i++) { + if (timerIDs[i] == involvedID) + return true; + } + return false; +} + +// --- cTVGuideTimerConflicts------------------------------------ + +cTVGuideTimerConflicts::cTVGuideTimerConflicts(void) { + numConflicts = 0; + currentConflict = -1; +} + +cTVGuideTimerConflicts::~cTVGuideTimerConflicts(void) { + for(std::vector<cTVGuideTimerConflict*>::const_iterator it = conflicts.begin(); it != conflicts.end(); it++) { + cTVGuideTimerConflict *conf = *it; + delete conf; + } + conflicts.clear(); +} + +void cTVGuideTimerConflicts::AddConflict(std::string epgSearchConflictLine) { + /* TIMERCONFLICT FORMAT: + The result list looks like this for example when we have 2 timer conflicts at one time: + 1190232780:152|30|50#152#45:45|10|50#152#45 + '1190232780' is the time of the conflict in seconds since 1970-01-01. + It's followed by list of timers that have a conflict at this time: + '152|30|50#1 int editTimer(cTimer *timer, bool active, int prio, int start, int stop); + 52#45' is the description of the first conflicting timer. Here: + '152' is VDR's timer id of this timer as returned from VDR's LSTT command + '30' is the percentage of recording that would be done (0...100) + '50#152#45' is the list of concurrent timers at this conflict + '45|10|50#152#45' describes the next conflict + */ + cTVGuideTimerConflict *conflict = new cTVGuideTimerConflict(); + splitstring s(epgSearchConflictLine.c_str()); + std::vector<std::string> flds = s.split(':'); + if (flds.size() < 2) + return; + conflict->time = atoi(flds[0].c_str()); + splitstring s2(flds[1].c_str()); + std::vector<std::string> flds2 = s2.split('|'); + if (flds2.size() < 3) + return; + conflict->timerID = atoi(flds2[0].c_str()); + conflict->percentPossible = atoi(flds2[1].c_str()); + splitstring s3(flds2[2].c_str()); + std::vector<std::string> flds3 = s3.split('#'); + std::vector<int> timerIDs; + for (int k = 0; k < (int)flds3.size(); k++) { + timerIDs.push_back(atoi(flds3[k].c_str()) - 1); + } + conflict->timerIDs = timerIDs; + conflicts.push_back(conflict); +} + +void cTVGuideTimerConflicts::CalculateConflicts(void) { + numConflicts = conflicts.size(); + for (int i=0; i < numConflicts; i++) { + cTimeInterval *unionSet = NULL; + int numTimers = conflicts[i]->timerIDs.size(); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_TIMERS_READ; + const cTimers* timers = Timers; +#else + const cTimers* timers = &Timers; +#endif + + for (int j=0; j < numTimers; j++) { + const cTimer *timer = timers->Get(conflicts[i]->timerIDs[j]); + if (timer) { + if (!unionSet) { + unionSet = new cTimeInterval(timer->StartTime(), timer->StopTime()); + } else { + cTimeInterval *timerInterval = new cTimeInterval(timer->StartTime(), timer->StopTime()); + cTimeInterval *newUnion = unionSet->Union(timerInterval); + delete unionSet; + delete timerInterval; + unionSet = newUnion; + } + } + } + conflicts[i]->timeStart = unionSet->Start(); + conflicts[i]->timeStop = unionSet->Stop(); + delete unionSet; + + cTimeInterval *intersect = NULL; + for (int j=0; j < numTimers; j++) { + const cTimer *timer = timers->Get(conflicts[i]->timerIDs[j]); + if (timer) { + if (!intersect) { + intersect = new cTimeInterval(timer->StartTime(), timer->StopTime()); + } else { + cTimeInterval *timerInterval = new cTimeInterval(timer->StartTime(), timer->StopTime()); + cTimeInterval *newIntersect = intersect->Intersect(timerInterval); + if (newIntersect) { + delete intersect; + intersect = newIntersect; + } + delete timerInterval; + } + } + } + conflicts[i]->overlapStart = intersect->Start(); + conflicts[i]->overlapStop = intersect->Stop(); + delete intersect; + } +} + +cTVGuideTimerConflict *cTVGuideTimerConflicts::GetCurrentConflict(void) { + if (currentConflict < 0) + return NULL; + if (currentConflict > (numConflicts-1)) + return NULL; + return conflicts[currentConflict]; +} + +int cTVGuideTimerConflicts::GetCurrentConflictTimerID(int timerIndex) { + if (currentConflict < 0) + return -1; + if (currentConflict > (numConflicts-1)) + return -1; + int numTimersInConflict = conflicts[currentConflict]->timerIDs.size(); + if (timerIndex > (numTimersInConflict - 1)) + return -1; + return conflicts[currentConflict]->timerIDs[timerIndex]; +} + +int cTVGuideTimerConflicts::GetCorrespondingConflict(int timerID) { + int conflictIndex = -1; + if (numConflicts > 0) { + for (int i=0; i<numConflicts; i++) { + if (conflicts[i]->timerInvolved(timerID)) { + conflictIndex = i; + break; + } + } + } + return conflictIndex; +} + +cTVGuideTimerConflict *cTVGuideTimerConflicts::GetConflict(int conflictIndex) { + if (conflictIndex < 0) + return NULL; + if (conflictIndex > (numConflicts-1)) + return NULL; + return conflicts[conflictIndex]; +} + +std::vector<cTVGuideTimerConflict*> cTVGuideTimerConflicts::GetConflictsBetween(time_t start, time_t stop) { + std::vector<cTVGuideTimerConflict*> conflictsFound; + for (int i=0; i < numConflicts; i++) { + if ((conflicts[i]->timeStart > start) && (conflicts[i]->timeStart < stop)|| + (conflicts[i]->timeStop > start) && (conflicts[i]->timeStop < stop)) + conflictsFound.push_back(conflicts[i]); + } + return conflictsFound; +} diff --git a/timerconflict.h b/timerconflict.h index d3def89..d26d7fd 100644 --- a/timerconflict.h +++ b/timerconflict.h @@ -1,38 +1,38 @@ -#ifndef __TVGUIDE_TIMERCONFLICT_H
-#define __TVGUIDE_TIMERCONFLICT_H
-
-class cTVGuideTimerConflict {
-public:
- cTVGuideTimerConflict(void);
- virtual ~cTVGuideTimerConflict(void);
- time_t time;
- time_t timeStart;
- time_t timeStop;
- time_t overlapStart;
- time_t overlapStop;
- int percentPossible;
- int timerID;
- std::vector<int> timerIDs;
- bool timerInvolved(int involvedID);
-};
-
-class cTVGuideTimerConflicts {
-private:
- std::vector<cTVGuideTimerConflict*> conflicts;
- int numConflicts;
- int currentConflict;
-public:
- cTVGuideTimerConflicts(void);
- virtual ~cTVGuideTimerConflicts(void);
- void AddConflict(std::string epgSearchConflictLine);
- void CalculateConflicts(void);
- int NumConflicts(void) {return numConflicts; };
- void SetCurrentConflict(int current) { currentConflict = current; };
- cTVGuideTimerConflict *GetCurrentConflict(void);
- int GetCurrentConflictTimerID(int timerIndex);
- int GetCorrespondingConflict(int timerID);
- cTVGuideTimerConflict *GetConflict(int conflictIndex);
- std::vector<cTVGuideTimerConflict*> GetConflictsBetween(time_t start, time_t stop);
-};
-
+#ifndef __TVGUIDE_TIMERCONFLICT_H +#define __TVGUIDE_TIMERCONFLICT_H + +class cTVGuideTimerConflict { +public: + cTVGuideTimerConflict(void); + virtual ~cTVGuideTimerConflict(void); + time_t time; + time_t timeStart; + time_t timeStop; + time_t overlapStart; + time_t overlapStop; + int percentPossible; + int timerID; + std::vector<int> timerIDs; + bool timerInvolved(int involvedID); +}; + +class cTVGuideTimerConflicts { +private: + std::vector<cTVGuideTimerConflict*> conflicts; + int numConflicts; + int currentConflict; +public: + cTVGuideTimerConflicts(void); + virtual ~cTVGuideTimerConflicts(void); + void AddConflict(std::string epgSearchConflictLine); + void CalculateConflicts(void); + int NumConflicts(void) {return numConflicts; }; + void SetCurrentConflict(int current) { currentConflict = current; }; + cTVGuideTimerConflict *GetCurrentConflict(void); + int GetCurrentConflictTimerID(int timerIndex); + int GetCorrespondingConflict(int timerID); + cTVGuideTimerConflict *GetConflict(int conflictIndex); + std::vector<cTVGuideTimerConflict*> GetConflictsBetween(time_t start, time_t stop); +}; + #endif //__TVGUIDE_RECMMANAGER_H
\ No newline at end of file diff --git a/tvguidengosd.c b/tvguidengosd.c index 8024672..bdb7f36 100644 --- a/tvguidengosd.c +++ b/tvguidengosd.c @@ -53,8 +53,12 @@ void cTVGuideOSD::Show(void) { timeManager->Now(); epgGrid = new cEpgGrid(rootView, timeManager); - - cChannel *startChannel = Channels.GetByNumber(cDevice::CurrentChannel()); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannel *startChannel = Channels->GetByNumber(cDevice::CurrentChannel()); +#else + const cChannel *startChannel = Channels.GetByNumber(cDevice::CurrentChannel()); +#endif epgGrid->Init(startChannel); epgGrid->Activate(); epgGrid->DrawHeader(); @@ -338,7 +342,13 @@ void cTVGuideOSD::CheckTimeout(void) { int newChannelNum = channelJumper->GetChannel(); delete channelJumper; channelJumper = NULL; - const cChannel *newChannel = Channels.GetByNumber(newChannelNum); +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_CHANNELS_READ; + const cChannels* channels = Channels; +#else + cChannels* channels = &Channels; +#endif + const cChannel *newChannel = channels->GetByNumber(newChannelNum); if (!newChannel) { return; } |