mirror of
				https://projects.vdr-developer.org/git/vdr-plugin-skindesigner.git
				synced 2023-10-19 15:58:31 +00:00 
			
		
		
		
	implemented epg2vdr support
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -70,6 +70,7 @@ OBJS = $(PLUGIN).o \ | ||||
|        extensions/cairoimage.o \ | ||||
|        extensions/curlfuncs.o \ | ||||
|        extensions/fontmanager.o \ | ||||
|        extensions/globaltimers.o \ | ||||
|        extensions/imagecache.o \ | ||||
|        extensions/helpers.o \ | ||||
|        extensions/imageloader.o \ | ||||
| @@ -80,7 +81,6 @@ OBJS = $(PLUGIN).o \ | ||||
|        extensions/skinsetup.o \ | ||||
|        extensions/skinrepo.o \ | ||||
|        extensions/extrecinfo.o \ | ||||
|        extensions/timers.o \ | ||||
|        coreengine/animation.o \ | ||||
|        coreengine/attribute.o \ | ||||
|        coreengine/attributes.o \ | ||||
|   | ||||
| @@ -504,6 +504,7 @@ enum class eDMTimersLT { | ||||
|     channelid, | ||||
|     channellogoexists, | ||||
|     isremotetimer, | ||||
|     remotehost, | ||||
|     count | ||||
| }; | ||||
|  | ||||
| @@ -898,6 +899,10 @@ enum class eLeMenuTimersST { | ||||
|     eventtitle, | ||||
|     eventstart, | ||||
|     eventstop, | ||||
|     state, | ||||
|     stateinfo, | ||||
|     action, | ||||
|     vdrname, | ||||
|     count | ||||
| }; | ||||
|  | ||||
| @@ -914,6 +919,8 @@ enum class eLeMenuTimersIT { | ||||
|     flagvps, | ||||
|     flagrecording, | ||||
|     flagpending, | ||||
|     isvdrrunning, | ||||
|     isremote, | ||||
|     count | ||||
| }; | ||||
|  | ||||
| @@ -933,6 +940,10 @@ enum class eCeMenuTimersST { | ||||
|     eventdescription, | ||||
|     posterpath, | ||||
|     bannerpath, | ||||
|     state, | ||||
|     stateinfo, | ||||
|     action, | ||||
|     vdrname, | ||||
|     count | ||||
| }; | ||||
|  | ||||
| @@ -957,6 +968,8 @@ enum class eCeMenuTimersIT { | ||||
|     hasbanner, | ||||
|     bannerwidth, | ||||
|     bannerheight, | ||||
|     isvdrrunning, | ||||
|     isremote, | ||||
|     count | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| #include "listelements.h" | ||||
| #include "../config.h" | ||||
| #include "../services/epgtimer.h" | ||||
| #include <sstream> | ||||
| #include <algorithm> | ||||
|  | ||||
| @@ -1181,6 +1182,10 @@ void cLeMenuTimers::SetTokenContainer(void) { | ||||
|     tokenContainer->DefineStringToken("{eventtitle}", (int)eLeMenuTimersST::eventtitle); | ||||
|     tokenContainer->DefineStringToken("{eventstart}", (int)eLeMenuTimersST::eventstart); | ||||
|     tokenContainer->DefineStringToken("{eventstop}", (int)eLeMenuTimersST::eventstop); | ||||
|     tokenContainer->DefineStringToken("{state}", (int)eLeMenuTimersST::state); | ||||
|     tokenContainer->DefineStringToken("{stateinfo}", (int)eLeMenuTimersST::stateinfo); | ||||
|     tokenContainer->DefineStringToken("{action}", (int)eLeMenuTimersST::action); | ||||
|     tokenContainer->DefineStringToken("{vdrname}", (int)eLeMenuTimersST::vdrname); | ||||
|     tokenContainer->DefineIntToken("{nummenuitem}", (int)eLeMenuTimersIT::nummenuitem); | ||||
|     tokenContainer->DefineIntToken("{current}", (int)eLeMenuTimersIT::current); | ||||
|     tokenContainer->DefineIntToken("{separator}", (int)eLeMenuTimersIT::separator); | ||||
| @@ -1193,6 +1198,8 @@ void cLeMenuTimers::SetTokenContainer(void) { | ||||
|     tokenContainer->DefineIntToken("{flagvps}", (int)eLeMenuTimersIT::flagvps); | ||||
|     tokenContainer->DefineIntToken("{flagrecording}", (int)eLeMenuTimersIT::flagrecording); | ||||
|     tokenContainer->DefineIntToken("{flagpending}", (int)eLeMenuTimersIT::flagpending); | ||||
|     tokenContainer->DefineIntToken("{isvdrrunning}", (int)eLeMenuTimersIT::isvdrrunning); | ||||
|     tokenContainer->DefineIntToken("{isremote}", (int)eLeMenuTimersIT::isremote); | ||||
|     InheritTokenContainer();     | ||||
| } | ||||
|  | ||||
| @@ -1279,6 +1286,21 @@ bool cLeMenuTimers::Parse(bool forced) { | ||||
|         tokenContainer->AddStringToken((int)eLeMenuTimersST::eventstart, *event->GetTimeString()); | ||||
|         tokenContainer->AddStringToken((int)eLeMenuTimersST::eventstop, *event->GetEndTimeString()); | ||||
|     } | ||||
|  | ||||
|     cEpgTimer_Interface_V1* epgTimer; | ||||
|     if (epgTimer = dynamic_cast<cEpgTimer_Interface_V1*>((cTimer*)timer)) { | ||||
|         tokenContainer->AddIntToken((int)eLeMenuTimersIT::isvdrrunning, epgTimer->isVdrRunning()); | ||||
|         tokenContainer->AddIntToken((int)eLeMenuTimersIT::isremote, epgTimer->isRemote()); | ||||
|         stringstream state; | ||||
|         state << epgTimer->State(); | ||||
|         tokenContainer->AddStringToken((int)eLeMenuTimersST::state, state.str().c_str()); | ||||
|         tokenContainer->AddStringToken((int)eLeMenuTimersST::stateinfo, epgTimer->StateInfo()); | ||||
|         tokenContainer->AddStringToken((int)eLeMenuTimersST::vdrname, epgTimer->VdrName()); | ||||
|         stringstream action; | ||||
|         action << epgTimer->Action(); | ||||
|         tokenContainer->AddStringToken((int)eLeMenuTimersST::action, action.str().c_str()); | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| @@ -1318,6 +1340,10 @@ void cCeMenuTimers::SetTokenContainer(void) { | ||||
|     tokenContainer->DefineStringToken("{eventdescription}", (int)eCeMenuTimersST::eventdescription); | ||||
|     tokenContainer->DefineStringToken("{posterpath}", (int)eCeMenuTimersST::posterpath); | ||||
|     tokenContainer->DefineStringToken("{bannerpath}", (int)eCeMenuTimersST::bannerpath); | ||||
|     tokenContainer->DefineStringToken("{state}", (int)eCeMenuTimersST::state); | ||||
|     tokenContainer->DefineStringToken("{stateinfo}", (int)eCeMenuTimersST::stateinfo); | ||||
|     tokenContainer->DefineStringToken("{action}", (int)eCeMenuTimersST::action); | ||||
|     tokenContainer->DefineStringToken("{vdrname}", (int)eCeMenuTimersST::vdrname); | ||||
|     tokenContainer->DefineIntToken("{menuitemx}", (int)eCeMenuTimersIT::menuitemx); | ||||
|     tokenContainer->DefineIntToken("{menuitemy}", (int)eCeMenuTimersIT::menuitemy); | ||||
|     tokenContainer->DefineIntToken("{menuitemwidth}", (int)eCeMenuTimersIT::menuitemwidth); | ||||
| @@ -1338,6 +1364,8 @@ void cCeMenuTimers::SetTokenContainer(void) { | ||||
|     tokenContainer->DefineIntToken("{hasbanner}", (int)eCeMenuTimersIT::hasbanner); | ||||
|     tokenContainer->DefineIntToken("{bannerwidth}", (int)eCeMenuTimersIT::bannerwidth); | ||||
|     tokenContainer->DefineIntToken("{bannerheight}", (int)eCeMenuTimersIT::bannerheight); | ||||
|     tokenContainer->DefineIntToken("{isvdrrunning}", (int)eCeMenuTimersIT::isvdrrunning); | ||||
|     tokenContainer->DefineIntToken("{isremote}", (int)eCeMenuTimersIT::isremote); | ||||
|     InheritTokenContainer(); | ||||
| } | ||||
|  | ||||
| @@ -1423,6 +1451,21 @@ bool cCeMenuTimers::Parse(bool forced) { | ||||
|         if (LoadFullScrapInfo(event, NULL)) | ||||
|             SetScraperPosterBannerTimer(tokenContainer); | ||||
|     } | ||||
|  | ||||
|     cEpgTimer_Interface_V1* epgTimer; | ||||
|     if (epgTimer = dynamic_cast<cEpgTimer_Interface_V1*>((cTimer*)timer)) { | ||||
|         tokenContainer->AddIntToken((int)eCeMenuTimersIT::isvdrrunning, epgTimer->isVdrRunning()); | ||||
|         tokenContainer->AddIntToken((int)eCeMenuTimersIT::isremote, epgTimer->isRemote()); | ||||
|         stringstream state; | ||||
|         state << epgTimer->State(); | ||||
|         tokenContainer->AddStringToken((int)eCeMenuTimersST::state, state.str().c_str()); | ||||
|         tokenContainer->AddStringToken((int)eCeMenuTimersST::stateinfo, epgTimer->StateInfo()); | ||||
|         tokenContainer->AddStringToken((int)eCeMenuTimersST::vdrname, epgTimer->VdrName()); | ||||
|         stringstream action; | ||||
|         action << epgTimer->Action(); | ||||
|         tokenContainer->AddStringToken((int)eCeMenuTimersST::action, action.str().c_str()); | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -68,6 +68,7 @@ void cViewChannel::SetViewElementObjects(void) { | ||||
|         else if (dynamic_cast<cVeDcEpgInfo*>(viewElements[i]))  | ||||
|         { | ||||
|             veEpgInfo = dynamic_cast<cVeDcEpgInfo*>(viewElements[i]); | ||||
|             veEpgInfo->SetGlobalTimers(&globalTimers); | ||||
|         } | ||||
|         else if (dynamic_cast<cVeDcProgressBar*>(viewElements[i]))  | ||||
|         { | ||||
| @@ -76,6 +77,7 @@ void cViewChannel::SetViewElementObjects(void) { | ||||
|         else if (dynamic_cast<cVeDcStatusInfo*>(viewElements[i]))  | ||||
|         { | ||||
|             veStatusInfo = dynamic_cast<cVeDcStatusInfo*>(viewElements[i]); | ||||
|             veStatusInfo->SetGlobalTimers(&globalTimers); | ||||
|         } | ||||
|         else if (dynamic_cast<cVeDcScraperContent*>(viewElements[i]))  | ||||
|         { | ||||
| @@ -102,6 +104,7 @@ void cViewChannel::ClearVariables(void) { | ||||
|     displayChannelGroups = false; | ||||
|     if (veCustomTokens) | ||||
|         veCustomTokens->Reset(); | ||||
|     globalTimers.ClearTimers(); | ||||
| } | ||||
|  | ||||
| void cViewChannel::SetChannel(const cChannel *channel, int number) { | ||||
| @@ -141,6 +144,9 @@ void cViewChannel::SetChannel(const cChannel *channel, int number) { | ||||
| } | ||||
|  | ||||
| void cViewChannel::SetEvents(const cEvent *present, const cEvent *following) { | ||||
|     if (init) { | ||||
|         globalTimers.LoadTimers(); | ||||
|     } | ||||
|     Clear((int)eVeDisplayChannel::epginfo); | ||||
|     Clear((int)eVeDisplayChannel::progressbar); | ||||
|     Clear((int)eVeDisplayChannel::scrapercontent); | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
| #define __VIEWDISPLAYCHANNEL_H | ||||
|  | ||||
| #include "view.h" | ||||
| #include "../extensions/globaltimers.h" | ||||
|  | ||||
| class cViewChannel : public cView { | ||||
| private: | ||||
| @@ -16,6 +17,7 @@ private: | ||||
|     cVeDcEcmInfo           *veEcmInfo; | ||||
|     bool channelChange; | ||||
|     bool displayChannelGroups; | ||||
|     cGlobalTimers globalTimers; | ||||
|     void SetViewElements(void); | ||||
|     void ClearVariables(void); | ||||
|     void SetViewElementObjects(void); | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| #include "viewelementsdisplaychannel.h" | ||||
| #include "../config.h" | ||||
| #include "../extensions/helpers.h" | ||||
| #include "../extensions/timers.h" | ||||
| #include "../services/scraper2vdr.h" | ||||
|  | ||||
| /****************************************************************** | ||||
| @@ -111,6 +110,7 @@ const char *cVeDcChannelGroup::GetChannelSep(const cChannel *c, bool prev) { | ||||
| * cVeDcEpgInfo | ||||
| ******************************************************************/ | ||||
| cVeDcEpgInfo::cVeDcEpgInfo(void) { | ||||
|     globalTimers = NULL;  | ||||
| } | ||||
|  | ||||
| cVeDcEpgInfo::~cVeDcEpgInfo(void) { | ||||
| @@ -176,24 +176,14 @@ void cVeDcEpgInfo::Close(void) { | ||||
|  | ||||
| bool cVeDcEpgInfo::EventHasTimer(const cEvent *e) { | ||||
|     if (!e) return false; | ||||
|     int timerCount = 0; | ||||
|     // BLOCK for LOCK_TIMERS_READ scope !! | ||||
|     { | ||||
| #if defined (APIVERSNUM) && (APIVERSNUM >= 20301) | ||||
|        LOCK_TIMERS_READ; | ||||
|        timerCount = Timers->Count(); | ||||
| #else | ||||
|        timerCount = Timers.Count(); | ||||
| #endif | ||||
|     } | ||||
|     cGlobalSortedTimers SortedTimers(timerCount); // local and remote timers | ||||
|     bool hasTimer = e->HasTimer(); | ||||
|     for (int i = 0; i < SortedTimers.Size() && !hasTimer; i++)  | ||||
|         if (const cTimer *Timer = SortedTimers[i])  | ||||
|     for (int i = 0; i < globalTimers->Size() && !hasTimer; i++)  | ||||
|         if (const cTimer *Timer = globalTimers->At(i))  | ||||
|             if (Timer->Channel()->GetChannelID() == e->ChannelID())  | ||||
|                 if (const cEvent *timerEvent = Timer->Event()) | ||||
|                     if (e->EventID() == timerEvent->EventID()) | ||||
|                         hasTimer = true; | ||||
|  | ||||
|     return hasTimer; | ||||
| } | ||||
|  | ||||
| @@ -328,19 +318,9 @@ void cVeDcStatusInfo::Set(const cChannel *c) { | ||||
|     bool isDolby = c->Dpid(0); | ||||
|     bool isEncrypted = c->Ca(); | ||||
|     bool isRecording = cRecordControls::Active(); | ||||
|     int timerCount = 0; | ||||
|     // BLOCK for LOCK_TIMERS_READ scope !! | ||||
|     { | ||||
| #if defined (APIVERSNUM) && (APIVERSNUM >= 20301) | ||||
|        LOCK_TIMERS_READ; | ||||
|        timerCount = Timers->Count(); | ||||
| #else | ||||
|        timerCount = Timers.Count(); | ||||
| #endif | ||||
|     } | ||||
|     cGlobalSortedTimers SortedTimers(timerCount); // local and remote timers | ||||
|     for (int i = 0; i < SortedTimers.Size() && !isRecording; i++) | ||||
|         if (const cTimer *Timer = SortedTimers[i]) | ||||
|  | ||||
|     for (int i = 0; i < globalTimers->Size() && !isRecording; i++) | ||||
|         if (const cTimer *Timer = globalTimers->At(i)) | ||||
|             if (Timer->Recording())  | ||||
|                 isRecording = true; | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
|  | ||||
| #include "viewelement.h" | ||||
| #include "../extensions/scrapmanager.h" | ||||
| #include "../extensions/globaltimers.h" | ||||
| #include "../services/dvbapi.h" | ||||
|  | ||||
| /****************************************************************** | ||||
| @@ -33,10 +34,12 @@ public: | ||||
| ******************************************************************/ | ||||
| class cVeDcEpgInfo : public cViewElement { | ||||
| private: | ||||
|     cGlobalTimers *globalTimers; | ||||
|     bool EventHasTimer(const cEvent *e); | ||||
| public: | ||||
|     cVeDcEpgInfo(void); | ||||
|     virtual ~cVeDcEpgInfo(void); | ||||
|     void SetGlobalTimers(cGlobalTimers *globalTimers) { this->globalTimers = globalTimers; }; | ||||
|     void SetTokenContainer(void); | ||||
|     void Set(const cEvent *p, const cEvent *f); | ||||
|     void Close(void); | ||||
| @@ -63,10 +66,12 @@ public: | ||||
| ******************************************************************/ | ||||
| class cVeDcStatusInfo : public cViewElement { | ||||
| private: | ||||
|     cGlobalTimers *globalTimers; | ||||
|     bool CheckMails(void); | ||||
| public: | ||||
|     cVeDcStatusInfo(void); | ||||
|     virtual ~cVeDcStatusInfo(void); | ||||
|     void SetGlobalTimers(cGlobalTimers *globalTimers) { this->globalTimers = globalTimers; }; | ||||
|     void SetTokenContainer(void); | ||||
|     void Set(const cChannel *c); | ||||
| }; | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| #include "viewelementsdisplaymenu.h" | ||||
| #include "../config.h" | ||||
| #include <vdr/videodir.h> | ||||
| #include "../extensions/timers.h" | ||||
| #include "../extensions/helpers.h" | ||||
| #include "../extensions/globaltimers.h" | ||||
| #include <sys/sysinfo.h> | ||||
| #include <fstream> | ||||
| #include <iostream> | ||||
| @@ -336,6 +336,7 @@ void cVeDmTimers::SetTokenContainer(void) { | ||||
|     tokenContainer->DefineLoopToken("{timers[channelid]}", (int)eDMTimersLT::channelid); | ||||
|     tokenContainer->DefineLoopToken("{timers[channellogoexists]}", (int)eDMTimersLT::channellogoexists); | ||||
|     tokenContainer->DefineLoopToken("{timers[isremotetimer]}", (int)eDMTimersLT::isremotetimer); | ||||
|     tokenContainer->DefineLoopToken("{timers[remotehost]}", (int)eDMTimersLT::remotehost); | ||||
|     tokenContainer->DefineIntToken("{numtimers}", (int)eDMTimersIT::numtimers); | ||||
|     tokenContainer->DefineIntToken("{numtimerconflicts}", (int)eDMTimersIT::numtimerconflicts); | ||||
|     tokenContainer->DefineIntToken("{timer1exists}", (int)eDMTimersIT::timer1exists); | ||||
| @@ -361,21 +362,15 @@ bool cVeDmTimers::Parse(bool forced) { | ||||
|     if (!cViewElement::Parse(forced)) | ||||
|         return false; | ||||
|     tokenContainer->Clear(); | ||||
|      | ||||
|     cGlobalTimers globalTimers; | ||||
|     globalTimers.LoadTimers(); | ||||
|     globalTimers.SortTimers(); | ||||
|     globalTimers.MarkLocalTimers(); | ||||
|  | ||||
|     int timerCount = 0; | ||||
|     // BLOCK for LOCK_TIMERS_READ scope !! | ||||
|     { | ||||
| #if defined (APIVERSNUM) && (APIVERSNUM >= 20301) | ||||
|        LOCK_TIMERS_READ; | ||||
|        timerCount = Timers->Count(); | ||||
| #else | ||||
|        timerCount = Timers.Count(); | ||||
| #endif | ||||
|     } | ||||
|     cGlobalSortedTimers SortedTimers(timerCount); // local and remote timers | ||||
|     int numTimers = SortedTimers.Size(); | ||||
|     int numTimers = globalTimers.Size(); | ||||
|     tokenContainer->AddIntToken((int)eDMTimersIT::numtimers, numTimers); | ||||
|     tokenContainer->AddIntToken((int)eDMTimersIT::numtimerconflicts, SortedTimers.NumTimerConfilicts()); | ||||
|     tokenContainer->AddIntToken((int)eDMTimersIT::numtimerconflicts, globalTimers.NumTimerConfilicts()); | ||||
|     for (int i=0; i<15; i++) { | ||||
|         if (i < numTimers) { | ||||
|             tokenContainer->AddIntToken(i+2, true); | ||||
| @@ -391,8 +386,9 @@ bool cVeDmTimers::Parse(bool forced) { | ||||
|     for (int i = 0; i < numTimers; i++) { | ||||
|         if (i >=15) | ||||
|             break; | ||||
|         const cTimer *Timer = SortedTimers[i]; | ||||
|         tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::isremotetimer, SortedTimers.IsRemoteTimer(i) ? "1" : "0"); | ||||
|         const cTimer *Timer = globalTimers[i]; | ||||
|         tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::isremotetimer, globalTimers.IsRemoteTimer(i) ? "1" : "0"); | ||||
|         tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::remotehost, globalTimers.RemoteHost(i)); | ||||
|         const cEvent *event = Timer->Event(); | ||||
|         if (event) { | ||||
|             tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::title, event->Title()); | ||||
| @@ -434,8 +430,8 @@ bool cVeDmTimers::Parse(bool forced) { | ||||
|                 timerDate = cString::sprintf("VPS %s", *timerDate); | ||||
|         } | ||||
|         tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::datetime, *timerDate); | ||||
|         tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::isremotetimer, SortedTimers.IsRemoteTimer(i) ? "1" : "0"); | ||||
|     } | ||||
|  | ||||
|     SetDirty(); | ||||
|     return true; | ||||
| } | ||||
| @@ -893,20 +889,12 @@ bool cVeDmLastrecordings::Parse(bool forced) { | ||||
|         return false; | ||||
|  | ||||
|     tokenContainer->Clear(); | ||||
|     int numTimers = 0; | ||||
|     // BLOCK for LOCK_TIMERS_READ scope !! | ||||
|     { | ||||
| #if defined (APIVERSNUM) && (APIVERSNUM >= 20301) | ||||
|         LOCK_TIMERS_READ; | ||||
|         numTimers = Timers->Count(); | ||||
| #else | ||||
|         numTimers = Timers.Count(); | ||||
| #endif | ||||
|     } | ||||
|     | ||||
|     cGlobalSortedTimers SortedTimers(numTimers);  // local and remote timers | ||||
|  | ||||
|     cGlobalTimers globalTimers; | ||||
|     globalTimers.LoadTimers(); | ||||
|      | ||||
|     //set number of timers so that it is possible to adapt this viewelement accordingly | ||||
|     tokenContainer->AddIntToken((int)eDMLastrecordingsIT::numtimers, SortedTimers.Size()); | ||||
|     tokenContainer->AddIntToken((int)eDMLastrecordingsIT::numtimers, globalTimers.Size()); | ||||
|  | ||||
|     list<const cRecording*> orderedRecs; | ||||
|  | ||||
| @@ -980,6 +968,7 @@ bool cVeDmLastrecordings::Parse(bool forced) { | ||||
|         if (i == MAX_RECORDINGS) | ||||
|             break; | ||||
|     } | ||||
|  | ||||
|     SetDirty(); | ||||
|     return true; | ||||
| } | ||||
|   | ||||
							
								
								
									
										233
									
								
								extensions/globaltimers.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								extensions/globaltimers.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,233 @@ | ||||
| #include "globaltimers.h" | ||||
| #include "../services/epgsearch.h" | ||||
| #include "../services/remotetimers.h" | ||||
| #include "../services/epgtimer.h" | ||||
|  | ||||
| static int CompareTimers(const void *a, const void *b) { | ||||
|     return (*(const cTimer **)a)->Compare(**(const cTimer **)b); | ||||
| } | ||||
|  | ||||
| bool cGlobalTimers::initial = true; | ||||
| cRemoteTimerRefresh *cGlobalTimers::remoteTimerRefresh = NULL; | ||||
|  | ||||
| cGlobalTimers::cGlobalTimers(void) : cVector<const cTimer*>(0) { | ||||
|     pEpg2Vdr = cPluginManager::GetPlugin("epg2vdr"); | ||||
|     pRemoteTimers = cPluginManager::GetPlugin("remotetimers"); | ||||
|     pEpgSearch = cPluginManager::GetPlugin("epgsearch"); | ||||
|     localTimer = NULL; | ||||
|     isEpg2VdrTimers = false; | ||||
| } | ||||
|  | ||||
| cGlobalTimers::~cGlobalTimers(void) { | ||||
|     if (localTimer) { | ||||
|         delete[] localTimer; | ||||
|     } | ||||
|     ClearTimers(); | ||||
| } | ||||
|  | ||||
| void cGlobalTimers::LoadTimers(void) { | ||||
|     uint64_t start = cTimeMs::Now(); | ||||
|     isEpg2VdrTimers = false; | ||||
|     bool epg2vdrOk = false; | ||||
|     if (pEpg2Vdr) { | ||||
|         epg2vdrOk = SetEpg2VdrTimers(); | ||||
|     } | ||||
|     if (!epg2vdrOk) { | ||||
|         SetLocalTimers();     | ||||
|         if (pRemoteTimers) { | ||||
|             SetRemoteTimers(initial); | ||||
|         }         | ||||
|     } | ||||
|     esyslog("skindesigner: loaded %d timers, needed %d ms", Size(), cTimeMs::Now() - start); | ||||
|     initial = false; | ||||
| } | ||||
|  | ||||
| void cGlobalTimers::SortTimers(void) { | ||||
|     Sort(CompareTimers); | ||||
| } | ||||
|  | ||||
| void cGlobalTimers::MarkLocalTimers(void) { | ||||
|     if (isEpg2VdrTimers) | ||||
|         return; | ||||
|  | ||||
|     if (localTimer) { | ||||
|         delete[] localTimer; | ||||
|         localTimer = NULL; | ||||
|     } | ||||
| #if defined (APIVERSNUM) && (APIVERSNUM >= 20301) | ||||
|     LOCK_TIMERS_READ; | ||||
|     const cTimers* timers = Timers; | ||||
| #else | ||||
|     const cTimers* timers = &Timers; | ||||
| #endif | ||||
|     int numTimers = Size(); | ||||
|     if (numTimers > 0) { | ||||
|         localTimer = new bool[numTimers]; | ||||
|         for (int i=0; i < numTimers; i++) { | ||||
|             if (!pRemoteTimers) { | ||||
|                 localTimer[i] = true; | ||||
|             } else { | ||||
|                 localTimer[i] = false; | ||||
|                 for (const cTimer *Timer = timers->First(); Timer; Timer = timers->Next(Timer)) { | ||||
|                     if (Timer == At(i)) { | ||||
|                         localTimer[i] = true; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void cGlobalTimers::SetLocalTimers(void) { | ||||
| #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)) { | ||||
|         if (Timer->HasFlags(tfActive)) | ||||
|             Append(Timer); | ||||
|     }     | ||||
| } | ||||
|  | ||||
| void cGlobalTimers::SetRemoteTimers(bool initial) { | ||||
|     if (initial) { | ||||
|         cString errorMsg; | ||||
|         pRemoteTimers->Service("RemoteTimers::RefreshTimers-v1.0", &errorMsg); | ||||
|     } | ||||
| #if defined (APIVERSNUM) && (APIVERSNUM >= 20301) | ||||
|     LOCK_SCHEDULES_READ; | ||||
|     const cSchedules* schedules = Schedules; | ||||
| #else | ||||
|     cSchedulesLock schedulesLock; | ||||
|     const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock); | ||||
| #endif | ||||
|     cTimer* remoteTimer = NULL; | ||||
|     while (pRemoteTimers->Service("RemoteTimers::ForEach-v1.0", &remoteTimer) && remoteTimer != NULL) { | ||||
|         remoteTimer->SetEventFromSchedule(schedules); // make sure the event is current | ||||
|         if (remoteTimer->HasFlags(tfActive)) | ||||
|             Append(remoteTimer); | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool cGlobalTimers::SetEpg2VdrTimers(void) { | ||||
|     bool ok = false; | ||||
|     cEpgTimer_Service_V1 data; | ||||
|     if (pEpg2Vdr->Service(EPG2VDR_TIMER_SERVICE, &data)) { | ||||
|         for (std::list<cEpgTimer_Interface_V1*>::iterator it = data.epgTimers.begin(); it != data.epgTimers.end(); ++it) { | ||||
|             ok = true; | ||||
|             isEpg2VdrTimers = true; | ||||
|             if ((*it)->HasFlags(tfActive)) { | ||||
|                 Append(*it); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return ok; | ||||
| } | ||||
|  | ||||
| int cGlobalTimers::NumTimerConfilicts(void) { | ||||
|     int numConflicts = 0; | ||||
|     if (pEpgSearch) { | ||||
|         Epgsearch_lastconflictinfo_v1_0 *serviceData = new Epgsearch_lastconflictinfo_v1_0; | ||||
|         if (serviceData) { | ||||
|             serviceData->nextConflict = 0; | ||||
|             serviceData->relevantConflicts = 0; | ||||
|             serviceData->totalConflicts = 0; | ||||
|             pEpgSearch->Service("Epgsearch-lastconflictinfo-v1.0", serviceData); | ||||
|             if (serviceData->relevantConflicts > 0) { | ||||
|                 numConflicts = serviceData->relevantConflicts; | ||||
|             } | ||||
|             delete serviceData; | ||||
|         } | ||||
|     } | ||||
|     return numConflicts; | ||||
| } | ||||
|  | ||||
| bool cGlobalTimers::IsRemoteTimer(int i) { | ||||
|     if (isEpg2VdrTimers) { | ||||
|         cEpgTimer_Interface_V1* epgTimer; | ||||
|         if (epgTimer = dynamic_cast<cEpgTimer_Interface_V1*>((cTimer*)At(i))) | ||||
|             return !epgTimer->isLocal(); | ||||
|         else | ||||
|             return false; | ||||
|     } | ||||
|     if (!localTimer) | ||||
|         return true; | ||||
|     if (i >= Size()) | ||||
|         return true; | ||||
|     return !(localTimer[i]); | ||||
| } | ||||
|  | ||||
| const char* cGlobalTimers::RemoteHost(int i) { | ||||
|     if (isEpg2VdrTimers) { | ||||
|         cEpgTimer_Interface_V1* epgTimer; | ||||
|         if (epgTimer = dynamic_cast<cEpgTimer_Interface_V1*>((cTimer*)At(i))) | ||||
|             return epgTimer->VdrName(); | ||||
|     } | ||||
|     return ""; | ||||
| } | ||||
|  | ||||
| void cGlobalTimers::ClearTimers(void) { | ||||
|     if (isEpg2VdrTimers) { | ||||
|         int size = Size(); | ||||
|         for (int i=0; i<size; i++) { | ||||
|             delete At(i); | ||||
|         } | ||||
|     } | ||||
|     Clear(); | ||||
| } | ||||
|  | ||||
| void cGlobalTimers::StartRefreshThread(void) { | ||||
|     if (remoteTimerRefresh == NULL) { | ||||
|         remoteTimerRefresh = new cRemoteTimerRefresh(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void cGlobalTimers::StopRefreshThread(void) { | ||||
|     if (!remoteTimerRefresh) | ||||
|         return; | ||||
|     delete remoteTimerRefresh; | ||||
|     remoteTimerRefresh = NULL; | ||||
|     initial = true; | ||||
| } | ||||
|  | ||||
| /************************************************************************* | ||||
| * cRemoteTimerRefresh | ||||
| *************************************************************************/ | ||||
| cRemoteTimerRefresh::cRemoteTimerRefresh(): cThread("skindesigner: RemoteTimers::RefreshTimers") { | ||||
|     pRemoteTimers = cPluginManager::GetPlugin("remotetimers"); | ||||
|     if (pRemoteTimers) | ||||
|         Start(); | ||||
| } | ||||
|  | ||||
| cRemoteTimerRefresh::~cRemoteTimerRefresh(void) { | ||||
|     Cancel(-1); | ||||
|     while (Active()) | ||||
|         cCondWait::SleepMs(10); | ||||
| } | ||||
|  | ||||
| void cRemoteTimerRefresh::Action(void) {     | ||||
| #define REFESH_INTERVALL_MS 30000 | ||||
|     int sleepSlice = 1000; | ||||
|     int slept = 0; | ||||
|     while (Running()) { | ||||
|         while (Running() && slept < REFESH_INTERVALL_MS) { | ||||
|             cCondWait::SleepMs(sleepSlice); | ||||
|             slept += sleepSlice; | ||||
|         } | ||||
|         slept = 0; | ||||
|         // make sure that no timer is currently being edited | ||||
|         if (!cOsd::IsOpen() && Running()) { | ||||
|             cString errorMsg; | ||||
|             pRemoteTimers->Service("RemoteTimers::RefreshTimers-v1.0", &errorMsg); | ||||
| #if defined (APIVERSNUM) && (APIVERSNUM >= 20301) | ||||
|             LOCK_TIMERS_WRITE; | ||||
|             Timers->SetModified(); | ||||
| #else | ||||
|             Timers.SetModified(); | ||||
| #endif | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										44
									
								
								extensions/globaltimers.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								extensions/globaltimers.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| #ifndef __GLOBALTIMERS_H | ||||
| #define __GLOBALTIMERS_H | ||||
|  | ||||
| #include <vdr/timers.h> | ||||
| #include <vdr/plugin.h> | ||||
|  | ||||
| class cRemoteTimerRefresh; | ||||
|  | ||||
| class cGlobalTimers : public cVector<const cTimer *> { | ||||
|     private: | ||||
|         static bool initial; | ||||
|         static cRemoteTimerRefresh *remoteTimerRefresh; | ||||
|         bool *localTimer; | ||||
|         cPlugin *pEpg2Vdr; | ||||
|         cPlugin *pRemoteTimers; | ||||
|         cPlugin *pEpgSearch; | ||||
|         bool isEpg2VdrTimers; | ||||
|         void SetLocalTimers(void); | ||||
|         void SetRemoteTimers(bool initial); | ||||
|         bool SetEpg2VdrTimers(void); | ||||
|     public: | ||||
|         cGlobalTimers(void); | ||||
|         virtual ~cGlobalTimers(void); | ||||
|         void LoadTimers(void); | ||||
|         void SortTimers(void); | ||||
|         void MarkLocalTimers(void); | ||||
|         int NumTimerConfilicts(void); | ||||
|         bool IsRemoteTimer(int i); | ||||
|         const char* RemoteHost(int i); | ||||
|         void ClearTimers(void); | ||||
|         static void StartRefreshThread(void); | ||||
|         static void StopRefreshThread(void); | ||||
| }; | ||||
|  | ||||
| class cRemoteTimerRefresh: public cThread { | ||||
|     private: | ||||
|         cPlugin* pRemoteTimers; | ||||
|     protected: | ||||
|         virtual void Action(void); | ||||
|     public: | ||||
|         cRemoteTimerRefresh(void); | ||||
|         virtual ~cRemoteTimerRefresh(void); | ||||
| }; | ||||
| #endif //__GLOBALTIMERS_H | ||||
| @@ -1,134 +0,0 @@ | ||||
| #include "timers.h" | ||||
| #include "../services/epgsearch.h" | ||||
| #include "../services/remotetimers.h" | ||||
|  | ||||
| static int CompareTimers(const void *a, const void *b) { | ||||
|     return (*(const cTimer **)a)->Compare(**(const cTimer **)b); | ||||
| } | ||||
|  | ||||
| cGlobalSortedTimers::cGlobalSortedTimers(int timerCount, bool forceRefresh) : cVector<const cTimer*>(timerCount) { | ||||
|     static bool initial = true; | ||||
|     static cRemoteTimerRefresh *remoteTimerRefresh = NULL; | ||||
|     localTimer = NULL; | ||||
|  | ||||
|     if (forceRefresh) | ||||
|         initial = true; | ||||
|     //check if remotetimers plugin is available | ||||
|     static cPlugin* pRemoteTimers = cPluginManager::GetPlugin("remotetimers"); | ||||
|  | ||||
| #if defined (APIVERSNUM) && (APIVERSNUM >= 20301) | ||||
|     LOCK_TIMERS_READ; | ||||
|     LOCK_SCHEDULES_READ; | ||||
|     const cTimers* timers = Timers; | ||||
|     const cSchedules* schedules = Schedules; | ||||
| #else | ||||
|     const cTimers* timers = &Timers; | ||||
|     cSchedulesLock schedulesLock; | ||||
|     const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock); | ||||
| #endif | ||||
|      | ||||
|     if (pRemoteTimers && initial) { | ||||
|         cString errorMsg; | ||||
|         pRemoteTimers->Service("RemoteTimers::RefreshTimers-v1.0", &errorMsg); | ||||
|         initial = false; | ||||
|     } | ||||
|  | ||||
|     for (const cTimer *Timer = timers->First(); Timer; Timer = timers->Next(Timer)) { | ||||
|         if (Timer->HasFlags(tfActive)) | ||||
|             Append(Timer); | ||||
|     } | ||||
|  | ||||
|     //if remotetimers plugin is available, take timers also from him | ||||
|     if (pRemoteTimers) { | ||||
|         cTimer* remoteTimer = NULL; | ||||
|         while (pRemoteTimers->Service("RemoteTimers::ForEach-v1.0", &remoteTimer) && remoteTimer != NULL) { | ||||
|             remoteTimer->SetEventFromSchedule(schedules); // make sure the event is current | ||||
|             if (remoteTimer->HasFlags(tfActive)) | ||||
|                 Append(remoteTimer); | ||||
|         } | ||||
|     } | ||||
|    | ||||
|     Sort(CompareTimers); | ||||
|      | ||||
|     int numTimers = Size(); | ||||
|     if (numTimers > 0) { | ||||
|         localTimer = new bool[numTimers]; | ||||
|         for (int i=0; i < numTimers; i++) { | ||||
|             if (!pRemoteTimers) { | ||||
|                 localTimer[i] = true; | ||||
|             } else { | ||||
|                 localTimer[i] = false; | ||||
|                 for (const cTimer *Timer = timers->First(); Timer; Timer = timers->Next(Timer)) { | ||||
|                     if (Timer == At(i)) { | ||||
|                         localTimer[i] = true; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (pRemoteTimers && (remoteTimerRefresh == NULL)) | ||||
|         remoteTimerRefresh = new cRemoteTimerRefresh(); | ||||
| } | ||||
|  | ||||
| cGlobalSortedTimers::~cGlobalSortedTimers(void) { | ||||
|     if (localTimer) { | ||||
|         delete[] localTimer; | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool cGlobalSortedTimers::IsRemoteTimer(int i) { | ||||
|     if (!localTimer) | ||||
|         return true; | ||||
|     if (i >= Size()) | ||||
|         return true; | ||||
|     return !(localTimer[i]); | ||||
| } | ||||
|  | ||||
|  | ||||
| int cGlobalSortedTimers::NumTimerConfilicts(void) { | ||||
|     int numConflicts = 0; | ||||
|     cPlugin *p = cPluginManager::GetPlugin("epgsearch"); | ||||
|     if (p) { | ||||
|         Epgsearch_lastconflictinfo_v1_0 *serviceData = new Epgsearch_lastconflictinfo_v1_0; | ||||
|         if (serviceData) { | ||||
|             serviceData->nextConflict = 0; | ||||
|             serviceData->relevantConflicts = 0; | ||||
|             serviceData->totalConflicts = 0; | ||||
|             p->Service("Epgsearch-lastconflictinfo-v1.0", serviceData); | ||||
|             if (serviceData->relevantConflicts > 0) { | ||||
|                 numConflicts = serviceData->relevantConflicts; | ||||
|             } | ||||
|             delete serviceData; | ||||
|         } | ||||
|     } | ||||
|     return numConflicts; | ||||
| } | ||||
|  | ||||
| cRemoteTimerRefresh::cRemoteTimerRefresh(): cThread("skindesigner: RemoteTimers::RefreshTimers") { | ||||
|     Start(); | ||||
| } | ||||
|  | ||||
| cRemoteTimerRefresh::~cRemoteTimerRefresh(void) { | ||||
|     Cancel(-1); | ||||
|     while (Active()) | ||||
|         cCondWait::SleepMs(10); | ||||
| } | ||||
|  | ||||
| void cRemoteTimerRefresh::Action(void) {     | ||||
| #define REFESH_INTERVALL_MS 30000 | ||||
|     while (Running()) { | ||||
|         cCondWait::SleepMs(REFESH_INTERVALL_MS); | ||||
|         // make sure that no timer is currently being edited | ||||
|         if (!cOsd::IsOpen()) { | ||||
|             cGlobalSortedTimers(true); | ||||
| #if defined (APIVERSNUM) && (APIVERSNUM >= 20301) | ||||
|             LOCK_TIMERS_WRITE; | ||||
|             Timers->SetModified(); | ||||
| #else | ||||
|             Timers.SetModified(); | ||||
| #endif | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,24 +0,0 @@ | ||||
| #ifndef __NOPACITY_TIMERS_H | ||||
| #define __NOPACITY_TIMERS_H | ||||
|  | ||||
| #include <vdr/timers.h> | ||||
| #include <vdr/plugin.h> | ||||
|  | ||||
| class cGlobalSortedTimers : public cVector<const cTimer *> { | ||||
|     private: | ||||
|         bool *localTimer; | ||||
|     public: | ||||
|         cGlobalSortedTimers(int timerCount, bool forceRefresh = false); | ||||
|         virtual ~cGlobalSortedTimers(void); | ||||
|         bool IsRemoteTimer(int i); | ||||
|         int NumTimerConfilicts(void); | ||||
| }; | ||||
|  | ||||
| class cRemoteTimerRefresh: public cThread { | ||||
|     protected: | ||||
|         virtual void Action(void); | ||||
|     public: | ||||
|         cRemoteTimerRefresh(void); | ||||
|         virtual ~cRemoteTimerRefresh(void); | ||||
| }; | ||||
| #endif //__NOPACITY_TIMERS_H | ||||
							
								
								
									
										121
									
								
								services/epgtimer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								services/epgtimer.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | ||||
| /* | ||||
|  * service.h: EPG2VDR plugin for the Video Disk Recorder | ||||
|  * | ||||
|  * See the README file for copyright information and how to reach the author. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef _SERVICE_H_  | ||||
| #define _SERVICE_H_  | ||||
|  | ||||
| #include <vdr/timers.h> | ||||
| #include <vdr/epg.h> | ||||
|  | ||||
| #include <list> | ||||
|  | ||||
| //*************************************************************************** | ||||
| // Timer - Skin Interface | ||||
| //*************************************************************************** | ||||
|  | ||||
| class cEpgEvent_Interface_V1 : public cEvent | ||||
| { | ||||
|    public: | ||||
|  | ||||
|       cEpgEvent_Interface_V1(tEventID EventID) | ||||
|          : cEvent(EventID) {} | ||||
|  | ||||
|       // #TODO ... getter | ||||
|        | ||||
|    protected: | ||||
|        | ||||
|       // #TODO ... attributes | ||||
| }; | ||||
|  | ||||
| //*************************************************************************** | ||||
| // Timer - Skin Interface | ||||
| //*************************************************************************** | ||||
|  | ||||
| class cEpgTimer_Interface_V1 : public cTimer | ||||
| { | ||||
|    public: | ||||
|        | ||||
|       cEpgTimer_Interface_V1(bool Instant = false, bool Pause = false, cChannel* Channel = 0) | ||||
|          : cTimer(Instant, Pause, Channel) {} | ||||
|        | ||||
|       long TimerId()              { return timerid; } | ||||
|       long EventId()              { return eventid; } | ||||
|       const char* VdrName()       { return vdrName ? vdrName : ""; } | ||||
|       const char* VdrUuid()       { return vdrUuid ? vdrUuid : ""; } | ||||
|       int isVdrRunning()          { return vdrRunning; } | ||||
|       int isLocal()               { return local; } | ||||
|       int isRemote()              { return !isLocal(); } | ||||
|  | ||||
|       char State()                { return state; } | ||||
|       const char* StateInfo()     { return stateInfo ? stateInfo : ""; } | ||||
|       char Action()               { return action; } | ||||
|  | ||||
|    protected: | ||||
|  | ||||
|       long timerid; | ||||
|       long eventid; | ||||
|  | ||||
|       char* vdrName; | ||||
|       char* vdrUuid; | ||||
|       int local; | ||||
|       int vdrRunning; | ||||
|        | ||||
|       char state; | ||||
|       char* stateInfo; | ||||
|       char action; | ||||
| }; | ||||
|  | ||||
| //*************************************************************************** | ||||
| // Timer - Service Interface | ||||
| //*************************************************************************** | ||||
|  | ||||
| struct cEpgTimer_Service_V1 | ||||
| { | ||||
|    std::list<cEpgTimer_Interface_V1*> epgTimers; | ||||
| }; | ||||
|  | ||||
| #define EPG2VDR_TIMER_SERVICE "Epg2Vdr_Timer_Service-v1.0" | ||||
|  | ||||
| #ifdef EPG2VDR | ||||
|  | ||||
| //*************************************************************************** | ||||
| // Class cEpgEvent | ||||
| //*************************************************************************** | ||||
|  | ||||
| class cEpgEvent : public cEpgEvent_Interface_V1 | ||||
| { | ||||
|    public: | ||||
|  | ||||
|       cEpgEvent(tEventID EventID); | ||||
|       virtual ~cEpgEvent() {} | ||||
|        | ||||
|       // #TODO ... setter | ||||
| }; | ||||
|  | ||||
| //*************************************************************************** | ||||
| // Class cEpgTimer | ||||
| //*************************************************************************** | ||||
|  | ||||
| class cEpgTimer : public cEpgTimer_Interface_V1 | ||||
| { | ||||
|    public: | ||||
|  | ||||
|       cEpgTimer(bool Instant = false, bool Pause = false, cChannel* Channel = 0); | ||||
|       virtual ~cEpgTimer(); | ||||
|  | ||||
|       void setTimerId(long id)    { timerid = id; } | ||||
|       void setEventId(long id)    { eventid = id; } | ||||
|       void setState(char s, const char* info); | ||||
|       void setAction(char a); | ||||
|       void setVdr(const char* name, const char* uuid = 0, int running = 0); | ||||
| }; | ||||
|  | ||||
| #endif // EPG2VDR | ||||
|  | ||||
| //*************************************************************************** | ||||
|  | ||||
| #endif // _SERVICE_H_  | ||||
| @@ -13,6 +13,7 @@ | ||||
| #include "designer.h" | ||||
| #include "setup.h" | ||||
| #include "libskindesignerapi/skindesignerapi.h" | ||||
| #include "extensions/globaltimers.h" | ||||
|  | ||||
| #if defined(APIVERSNUM) && APIVERSNUM < 20200 | ||||
| #error "VDR-2.2.0 API version or greater is required!" | ||||
| @@ -111,6 +112,7 @@ bool cPluginSkinDesigner::Initialize(void) { | ||||
| bool cPluginSkinDesigner::Start(void) { | ||||
|     cXmlParser::InitLibXML(); | ||||
|     cImageImporterSVG::InitLibRSVG(); | ||||
|     cGlobalTimers::StartRefreshThread(); | ||||
|     bool trueColorAvailable = true; | ||||
|      | ||||
|     if (!cOsdProvider::SupportsTrueColor()) { | ||||
| @@ -164,6 +166,7 @@ void cPluginSkinDesigner::Stop(void) { | ||||
|     delete fontManager; | ||||
|     delete plgManager; | ||||
|     cXmlParser::CleanupLibXML(); | ||||
|     cGlobalTimers::StopRefreshThread(); | ||||
| } | ||||
|  | ||||
| void cPluginSkinDesigner::Housekeeping(void) { | ||||
|   | ||||
							
								
								
									
										89
									
								
								skins/estuary4vdr/svgtemplates/icons/ico_remotetimer.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								skins/estuary4vdr/svgtemplates/icons/ico_remotetimer.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    version="1.1" | ||||
|    id="Capa_1" | ||||
|    x="0px" | ||||
|    y="0px" | ||||
|    viewBox="0 0 484.6 484.6" | ||||
|    style="enable-background:new 0 0 484.6 484.6;" | ||||
|    xml:space="preserve" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="ico_remotetimer.svg"><metadata | ||||
|      id="metadata59"><rdf:RDF><cc:Work | ||||
|          rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs | ||||
|      id="defs57" /><sodipodi:namedview | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1" | ||||
|      objecttolerance="10" | ||||
|      gridtolerance="10" | ||||
|      guidetolerance="10" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1017" | ||||
|      id="namedview55" | ||||
|      showgrid="false" | ||||
|      inkscape:zoom="0.48699958" | ||||
|      inkscape:cx="-13.347034" | ||||
|      inkscape:cy="242.3" | ||||
|      inkscape:window-x="-8" | ||||
|      inkscape:window-y="-8" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:current-layer="Capa_1" /><g | ||||
|      id="g3" | ||||
|      style="fill:#{sdcol(icon)};fill-opacity:1"><g | ||||
|        id="g5" | ||||
|        style="fill:#{sdcol(icon)};fill-opacity:1"><path | ||||
|          d="M297.2,396.6c-3.2,0-6.3,1.3-8.5,3.5s-3.5,5.3-3.5,8.5s1.3,6.3,3.5,8.5s5.3,3.5,8.5,3.5s6.3-1.3,8.5-3.5s3.5-5.3,3.5-8.5    s-1.3-6.3-3.5-8.5C303.5,397.9,300.4,396.6,297.2,396.6z" | ||||
|          id="path7" | ||||
|          style="fill:#{sdcol(icon)};fill-opacity:1" /><path | ||||
|          d="M242.3,396.6c-6.6,0-12,5.4-12,12s5.4,12,12,12s12-5.4,12-12C254.3,402,248.9,396.6,242.3,396.6z" | ||||
|          id="path9" | ||||
|          style="fill:#{sdcol(icon)};fill-opacity:1" /><path | ||||
|          d="M187.4,396.6c-3.2,0-6.3,1.3-8.5,3.5s-3.5,5.3-3.5,8.5c0,3.1,1.3,6.3,3.5,8.5s5.3,3.5,8.5,3.5s6.3-1.3,8.5-3.5    s3.5-5.3,3.5-8.5s-1.3-6.3-3.5-8.5C193.6,397.9,190.5,396.6,187.4,396.6z" | ||||
|          id="path11" | ||||
|          style="fill:#{sdcol(icon)};fill-opacity:1" /><path | ||||
|          d="M187.4,341.7c-6.6,0-12,5.4-12,12s5.4,12,12,12s12-5.4,12-12S194,341.7,187.4,341.7z" | ||||
|          id="path13" | ||||
|          style="fill:#{sdcol(icon)};fill-opacity:1" /><path | ||||
|          d="M187.4,286.8c-3.2,0-6.3,1.3-8.5,3.5s-3.5,5.3-3.5,8.5s1.3,6.3,3.5,8.5s5.3,3.5,8.5,3.5s6.3-1.3,8.5-3.5s3.5-5.3,3.5-8.5    s-1.3-6.3-3.5-8.5C193.6,288.1,190.5,286.8,187.4,286.8z" | ||||
|          id="path15" | ||||
|          style="fill:#{sdcol(icon)};fill-opacity:1" /><path | ||||
|          d="M242.3,286.8c-6.6,0-12,5.4-12,12s5.4,12,12,12s12-5.4,12-12S248.9,286.8,242.3,286.8z" | ||||
|          id="path17" | ||||
|          style="fill:#{sdcol(icon)};fill-opacity:1" /><path | ||||
|          d="M297.2,286.8c-3.2,0-6.3,1.3-8.5,3.5s-3.5,5.3-3.5,8.5s1.3,6.3,3.5,8.5s5.3,3.5,8.5,3.5s6.3-1.3,8.5-3.5s3.5-5.3,3.5-8.5    s-1.3-6.3-3.5-8.5C303.5,288.1,300.4,286.8,297.2,286.8z" | ||||
|          id="path19" | ||||
|          style="fill:#{sdcol(icon)};fill-opacity:1" /><path | ||||
|          d="M297.2,341.7c-6.6,0-12,5.4-12,12s5.4,12,12,12s12-5.4,12-12S303.8,341.7,297.2,341.7z" | ||||
|          id="path21" | ||||
|          style="fill:#{sdcol(icon)};fill-opacity:1" /><path | ||||
|          d="M472.6,286.8h-42.9v-43.6c0-6.6-5.4-12-12-12H254.3v-33.4h42.9c6.6,0,12-5.4,12-12V76c0-6.6-5.4-12-12-12H187.4    c-6.6,0-12,5.4-12,12v109.8c0,6.6,5.4,12,12,12h42.9v33.4H66.9c-6.6,0-12,5.4-12,12v43.6H12c-6.6,0-12,5.4-12,12v109.8    c0,6.6,5.4,12,12,12h109.8c6.6,0,12-5.4,12-12V298.8c0-6.6-5.4-12-12-12H78.9v-31.6h326.8v31.6h-42.9c-6.6,0-12,5.4-12,12v109.8    c0,6.6,5.4,12,12,12h109.8c6.6,0,12-5.4,12-12V298.8C484.6,292.2,479.3,286.8,472.6,286.8z M109.8,310.8v85.8H24v-85.8H109.8z     M199.4,173.8V88h85.8v85.8H199.4z M460.6,396.6h-85.8v-85.8h85.8V396.6z" | ||||
|          id="path23" | ||||
|          style="fill:#{sdcol(icon)};fill-opacity:1" /></g></g><g | ||||
|      id="g25" /><g | ||||
|      id="g27" /><g | ||||
|      id="g29" /><g | ||||
|      id="g31" /><g | ||||
|      id="g33" /><g | ||||
|      id="g35" /><g | ||||
|      id="g37" /><g | ||||
|      id="g39" /><g | ||||
|      id="g41" /><g | ||||
|      id="g43" /><g | ||||
|      id="g45" /><g | ||||
|      id="g47" /><g | ||||
|      id="g49" /><g | ||||
|      id="g51" /><g | ||||
|      id="g53" /></svg> | ||||
| After Width: | Height: | Size: 4.3 KiB | 
| @@ -0,0 +1,89 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    version="1.1" | ||||
|    id="Capa_1" | ||||
|    x="0px" | ||||
|    y="0px" | ||||
|    viewBox="0 0 484.6 484.6" | ||||
|    style="enable-background:new 0 0 484.6 484.6;" | ||||
|    xml:space="preserve" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="ico_remotetimer.svg"><metadata | ||||
|      id="metadata59"><rdf:RDF><cc:Work | ||||
|          rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs | ||||
|      id="defs57" /><sodipodi:namedview | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1" | ||||
|      objecttolerance="10" | ||||
|      gridtolerance="10" | ||||
|      guidetolerance="10" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1017" | ||||
|      id="namedview55" | ||||
|      showgrid="false" | ||||
|      inkscape:zoom="0.48699958" | ||||
|      inkscape:cx="-13.347034" | ||||
|      inkscape:cy="242.3" | ||||
|      inkscape:window-x="-8" | ||||
|      inkscape:window-y="-8" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:current-layer="Capa_1" /><g | ||||
|      id="g3" | ||||
|      style="fill:#{sdcol(iconactive)};fill-opacity:1"><g | ||||
|        id="g5" | ||||
|        style="fill:#{sdcol(iconactive)};fill-opacity:1"><path | ||||
|          d="M297.2,396.6c-3.2,0-6.3,1.3-8.5,3.5s-3.5,5.3-3.5,8.5s1.3,6.3,3.5,8.5s5.3,3.5,8.5,3.5s6.3-1.3,8.5-3.5s3.5-5.3,3.5-8.5    s-1.3-6.3-3.5-8.5C303.5,397.9,300.4,396.6,297.2,396.6z" | ||||
|          id="path7" | ||||
|          style="fill:#{sdcol(iconactive)};fill-opacity:1" /><path | ||||
|          d="M242.3,396.6c-6.6,0-12,5.4-12,12s5.4,12,12,12s12-5.4,12-12C254.3,402,248.9,396.6,242.3,396.6z" | ||||
|          id="path9" | ||||
|          style="fill:#{sdcol(iconactive)};fill-opacity:1" /><path | ||||
|          d="M187.4,396.6c-3.2,0-6.3,1.3-8.5,3.5s-3.5,5.3-3.5,8.5c0,3.1,1.3,6.3,3.5,8.5s5.3,3.5,8.5,3.5s6.3-1.3,8.5-3.5    s3.5-5.3,3.5-8.5s-1.3-6.3-3.5-8.5C193.6,397.9,190.5,396.6,187.4,396.6z" | ||||
|          id="path11" | ||||
|          style="fill:#{sdcol(iconactive)};fill-opacity:1" /><path | ||||
|          d="M187.4,341.7c-6.6,0-12,5.4-12,12s5.4,12,12,12s12-5.4,12-12S194,341.7,187.4,341.7z" | ||||
|          id="path13" | ||||
|          style="fill:#{sdcol(iconactive)};fill-opacity:1" /><path | ||||
|          d="M187.4,286.8c-3.2,0-6.3,1.3-8.5,3.5s-3.5,5.3-3.5,8.5s1.3,6.3,3.5,8.5s5.3,3.5,8.5,3.5s6.3-1.3,8.5-3.5s3.5-5.3,3.5-8.5    s-1.3-6.3-3.5-8.5C193.6,288.1,190.5,286.8,187.4,286.8z" | ||||
|          id="path15" | ||||
|          style="fill:#{sdcol(iconactive)};fill-opacity:1" /><path | ||||
|          d="M242.3,286.8c-6.6,0-12,5.4-12,12s5.4,12,12,12s12-5.4,12-12S248.9,286.8,242.3,286.8z" | ||||
|          id="path17" | ||||
|          style="fill:#{sdcol(iconactive)};fill-opacity:1" /><path | ||||
|          d="M297.2,286.8c-3.2,0-6.3,1.3-8.5,3.5s-3.5,5.3-3.5,8.5s1.3,6.3,3.5,8.5s5.3,3.5,8.5,3.5s6.3-1.3,8.5-3.5s3.5-5.3,3.5-8.5    s-1.3-6.3-3.5-8.5C303.5,288.1,300.4,286.8,297.2,286.8z" | ||||
|          id="path19" | ||||
|          style="fill:#{sdcol(iconactive)};fill-opacity:1" /><path | ||||
|          d="M297.2,341.7c-6.6,0-12,5.4-12,12s5.4,12,12,12s12-5.4,12-12S303.8,341.7,297.2,341.7z" | ||||
|          id="path21" | ||||
|          style="fill:#{sdcol(iconactive)};fill-opacity:1" /><path | ||||
|          d="M472.6,286.8h-42.9v-43.6c0-6.6-5.4-12-12-12H254.3v-33.4h42.9c6.6,0,12-5.4,12-12V76c0-6.6-5.4-12-12-12H187.4    c-6.6,0-12,5.4-12,12v109.8c0,6.6,5.4,12,12,12h42.9v33.4H66.9c-6.6,0-12,5.4-12,12v43.6H12c-6.6,0-12,5.4-12,12v109.8    c0,6.6,5.4,12,12,12h109.8c6.6,0,12-5.4,12-12V298.8c0-6.6-5.4-12-12-12H78.9v-31.6h326.8v31.6h-42.9c-6.6,0-12,5.4-12,12v109.8    c0,6.6,5.4,12,12,12h109.8c6.6,0,12-5.4,12-12V298.8C484.6,292.2,479.3,286.8,472.6,286.8z M109.8,310.8v85.8H24v-85.8H109.8z     M199.4,173.8V88h85.8v85.8H199.4z M460.6,396.6h-85.8v-85.8h85.8V396.6z" | ||||
|          id="path23" | ||||
|          style="fill:#{sdcol(iconactive)};fill-opacity:1" /></g></g><g | ||||
|      id="g25" /><g | ||||
|      id="g27" /><g | ||||
|      id="g29" /><g | ||||
|      id="g31" /><g | ||||
|      id="g33" /><g | ||||
|      id="g35" /><g | ||||
|      id="g37" /><g | ||||
|      id="g39" /><g | ||||
|      id="g41" /><g | ||||
|      id="g43" /><g | ||||
|      id="g45" /><g | ||||
|      id="g47" /><g | ||||
|      id="g49" /><g | ||||
|      id="g51" /><g | ||||
|      id="g53" /></svg> | ||||
| After Width: | Height: | Size: 4.4 KiB | 
| @@ -38,7 +38,9 @@ | ||||
|         <area condition="{numtimers}" x="2%" y="78%" width="28%" height="14%" layer="3"> | ||||
|             <loop name="timers" x="5" y="3" orientation="vertical" columnwidth="{areawidth}" rowheight="{areaheight}/3" overflow="cut"> | ||||
|                 <drawimage cache="true" name="logo" imagetype="channellogo" path="{timers[channelid]}" width="{columnwidth}*0.15" height="{rowheight}*0.75" x="10" valign="center" /> | ||||
|                 <drawtext  x="{posx(logo)} + {width(logo)} + 10" y="0" font="{regular}" fontsize="{rowheight}*0.4" color="{fontdefault}" text="{timers[datetime]}" /> | ||||
|                 <drawtext  name="datetime" x="{posx(logo)} + {width(logo)} + 10" y="0" font="{regular}" fontsize="{rowheight}*0.4" color="{fontdefault}" text="{timers[datetime]}" /> | ||||
|                 <drawimage condition="{timers[isremotetimer]}" name="remotetimericon" imagetype="icon" path="ico_remotetimer" width="{rowheight}*0.4" height="{rowheight}*0.4" x="{posx(datetime)} + {width(datetime)} + 10" y="0" /> | ||||
|                 <drawtext  condition="{timers[isremotetimer]}" x="{posx(remotetimericon)} + {width(remotetimericon)} + 10" y="0" font="{regular}" fontsize="{rowheight}*0.4" color="{fontdefault}" text="{timers[remotehost]}" /> | ||||
|                 <drawtext x="{posx(logo)} + {width(logo)} + 10" y="{rowheight}*0.35" width="{columnwidth} - {posx(logo)} - {width(logo)} - 20" font="{regular}" fontsize="{rowheight}*0.6" color="{fontdefault}" text="{timers[title]}" /> | ||||
|             </loop> | ||||
|         </area> | ||||
|   | ||||
| @@ -31,6 +31,8 @@ | ||||
|                 <drawimage condition="{current}++not{flagactive}++not{flagrecording}" imagetype="icon" path="ico_no_active" align="right" width="{areaheight}" height="{areaheight}" valign="center" /> | ||||
|                 <drawimage condition="not{current}++{flagrecording}" imagetype="icon" path="ico_recording" align="right" width="{areaheight}" height="{areaheight}" valign="center" /> | ||||
|                 <drawimage condition="{current}++{flagrecording}" imagetype="icon" path="ico_recording_active" align="right" width="{areaheight}" height="{areaheight}" valign="center" /> | ||||
|                 <drawimage condition="{current}++{isremote}" imagetype="icon" path="ico_remotetimer_active" x="{areawidth} - 2*{areaheight} - 10" width="{areaheight}" height="{areaheight}" valign="center" /> | ||||
|                 <drawimage condition="not{current}++{isremote}" imagetype="icon" path="ico_remotetimer" x="{areawidth} - 2*{areaheight} - 10" width="{areaheight}" height="{areaheight}" valign="center" /> | ||||
|             </area> | ||||
|         </listelement> | ||||
|         <currentelement delay="100" fadetime="200"> | ||||
|   | ||||
| @@ -15,7 +15,8 @@ | ||||
|     {timers[channelnumber]}      number of channel | ||||
|     {timers[channelid]}          ChannelID of channel | ||||
|     {timers[channellogoexists]}  true if channel logo exists | ||||
|     {timers[isremotetimer]}      true if timer is a remote timer from remotetimers plugin | ||||
|     {timers[isremotetimer]}      true if timer is a remote timer from remotetimers or epg2vdr plugin | ||||
|     {timers[remotehost]}         name of host on which timer is set. only for epg2vdr timers available | ||||
|     --> | ||||
|     <timers> | ||||
|     </timers> | ||||
|   | ||||
| @@ -23,6 +23,12 @@ | ||||
|         {flagvps}           true if timer uses VPS | ||||
|         {flagrecording}     true if is recording currently | ||||
|         {flagpending}       true if timer is pending | ||||
|         {isremote}          true if timer is a epg2vdr remote timer | ||||
|         {vdrname}           name of vdr on which epg2vdr timer is located | ||||
|         {isvdrrunning}      true if vdr on which epg2vdr timer is located is running | ||||
|         {action}            action of epg2vdr timer | ||||
|         {state}             state of epg2vdr timer | ||||
|         {stateinfo}         stateinfo of epg2vdr timer | ||||
|         --> | ||||
|         <listelement> | ||||
|         </listelement> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user