diff options
author | mrwastl <mrwastl@users.sourceforge.net> | 2011-09-17 21:28:10 +0200 |
---|---|---|
committer | mrwastl <mrwastl@users.sourceforge.net> | 2011-09-17 21:28:10 +0200 |
commit | 0703b948dd63eb281df5dc531abdf66818becdf7 (patch) | |
tree | b76b3ba4634a95ed71c0dd2ab1e1a4354109870d | |
parent | 9e0f177243221e2123758d196315cb63d0f8902b (diff) | |
download | vdr-plugin-graphlcd-0703b948dd63eb281df5dc531abdf66818becdf7.tar.gz vdr-plugin-graphlcd-0703b948dd63eb281df5dc531abdf66818becdf7.tar.bz2 |
cExtData is now a singleton class, thus its content survives a DISCONN/CONNECT of a display; trans() now works as expected; three new tokens: 'IsMenuList', 'MenuText', 'MenuTextScroll'; support added for ':clean' and ':rest' for tokens 'MenuTitle', 'MenuCurrent', and 'MenuText'
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | common.c | 61 | ||||
-rw-r--r-- | common.h | 6 | ||||
-rw-r--r-- | display.c | 51 | ||||
-rw-r--r-- | display.h | 21 | ||||
-rw-r--r-- | extdata.c | 88 | ||||
-rw-r--r-- | extdata.h | 46 | ||||
-rw-r--r-- | plugin.c | 13 | ||||
-rw-r--r-- | skinconfig.c | 34 | ||||
-rw-r--r-- | state.c | 18 | ||||
-rw-r--r-- | state.h | 3 |
11 files changed, 261 insertions, 82 deletions
@@ -78,7 +78,7 @@ endif ### The object files (add further files here): #OBJS = alias.o common.o display.o i18n.o menu.o plugin.o setup.o skinconfig.o state.o strfct.o -OBJS = alias.o common.o display.o menu.o plugin.o setup.o skinconfig.o state.o strfct.o service.o +OBJS = alias.o common.o display.o menu.o plugin.o setup.o skinconfig.o state.o strfct.o service.o extdata.o ### The main target: TARGETS = libvdr-$(PLUGIN).so @@ -1,10 +1,13 @@ #include <time.h> #include <glcdskin/type.h> +#include <glcdskin/string.h> #include <vdr/plugin.h> #include <string.h> +#include "strfct.h" + #if APIVERSNUM < 10503 #include <locale.h> @@ -157,3 +160,61 @@ int ParanoiaStrcmp(const char *s1, const char *s2) else return rv; } + +const std::string SplitText(const std::string &Text, const std::string &Delim, bool firstPart = true) { + size_t found = Text.find(Delim); + + if (found != std::string::npos) { + return (firstPart) ? Text.substr(0, found) : Text.substr(found + Delim.size()); + } + return (firstPart) ? Text : NULL; +} + +const std::string SplitToken(const std::string &Token, const struct GLCD::tSkinAttrib Attrib, bool extSplit) { + if (Attrib.Type == GLCD::aClean) { + if (extSplit) { + std::string Text = SplitText(Token, " - ", true); + + // also cut leading index numbers, eg: "1 Menu" -> "Menu" + size_t pos = 0; + bool exitw = false; + bool valid = true; + + while (!exitw && valid && pos < Text.size()-1) { + if (Text[pos] == ' ') { + pos++; + } else { + valid = (isdigit(Text[pos]) || Text[pos] == ' ' || Text[pos] == '\t') ? true : false; + exitw = true; + } + } + + exitw = false; + while (!exitw && valid && pos < Text.size()-1) { + if (isdigit(Text[pos])) { + pos++; + } else { + valid = (Text[pos] == ' ' || Text[pos] == '\t') ? true : false; + exitw = true; + } + } + + exitw = false; + while (!exitw && valid && pos < Text.size()-1) { + if (Text[pos] == ' ') { + pos++; + } else { + exitw = true; + } + } + + if (valid && Text[pos] == '\t') + pos++; + return trim( (valid) ? Text.substr(pos) : Text ); + } + return SplitText(Token, " - ", true); + } else if (Attrib.Type == GLCD::aRest) { + return SplitText(Token, " - ", false); + } + return Token; +} @@ -1,3 +1,9 @@ + +#include <glcdskin/string.h> + + GLCD::cType TimeType(time_t Time, const std::string &Format); GLCD::cType DurationType(int Index, const std::string &Format); int ParanoiaStrcmp(const char *s1, const char *s2); +const std::string SplitText(const std::string &Text, const std::string &Delim, bool firstPart = true); +const std::string SplitToken(const std::string &Token, const struct GLCD::tSkinAttrib Attrib, bool extSplit = false); @@ -56,8 +56,6 @@ cGraphLCDDisplay::cGraphLCDDisplay() bBrightnessActive = true; mService = NULL; /* cannot be initialised here (mGraphLCDState not yet available) */ - - mExtData = new cExtData(); } cGraphLCDDisplay::~cGraphLCDDisplay() @@ -70,8 +68,6 @@ cGraphLCDDisplay::~cGraphLCDDisplay() delete mGraphLCDState; delete mService; - - delete mExtData; } bool cGraphLCDDisplay::Initialise(GLCD::cDriver * Lcd, const std::string & CfgPath, const std::string & SkinsPath, const std::string & SkinName) @@ -502,50 +498,3 @@ void cGraphLCDDisplay::Clear() { #endif mLcd->Refresh(false); } - - - -bool cExtData::Set(std::string key, std::string value, uint32_t expire) { - data[key] = value; - - if (expire > 0) { - expData[key] = cTimeMs::Now() + (expire * 1000); - } else { - expData.erase(key); // just in case of an old expiration entry for key - } - return true; -} - - -bool cExtData::Unset(std::string key) { - expData.erase(key); // ignore result; - return ( (data.erase(key) > 0) ? true : false ); -} - - -bool cExtData::IsSet(std::string key) { - std::string ret = Get(key); - return ( (ret != "") ? true : false ); -} - - -std::string cExtData::Get(std::string key) { - it = data.find(key); - if ( it != data.end() ) { - expDataIt = expData.find(key); - if ( expDataIt != expData.end() ) { - uint64_t expts = (*expDataIt).second; - if ( cTimeMs::Now() > expts ) { - expData.erase(key); - data.erase(key); - return ""; - } else { - return (*it).second; - } - } else { - return (*it).second; - } - } else { - return ""; - } -} @@ -48,25 +48,6 @@ enum eDisplayMode DisplayModeInteractive }; -// external data set via SVDRP -class cExtData -{ -private: - std::map<std::string,std::string> data; - std::map<std::string,std::string>::iterator it; - std::map<std::string,uint64_t> expData; - std::map<std::string,uint64_t>::iterator expDataIt; -public: - cExtData(void) {} - ~cExtData(void) { data.clear(); expData.clear(); } - - bool Set(std::string key, std::string value, uint32_t expire = 0); - bool Unset(std::string key); - bool IsSet(std::string key); - std::string Get(std::string key); -}; - - // Display update Thread class cGraphLCDDisplay : public cThread { @@ -91,7 +72,6 @@ public: GLCD::cDriver * GetDriver() const { return mLcd; } const eDisplayMode GetDisplayMode() const { return mDisplayMode; } - cExtData * GetExtData() const { return mExtData; } protected: virtual void Action(); @@ -125,7 +105,6 @@ private: /* display mode (normal or interactive) */ eDisplayMode mDisplayMode; uint64_t LastTimeDisplayMode; - cExtData * mExtData; }; #endif diff --git a/extdata.c b/extdata.c new file mode 100644 index 0000000..01107c1 --- /dev/null +++ b/extdata.c @@ -0,0 +1,88 @@ +/* + * GraphLCD plugin for the Video Disk Recorder + * + * extdata.c - external data sent via SVDRP + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2011 Wolfgang Astleitner <mrwastl AT users sourceforge net> + */ + +#include "extdata.h" + +#include <vdr/tools.h> + +#include <stdio.h> +cExtData * cExtData::mExtDataInstance = NULL; + +cExtData * cExtData::GetExtData(void) { + if (mExtDataInstance == NULL) { + mExtDataInstance = new cExtData(); + } + return mExtDataInstance; +} + + +void cExtData::ReleaseExtData(void) { + delete mExtDataInstance; + mExtDataInstance = NULL; +} + + +cExtData::~cExtData(void) { + data.clear(); + expData.clear(); +} + + +bool cExtData::Set(std::string key, std::string value, uint32_t expire) { + if (mExtDataInstance == NULL) return false; // paranoia check + + data[key] = value; + + if (expire > 0) { + expData[key] = cTimeMs::Now() + (expire * 1000); + } else { + expData.erase(key); // just in case of an old expiration entry for key + } + return true; +} + + +bool cExtData::Unset(std::string key) { + if (mExtDataInstance == NULL) return false; // paranoia check + + expData.erase(key); // ignore result; + return ( (data.erase(key) > 0) ? true : false ); +} + + +bool cExtData::IsSet(std::string key) { + std::string ret = Get(key); + return ( (ret != "") ? true : false ); +} + + +std::string cExtData::Get(std::string key) { + if (mExtDataInstance == NULL) return ""; // paranoia check + + it = data.find(key); + if ( it != data.end() ) { + expDataIt = expData.find(key); + if ( expDataIt != expData.end() ) { + uint64_t expts = (*expDataIt).second; + if ( cTimeMs::Now() > expts ) { + expData.erase(key); + data.erase(key); + return ""; + } else { + return (*it).second; + } + } else { + return (*it).second; + } + } else { + return ""; + } +} diff --git a/extdata.h b/extdata.h new file mode 100644 index 0000000..2e2dd8c --- /dev/null +++ b/extdata.h @@ -0,0 +1,46 @@ +/* + * GraphLCD plugin for the Video Disk Recorder + * + * extdata.h - external data sent via SVDRP + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2011 Wolfgang Astleitner <mrwastl AT users sourceforge net> + */ + +#ifndef _GRAPHLCD_EXTDATA_H_ +#define _GRAPHLCD_EXTDATA_H_ + +#include <stdint.h> + +#include <string> +#include <map> + + +// external data set via SVDRP +class cExtData { + friend class cGraphLCDSkinConfig; + friend class cPluginGraphLCD; +private: + std::map<std::string,std::string> data; + std::map<std::string,std::string>::iterator it; + std::map<std::string,uint64_t> expData; + std::map<std::string,uint64_t>::iterator expDataIt; + + static cExtData * mExtDataInstance; + + cExtData(void) {} + ~cExtData(void); +protected: + static cExtData * GetExtData(void); + static void ReleaseExtData(void); + +public: + bool Set(std::string key, std::string value, uint32_t expire = 0); + bool Unset(std::string key); + bool IsSet(std::string key); + std::string Get(std::string key); +}; + +#endif @@ -24,6 +24,7 @@ #include "display.h" #include "global.h" #include "menu.h" +#include "extdata.h" #include <vdr/plugin.h> @@ -53,6 +54,7 @@ private: std::string mSkinName; GLCD::cDriver * mLcd; cGraphLCDDisplay * mDisplay; + cExtData * mExtData; uint64_t to_timestamp; bool ConnectDisplay(); @@ -85,11 +87,14 @@ cPluginGraphLCD::cPluginGraphLCD() mLcd(NULL), mDisplay(NULL) { + mExtData = cExtData::GetExtData(); } cPluginGraphLCD::~cPluginGraphLCD() { DisconnectDisplay(); + mExtData->ReleaseExtData(); + mExtData = NULL; } const char * cPluginGraphLCD::CommandLineHelp() @@ -361,7 +366,7 @@ cString cPluginGraphLCD::SVDRPCommand(const char *Command, const char *Option, i if (firstpos != std::string::npos) { std::string key = option.substr(0, firstpos); if ( isalpha(key[0]) ) { - mDisplay->GetExtData()->Set(key, option.substr(firstpos+1)); + mExtData->Set(key, option.substr(firstpos+1)); return "SET ok"; } } @@ -373,7 +378,7 @@ cString cPluginGraphLCD::SVDRPCommand(const char *Command, const char *Option, i std::string value = option.substr(secondpos+1); if ( isalpha(key[0]) && isdigit(option[0]) ) { uint32_t expsec = (uint32_t)strtoul( option.substr(0, firstpos).c_str(), NULL, 10); - mDisplay->GetExtData()->Set( key, value, expsec ); + mExtData->Set( key, value, expsec ); return "SETEXP ok"; } } @@ -381,7 +386,7 @@ cString cPluginGraphLCD::SVDRPCommand(const char *Command, const char *Option, i } else if (strcasecmp(Command, "UNSET") == 0) { if (firstpos == std::string::npos) { - mDisplay->GetExtData()->Unset( option ); + mExtData->Unset( option ); return "UNSET ok"; } else { return "UNSET requires exactly one parameter: UNSET <key>."; @@ -389,7 +394,7 @@ cString cPluginGraphLCD::SVDRPCommand(const char *Command, const char *Option, i } else if (strcasecmp(Command, "GET") == 0) { if (firstpos == std::string::npos) { - std::string res = mDisplay->GetExtData()->Get( option ); + std::string res = mExtData->Get( option ); std::string retval = "GET "; retval.append(option); retval.append(": "); if (res != "" ) { retval.append(res); diff --git a/skinconfig.c b/skinconfig.c index ec39da0..eb405d1 100644 --- a/skinconfig.c +++ b/skinconfig.c @@ -19,6 +19,7 @@ #include "state.h" #include "skinconfig.h" #include "service.h" +#include "extdata.h" typedef enum _eTokenId { @@ -113,6 +114,9 @@ typedef enum _eTokenId tokMenuItem, tokMenuCurrent, tokIsMenuCurrent, + tokIsMenuList, + tokMenuText, + tokMenuTextScroll, tokButtonRed, tokButtonGreen, tokButtonYellow, @@ -245,6 +249,9 @@ static const std::string Tokens[tokCountToken] = "MenuItem", "MenuCurrent", "IsMenuCurrent", + "IsMenuList", + "MenuText", + "MenuTextScroll", "ButtonRed", "ButtonGreen", "ButtonYellow", @@ -329,7 +336,7 @@ std::string cGraphLCDSkinConfig::CharSet(void) std::string cGraphLCDSkinConfig::Translate(const std::string & Text) { - return Text; + return I18nTranslate(Text.c_str()); } GLCD::cType cGraphLCDSkinConfig::GetToken(const GLCD::tSkinToken & Token) @@ -580,7 +587,7 @@ GLCD::cType cGraphLCDSkinConfig::GetToken(const GLCD::tSkinToken & Token) case tokMessage: return osd.message; case tokMenuTitle: - return osd.title; + return SplitToken(osd.title, Token.Attrib); case tokMenuItem: case tokMenuCurrent: case tokIsMenuCurrent: @@ -610,7 +617,9 @@ GLCD::cType cGraphLCDSkinConfig::GetToken(const GLCD::tSkinToken & Token) else if (Token.Id == tokMenuCurrent) { if (Token.Index < maxItems && Token.Index == currentIndex) - return osd.items[topIndex + Token.Index]; + return SplitToken(osd.items[topIndex + Token.Index], Token.Attrib); + else if (Token.Index < 0) // outside of <list/>: return last MenuCurrent + return SplitToken(osd.items[topIndex], Token.Attrib, true); } else if (Token.Id == tokIsMenuCurrent) { @@ -619,6 +628,15 @@ GLCD::cType cGraphLCDSkinConfig::GetToken(const GLCD::tSkinToken & Token) } return false; } + case tokIsMenuList: + return (osd.items.size() == 0) ? false : true; + case tokMenuText: + return SplitToken(osd.textItem, Token.Attrib); + case tokMenuTextScroll: { + int curr_scroll = osd.currentTextItemScroll; + mState->ResetOsdStateScroll(); + return curr_scroll; + } case tokButtonRed: return osd.redButton; case tokButtonGreen: @@ -719,14 +737,20 @@ GLCD::cType cGraphLCDSkinConfig::GetToken(const GLCD::tSkinToken & Token) if (Token.Attrib.Text == "") return false; - return mDisplay->GetExtData()->IsSet( Token.Attrib.Text ); + cExtData * extData = cExtData::GetExtData(); + if (extData) + return extData->IsSet( Token.Attrib.Text ); + return false; } break; case tokExtDataItem: { if (Token.Attrib.Text == "") return false; - return mDisplay->GetExtData()->Get( Token.Attrib.Text ); + cExtData * extData = cExtData::GetExtData(); + if (extData) + return extData->Get( Token.Attrib.Text ); + return false; } break; default: @@ -73,6 +73,8 @@ cGraphLCDState::cGraphLCDState(cGraphLCDDisplay * Display) mOsd.message = ""; mOsd.textItem = ""; mOsd.currentItemIndex = -1; + mOsd.currentTextItemScroll = 0; + mOsd.currentTextItemScrollReset = false; mVolume.value = -1; mVolume.lastChange = 0; @@ -364,6 +366,11 @@ void cGraphLCDState::Tick() { mutex.Lock(); + if (mOsd.currentTextItemScrollReset) { // mOsd.currentTextItemScroll has been read since last update? -> reset to 0 + mOsd.currentTextItemScroll = 0; + mOsd.currentTextItemScrollReset = false; + } + tickUsed = true; if (mReplay.control) @@ -400,6 +407,8 @@ void cGraphLCDState::OsdClear() mOsd.blueButton = ""; mOsd.message = ""; mOsd.textItem = ""; + mOsd.currentTextItemScroll = 0; + mOsd.currentTextItemScrollReset = false; mutex.Unlock(); mDisplay->SetMenuClear(); @@ -556,9 +565,14 @@ void cGraphLCDState::OsdTextItem(const char * Text, bool Scroll) if (GraphLCDSetup.PluginActive) { mutex.Lock(); + if (Text) { mOsd.textItem = trim(Text); + mOsd.currentTextItemScroll = 0; + mOsd.currentTextItemScrollReset = false; + } else { + mOsd.currentTextItemScroll += (Scroll) ? -1 : 1; } mutex.Unlock(); //mDisplay->SetOsdTextItem(Text, Scroll); @@ -863,6 +877,10 @@ tOsdState cGraphLCDState::GetOsdState() return ret; } +void cGraphLCDState::ResetOsdStateScroll() { + mOsd.currentTextItemScrollReset = true; +} + tVolumeState cGraphLCDState::GetVolumeState() { tVolumeState ret; @@ -85,6 +85,8 @@ struct tOsdState std::string textItem; std::string message; int currentItemIndex; + int currentTextItemScroll; + bool currentTextItemScrollReset; }; struct tVolumeState @@ -144,6 +146,7 @@ public: bool IsRecording(int CardNumber); std::string Recordings(int CardNumber); tOsdState GetOsdState(); + void ResetOsdStateScroll(); tVolumeState GetVolumeState(); bool ShowMessage(); }; |