mirror of
				https://projects.vdr-developer.org/git/vdr-plugin-skindesigner.git
				synced 2023-10-19 15:58:31 +00:00 
			
		
		
		
	Merge branch 'master' of git://projects.vdr-developer.org/vdr-plugin-skindesigner
This commit is contained in:
		
							
								
								
									
										8
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								HISTORY
									
									
									
									
									
								
							| @@ -47,5 +47,11 @@ Version 0.0.3 | ||||
| - changed skin metrixHD to display bitrate infos | ||||
| - added "active" Token for cutting marks so that a mark can be displayed in a dedicated way if current position | ||||
|   in replay exactly hits the mark | ||||
|  | ||||
| - added {channelname}, {channelid}, {channellogoexists} for all schedules list and current views | ||||
| - added printf function for <drawtext>, see Wiki for documentation | ||||
| - removed code for displaying bitrates in displaychannel again because of incompatibility with dvbapi Plugin | ||||
| - optimized performance when creating a menu list | ||||
| - fixed Bug that displaychannel was not shown after closing displaymenu with "backspace" (with active  | ||||
|   menuorg plugin) | ||||
| - fixed Bug with menuselection Patch | ||||
|  | ||||
|   | ||||
							
								
								
									
										1
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Makefile
									
									
									
									
									
								
							| @@ -68,7 +68,6 @@ OBJS = $(PLUGIN).o \ | ||||
|        libcore/recfolderinfo.o \ | ||||
|        libcore/extrecinfo.o \ | ||||
|        libcore/timers.o \ | ||||
|        libcore/femonreceiver.o \ | ||||
|        libtemplate/globals.o \ | ||||
|        libtemplate/parameter.o \ | ||||
|        libtemplate/template.o \ | ||||
|   | ||||
							
								
								
									
										2
									
								
								config.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								config.c
									
									
									
									
									
								
							| @@ -23,8 +23,6 @@ cDesignerConfig::cDesignerConfig() { | ||||
|     //menu display style, display menu items  | ||||
|     //one after each other or in one step | ||||
|     blockFlush = 1; | ||||
|     //interval for femon receiver to recalculate bitrates in tenth of a second | ||||
|     bitrateCalcInterval = 10; | ||||
|     //remember current skin and theme, osd size and osd fonts | ||||
|     SetSkin(); | ||||
|     SetOSDSize(); | ||||
|   | ||||
							
								
								
									
										1
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								config.h
									
									
									
									
									
								
							| @@ -61,7 +61,6 @@ public: | ||||
|     int rerunDistance; | ||||
|     int rerunMaxChannel; | ||||
|     int blockFlush; | ||||
|     int bitrateCalcInterval; | ||||
| }; | ||||
|  | ||||
| #ifdef DEFINE_CONFIG | ||||
|   | ||||
| @@ -159,7 +159,6 @@ void cSDDisplayChannel::SetMessage(eMessageType Type, const char *Text) { | ||||
|     channelView->ClearSignalBackground(); | ||||
|     channelView->ClearScraperContent(); | ||||
|     channelView->ClearAudioInfo(); | ||||
|     channelView->ClearBitrates(); | ||||
|     channelView->DisplayMessage(Type, Text); | ||||
|     groupSep = true; | ||||
| } | ||||
| @@ -187,14 +186,12 @@ void cSDDisplayChannel::Flush(void) { | ||||
|         channelView->DrawSignal(); | ||||
|         channelView->DrawAudioInfo(); | ||||
|         channelView->DrawDevices(initial); | ||||
|         channelView->DrawBitrates(); | ||||
|     } else { | ||||
|         channelView->ClearStatusIcons(); | ||||
|         channelView->ClearScreenResolution(); | ||||
|         channelView->ClearSignal(); | ||||
|         channelView->ClearSignalBackground(); | ||||
|         channelView->ClearDevices(); | ||||
|         channelView->DrawBitrates(); | ||||
|     } | ||||
|  | ||||
|     if (initial) { | ||||
|   | ||||
| @@ -81,17 +81,18 @@ bool cSDDisplayMenu::SetItemEvent(const cEvent *Event, int Index, bool Current, | ||||
|         return false; | ||||
|     if (config.blockFlush) | ||||
|         rootView->LockFlush(); | ||||
|     if (Current) { | ||||
|         if (Channel) { | ||||
|             rootView->SetChannel(Channel); | ||||
|         } else if (Event) { | ||||
|             rootView->SetChannel(Channels.GetByChannelID(Event->ChannelID())); | ||||
|         } | ||||
|     const cChannel *channel = Channel; | ||||
|     if (!channel) { | ||||
|         channel = rootView->GetChannel(); | ||||
|     }  | ||||
|     if (!channel && Event) { | ||||
|         channel = Channels.GetByChannelID(Event->ChannelID()); | ||||
|         rootView->SetChannel(channel); | ||||
|     } | ||||
|     cDisplayMenuListView *list = rootView->GetListView(); | ||||
|     if (!list) | ||||
|         return false; | ||||
|     list->AddSchedulesMenuItem(Index, Event, Channel, TimerMatch, MenuCategory(), Current, Selectable); | ||||
|     list->AddSchedulesMenuItem(Index, Event, channel, TimerMatch, MenuCategory(), Current, Selectable); | ||||
|     if (state == vsIdle) | ||||
|         state = vsMenuUpdate; | ||||
|     return true; | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| <!ELEMENT displaychannel (background | channelinfo | epginfo | progressbar | progressbarback |   | ||||
|                           statusinfo | audioinfo | screenresolution | channelgroup |  | ||||
|                           signalquality | signalqualityback | devices | bitrate | scrapercontent |   | ||||
|                           signalquality | signalqualityback | devices | scrapercontent |   | ||||
|                           datetime | message | customtokens)* > | ||||
| <!ATTLIST displaychannel | ||||
|   x CDATA #REQUIRED | ||||
| @@ -78,11 +78,6 @@ | ||||
|   debug CDATA #IMPLIED | ||||
| > | ||||
|  | ||||
| <!ELEMENT bitrate (area|areascroll)*> | ||||
| <!ATTLIST bitrate | ||||
|   debug CDATA #IMPLIED | ||||
| > | ||||
|  | ||||
| <!ELEMENT scrapercontent (area|areascroll)*> | ||||
| <!ATTLIST scrapercontent | ||||
|   debug CDATA #IMPLIED | ||||
|   | ||||
| @@ -1,184 +0,0 @@ | ||||
| #include <unistd.h> | ||||
| #include "../config.h" | ||||
| #include "femonreceiver.h" | ||||
|  | ||||
| cFemonReceiver::cFemonReceiver(const cChannel *Channel, int ATrack, int DTrack) | ||||
|     : cReceiver(Channel), | ||||
|     cThread("femon receiver"), | ||||
|     m_Mutex(), | ||||
|     m_Sleep(), | ||||
|     m_Active(false), | ||||
|     m_VideoBuffer(KILOBYTE(512), TS_SIZE, false, "Femon video"), | ||||
|     m_VideoType(Channel ? Channel->Vtype(): 0), | ||||
|     m_VideoPid(Channel ? Channel->Vpid() : 0), | ||||
|     m_VideoPacketCount(0), | ||||
|     m_AudioBuffer(KILOBYTE(256), TS_SIZE, false, "Femon audio"), | ||||
|     m_AudioPid(Channel ? Channel->Apid(ATrack) : 0), | ||||
|     m_AudioPacketCount(0), | ||||
|     m_AC3Buffer(KILOBYTE(256), TS_SIZE, false, "Femon AC3"), | ||||
|     m_AC3Pid(Channel ? Channel->Dpid(DTrack) : 0), | ||||
|     m_AC3PacketCount(0) | ||||
| { | ||||
|     SetPids(NULL); | ||||
|     AddPid(m_VideoPid); | ||||
|     AddPid(m_AudioPid); | ||||
|     AddPid(m_AC3Pid); | ||||
|  | ||||
|     m_VideoBuffer.SetTimeouts(0, 100); | ||||
|     m_AudioBuffer.SetTimeouts(0, 100); | ||||
|     m_AC3Buffer.SetTimeouts(0, 100); | ||||
|  | ||||
|     m_VideoBitrate = 0.0; | ||||
|     m_AudioBitrate = 0.0; | ||||
|     m_AC3Bitrate = 0.0; | ||||
| } | ||||
|  | ||||
| cFemonReceiver::~cFemonReceiver(void) | ||||
| { | ||||
|     Deactivate(); | ||||
| } | ||||
|  | ||||
| void cFemonReceiver::Deactivate(void) | ||||
| { | ||||
|     Detach(); | ||||
|     if (m_Active) { | ||||
|         m_Active = false; | ||||
|         m_Sleep.Signal(); | ||||
|         if (Running()) | ||||
|             Cancel(3); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void cFemonReceiver::Activate(bool On) | ||||
| { | ||||
|     if (On) | ||||
|         Start(); | ||||
|     else | ||||
|         Deactivate(); | ||||
| } | ||||
|  | ||||
| void cFemonReceiver::Receive(uchar *Data, int Length) | ||||
| { | ||||
|     // TS packet length: TS_SIZE | ||||
|     if (Running() && (*Data == TS_SYNC_BYTE) && (Length == TS_SIZE)) { | ||||
|         int len, pid = TsPid(Data); | ||||
|         if (pid == m_VideoPid) { | ||||
|             ++m_VideoPacketCount; | ||||
|             len = m_VideoBuffer.Put(Data, Length); | ||||
|             if (len != Length) { | ||||
|                 m_VideoBuffer.ReportOverflow(Length - len); | ||||
|                 m_VideoBuffer.Clear(); | ||||
|             } | ||||
|         } | ||||
|         else if (pid == m_AudioPid) { | ||||
|             ++m_AudioPacketCount; | ||||
|             len = m_AudioBuffer.Put(Data, Length); | ||||
|             if (len != Length) { | ||||
|                 m_AudioBuffer.ReportOverflow(Length - len); | ||||
|                 m_AudioBuffer.Clear(); | ||||
|             } | ||||
|         } | ||||
|         else if (pid == m_AC3Pid) { | ||||
|             ++m_AC3PacketCount; | ||||
|             len = m_AC3Buffer.Put(Data, Length); | ||||
|             if (len != Length) { | ||||
|                 m_AC3Buffer.ReportOverflow(Length - len); | ||||
|                 m_AC3Buffer.Clear(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void cFemonReceiver::Action(void) | ||||
| { | ||||
|     cTimeMs calcPeriod(0); | ||||
|     m_Active = true; | ||||
|     bool init = true; | ||||
|     while (Running() && m_Active) { | ||||
|         uint8_t *Data; | ||||
|         double timeout; | ||||
|         int Length; | ||||
|         bool processed = false; | ||||
|  | ||||
|         // process available video data | ||||
|         while ((Data = m_VideoBuffer.Get(Length))) { | ||||
|             if (!m_Active || (Length < TS_SIZE)) | ||||
|                 break; | ||||
|             Length = TS_SIZE; | ||||
|             if (*Data != TS_SYNC_BYTE) { | ||||
|                 for (int i = 1; i < Length; ++i) { | ||||
|                     if (Data[i] == TS_SYNC_BYTE) { | ||||
|                         Length = i; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|                 m_VideoBuffer.Del(Length); | ||||
|                 continue; | ||||
|             } | ||||
|             processed = true; | ||||
|             if (TsPayloadStart(Data)) { | ||||
|                 m_VideoAssembler.Reset(); | ||||
|             } | ||||
|             m_VideoAssembler.PutTs(Data, Length); | ||||
|             m_VideoBuffer.Del(Length); | ||||
|         } | ||||
|  | ||||
|         // process available audio data | ||||
|         while ((Data = m_AudioBuffer.Get(Length))) { | ||||
|             if (!m_Active || (Length < TS_SIZE)) | ||||
|                 break; | ||||
|             Length = TS_SIZE; | ||||
|             if (*Data != TS_SYNC_BYTE) { | ||||
|                 for (int i = 1; i < Length; ++i) { | ||||
|                     if (Data[i] == TS_SYNC_BYTE) { | ||||
|                         Length = i; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|                 m_AudioBuffer.Del(Length); | ||||
|                 continue; | ||||
|             } | ||||
|             processed = true; | ||||
|             m_AudioAssembler.PutTs(Data, Length); | ||||
|             m_AudioBuffer.Del(Length); | ||||
|         } | ||||
|  | ||||
|         // process available dolby data | ||||
|         while ((Data = m_AC3Buffer.Get(Length))) { | ||||
|             if (!m_Active || (Length < TS_SIZE)) | ||||
|                 break; | ||||
|             Length = TS_SIZE; | ||||
|             if (*Data != TS_SYNC_BYTE) { | ||||
|                 for (int i = 1; i < Length; ++i) { | ||||
|                     if (Data[i] == TS_SYNC_BYTE) { | ||||
|                         Length = i; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|                 m_AC3Buffer.Del(Length); | ||||
|                 continue; | ||||
|             } | ||||
|             processed = true; | ||||
|             m_AC3Assembler.PutTs(Data, Length); | ||||
|             m_AC3Buffer.Del(Length); | ||||
|         } | ||||
|  | ||||
|         // calculate bitrates | ||||
|         timeout = double(calcPeriod.Elapsed()); | ||||
|         if (m_Active && (init || (timeout >= (100.0 * config.bitrateCalcInterval )))) { | ||||
|             // TS packet 188 bytes - 4 byte header; MPEG standard defines 1Mbit = 1000000bit | ||||
|             // PES headers should be compensated! | ||||
|             m_VideoBitrate     = (1000.0 * 8.0 * 184.0 * m_VideoPacketCount) / timeout; | ||||
|             m_VideoPacketCount = 0; | ||||
|             m_AudioBitrate     = (1000.0 * 8.0 * 184.0 * m_AudioPacketCount) / timeout; | ||||
|             m_AudioPacketCount = 0; | ||||
|             m_AC3Bitrate       = (1000.0 * 8.0 * 184.0 * m_AC3PacketCount)   / timeout; | ||||
|             m_AC3PacketCount   = 0; | ||||
|             calcPeriod.Set(0); | ||||
|             init = false; | ||||
|         } | ||||
|  | ||||
|         if (!processed) | ||||
|             m_Sleep.Wait(10); // to avoid busy loop and reduce cpu load | ||||
|     } | ||||
| } | ||||
| @@ -1,53 +0,0 @@ | ||||
| #ifndef __FEMONRECEIVER_H | ||||
| #define __FEMONRECEIVER_H | ||||
|  | ||||
| #include <vdr/thread.h> | ||||
| #include <vdr/receiver.h> | ||||
|  | ||||
| class cFemonReceiver : public cReceiver, public cThread { | ||||
|     private: | ||||
|         cMutex            m_Mutex; | ||||
|         cCondWait         m_Sleep; | ||||
|         bool              m_Active; | ||||
|  | ||||
|         cRingBufferLinear m_VideoBuffer; | ||||
|         cTsToPes          m_VideoAssembler; | ||||
|         int               m_VideoType; | ||||
|         int               m_VideoPid; | ||||
|         int               m_VideoPacketCount; | ||||
|         double            m_VideoBitrate; | ||||
|  | ||||
|         cRingBufferLinear m_AudioBuffer; | ||||
|         cTsToPes          m_AudioAssembler; | ||||
|         int               m_AudioPid; | ||||
|         int               m_AudioPacketCount; | ||||
|         double            m_AudioBitrate; | ||||
|         bool              m_AudioValid; | ||||
|  | ||||
|         cRingBufferLinear m_AC3Buffer; | ||||
|         cTsToPes          m_AC3Assembler; | ||||
|         int               m_AC3Pid; | ||||
|         int               m_AC3PacketCount; | ||||
|         double            m_AC3Bitrate; | ||||
|         bool              m_AC3Valid; | ||||
|  | ||||
|     protected: | ||||
|         virtual void Activate(bool On); | ||||
|         virtual void Receive(uchar *Data, int Length); | ||||
|         virtual void Action(void); | ||||
|  | ||||
|     public: | ||||
|         cFemonReceiver(const cChannel* Channel, int ATrack, int DTrack); | ||||
|         virtual ~cFemonReceiver(); | ||||
|         void Deactivate(void); | ||||
|  | ||||
|         double VideoBitrate(void)         { cMutexLock MutexLock(&m_Mutex); | ||||
|             return m_VideoBitrate; };                // bit/s | ||||
|         double AudioBitrate(void)         { cMutexLock MutexLock(&m_Mutex); | ||||
|             return m_AudioBitrate; };                // bit/s | ||||
|         double AC3Bitrate(void)           { cMutexLock MutexLock(&m_Mutex); | ||||
|             return m_AC3Bitrate; };                  // bit/s | ||||
| }; | ||||
|  | ||||
| #endif //__FEMONRECEIVER_H | ||||
|  | ||||
| @@ -39,6 +39,7 @@ cPixmapContainer::~cPixmapContainer(void) { | ||||
|         osd = NULL; | ||||
|         mutex.Unlock(); | ||||
|     } | ||||
|     flushState = fsOpen; | ||||
| } | ||||
|  | ||||
| bool cPixmapContainer::CreateOsd(int Left, int Top, int Width, int Height) { | ||||
|   | ||||
| @@ -83,13 +83,15 @@ public: | ||||
| enum eTextTokenType { | ||||
|     ttConstString, | ||||
|     ttToken, | ||||
|     ttConditionalToken | ||||
|     ttConditionalToken, | ||||
|     ttPrintfToken | ||||
| }; | ||||
|  | ||||
| class cTextToken { | ||||
| public: | ||||
|     eTextTokenType type; | ||||
|     string value; | ||||
|     vector<string> parameters; | ||||
|     vector<cTextToken> subTokens; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -272,6 +272,36 @@ bool cTemplateFunction::CalculateParameters(void) { | ||||
|     return paramsValid; | ||||
| }     | ||||
|  | ||||
| bool cTemplateFunction::ReCalculateParameters(void) { | ||||
|     bool paramValid = true; | ||||
|     bool paramsValid = true; | ||||
|     for (map< eParamType, string >::iterator param = nativeParameters.begin(); param != nativeParameters.end(); param++) {  | ||||
|         paramValid = true; | ||||
|         eParamType type = param->first; | ||||
|         string value = param->second; | ||||
|         switch (type) { | ||||
|             case ptX: | ||||
|             case ptY: | ||||
|             case ptWidth: | ||||
|             case ptHeight: | ||||
|             case ptMenuItemWidth: | ||||
|             case ptFontSize: | ||||
|             case ptFloatWidth: | ||||
|             case ptFloatHeight: | ||||
|             case ptMaxLines: | ||||
|             case ptColumnWidth: | ||||
|             case ptRowHeight: | ||||
|                 SetNumericParameter(type, value); | ||||
|                 break; | ||||
|         } | ||||
|         if (!paramValid) { | ||||
|             paramsValid = false; | ||||
|             esyslog("skindesigner: %s: invalid parameter %d, value %s", GetFuncName().c_str(), type, value.c_str()); | ||||
|         } | ||||
|     } | ||||
|     return paramsValid; | ||||
| }     | ||||
|  | ||||
| void cTemplateFunction::CompleteParameters(void) { | ||||
|     switch (type) { | ||||
|         case ftDrawImage: { | ||||
| @@ -733,8 +763,11 @@ bool cTemplateFunction::SetNumericParameter(eParamType type, string value) { | ||||
|         if (this->type < ftLoop && type == ptY) { | ||||
|             val += containerY; | ||||
|         } | ||||
|         numericParameters.erase(type); | ||||
|         numericDynamicParameters.erase(type); | ||||
|         numericParameters.insert(pair<eParamType, int>(type, val)); | ||||
|     } else { | ||||
|         numericDynamicParameters.erase(type); | ||||
|         numericDynamicParameters.insert(pair<eParamType, string>(type, parsedValue)); | ||||
|     } | ||||
|     return param.Valid(); | ||||
| @@ -844,7 +877,9 @@ bool cTemplateFunction::SetTextTokens(string value) { | ||||
|         //search for conditional token or normal token | ||||
|         size_t tokenStart = value.find_first_of('{'); | ||||
|         size_t conditionStart = value.find_first_of('|'); | ||||
|         size_t printfStart = value.find("{printf("); | ||||
|         if (tokenStart == string::npos && conditionStart == string::npos) { | ||||
|         //find constant strings | ||||
|             if (value.size() > 0) { | ||||
|                 cTextToken token; | ||||
|                 token.type = ttConstString; | ||||
| @@ -855,12 +890,25 @@ bool cTemplateFunction::SetTextTokens(string value) { | ||||
|             continue; | ||||
|         } else if (tokenStart != string::npos && conditionStart == string::npos) { | ||||
|             size_t tokenEnd = value.find_first_of('}'); | ||||
|             ParseTextToken(value, tokenStart, tokenEnd); | ||||
|             if (printfStart != string::npos && printfStart <= tokenStart) { | ||||
|                 //replace printf text token | ||||
|                 ParsePrintfTextToken(value, printfStart, tokenEnd); | ||||
|             } else { | ||||
|                 //replace normal text token | ||||
|                 ParseTextToken(value, tokenStart, tokenEnd); | ||||
|             } | ||||
|         } else if (tokenStart != string::npos && conditionStart != string::npos) { | ||||
|             if (tokenStart < conditionStart) { | ||||
|                 size_t tokenEnd = value.find_first_of('}'); | ||||
|                 ParseTextToken(value, tokenStart, tokenEnd); | ||||
|                 if (printfStart != string::npos && printfStart <= tokenStart) { | ||||
|                     //replace printf text token | ||||
|                     ParsePrintfTextToken(value, printfStart, tokenEnd); | ||||
|                 } else { | ||||
|                     //replace normal text token | ||||
|                     ParseTextToken(value, tokenStart, tokenEnd); | ||||
|                 } | ||||
|             } else { | ||||
|                 //replace conditional text token | ||||
|                 size_t conditionEnd = value.find_first_of('|', conditionStart+1); | ||||
|                 ParseConditionalTextToken(value, conditionStart, conditionEnd); | ||||
|             } | ||||
| @@ -931,6 +979,34 @@ void cTemplateFunction::ParseConditionalTextToken(string &value, size_t start, s | ||||
|  | ||||
| } | ||||
|  | ||||
| void cTemplateFunction::ParsePrintfTextToken(string &value, size_t start, size_t end) { | ||||
|     cTextToken token; | ||||
|     if (start > 0) { | ||||
|         string constString = value.substr(0, start); | ||||
|         value = value.replace(0, start, ""); | ||||
|         token.type = ttConstString; | ||||
|         token.value = constString; | ||||
|         textTokens.push_back(token); | ||||
|     } else { | ||||
|         token.type = ttPrintfToken; | ||||
|         //fetch parameter list from printf | ||||
|         string printfParams = value.substr(start + 8, end - start - 9); | ||||
|         value = value.replace(0, end - start + 1, ""); | ||||
|         splitstring s(printfParams.c_str()); | ||||
|         vector<string> flds = s.split(',', 1); | ||||
|  | ||||
|         int numParams = flds.size(); | ||||
|         if (numParams < 1) | ||||
|             return; | ||||
|         string formatString = trim(flds[0]); | ||||
|         token.value = formatString.substr(1, formatString.size() - 2); | ||||
|         for (int i=1; i < numParams; i++) { | ||||
|             token.parameters.push_back(trim(flds[i])); | ||||
|         } | ||||
|     } | ||||
|     textTokens.push_back(token); | ||||
| } | ||||
|  | ||||
| bool cTemplateFunction::SetScrollMode(string value) { | ||||
|     eScrollMode mode = smNone; | ||||
|     bool ok = true; | ||||
| @@ -1063,6 +1139,45 @@ void cTemplateFunction::ParseStringParameters(void) { | ||||
|                     found = true; | ||||
|                 } | ||||
|             } | ||||
|         } else if ((*it).type == ttPrintfToken) { | ||||
|             cTextToken token = *it; | ||||
|             int paramCount = token.parameters.size(); | ||||
|             string printfResult = ""; | ||||
|             switch (paramCount) { | ||||
|                 case 1: { | ||||
|                     int param1 = ReplaceIntToken(token.parameters[0]); | ||||
|                     printfResult = *cString::sprintf(token.value.c_str(), param1); | ||||
|                     break; } | ||||
|                 case 2: { | ||||
|                     int param1 = ReplaceIntToken(token.parameters[0]); | ||||
|                     int param2 = ReplaceIntToken(token.parameters[1]); | ||||
|                     printfResult = *cString::sprintf(token.value.c_str(), param1, param2); | ||||
|                     break; } | ||||
|                 case 3: { | ||||
|                     int param1 = ReplaceIntToken(token.parameters[0]); | ||||
|                     int param2 = ReplaceIntToken(token.parameters[1]); | ||||
|                     int param3 = ReplaceIntToken(token.parameters[2]); | ||||
|                     printfResult = *cString::sprintf(token.value.c_str(), param1, param2, param3); | ||||
|                     break; } | ||||
|                 case 4: { | ||||
|                     int param1 = ReplaceIntToken(token.parameters[0]); | ||||
|                     int param2 = ReplaceIntToken(token.parameters[1]); | ||||
|                     int param3 = ReplaceIntToken(token.parameters[2]); | ||||
|                     int param4 = ReplaceIntToken(token.parameters[3]); | ||||
|                     printfResult = *cString::sprintf(token.value.c_str(), param1, param2, param3, param4); | ||||
|                     break; } | ||||
|                 case 5: { | ||||
|                     int param1 = ReplaceIntToken(token.parameters[0]); | ||||
|                     int param2 = ReplaceIntToken(token.parameters[1]); | ||||
|                     int param3 = ReplaceIntToken(token.parameters[2]); | ||||
|                     int param4 = ReplaceIntToken(token.parameters[3]); | ||||
|                     int param5 = ReplaceIntToken(token.parameters[4]); | ||||
|                     printfResult = *cString::sprintf(token.value.c_str(), param1, param2, param3, param4, param5); | ||||
|                     break; } | ||||
|                 default: | ||||
|                     break; | ||||
|             } | ||||
|             text << printfResult; | ||||
|         } | ||||
|     } | ||||
|     parsedText = text.str(); | ||||
| @@ -1239,6 +1354,21 @@ int cTemplateFunction::CalculateTextBoxHeight(void) { | ||||
|     return ((textLinesTall+textLinesFull) * fontHeight); | ||||
| } | ||||
|  | ||||
| int cTemplateFunction::ReplaceIntToken(string intTok) { | ||||
|     if (intTokens) { | ||||
|         map<string,int>::iterator hit = intTokens->find(intTok); | ||||
|         if (hit != intTokens->end()) | ||||
|             return hit->second; | ||||
|     } | ||||
|     if (stringTokens) { | ||||
|         map<string,string>::iterator hit = stringTokens->find(intTok); | ||||
|         if (hit != stringTokens->end()) {             | ||||
|             return atoi(hit->second.c_str()); | ||||
|         } | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /******************************************************************* | ||||
| * Helper Functions | ||||
| *******************************************************************/ | ||||
| @@ -1466,6 +1596,8 @@ void cTemplateFunction::Debug(void) { | ||||
|                 tokType = "Token: "; | ||||
|             else if (tokenType == ttConditionalToken) | ||||
|                 tokType = "Conditional Token: "; | ||||
|             else if (tokenType == ttPrintfToken) | ||||
|                 tokType = "PrintF Token: "; | ||||
|             esyslog("skindesigner: %s %d = \"%s\"", tokType.c_str(), i++, (*it).value.c_str()); | ||||
|             if (tokenType == ttConditionalToken) { | ||||
|                 for (vector<cTextToken>::iterator it2 = (*it).subTokens.begin(); it2 != (*it).subTokens.end(); it2++) { | ||||
| @@ -1478,6 +1610,11 @@ void cTemplateFunction::Debug(void) { | ||||
|                     esyslog("skindesigner: %s \"%s\"", tokTypeCond.c_str(), (*it2).value.c_str()); | ||||
|                 } | ||||
|             } | ||||
|             if (tokenType == ttPrintfToken) { | ||||
|                 for (vector<string>::iterator it2 = (*it).parameters.begin(); it2 != (*it).parameters.end(); it2++) { | ||||
|                     esyslog("skindesigner: Printf parameter: %s", (*it2).c_str()); | ||||
|                 }                 | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     if (fontName.size() > 0) { | ||||
|   | ||||
| @@ -143,6 +143,7 @@ protected: | ||||
|     bool SetTextTokens(string value); | ||||
|     void ParseTextToken(string &value, size_t start, size_t end); | ||||
|     void ParseConditionalTextToken(string &value, size_t start, size_t end); | ||||
|     void ParsePrintfTextToken(string &value, size_t start, size_t end); | ||||
|     bool SetScrollMode(string value); | ||||
|     bool SetScrollSpeed(string value); | ||||
|     bool SetOrientation(string value); | ||||
| @@ -152,6 +153,7 @@ protected: | ||||
|     void ParseNumericalParameters(void); | ||||
|     void CalculateAlign(int elementWidth, int elementHeight); | ||||
|     int CalculateTextBoxHeight(void); | ||||
|     int ReplaceIntToken(string intTok); | ||||
| public: | ||||
|     cTemplateFunction(eFuncType type); | ||||
|     virtual ~cTemplateFunction(void); | ||||
| @@ -170,6 +172,8 @@ public: | ||||
|     void SetTranslatedText(string translation); | ||||
|     //PreCache Parameters  | ||||
|     bool CalculateParameters(void); | ||||
|     //Complete Parameters  | ||||
|     bool ReCalculateParameters(void); | ||||
|     void CompleteParameters(void); | ||||
|     //Set and Unset Dynamic Tokens from view | ||||
|     void SetStringTokens(map < string, string > *tok) { stringTokens = tok; }; | ||||
|   | ||||
| @@ -78,11 +78,12 @@ void cTemplatePixmap::ParseDynamicParameters(map <string,int> *intTokens, bool i | ||||
|  | ||||
|     for (vector<cTemplateFunction*>::iterator func = functions.begin(); func != functions.end(); func++) { | ||||
|         (*func)->SetContainer(x, y, width, height); | ||||
|         (*func)->CalculateParameters(); | ||||
|         (*func)->ReCalculateParameters(); | ||||
|         (*func)->CompleteParameters(); | ||||
|         if ((*func)->GetType() == ftLoop) { | ||||
|             cTemplateLoopFunction *loopFunc = dynamic_cast<cTemplateLoopFunction*>(*func); | ||||
|             if (!loopFunc->Ready()) { | ||||
|                 loopFunc->CalculateParameters(); | ||||
|                 loopFunc->SetIntTokens(intTokens); | ||||
|                 loopFunc->ParseParameters(); | ||||
|                 loopFunc->UnsetIntTokens(); | ||||
| @@ -137,8 +138,6 @@ bool cTemplatePixmap::CalculateParameters(void) { | ||||
|  | ||||
|     for (vector<cTemplateFunction*>::iterator func = functions.begin(); func != functions.end(); func++) { | ||||
|         (*func)->SetGlobals(globals); | ||||
|         if (!Ready()) | ||||
|             continue; | ||||
|         (*func)->SetContainer(0, 0, pixWidth, pixHeight); | ||||
|         paramsValid = (*func)->CalculateParameters(); | ||||
|         (*func)->CompleteParameters(); | ||||
|   | ||||
| @@ -362,6 +362,7 @@ void cTemplateView::PreCache(bool isSubview) { | ||||
|         pixOffset += viewElement->GetNumPixmaps(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     //Cache ViewLists | ||||
|     for (map < eViewList, cTemplateViewList* >::iterator it = viewLists.begin(); it != viewLists.end(); it++) { | ||||
|         cTemplateViewList *viewList = it->second; | ||||
| @@ -613,7 +614,6 @@ void cTemplateViewChannel::SetViewElements(void) { | ||||
|     viewElementsAllowed.insert("signalquality"); | ||||
|     viewElementsAllowed.insert("signalqualityback"); | ||||
|     viewElementsAllowed.insert("devices"); | ||||
|     viewElementsAllowed.insert("bitrate"); | ||||
|     viewElementsAllowed.insert("scrapercontent"); | ||||
|     viewElementsAllowed.insert("datetime"); | ||||
|     viewElementsAllowed.insert("message"); | ||||
| @@ -656,9 +656,6 @@ string cTemplateViewChannel::GetViewElementName(eViewElement ve) { | ||||
|         case veSignalQualityBack: | ||||
|             name = "Signal Quality Background"; | ||||
|             break; | ||||
|         case veBitRate: | ||||
|             name = "Bit Rate"; | ||||
|             break; | ||||
|         case veDevices: | ||||
|             name = "Devices"; | ||||
|             break; | ||||
| @@ -706,8 +703,6 @@ void cTemplateViewChannel::AddPixmap(string sViewElement, cTemplatePixmap *pix, | ||||
|         ve = veSignalQuality; | ||||
|     } else if (!sViewElement.compare("signalqualityback")) { | ||||
|         ve = veSignalQualityBack; | ||||
|     } else if (!sViewElement.compare("bitrate")) { | ||||
|         ve = veBitRate; | ||||
|     } else if (!sViewElement.compare("devices")) { | ||||
|         ve = veDevices; | ||||
|     } else if (!sViewElement.compare("scrapercontent")) { | ||||
|   | ||||
| @@ -37,7 +37,6 @@ enum eViewElement { | ||||
|     veScreenResolution, | ||||
|     veSignalQuality, | ||||
|     veSignalQualityBack, | ||||
|     veBitRate, | ||||
|     veScraperContent, | ||||
|     //DisplayMenu ViewElements | ||||
|     veHeader, | ||||
|   | ||||
| @@ -164,9 +164,8 @@ | ||||
|     {signalquality}                     SNR value of currently displayed channel | ||||
|     --> | ||||
|     <signalquality> | ||||
|         <area x="22%" y="94%" width="10%" height="6%" layer="3"> | ||||
|             <drawtext x="0" y="0" font="{light}" fontsize="50%" color="{clrWhite}" text="STR: {signalstrength}%" /> | ||||
|             <drawtext x="0" y="50%" font="{light}" fontsize="50%" color="{clrWhite}" text="SNR: {signalquality}%" /> | ||||
|         <area x="22%" y="94%" width="76%" height="6%" layer="3"> | ||||
|             <drawtext x="0" valign="center" font="{light}" fontsize="70%" color="{clrWhite}" text="STR: {signalstrength}% SNR: {signalquality}%" /> | ||||
|         </area> | ||||
|     </signalquality> | ||||
|  | ||||
| @@ -209,19 +208,6 @@ | ||||
|         </area> | ||||
|     </devices> | ||||
|  | ||||
|     <!-- Available Variables scrapercontent: | ||||
|     {bitratevideo}            bitrate of currently displayed video track in MBit/s (with two decimal places) | ||||
|     {bitrateaudio}            bitrate of currently displayed stereo audio track in KBit/s | ||||
|     {bitratedolby}            bitrate of currently displayed ac3 audio track in KBit/s | ||||
|     {isdolby}                 true if bitrate of ac3 stream is > 0 | ||||
|     --> | ||||
|     <bitrate> | ||||
|         <area x="32%" y="94%" width="15%" height="6%" layer="3"> | ||||
|             <drawtext x="0" y="0" font="{light}" fontsize="50%" color="{clrWhite}" text="Video: {bitratevideo} MBit/s" /> | ||||
|             <drawtext condition="not{isdolby}" x="0" y="50%" font="{light}" fontsize="50%" color="{clrWhite}" text="Stereo: {bitrateaudio} KBit/s" /> | ||||
|             <drawtext condition="{isdolby}" x="0" y="50%" font="{light}" fontsize="50%" color="{clrWhite}" text="AC3: {bitratedolby} KBit/s" /> | ||||
|         </area> | ||||
|     </bitrate> | ||||
|     <!-- Available Variables scrapercontent: | ||||
|     {mediapath}                         Full Path of Poster or Banner to use in image path attribute | ||||
|     {mediawidth}                        width of image in pixel | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
|         <!-- Available Variables recordings menu listelement: | ||||
|         {nummenuitem}           number of item in list, starts with 1 | ||||
|         {name}                  Name of recording | ||||
|         {date}                  Date of recording | ||||
|         {date}                  Date of recording (day dd.mm.yyyy) | ||||
|         {time}                  Time of recording | ||||
|         {daynumeric}            day as number | ||||
|         {month}                 month as number | ||||
| @@ -39,7 +39,7 @@ | ||||
|             </area> | ||||
|             <!-- recording item --> | ||||
|             <area condition="not{folder}" x="1%" width="58%" layer="2"> | ||||
|                 <drawtext x="10" valign="center" font="{light}" fontsize="85%" color="{clrWhite}" text="{date} {time}" /> | ||||
|                 <drawtext x="10" valign="center" font="{light}" fontsize="85%" color="{clrWhite}" text="{printf('%02d.%02d.%d', daynumeric, month, year)} {time}" /> | ||||
|                 <drawtext x="35%" width="60%" valign="center" font="{light}" fontsize="85%" color="{clrWhite}" text="{name}" /> | ||||
|                 <drawimage condition="{new}" name="new" imagetype="icon" path="ico_recnew" x="{areawidth} - {areaheight}" width="0.9*{areaheight}" height="0.9*{areaheight}" valign="center" /> | ||||
|                 <drawimage condition="{new}++{cutted}" imagetype="icon" path="ico_cutted" x="{areawidth} - 2*{areaheight}" width="0.9*{areaheight}" height="0.9*{areaheight}" valign="center" /> | ||||
|   | ||||
| @@ -40,8 +40,9 @@ | ||||
|         {durationminutes}         duration, rest of minutes | ||||
|         {current}                 true if item is currently selected  | ||||
|         {separator}               true if item is a list separator  | ||||
|         {channelname}             Channel Name (for what's on now and next) | ||||
|         {channelid}               ChannelID as path to display channel logo (for what's on now and next) | ||||
|         {channelname}             Channel Name | ||||
|         {channelid}               ChannelID as path to display channel logo | ||||
|         {channellogoexists}       true if a channel logo exists  | ||||
|         {whatson}                 true if menu "What's on" is displayed | ||||
|         {whatsonnow}              true if menu "What's on now" is displayed | ||||
|         {whatsonnext}             true if menu "What's on next" is displayed | ||||
| @@ -124,7 +125,9 @@ | ||||
|         {duration}                duration of event | ||||
|         {durationhours}           duration, full hours | ||||
|         {durationminutes}         duration, rest of minutes | ||||
|         {channelname}             Channel Name | ||||
|         {channelid}               ChannelID as path to display channel logo | ||||
|         {channellogoexists}       true if a channel logo exists  | ||||
|         {hasposter}               true if a scraped poster is available for this element | ||||
|         {posterwidth}             width of scraped poster | ||||
|         {posterheight}            height of scraped poster | ||||
|   | ||||
| @@ -80,7 +80,7 @@ | ||||
|             <area x="32%" y="2%" width="67%" height="96%" layer="2"> | ||||
|                 <fill color="{clrTransBlack}" /> | ||||
|             </area> | ||||
|             <area x="32%" y="2%" width="67%" height="96%" layer="2"> | ||||
|             <area condition="{flagactive}" x="32%" y="2%" width="67%" height="96%" layer="2"> | ||||
|                 <!-- title --> | ||||
|                 <drawtext name="title" align="center" y="0" font="{vdrOsd}" width="{areawidth}-20" fontsize="8%" color="{clrWhite}" text="{eventtitle} - {eventshorttext}" /> | ||||
|                 <!-- start and stop if event is not running --> | ||||
| @@ -91,6 +91,10 @@ | ||||
|                 <drawtextbox condition="{hasposter}" x="10" y="{posy(poster)}" width="99%" height="{areaheight} - {posy(poster)}" float="topright" floatwidth="{width(poster)} + 10" floatheight="{height(poster)} + 20" font="{vdrOsd}" fontsize="5%" color="{clrWhite}" text="{eventdescription}" /> | ||||
|                 <drawtextbox condition="not{hasposter}" x="10" y="{posy(poster)}" width="99%" height="{areaheight} - {posy(poster)}" font="{vdrOsd}" fontsize="5%" color="{clrWhite}" text="{eventdescription}" /> | ||||
|             </area> | ||||
|             <area condition="not{flagactive}" x="32%" y="2%" width="67%" height="96%" layer="2"> | ||||
|                 <drawtext x="10" y="0" font="{vdrOsd}" fontsize="8%" color="{clrWhite}" text="{channelname}" /> | ||||
|                 <drawtext x="10" y="10%" font="{vdrOsd}" fontsize="6%" color="{clrWhite}" text="{timerstart} - {timerstop}" /> | ||||
|             </area> | ||||
|         </currentelement> | ||||
|          | ||||
|     </menuitems> | ||||
|   | ||||
| @@ -125,15 +125,6 @@ | ||||
|     <devices> | ||||
|     </devices> | ||||
|  | ||||
|     <!-- Available Variables scrapercontent: | ||||
|     {bitratevideo}            bitrate of currently displayed video track in MBit/s (with two decimal places) | ||||
|     {bitrateaudio}            bitrate of currently displayed stereo audio track in KBit/s | ||||
|     {bitratedolby}            bitrate of currently displayed ac3 audio track in KBit/s | ||||
|     {isdolby}                 true if bitrate of ac3 stream is > 0 | ||||
|     --> | ||||
|     <bitrate> | ||||
|     </bitrate> | ||||
|      | ||||
|     <!-- Available Variables scrapercontent: | ||||
|     {mediapath}                         Full Path of Poster or Banner to use in image path attribute | ||||
|     {mediawidth}                        width of image in pixel | ||||
|   | ||||
| @@ -34,8 +34,9 @@ | ||||
|         {durationminutes}         duration, rest of minutes | ||||
|         {current}                 true if item is currently selected  | ||||
|         {separator}               true if item is a list separator  | ||||
|         {channelname}             Channel Name (for what's on now and next) | ||||
|         {channelid}               ChannelID as path to display channel logo (for what's on now and next) | ||||
|         {channelname}             Channel Name | ||||
|         {channelid}               ChannelID as path to display channel logo | ||||
|         {channellogoexists}       true if a channel logo exists  | ||||
|         {whatson}                 true if menu "What's on" is displayed | ||||
|         {whatsonnow}              true if menu "What's on now" is displayed | ||||
|         {whatsonnext}             true if menu "What's on next" is displayed | ||||
| @@ -65,7 +66,9 @@ | ||||
|         {duration}                duration of event | ||||
|         {durationhours}           duration, full hours | ||||
|         {durationminutes}         duration, rest of minutes | ||||
|         {channelname}             Channel Name | ||||
|         {channelid}               ChannelID as path to display channel logo | ||||
|         {channellogoexists}       true if a channel logo exists  | ||||
|         {hasposter}               true if a scraped poster is available for this element | ||||
|         {posterwidth}             width of scraped poster | ||||
|         {posterheight}            height of scraped poster | ||||
|   | ||||
| @@ -17,7 +17,6 @@ cDisplayChannelView::cDisplayChannelView(cTemplateView *tmplView) : cView(tmplVi | ||||
|     lastTracDesc = ""; | ||||
|     lastTrackLang = ""; | ||||
|     InitDevices(); | ||||
|     InitFemonReceiver(); | ||||
|     DeleteOsdOnExit(); | ||||
|     SetFadeTime(tmplView->GetNumericParameter(ptFadeTime)); | ||||
| } | ||||
| @@ -424,33 +423,6 @@ void cDisplayChannelView::ClearDevices(void) { | ||||
|     ClearViewElement(veDevices); | ||||
| } | ||||
|  | ||||
| void cDisplayChannelView::DrawBitrates(void) { | ||||
|     if (!ViewElementImplemented(veBitRate)) { | ||||
|         return; | ||||
|     } | ||||
|     double bitrateVideo; | ||||
|     double bitrateAudio; | ||||
|     double bitrateDolby; | ||||
|  | ||||
|     bool changed = GetBitrates(bitrateVideo, bitrateAudio, bitrateDolby); | ||||
|     if (!changed) { | ||||
|         return; | ||||
|     } | ||||
|     map < string, string > stringTokens; | ||||
|     map < string, int > intTokens; | ||||
|     stringTokens.insert(pair<string,string>("bitratevideo", *cString::sprintf("%.2f", bitrateVideo))); | ||||
|     intTokens.insert(pair<string,int>("bitrateaudio", bitrateAudio)); | ||||
|     intTokens.insert(pair<string,int>("bitratedolby", bitrateDolby)); | ||||
|     intTokens.insert(pair<string,int>("isdolby", (bitrateDolby > 0) ? true : false)); | ||||
|  | ||||
|     ClearBitrates(); | ||||
|     DrawViewElement(veBitRate, &stringTokens, &intTokens); | ||||
| } | ||||
|  | ||||
| void cDisplayChannelView::ClearBitrates(void) { | ||||
|     ClearViewElement(veBitRate); | ||||
| } | ||||
|  | ||||
| void cDisplayChannelView::DrawChannelGroups(const cChannel *Channel, cString ChannelName) { | ||||
|     if (!ViewElementImplemented(veChannelGroup)) { | ||||
|         return; | ||||
|   | ||||
| @@ -47,8 +47,6 @@ public: | ||||
|     void ClearSignalBackground(void); | ||||
|     void DrawDevices(bool initial); | ||||
|     void ClearDevices(void); | ||||
|     void DrawBitrates(void); | ||||
|     void ClearBitrates(void); | ||||
|     void DrawChannelGroups(const cChannel *Channel, cString ChannelName); | ||||
|     void ClearChannelGroups(void); | ||||
|     void DisplayMessage(eMessageType Type, const char *Text); | ||||
|   | ||||
| @@ -165,7 +165,10 @@ void cDisplayMenuItemCurrentSchedulesView::Render(void) { | ||||
|         SetScraperPoster(event); | ||||
|     } | ||||
|     if (channel) { | ||||
|         stringTokens.insert(pair<string,string>("channelid", *(channel->GetChannelID().ToString()))); | ||||
|         stringTokens.insert(pair<string,string>("channelname", channel->Name() ? channel->Name() : "")); | ||||
|         string channelID = *(channel->GetChannelID().ToString()); | ||||
|         stringTokens.insert(pair<string,string>("channelid", channelID)); | ||||
|         intTokens.insert(pair<string, int>("channellogoexists", imgCache->LogoExists(channelID))); | ||||
|     } | ||||
|  | ||||
|     vector< map<string,string> > schedulesTokens; | ||||
| @@ -454,7 +457,7 @@ void cDisplayMenuItemCurrentTimerView::Render(void) { | ||||
|         SetScraperPoster(event); | ||||
|     } else { | ||||
|         stringTokens.insert(pair<string,string>("eventtitle", "")); | ||||
|         stringTokens.insert(pair<string,string>("eventtitle", "")); | ||||
|         stringTokens.insert(pair<string,string>("eventstart", "")); | ||||
|         stringTokens.insert(pair<string,string>("eventstop", "")); | ||||
|         stringTokens.insert(pair<string,string>("eventshorttext", "")); | ||||
|         stringTokens.insert(pair<string,string>("eventdescription", "")); | ||||
|   | ||||
| @@ -333,13 +333,16 @@ void cDisplayMenuItemSchedulesView::SetTokens(void) { | ||||
|     } | ||||
|     if (channel) { | ||||
|         stringTokens.insert(pair<string,string>("channelname", channel->Name() ? channel->Name() : "")); | ||||
|         stringTokens.insert(pair<string,string>("channelid", *(channel->GetChannelID().ToString()))); | ||||
|         string channelID = *(channel->GetChannelID().ToString()); | ||||
|         stringTokens.insert(pair<string,string>("channelid", channelID)); | ||||
|         intTokens.insert(pair<string, int>("channellogoexists", imgCache->LogoExists(channelID))); | ||||
|         if (!event && !selectable) { | ||||
|             stringTokens.insert(pair<string,string>("title", channel->Name() ? ParseSeparator(channel->Name()) : "")); | ||||
|         } | ||||
|     } else { | ||||
|         stringTokens.insert(pair<string,string>("channelname", "")); | ||||
|         stringTokens.insert(pair<string,string>("channelid", "")); | ||||
|         intTokens.insert(pair<string, int>("channellogoexists", 0)); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -95,6 +95,8 @@ void cDisplayMenuListView::Clear(void) { | ||||
| } | ||||
|  | ||||
| void cDisplayMenuListView::AddDefaultMenuItem(int index, string *tabTexts, bool current, bool selectable) { | ||||
|     if (index >= itemCount) | ||||
|         return; | ||||
|     if (menuItems[index]) { | ||||
|         cDisplayMenuItemDefaultView *menuItem = dynamic_cast<cDisplayMenuItemDefaultView*>(menuItems[index]); | ||||
|         if (!menuItem) | ||||
| @@ -114,6 +116,8 @@ void cDisplayMenuListView::AddDefaultMenuItem(int index, string *tabTexts, bool | ||||
| } | ||||
|  | ||||
| void cDisplayMenuListView::AddMainMenuItem(int index, const char *itemText, bool current, bool selectable) { | ||||
|     if (index >= itemCount) | ||||
|         return; | ||||
|     if (menuItems[index]) { | ||||
|         menuItems[index]->SetCurrent(current); | ||||
|         return; | ||||
| @@ -123,6 +127,8 @@ void cDisplayMenuListView::AddMainMenuItem(int index, const char *itemText, bool | ||||
| } | ||||
|  | ||||
| void cDisplayMenuListView::AddSetupMenuItem(int index, const char *itemText, bool current, bool selectable) { | ||||
|     if (index >= itemCount) | ||||
|         return; | ||||
|     if (menuItems[index]) { | ||||
|         menuItems[index]->SetCurrent(current); | ||||
|         return; | ||||
| @@ -133,6 +139,8 @@ void cDisplayMenuListView::AddSetupMenuItem(int index, const char *itemText, boo | ||||
|  | ||||
| void cDisplayMenuListView::AddSchedulesMenuItem(int index, const cEvent *event, const cChannel *channel, eTimerMatch timerMatch,  | ||||
|                                                 eMenuCategory cat, bool current, bool selectable) { | ||||
|     if (index >= itemCount) | ||||
|         return; | ||||
|     if (menuItems[index]) { | ||||
|         menuItems[index]->SetCurrent(current); | ||||
|         return; | ||||
| @@ -142,6 +150,8 @@ void cDisplayMenuListView::AddSchedulesMenuItem(int index, const cEvent *event, | ||||
| } | ||||
|  | ||||
| void cDisplayMenuListView::AddChannelsMenuItem(int index, const cChannel *channel, bool withProvider, bool current, bool selectable) { | ||||
|     if (index >= itemCount) | ||||
|         return; | ||||
|     if (menuItems[index]) { | ||||
|         menuItems[index]->SetCurrent(current); | ||||
|         return; | ||||
| @@ -151,6 +161,8 @@ void cDisplayMenuListView::AddChannelsMenuItem(int index, const cChannel *channe | ||||
| } | ||||
|  | ||||
| void cDisplayMenuListView::AddTimersMenuItem(int index, const cTimer *timer, bool current, bool selectable) { | ||||
|     if (index >= itemCount) | ||||
|         return; | ||||
|     if (menuItems[index]) { | ||||
|         menuItems[index]->SetCurrent(current); | ||||
|         return; | ||||
| @@ -160,6 +172,8 @@ void cDisplayMenuListView::AddTimersMenuItem(int index, const cTimer *timer, boo | ||||
| } | ||||
|  | ||||
| void cDisplayMenuListView::AddRecordingMenuItem(int index, const cRecording *recording, int level, int total, int isNew, bool current, bool selectable) { | ||||
|     if (index >= itemCount) | ||||
|         return; | ||||
|     if (menuItems[index]) { | ||||
|         menuItems[index]->SetCurrent(current); | ||||
|         return; | ||||
| @@ -169,6 +183,8 @@ void cDisplayMenuListView::AddRecordingMenuItem(int index, const cRecording *rec | ||||
| } | ||||
|  | ||||
| void cDisplayMenuListView::AddTracksMenuItem(int index, const char *title, bool current, bool selectable) { | ||||
|     if (index >= itemCount) | ||||
|         return; | ||||
|     if (menuItems[index]) { | ||||
|         menuItems[index]->SetCurrent(current); | ||||
|         return; | ||||
|   | ||||
| @@ -36,6 +36,7 @@ public: | ||||
|     void SetMenu(eMenuCategory menuCat, bool menuInit); | ||||
|     void SetTitle(const char *title); | ||||
|     void SetChannel(const cChannel *channel) { view->SetChannel(channel); }; | ||||
|     const cChannel *GetChannel(void) { return view->GetChannel(); }; | ||||
|     void SetButtonTexts(const char *Red, const char *Green, const char *Yellow, const char *Blue); | ||||
|     void SetTabs(int tab1, int tab2, int tab3, int tab4, int tab5); | ||||
|     void SetMessage(eMessageType type, const char *text); | ||||
|   | ||||
| @@ -432,8 +432,9 @@ bool cDisplayMenuSchedulesView::DrawHeader(void) { | ||||
|     if (channel) { | ||||
|         stringTokens.insert(pair<string,string>("channelnumber", *cString::sprintf("%d", channel->Number()))); | ||||
|         stringTokens.insert(pair<string,string>("channelname", channel->Name())); | ||||
|         stringTokens.insert(pair<string,string>("channelid", *(channel->GetChannelID().ToString()))); | ||||
|          | ||||
|         string channelID = *(channel->GetChannelID().ToString()); | ||||
|         stringTokens.insert(pair<string,string>("channelid", channelID)); | ||||
|         intTokens.insert(pair<string, int>("channellogoexists", imgCache->LogoExists(channelID))); | ||||
|     } | ||||
|     bool hasIcon = false; | ||||
|     string icon = imgCache->GetIconName(menuTitle, cat); | ||||
|   | ||||
| @@ -17,6 +17,7 @@ public: | ||||
|     void SetMenuCat(eMenuCategory newCat) { cat = newCat; }; | ||||
|     void SetTitle(const char *title) {menuTitle = title; }; | ||||
|     virtual void SetChannel(const cChannel *channel) {}; | ||||
|     virtual const cChannel *GetChannel(void) { return NULL; }; | ||||
|     void SetButtonTexts(string *buttonTexts) { this->buttonTexts = buttonTexts; }; | ||||
|     bool DrawBackground(void); | ||||
|     virtual bool DrawHeader(void); | ||||
| @@ -51,6 +52,7 @@ public: | ||||
|     cDisplayMenuSchedulesView(cTemplateView *tmplView, eMenuCategory menuCat, bool menuInit); | ||||
|     virtual ~cDisplayMenuSchedulesView(); | ||||
|     void SetChannel(const cChannel *channel) { this->channel = channel; }; | ||||
|     const cChannel *GetChannel(void) { return channel; }; | ||||
|     bool DrawHeader(void); | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -4,8 +4,6 @@ | ||||
|  | ||||
| cViewHelpers::cViewHelpers(void) { | ||||
|     devicesInit = false; | ||||
|     femonReceiver = NULL; | ||||
|     bitrateVideoLast = bitrateAudioLast = bitrateDolbyLast = 0.0; | ||||
| } | ||||
|  | ||||
| cViewHelpers::~cViewHelpers() { | ||||
| @@ -14,10 +12,6 @@ cViewHelpers::~cViewHelpers() { | ||||
|         delete[] lastSignalQuality; | ||||
|         delete[] recDevices; | ||||
|     } | ||||
|      if (femonReceiver) { | ||||
|         femonReceiver->Deactivate(); | ||||
|         delete femonReceiver; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void cViewHelpers::InitDevices(void) { | ||||
| @@ -138,69 +132,3 @@ bool cViewHelpers::SetDevices(bool initial, map<string,int> *intTokens, vector<m | ||||
|      | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| void cViewHelpers::InitFemonReceiver(void) { | ||||
|     const cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); | ||||
|     eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); | ||||
|     if (channel) { | ||||
|         femonReceiver = new cFemonReceiver(channel,  | ||||
|                                            IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0,  | ||||
|                                            IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0); | ||||
|         cDevice::ActualDevice()->AttachReceiver(femonReceiver); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void cViewHelpers::ChannelSwitch(const cDevice * device, int channelNumber, bool liveView) { | ||||
|     if (!femonReceiver) | ||||
|         return; | ||||
|     bitrateVideoLast = bitrateAudioLast = bitrateDolbyLast = 0.0; | ||||
|     eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); | ||||
|     const cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); | ||||
|  | ||||
|     if (!liveView || !channelNumber || !channel || channel->Number() != channelNumber) | ||||
|         return; | ||||
|  | ||||
|     if (femonReceiver) { | ||||
|         femonReceiver->Deactivate(); | ||||
|         delete femonReceiver; | ||||
|         femonReceiver = NULL; | ||||
|     } | ||||
|     if (channel) { | ||||
|         femonReceiver = new cFemonReceiver(channel,  | ||||
|                                            IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0,  | ||||
|                                            IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0); | ||||
|         cDevice::ActualDevice()->AttachReceiver(femonReceiver); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void cViewHelpers::SetAudioTrack(int Index, const char * const *Tracks) { | ||||
|     if (!femonReceiver) | ||||
|         return; | ||||
|     bitrateVideoLast = bitrateAudioLast = bitrateDolbyLast = 0.0; | ||||
|     eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); | ||||
|     if (femonReceiver) { | ||||
|         femonReceiver->Deactivate(); | ||||
|         delete femonReceiver; | ||||
|         femonReceiver = NULL; | ||||
|     } | ||||
|     const cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); | ||||
|     if (channel) { | ||||
|         femonReceiver = new cFemonReceiver(channel,  | ||||
|                                            IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0,  | ||||
|                                            IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0); | ||||
|         cDevice::ActualDevice()->AttachReceiver(femonReceiver); | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool cViewHelpers::GetBitrates(double &bitrateVideo, double &bitrateAudio, double &bitrateDolby) { | ||||
|     bitrateVideo = (int)(femonReceiver->VideoBitrate() / 1024 / 1024 * 100 + 0.5) / 100.0; | ||||
|     bitrateAudio = (int)(femonReceiver->AudioBitrate() / 1024 * 100 + 0.5) / 100.0; | ||||
|     bitrateDolby = (int)(femonReceiver->AC3Bitrate() / 1024 * 100 + 0.5) / 100.0; | ||||
|     if (bitrateVideo != bitrateVideoLast || bitrateAudio != bitrateAudioLast || bitrateDolby != bitrateDolbyLast) { | ||||
|         bitrateVideoLast = bitrateVideo; | ||||
|         bitrateAudioLast = bitrateAudio; | ||||
|         bitrateDolbyLast = bitrateDolby; | ||||
|         return true; | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
|   | ||||
| @@ -1,26 +1,15 @@ | ||||
| #ifndef __VIEWHELPERS_H | ||||
| #define __VIEWHELPERS_H | ||||
|  | ||||
| #include <vdr/status.h> | ||||
| #include "../libcore/femonreceiver.h" | ||||
|  | ||||
| class cViewHelpers : public cStatus { | ||||
| class cViewHelpers { | ||||
| private: | ||||
|     bool devicesInit; | ||||
|     int* lastSignalStrength; | ||||
|     int* lastSignalQuality; | ||||
|     bool* recDevices; | ||||
|     cFemonReceiver *femonReceiver; | ||||
|     double bitrateVideoLast; | ||||
|     double bitrateAudioLast; | ||||
|     double bitrateDolbyLast; | ||||
| protected: | ||||
|     virtual void ChannelSwitch(const cDevice *device, int channelNumber, bool liveView); | ||||
|     virtual void SetAudioTrack(int Index, const char * const *Tracks); | ||||
|     void InitDevices(void); | ||||
|     bool SetDevices(bool initial, map<string,int> *intTokens, vector<map<string,string> > *devices); | ||||
|     void InitFemonReceiver(void); | ||||
|     bool GetBitrates(double &bitrateVideo, double &bitrateAudio, double &bitrateDolby); | ||||
| public: | ||||
|     cViewHelpers(void); | ||||
|     virtual ~cViewHelpers(void); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user