summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrwastl <mrwastl@users.sourceforge.net>2011-09-17 21:28:10 +0200
committermrwastl <mrwastl@users.sourceforge.net>2011-09-17 21:28:10 +0200
commit0703b948dd63eb281df5dc531abdf66818becdf7 (patch)
treeb76b3ba4634a95ed71c0dd2ab1e1a4354109870d
parent9e0f177243221e2123758d196315cb63d0f8902b (diff)
downloadvdr-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--Makefile2
-rw-r--r--common.c61
-rw-r--r--common.h6
-rw-r--r--display.c51
-rw-r--r--display.h21
-rw-r--r--extdata.c88
-rw-r--r--extdata.h46
-rw-r--r--plugin.c13
-rw-r--r--skinconfig.c34
-rw-r--r--state.c18
-rw-r--r--state.h3
11 files changed, 261 insertions, 82 deletions
diff --git a/Makefile b/Makefile
index 557b8d4..59210fa 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/common.c b/common.c
index 439540d..1b73d13 100644
--- a/common.c
+++ b/common.c
@@ -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;
+}
diff --git a/common.h b/common.h
index 6412d17..f6c3683 100644
--- a/common.h
+++ b/common.h
@@ -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);
diff --git a/display.c b/display.c
index e92cf05..8823ccf 100644
--- a/display.c
+++ b/display.c
@@ -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 "";
- }
-}
diff --git a/display.h b/display.h
index 08276c3..3c7d7dd 100644
--- a/display.h
+++ b/display.h
@@ -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
diff --git a/plugin.c b/plugin.c
index 8bd7496..50a75b4 100644
--- a/plugin.c
+++ b/plugin.c
@@ -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:
diff --git a/state.c b/state.c
index ba52f3a..b2adb37 100644
--- a/state.c
+++ b/state.c
@@ -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;
diff --git a/state.h b/state.h
index a584bd0..d2a8304 100644
--- a/state.h
+++ b/state.h
@@ -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();
};