diff options
author | louis <louis.braun@gmx.de> | 2013-04-07 10:39:42 +0200 |
---|---|---|
committer | louis <louis.braun@gmx.de> | 2013-04-07 10:39:42 +0200 |
commit | fba3191de71867e91eb51cde93136fcdda64c0ab (patch) | |
tree | e99221ec2c9a7dc612b7e818c4b544a0c1e65a1d | |
parent | 518e7e87332e2b53e9f3e5f9fc853abaec2b360f (diff) | |
download | skin-nopacity-fba3191de71867e91eb51cde93136fcdda64c0ab.tar.gz skin-nopacity-fba3191de71867e91eb51cde93136fcdda64c0ab.tar.bz2 |
Added RSS Feed support
-rw-r--r-- | HISTORY | 1 | ||||
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | README | 49 | ||||
-rw-r--r-- | conf/rssfeeds.conf | 4 | ||||
-rw-r--r-- | config.c | 85 | ||||
-rw-r--r-- | config.h | 15 | ||||
-rw-r--r-- | displaymenu.c | 54 | ||||
-rw-r--r-- | displaymenu.h | 5 | ||||
-rw-r--r-- | displaymenuview.c | 58 | ||||
-rw-r--r-- | displaymenuview.h | 11 | ||||
-rw-r--r-- | icons/skinIcons/rss.png | bin | 0 -> 10661 bytes | |||
-rw-r--r-- | menudetailview.c | 2 | ||||
-rw-r--r-- | nopacity.c | 22 | ||||
-rw-r--r-- | nopacity.h | 6 | ||||
-rw-r--r-- | po/de_DE.po | 35 | ||||
-rw-r--r-- | po/it_IT.po | 35 | ||||
-rw-r--r-- | po/sk_SK.po | 35 | ||||
-rw-r--r-- | rssreader.c | 254 | ||||
-rw-r--r-- | rssreader.h | 58 | ||||
-rw-r--r-- | setup.c | 52 | ||||
-rw-r--r-- | setup.h | 9 | ||||
-rw-r--r-- | skinnopacity.c | 20 |
22 files changed, 798 insertions, 15 deletions
@@ -186,3 +186,4 @@ Version 0.1.1 to avoid nasty font pixelation effect - changed tracks display to fixed track item height - changed stereo and ac3 icons in tracks display +- Added RSS Feed support @@ -53,8 +53,11 @@ INCLUDES += $(shell pkg-config --cflags-only-I Magick++) DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' DEFINES += -DMAGICKCORE_HDRI_ENABLE=0 DEFINES += -DMAGICKCORE_QUANTUM_DEPTH=16 +DEFINES += $(shell xml2-config --cflags) LIBS += $(shell pkg-config --libs Magick++) +LIBS += $(shell pkg-config --libs libcurl) +LIBS += $(shell xml2-config --libs) ### The object files (add further files here): @@ -25,6 +25,8 @@ Requirements - epgsearch Git since commit ba7c6277 (2013-01-03) to correctly replace the schedules menu with epgsearch +- Installed libCurl and libXML2 for displaying RSS Feeds + Description ----------- @@ -104,6 +106,43 @@ Additional hint: some channels have slashes in their name (in germany nick/comed In this example, as a dirty hack just create a folder in your channel logo directory named "nick" and place an image named "comedy.png" inside this folder. +RSS Feeds +--------- + +nOpacity supports the display RSS Feeds in the VDR menu. On VDR startup nOpacity tries to load +the RSS config file "rssfeeds.conf" from the plugin config directory. In this file rss feeds +can be set up per line in the following format: + +[rssfeedname1] rssfeedurl1 +[rssfeedname2] rssfeedurl2 +... ... + +An example for this file is located in the plugin source directory under "conf". This file is +not automatically copied to the plugin config directory by a "make install", it has to be +copied manually, because otherwise an update of the plugin would destroy your customizations. + +If no rssfeeds.conf can be located during startup, only one default rss feed ("Tagesschau") +will be used. + +Each rss feed configured in this file can be selected in the plugin setup for the values +"RSS Feed 1" to "RSS Feed 5". Per default "RSS Feed 1" points to the first feed from the +config file, "RSS Feed 2" up to "RSS Feed 5" are empty. + +If the VDR Menu is opened, RSS Feed 1 is displayed at startup. If one or more of the fields +"RSS Feed 2" to "RSS Feed 5" are activated, it can be toggled through these feeds via svdrp +with the command: + +svdrpsend plug skinnopacity NEXTFEED + +With the command + +svdrpsend plug skinnopacity NEXTMESG + +you can switch to the next message in the current feed. + +Just configure this commands for one of your remote control buttons to easily toggle between +the different feeds or switch to the next message inside a feed. + Themes and theme specific Icons ------------------------------- @@ -305,3 +344,13 @@ Customizing, Skin Setup Options Remark: the volume display is always positioned in the center of the screen, with bottom border it can be moved to the top. - Adjust Font Size + +* RSS Feeds: + +- Display RSS Feed +- Height of RSS Feed Line (Percent of OSD Height): Default 5% +- RSS Feed 1: First feed in rssfeeds.conf +- RSS Feed 2 - 5: Optional feeds which can be selected via svdrp +- Scrolling Speed: slow / medium / fast +- Scrolling Delay in s: Default 3 s +- Adjust Font Size diff --git a/conf/rssfeeds.conf b/conf/rssfeeds.conf new file mode 100644 index 0000000..c0f7e62 --- /dev/null +++ b/conf/rssfeeds.conf @@ -0,0 +1,4 @@ +[Tagesschau] http://www.tagesschau.de/xml/rss2 +[Kicker] http://rss.kicker.de/news/aktuell +[Spiegel Online] http://www.spiegel.de/schlagzeilen/tops/index.rss +[Focus] http://rss2.focus.de/c/32191/f/443312/index.rss @@ -1,3 +1,5 @@ +#include <string> +#include <vector> #include "config.h" cNopacityConfig::cNopacityConfig() { @@ -134,6 +136,17 @@ cNopacityConfig::cNopacityConfig() { fontDetailViewHeader = 0; fontDetailViewHeaderLarge = 0; fontEPGInfoWindow = 0; + //RSS Feeds + displayRSSFeed = 1; + rssFeedHeight = 5; + fontRssFeed = 0; + rssScrollDelay = 2; + rssScrollSpeed = 1; + rssFeed[0] = 0; + rssFeed[1] = 0; + rssFeed[2] = 0; + rssFeed[3] = 0; + rssFeed[4] = 0; } cNopacityConfig::~cNopacityConfig() { @@ -173,7 +186,16 @@ void cNopacityConfig::setDynamicValues() { menuInfoScrollFrameTime = 30; else if (menuInfoScrollSpeed == 3) menuInfoScrollFrameTime = 15; - + + rssScrollFrameTime = 0; + if (rssScrollSpeed == 0) + rssScrollFrameTime = 30; + else if (rssScrollSpeed == 1) + rssScrollFrameTime = 15; + else if (rssScrollSpeed == 2) + rssScrollFrameTime = 5; + + logoPathDefault = cString::sprintf("%s/logos/", cPlugin::ResourceDirectory(PLUGIN_NAME_I18N)); iconPathDefault = cString::sprintf("%s/icons/", cPlugin::ResourceDirectory(PLUGIN_NAME_I18N)); epgImagePathDefault = cString::sprintf("%s/epgimages/", cPlugin::CacheDirectory(PLUGIN_NAME_I18N)); @@ -183,6 +205,57 @@ void cNopacityConfig::setDynamicValues() { dsyslog("nopacity: using EPG Images Directory %s", (epgImagePathSet)?(*epgImagePath):(*epgImagePathDefault)); } +void cNopacityConfig::loadRssFeeds(void) { + cString rssconf = cString::sprintf("%s/rssfeeds.conf", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N)); + dsyslog("nopacity: trying to load rss feeds from %s", *rssconf); + FILE *f = fopen(*rssconf, "r"); + bool foundEntries = false; + if (f) { + char *line; + cReadLine ReadLine; + while ((line = ReadLine.Read(f)) != NULL) { + try { + std::string currentLine = line; + size_t startTag = currentLine.find_first_of('[') + 1; + size_t endTag = currentLine.find_first_of(']'); + if (endTag != std::string::npos) { + std::string rssName = currentLine.substr(startTag, endTag - 1); + std::string rssUrl = currentLine.substr(endTag + 1); + size_t startUrl = rssUrl.find_first_of("http"); + if (startUrl != std::string::npos) { + rssUrl = rssUrl.substr(startUrl); + size_t whitespaces = rssUrl.find_first_of(" "); + if (whitespaces != std::string::npos) { + rssUrl = rssUrl.substr(0, whitespaces); + } + RssFeed feed; + feed.name = rssName; + feed.url = rssUrl; + rssFeeds.push_back(feed); + foundEntries = true; + } + } + } catch (...) {} + } + fclose(f); + } + if (foundEntries) { + dsyslog("nopacity: loaded %d rss feeds from %s", rssFeeds.size(), *rssconf); + int i = 1; + for (std::vector<RssFeed>::iterator it = rssFeeds.begin(); it != rssFeeds.end(); it++) { + dsyslog("nopacity: RssFeed %d: name %s, URL: %s", i, it->name.c_str(), it->url.c_str()); + i++; + } + } else { + dsyslog("nopacity: no valid rss config found, using default rss feed"); + RssFeed feed; + feed.name = "Tagesschau"; + feed.url = "http://www.tagesschau.de/xml/rss2"; + rssFeeds.push_back(feed); + } +} + + void cNopacityConfig::SetLogoPath(cString path) { logoPath = path; logoPathSet = true; @@ -319,6 +392,16 @@ bool cNopacityConfig::SetupParse(const char *Name, const char *Value) { else if (strcmp(Name, "fontDetailViewHeader") == 0) fontDetailViewHeader = atoi(Value); else if (strcmp(Name, "fontDetailViewHeaderLarge") == 0) fontDetailViewHeaderLarge = atoi(Value); else if (strcmp(Name, "fontEPGInfoWindow") == 0) fontEPGInfoWindow = atoi(Value); + else if (strcmp(Name, "displayRSSFeed") == 0) displayRSSFeed = atoi(Value); + else if (strcmp(Name, "rssFeedHeight") == 0) rssFeedHeight = atoi(Value); + else if (strcmp(Name, "fontRssFeed") == 0) fontRssFeed = atoi(Value); + else if (strcmp(Name, "rssScrollDelay") == 0) rssScrollDelay = atoi(Value); + else if (strcmp(Name, "rssScrollSpeed") == 0) rssScrollSpeed = atoi(Value); + else if (strcmp(Name, "rssFeed[0]") == 0) rssFeed[0] = atoi(Value); + else if (strcmp(Name, "rssFeed[1]") == 0) rssFeed[1] = atoi(Value); + else if (strcmp(Name, "rssFeed[2]") == 0) rssFeed[2] = atoi(Value); + else if (strcmp(Name, "rssFeed[3]") == 0) rssFeed[3] = atoi(Value); + else if (strcmp(Name, "rssFeed[4]") == 0) rssFeed[4] = atoi(Value); else return false; return true; @@ -1,6 +1,11 @@ #ifndef __NOPACITY_CONFIG_H
#define __NOPACITY_CONFIG_H
+struct RssFeed {
+ std::string name;
+ std::string url;
+};
+
class cNopacityConfig {
private:
public:
@@ -17,6 +22,7 @@ class cNopacityConfig { cString iconPathDefault;
cString epgImagePathDefault;
void setDynamicValues();
+ void loadRssFeeds(void);
//Common
int fontIndex;
const char *fontDefaultName;
@@ -160,6 +166,15 @@ class cNopacityConfig { int fontDetailViewHeader;
int fontDetailViewHeaderLarge;
int fontEPGInfoWindow;
+ //RSS Feeds
+ std::vector<RssFeed> rssFeeds;
+ int displayRSSFeed;
+ int rssFeedHeight;
+ int fontRssFeed;
+ int rssScrollDelay;
+ int rssScrollSpeed;
+ int rssScrollFrameTime;
+ int rssFeed[5];
};
#endif //__NOPACITY_CONFIG_H
\ No newline at end of file diff --git a/displaymenu.c b/displaymenu.c index 0bedb00..b059707 100644 --- a/displaymenu.c +++ b/displaymenu.c @@ -9,6 +9,7 @@ namespace PluginRemoteTimers { #include <string> cNopacityDisplayMenu::cNopacityDisplayMenu(void) { +esyslog("nopacity: starting menu"); config.setDynamicValues(); menuCategoryLast = mcUndefined; FrameTime = config.menuFrameTime; @@ -32,12 +33,27 @@ cNopacityDisplayMenu::cNopacityDisplayMenu(void) { menuView->CreateBackgroundImages(handleBackgrounds, handleButtons); menuView->DrawHeaderLogo(); menuView->DrawBorderDecoration(); + currentFeed = 0; + if (config.displayRSSFeed) { + menuView->DrawRssFeed(config.rssFeeds[config.rssFeed[currentFeed]].name); + rssReader = new cRssReader(osd, menuView->GetRssFeedFont(), menuView->GetRssFeedPosition(), menuView->GetRssFeedSize()); + rssReader->SetFeed(config.rssFeeds[config.rssFeed[currentFeed]].url); + rssReader->Start(); + } else + rssReader = NULL; } cNopacityDisplayMenu::~cNopacityDisplayMenu() { Cancel(-1); while (Active()) cCondWait::SleepMs(10); + if (rssReader) { + rssReader->Stop(); + while (rssReader->Active()) + cCondWait::SleepMs(10); + delete rssReader; + rssReader = NULL; + } delete menuView; menuItems.Clear(); if (detailView) { @@ -51,6 +67,7 @@ cNopacityDisplayMenu::~cNopacityDisplayMenu() { delete osd; cDevice::PrimaryDevice()->ScaleVideo(cRect::Null); + menuActive = false; } void cNopacityDisplayMenu::DrawDisk(void) { @@ -757,3 +774,40 @@ void cNopacityDisplayMenu::Action(void) { break; } } + +void cNopacityDisplayMenu::SwitchNextRssMessage(void) { + if (!config.displayRSSFeed) + return; + if (rssReader) { + rssReader->SwitchNextMessage(); + } +} + +void cNopacityDisplayMenu::SwitchNextRssFeed(void) { + if (!config.displayRSSFeed) + return; + if (rssReader) { + rssReader->Stop(); + while (rssReader->Active()) + cCondWait::SleepMs(10); + delete rssReader; + rssReader = NULL; + } + SetNextFeed(); + int feedNum = (config.rssFeed[currentFeed]==0)?0:(config.rssFeed[currentFeed]-1); + menuView->DrawRssFeed(config.rssFeeds[feedNum].name); + rssReader = new cRssReader(osd, menuView->GetRssFeedFont(), menuView->GetRssFeedPosition(), menuView->GetRssFeedSize()); + rssReader->SetFeed(config.rssFeeds[feedNum].url); + rssReader->Start(); +} + +void cNopacityDisplayMenu::SetNextFeed(void) { + int nextFeed = 0; + for (int i = 1; i<6; i++) { + nextFeed = (currentFeed + i)%5; + if ((nextFeed == 0)||(config.rssFeed[nextFeed] > 0)) { + currentFeed = nextFeed; + break; + } + } +}
\ No newline at end of file diff --git a/displaymenu.h b/displaymenu.h index 3089f0d..83692bb 100644 --- a/displaymenu.h +++ b/displaymenu.h @@ -23,6 +23,9 @@ private: int handleButtons[4]; int positionButtons[4]; cRect videoWindowRect; + cRssReader *rssReader; + int currentFeed; + void SetNextFeed(void); void DrawDisk(void); int CheckTimerConflict(bool timersChanged); void DrawTimers(bool timersChanged, int numConflicts); @@ -54,6 +57,8 @@ public: virtual void SetTabs(int Tab1, int Tab2 = 0, int Tab3 = 0, int Tab4 = 0, int Tab5 = 0); virtual int GetTextAreaWidth(void) const; virtual const cFont *GetTextAreaFont(bool FixedFont) const; + void SwitchNextRssMessage(void); + void SwitchNextRssFeed(void); }; #endif //__NOPACITY_DISPLAYMENU_H
\ No newline at end of file diff --git a/displaymenuview.c b/displaymenuview.c index f418990..0b4fed1 100644 --- a/displaymenuview.c +++ b/displaymenuview.c @@ -19,7 +19,12 @@ cNopacityDisplayMenuView::~cNopacityDisplayMenuView(void) { osd->DestroyPixmap(pixmapDiskUsageLabel); if (pixmapHeaderIcon) osd->DestroyPixmap(pixmapHeaderIcon); - + if (pixmapRssFeed) + osd->DestroyPixmap(pixmapRssFeed); + if (pixmapRssFeedBackground) + osd->DestroyPixmap(pixmapRssFeedBackground); + if (pixmapRssFeedIcon) + osd->DestroyPixmap(pixmapRssFeedIcon); delete fontHeader; delete fontDate; delete fontMenuitemLarge; @@ -39,6 +44,7 @@ cNopacityDisplayMenuView::~cNopacityDisplayMenuView(void) { delete fontButtons; delete fontMessage; delete fontEPGInfoWindow; + delete fontRssFeed; } cOsd *cNopacityDisplayMenuView::createOsd(void) { @@ -56,7 +62,8 @@ void cNopacityDisplayMenuView::SetGeometry(void) { dateWidth = osdWidth * 0.3; headerHeight = osdHeight * config.headerHeight / 100; footerHeight = osdHeight * config.footerHeight / 100; - contentHeight = osdHeight - headerHeight - footerHeight; + rssFeedHeight = (config.displayRSSFeed)?(osdHeight * config.rssFeedHeight / 100):0; + contentHeight = osdHeight - headerHeight - footerHeight - rssFeedHeight; contentWidthMain = osdWidth * config.menuWidthMain / 100; contentWidthSchedules = osdWidth * config.menuWidthSchedules / 100; contentWidthChannels = osdWidth * config.menuWidthChannels / 100; @@ -163,7 +170,7 @@ void cNopacityDisplayMenuView::CreatePixmaps(void) { pixmapHeaderLogo = osd->CreatePixmap(-1, cRect(logoX, 0, config.menuHeaderLogoWidth, config.menuHeaderLogoHeight)); int labelX = (config.menuAdjustLeft) ? 0 : dateWidth; pixmapHeaderLabel = osd->CreatePixmap(2, cRect(labelX, 0, osdWidth - dateWidth, headerHeight)); - pixmapFooter = osd->CreatePixmap(1, cRect(0, osdHeight-footerHeight, osdWidth, footerHeight)); + pixmapFooter = osd->CreatePixmap(1, cRect(0, osdHeight - rssFeedHeight - footerHeight, osdWidth, footerHeight)); int drawPortWidth = osdWidth + contentWidthFull - contentWidthMinimum; pixmapContent = osd->CreatePixmap(1, cRect(0, headerHeight, osdWidth, contentHeight), cRect(0, 0, drawPortWidth, contentHeight)); @@ -174,6 +181,15 @@ void cNopacityDisplayMenuView::CreatePixmaps(void) { int scrollbarX = (config.menuAdjustLeft) ? contentWidthMain : (osdWidth - contentWidthMain); pixmapScrollbar = osd->CreatePixmap(2, cRect(scrollbarX, headerHeight + spaceMenu, widthScrollbar, contentHeight - 2 * spaceMenu)); + if (config.displayRSSFeed) { + pixmapRssFeedBackground = osd->CreatePixmap(1, cRect(0, headerHeight + contentHeight + footerHeight, osdWidth, rssFeedHeight)); + pixmapRssFeed = osd->CreatePixmap(2, cRect(0, headerHeight + contentHeight + footerHeight, osdWidth, rssFeedHeight)); + pixmapRssFeedIcon = osd->CreatePixmap(3, cRect(0, headerHeight + contentHeight + footerHeight, rssFeedHeight, rssFeedHeight)); + } else { + pixmapRssFeedBackground = NULL; + pixmapRssFeed = NULL; + pixmapRssFeedIcon = NULL; + } pixmapHeaderLogo->Fill(clrTransparent); pixmapHeaderLabel->Fill(clrTransparent); pixmapDiskUsage->Fill(clrTransparent); @@ -226,6 +242,7 @@ void cNopacityDisplayMenuView::CreateFonts(void) { fontButtons = cFont::CreateFont(config.fontName, buttonHeight*0.8 + config.fontButtons); fontMessage = cFont::CreateFont(config.fontName, messageHeight / 3 + config.fontMessageMenu); fontEPGInfoWindow = cFont::CreateFont(config.fontName, (config.menuHeightInfoWindow * contentHeight / 100)/ 6 + config.fontEPGInfoWindow); + fontRssFeed = cFont::CreateFont(config.fontName, (rssFeedHeight / 2) + 3 + config.fontRssFeed); } cFont *cNopacityDisplayMenuView::GetMenuItemFont(eMenuCategory menuCat) { @@ -512,7 +529,7 @@ void cNopacityDisplayMenuView::AdjustContentBackground(eMenuCategory menuCat, eM } osd->DestroyPixmap(pixmapScrollbar); int scrollbarX = (config.menuAdjustLeft)?(contentWidth):(osdWidth - contentWidth - widthScrollbar); - pixmapScrollbar = osd->CreatePixmap(2, cRect(scrollbarX , headerHeight + spaceMenu, widthScrollbar, osdHeight - headerHeight - footerHeight - 2*spaceMenu)); + pixmapScrollbar = osd->CreatePixmap(2, cRect(scrollbarX , headerHeight + spaceMenu, widthScrollbar, contentHeight - 2*spaceMenu)); pixmapScrollbar->Fill(clrTransparent); } @@ -805,3 +822,36 @@ void cNopacityDisplayMenuView::SetDetailViewSize(eDetailViewType detailViewType, top = headerHeight; detailView->SetGeometry(x, width, height, top, contentBorder, detailHeaderHeight); } + +void cNopacityDisplayMenuView::DrawRssFeed(std::string feedName) { + pixmapRssFeedBackground->Fill(clrBlack); + pixmapRssFeed->Fill(clrTransparent); + feedNameLength = fontRssFeed->Width(feedName.c_str()); + int labelWidth = 2 + rssFeedHeight + 2 + feedNameLength + 6; + pixmapRssFeed->Fill(Theme.Color(clrMenuBorder)); + cImageLoader imgLoader; + imgLoader.DrawBackground(Theme.Color(clrMenuItemHigh), Theme.Color(clrMenuItemHighBlend), labelWidth, rssFeedHeight - 4); + pixmapRssFeed->DrawImage(cPoint(2,2), imgLoader.GetImage()); + + imgLoader.DrawBackground(Theme.Color(clrMenuItem), Theme.Color(clrMenuItemBlend), osdWidth - labelWidth - 2, rssFeedHeight - 4); + pixmapRssFeed->DrawImage(cPoint(labelWidth,2), imgLoader.GetImage()); + + pixmapRssFeed->DrawText(cPoint(rssFeedHeight + 2, (rssFeedHeight - fontRssFeed->Height()) / 2), feedName.c_str(), Theme.Color(clrMenuFontHeader), clrTransparent, fontRssFeed); + pixmapRssFeedIcon->Fill(clrTransparent); + if (imgLoader.LoadIcon("skinIcons/rss", rssFeedHeight-4)) { + cImage icon = imgLoader.GetImage(); + pixmapRssFeedIcon->DrawImage(cPoint(2,2), icon); + } +} + +cPoint cNopacityDisplayMenuView::GetRssFeedPosition(void) { + int x = rssFeedHeight + feedNameLength + 10; + int y = osdHeight - rssFeedHeight + 2; + return cPoint(x, y); +} + +cPoint cNopacityDisplayMenuView::GetRssFeedSize(void) { + int width = osdWidth - (rssFeedHeight + feedNameLength + 12); + int height = rssFeedHeight - 4; + return cPoint(width, height); +} diff --git a/displaymenuview.h b/displaymenuview.h index 63af3c8..9ba3bf3 100644 --- a/displaymenuview.h +++ b/displaymenuview.h @@ -20,6 +20,9 @@ class cNopacityDisplayMenuView { cPixmap *pixmapDiskUsageIcon; cPixmap *pixmapDiskUsageLabel; cPixmap *pixmapStatus; + cPixmap *pixmapRssFeed; + cPixmap *pixmapRssFeedBackground; + cPixmap *pixmapRssFeedIcon; cFont *fontHeader; cFont *fontDate; cFont *fontMenuitemLarge; @@ -39,11 +42,12 @@ class cNopacityDisplayMenuView { cFont *fontButtons; cFont *fontMessage; cFont *fontEPGInfoWindow; + cFont *fontRssFeed; int osdWidth, osdHeight; int osdLeft, osdTop; int widthScrollbar; int dateWidth; - int headerHeight, footerHeight, contentHeight; + int headerHeight, footerHeight, rssFeedHeight, contentHeight; int contentWidthFull; int contentWidthMain; int contentWidthSchedules; @@ -63,6 +67,7 @@ class cNopacityDisplayMenuView { int timersWidth; int buttonsBorder, buttonWidth, buttonHeight; int messageWidth, messageHeight; + int feedNameLength; int avrgFontWidth; cRect textWindowSizeSchedules; cRect textWindowSizeRecordings; @@ -114,6 +119,10 @@ class cNopacityDisplayMenuView { void DrawMessage(eMessageType Type, const char *Text); void ClearMessage(void); void SetDetailViewSize(eDetailViewType detailViewType, cNopacityMenuDetailView *detailView); + void DrawRssFeed(std::string feedName); + cFont *GetRssFeedFont(void) {return fontRssFeed;}; + cPoint GetRssFeedPosition(void); + cPoint GetRssFeedSize(void); int spaceMenu; }; diff --git a/icons/skinIcons/rss.png b/icons/skinIcons/rss.png Binary files differnew file mode 100644 index 0000000..b1c7bbe --- /dev/null +++ b/icons/skinIcons/rss.png diff --git a/menudetailview.c b/menudetailview.c index 36165d2..6c22d16 100644 --- a/menudetailview.c +++ b/menudetailview.c @@ -655,4 +655,4 @@ void cNopacityMenuDetailTextView::CreatePixmaps(void) { void cNopacityMenuDetailTextView::Render(void) { DrawTextWrapper(&content, 0); -}
\ No newline at end of file +} @@ -2,6 +2,7 @@ #include <vdr/menu.h> static cTheme Theme; +static bool menuActive = false; //COMMON #define CLR_TRANSBLACK 0xDD000000 @@ -131,6 +132,7 @@ cNopacityConfig config; #include "imageloader.c" #include "nopacity.h" #include "helpers.c" +#include "rssreader.c" #include "displaychannel.c" #include "textwindow.c" #include "timers.c" @@ -143,8 +145,12 @@ cNopacityConfig config; #include "displaytracks.c" #include "displaymessage.c" + + cNopacity::cNopacity(void) : cSkin("nOpacity", &::Theme) { + displayMenu = NULL; config.setDynamicValues(); + config.loadRssFeeds(); } const char *cNopacity::Description(void) { @@ -156,7 +162,10 @@ cSkinDisplayChannel *cNopacity::DisplayChannel(bool WithInfo) { } cSkinDisplayMenu *cNopacity::DisplayMenu(void) { - return new cNopacityDisplayMenu; + cNopacityDisplayMenu *menu = new cNopacityDisplayMenu; + displayMenu = menu; + menuActive = true; + return menu; } cSkinDisplayReplay *cNopacity::DisplayReplay(bool ModeOnly) { @@ -175,3 +184,14 @@ cSkinDisplayMessage *cNopacity::DisplayMessage(void) { return new cNopacityDisplayMessage; } +void cNopacity::svdrpSwitchRss(void) { + if (menuActive) { + displayMenu->SwitchNextRssFeed(); + } +} + +void cNopacity::svdrpSwitchMessage(void) { + if (menuActive) { + displayMenu->SwitchNextRssMessage(); + } +}
\ No newline at end of file @@ -4,7 +4,11 @@ #include <vdr/skins.h> #include <vdr/videodir.h> +class cNopacityDisplayMenu; + class cNopacity : public cSkin { +private: + cNopacityDisplayMenu *displayMenu; public: cNopacity(void); virtual const char *Description(void); @@ -14,5 +18,7 @@ public: virtual cSkinDisplayVolume *DisplayVolume(void); virtual cSkinDisplayTracks *DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks); virtual cSkinDisplayMessage *DisplayMessage(void); + void svdrpSwitchRss(void); + void svdrpSwitchMessage(void); }; #endif //__NOPACITY_H diff --git a/po/de_DE.po b/po/de_DE.po index 7b753ac..7627d81 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: skinnopacity 0.0.1\n" "Report-Msgid-Bugs-To: <see README>\n" -"POT-Creation-Date: 2013-03-24 11:09+0100\n" +"POT-Creation-Date: 2013-03-31 14:22+0200\n" "PO-Revision-Date: 2012-11-11 17:49+0200\n" "Last-Translator: louis\n" "Language-Team: \n" @@ -92,6 +92,9 @@ msgstr "Audio Spuren" msgid "Messages" msgstr "Nachrichten" +msgid "RSS Feeds" +msgstr "RSS Feeds" + msgid "right" msgstr "rechts" @@ -395,6 +398,36 @@ msgstr "Breite der Lautstärken Anzeige (% der OSD Breite)" msgid "Height of Volume Display (Percent of OSD Height)" msgstr "Höhe der Lautstärken Anzeige (% der OSD Höhe)" +msgid "none" +msgstr "keiner" + +msgid "Display RSS Feed" +msgstr "RSS Feed anzeigen" + +msgid "Height of RSS Feed Line (Percent of OSD Height)" +msgstr "Höhe des RSS Feeds (% der OSD Höhe)" + +msgid "RSS Feed 1" +msgstr "RSS Feed 1" + +msgid "RSS Feed 2" +msgstr "RSS Feed 2" + +msgid "RSS Feed 3" +msgstr "RSS Feed 3" + +msgid "RSS Feed 4" +msgstr "RSS Feed 4" + +msgid "RSS Feed 5" +msgstr "RSS Feed 5" + +msgid "Scrolling Speed" +msgstr "Scroll Geschwindigkeit" + +msgid "Scrolling Delay in s" +msgstr "Scroll Verzögerung in s" + msgid "conflict" msgstr "Konflikt" diff --git a/po/it_IT.po b/po/it_IT.po index 6d356fb..9c7011f 100644 --- a/po/it_IT.po +++ b/po/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: skinnopacity 0.0.1\n" "Report-Msgid-Bugs-To: <see README>\n" -"POT-Creation-Date: 2013-03-24 11:09+0100\n" +"POT-Creation-Date: 2013-03-31 14:22+0200\n" "PO-Revision-Date: 2013-03-19 22:56+0100\n" "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n" "Language-Team: \n" @@ -95,6 +95,9 @@ msgstr "Tracce audio" msgid "Messages" msgstr "Messaggi" +msgid "RSS Feeds" +msgstr "" + msgid "right" msgstr "destra" @@ -398,6 +401,36 @@ msgstr "Larghezza di Mostra volume (% altezza OSD)" msgid "Height of Volume Display (Percent of OSD Height)" msgstr "Altezza di Mostra volume (% altezza OSD)" +msgid "none" +msgstr "" + +msgid "Display RSS Feed" +msgstr "" + +msgid "Height of RSS Feed Line (Percent of OSD Height)" +msgstr "" + +msgid "RSS Feed 1" +msgstr "" + +msgid "RSS Feed 2" +msgstr "" + +msgid "RSS Feed 3" +msgstr "" + +msgid "RSS Feed 4" +msgstr "" + +msgid "RSS Feed 5" +msgstr "" + +msgid "Scrolling Speed" +msgstr "" + +msgid "Scrolling Delay in s" +msgstr "" + msgid "conflict" msgstr "conflitto" diff --git a/po/sk_SK.po b/po/sk_SK.po index dceb7e4..7513c1b 100644 --- a/po/sk_SK.po +++ b/po/sk_SK.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-skinnopacity 0.0.6\n" "Report-Msgid-Bugs-To: <see README>\n" -"POT-Creation-Date: 2013-03-24 11:09+0100\n" +"POT-Creation-Date: 2013-03-31 14:22+0200\n" "PO-Revision-Date: 2013-03-12 15:59+0100\n" "Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n" "Language-Team: \n" @@ -95,6 +95,9 @@ msgstr "Zvuková stopa" msgid "Messages" msgstr "Správy" +msgid "RSS Feeds" +msgstr "" + msgid "right" msgstr "vpravo" @@ -398,6 +401,36 @@ msgstr "©írka zobrazenia hlasitosti (Percent z OSD ¹írky)" msgid "Height of Volume Display (Percent of OSD Height)" msgstr "" +msgid "none" +msgstr "" + +msgid "Display RSS Feed" +msgstr "" + +msgid "Height of RSS Feed Line (Percent of OSD Height)" +msgstr "" + +msgid "RSS Feed 1" +msgstr "" + +msgid "RSS Feed 2" +msgstr "" + +msgid "RSS Feed 3" +msgstr "" + +msgid "RSS Feed 4" +msgstr "" + +msgid "RSS Feed 5" +msgstr "" + +msgid "Scrolling Speed" +msgstr "" + +msgid "Scrolling Delay in s" +msgstr "" + msgid "conflict" msgstr "konflikt" diff --git a/rssreader.c b/rssreader.c new file mode 100644 index 0000000..d3ff151 --- /dev/null +++ b/rssreader.c @@ -0,0 +1,254 @@ +#include "rssreader.h" + +static size_t WriteXMLMemoryCallback(void* pointer, size_t size, size_t nmemb, void* xmlData) { + size_t realsize = size * nmemb; + struct XMLMemoryStruct* memStruct = (struct XMLMemoryStruct*)xmlData; + if (memStruct->memory) + memStruct->memory = (char*)realloc(memStruct->memory, memStruct->size + realsize + 1); + else + memStruct->memory = (char*)malloc(memStruct->size + realsize + 1); + if (memStruct->memory) { + memcpy (&(memStruct->memory[memStruct->size]), pointer, realsize); + memStruct->size += realsize; + memStruct->memory[memStruct->size] = 0; + } + return realsize; +} + +cRssReader::cRssReader(cOsd *osd, cFont *font, cPoint position, cPoint size) { + this->osd = osd; + this->font = font; + pixmap = NULL; + + x = position.X(); + y = position.Y(); + + width = size.X(); + height = size.Y(); + + xmlData.memory = 0; + xmlData.size = 0; + + useProxy = false; + httpproxy = ""; + + separator = " +++ "; + currentElement = 0; + switchToNextMessage = false; +} + +cRssReader::~cRssReader() { + osd->DestroyPixmap(pixmap); +} + +int cRssReader::readRssURL(const char *url) { + CURL* my_curl_handle; + long code; + if (xmlData.memory) + free(xmlData.memory); + xmlData.memory = 0; + xmlData.size = 0; + if (curl_global_init(CURL_GLOBAL_ALL) != 0) { + esyslog("nopacity: Error, something went wrong with curl_global_init()"); + return -1; + } + my_curl_handle = curl_easy_init(); + if (!my_curl_handle) { + esyslog("nopacity: Error, unable to get handle from curl_easy_init()"); + return -1; + } + if (useProxy) { + curl_easy_setopt(my_curl_handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); + curl_easy_setopt(my_curl_handle, CURLOPT_PROXY, httpproxy.c_str()); // Specify HTTP proxy + } + curl_easy_setopt(my_curl_handle, CURLOPT_URL, url); // Specify URL to get + curl_easy_setopt(my_curl_handle, CURLOPT_FOLLOWLOCATION, 0); // don't follow redirects + curl_easy_setopt(my_curl_handle, CURLOPT_WRITEFUNCTION, WriteXMLMemoryCallback); // Send all data to this function + curl_easy_setopt(my_curl_handle, CURLOPT_WRITEDATA, (void*)&xmlData); // Pass our 'data' struct to the callback function + curl_easy_setopt(my_curl_handle, CURLOPT_MAXFILESIZE, 1024*1024); // Set maximum file size to get (bytes) + curl_easy_setopt(my_curl_handle, CURLOPT_NOPROGRESS, 1); // No progress meter + curl_easy_setopt(my_curl_handle, CURLOPT_NOSIGNAL, 1); // No signaling + curl_easy_setopt(my_curl_handle, CURLOPT_TIMEOUT, 30); // Set timeout to 30 seconds + curl_easy_setopt(my_curl_handle, CURLOPT_USERAGENT, NOPACITY_USERAGENT); // Some servers don't like requests that are made without a user-agent field + + if (curl_easy_perform(my_curl_handle) != 0) { + curl_easy_cleanup(my_curl_handle); // Cleanup curl stuff + if (xmlData.memory) { + free(xmlData.memory); + xmlData.memory = 0; + xmlData.size = 0; + } + esyslog("nopacity: Error, download of '%s' failed", url); + return -1; + } + curl_easy_getinfo(my_curl_handle, CURLINFO_HTTP_CODE, &code); + if (code == 404) { + if (xmlData.memory) + free(xmlData.memory); + xmlData.memory = 0; + xmlData.size = 0; + } + curl_easy_cleanup(my_curl_handle); // Cleanup curl stuff + + return xmlData.size; +} + +void cRssReader::traverseTree(xmlNode * a_node, bool foundItem) { + xmlNode *cur_node = NULL; + xmlChar *node_content; + bool foundItemAct = false; + for (cur_node = a_node; cur_node; cur_node = cur_node->next) { + if (cur_node->type == XML_ELEMENT_NODE) { + if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"item"))){ + foundItemAct = true; + saveItem(); + } else { + if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"title")) && foundItem){ + node_content = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); + if (node_content) + title = (const char *)node_content; + else + title = ""; + xmlFree(node_content); + } + if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"description")) && foundItem){ + node_content = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); + if (node_content) + content = (const char *)node_content; + else + content = ""; + xmlFree(node_content); + } + } + } + traverseTree(cur_node->children, foundItemAct); + } + +} + +void cRssReader::saveItem(void) { + if (!title.length()) + return; + RssElement rssElement; + rssElement.title = title; + rssElement.content = content; + int width = font->Width(title.c_str()) + font->Width(": ") + font->Width(content.c_str()) + font->Width(separator.c_str()); + rssElement.width = width; + rssElements.push_back(rssElement); +} + +void cRssReader::saveRss(void) { + xmlNode *root_element = NULL; + root_element = xmlDocGetRootElement(doc); + traverseTree(root_element, false); + saveItem(); + xmlFreeDoc(doc); +} + +void cRssReader::createPixmap(void) { + if (pixmap) + osd->DestroyPixmap(pixmap); + pixmap = osd->CreatePixmap(7, cRect(x, y, width, height), cRect(0, 0, rssElements[currentElement].width, height)); + pixmap->Fill(clrTransparent); + pixmap->SetAlpha(0); +} + +void cRssReader::drawText(void) { + int currentX = 5; + int textY = (height - font->Height()) / 2; + cString text = cString::sprintf("%s: ", rssElements[currentElement].title.c_str()); + pixmap->DrawText(cPoint(currentX, textY), *text, Theme.Color(clrMenuFontMenuItemHigh), clrTransparent, font); + currentX += font->Width(*text); + text = cString::sprintf("%s%s", rssElements[currentElement].content.c_str(), separator.c_str()); + pixmap->DrawText(cPoint(currentX, textY), *text, Theme.Color(clrMenuFontMenuItem), clrTransparent, font); +} + +void cRssReader::DoSleep(int duration) { + int sleepSlice = 10; + for (int i = 0; Running() && (i*sleepSlice < duration); i++) + cCondWait::SleepMs(sleepSlice); +} + +void cRssReader::Action(void) { + int success = readRssURL(feedUrl.c_str()); + if (success < 1) + return; + if (!strstr(xmlData.memory, "rss")) + return; + doc = NULL; + doc = xmlReadMemory(xmlData.memory, strlen(xmlData.memory), "noname.xml", NULL, 0); + if (doc == NULL) { + return; + } + saveRss(); + + int numElements = rssElements.size(); + int scrollDelay = config.rssScrollDelay * 1000; + int drawPortX; + int FrameTime = config.rssScrollFrameTime; + int maxX; + bool doSleep; + + createPixmap(); + drawText(); + fadeInOut(true); + DoSleep(scrollDelay); + doSleep = false; + maxX = pixmap->DrawPort().Width() - pixmap->ViewPort().Width(); + + while (Running()) { + if (doSleep) { + fadeInOut(true); + DoSleep(scrollDelay); + doSleep = false; + } + uint64_t Now = cTimeMs::Now(); + cPixmap::Lock(); + drawPortX = pixmap->DrawPort().X(); + drawPortX -= 1; + cPixmap::Unlock(); + if ((abs(drawPortX) > maxX) || switchToNextMessage) { + if (!switchToNextMessage) + DoSleep(scrollDelay); + else + switchToNextMessage = false; + fadeInOut(false); + currentElement = (currentElement + 1)%numElements; + createPixmap(); + drawText(); + maxX = pixmap->DrawPort().Width() - pixmap->ViewPort().Width(); + drawPortX = 0; + doSleep = true; + } + cPixmap::Lock(); + if (Running()) + pixmap->SetDrawPortPoint(cPoint(drawPortX, 0)); + cPixmap::Unlock(); + int Delta = cTimeMs::Now() - Now; + if (Running()) + osd->Flush(); + if (Running() && (Delta < FrameTime)) + cCondWait::SleepMs(FrameTime - Delta); + } + +} + +void cRssReader::fadeInOut(bool fadeIn) { + int frameTime = 50; + int alpha = (fadeIn)?0:225; + for (int i=0; i<10; i++) { + if (Running()) { + if (fadeIn) + alpha += 26; + else + alpha -= 26; + if (alpha < 0) alpha = 0; + if (alpha > 255) alpha = 255; + cPixmap::Lock(); + pixmap->SetAlpha(alpha); + cPixmap::Unlock(); + osd->Flush(); + } + DoSleep(frameTime); + } +} diff --git a/rssreader.h b/rssreader.h new file mode 100644 index 0000000..44fe36a --- /dev/null +++ b/rssreader.h @@ -0,0 +1,58 @@ +#ifndef __NOPACITY_RSSREADER_H
+#define __NOPACITY_RSSREADER_H
+
+#include <curl/curl.h>
+#include <curl/easy.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <string>
+#include <vector>
+
+#define NOPACITY_USERAGENT "libcurl-agent/1.0"
+
+struct XMLMemoryStruct {
+ char *memory;
+ size_t size;
+};
+
+struct RssElement {
+ std::string title;
+ std::string content;
+ int width;
+};
+
+class cRssReader : public cThread{
+public:
+ cRssReader(cOsd *osd, cFont *font, cPoint position, cPoint size);
+ ~cRssReader();
+ virtual void Action(void);
+ void Stop(void) {Cancel(-1);};
+ void SetFeed(std::string feedUrl) {this->feedUrl = feedUrl;};
+ void SwitchNextMessage(void) {switchToNextMessage = true;};
+private:
+ cOsd *osd;
+ cFont *font;
+ cPixmap *pixmap;
+ std::string feedUrl;
+ int x, y;
+ int width, height;
+ void createPixmap(void);
+ void drawText(void);
+ int readRssURL(const char *url);
+ void saveRss(void);
+ void traverseTree(xmlNode * a_node, bool foundItem);
+ void saveItem(void);
+ void fadeInOut(bool fadeIn);
+ XMLMemoryStruct xmlData;
+ xmlDoc *doc;
+ std::string title, content;
+ std::vector<RssElement> rssElements;
+ int currentElement;
+ bool useProxy;
+ std::string httpproxy;
+ std::string separator;
+ void DoSleep(int duration);
+ bool switchToNextMessage;
+};
+
+#endif //__NOPACITY_RSSREADER_H
\ No newline at end of file @@ -26,6 +26,7 @@ void cNopacitySetup::Setup(void) { Add(new cOsdItem(tr("Audio Tracks"))); Add(new cOsdItem(tr("Messages"))); Add(new cOsdItem(tr("Volume"))); + Add(new cOsdItem(tr("RSS Feeds"))); SetCurrent(Get(currentItem)); Display(); @@ -61,6 +62,8 @@ eOSState cNopacitySetup::ProcessKey(eKeys Key) { state = AddSubMenu(new cNopacitySetupMessageDisplay(&tmpNopacityConfig)); if (strcmp(ItemText, tr("Volume")) == 0) state = AddSubMenu(new cNopacitySetupVolumeDisplay(&tmpNopacityConfig)); + if (strcmp(ItemText, tr("RSS Feeds")) == 0) + state = AddSubMenu(new cNopacitySetupRssFeed(&tmpNopacityConfig)); } } return state; @@ -188,6 +191,16 @@ void cNopacitySetup::Store(void) { SetupStore("fontDetailViewHeader", config.fontDetailViewHeader); SetupStore("fontDetailViewHeaderLarge", config.fontDetailViewHeaderLarge); SetupStore("fontEPGInfoWindow", config.fontEPGInfoWindow); + SetupStore("displayRSSFeed", config.displayRSSFeed); + SetupStore("rssFeedHeight", config.rssFeedHeight); + SetupStore("rssFeed[0]", config.rssFeed[0]); + SetupStore("rssFeed[1]", config.rssFeed[1]); + SetupStore("rssFeed[2]", config.rssFeed[2]); + SetupStore("rssFeed[3]", config.rssFeed[3]); + SetupStore("rssFeed[4]", config.rssFeed[4]); + SetupStore("fontRssFeed", config.fontRssFeed); + SetupStore("rssScrollDelay", config.rssScrollDelay); + SetupStore("rssScrollSpeed", config.rssScrollSpeed); } //------------------------------------------------------------------------------------------------------------------ @@ -538,3 +551,42 @@ void cNopacitySetupVolumeDisplay::Set(void) { SetCurrent(Get(currentItem)); Display(); } + +//-----RSS Feeds------------------------------------------------------------------------------------------------------------- + +cNopacitySetupRssFeed::cNopacitySetupRssFeed(cNopacityConfig* data) : cMenuSetupSubMenu(tr("RSS Feeds"), data) { + scrollSpeed[0] = tr("slow"); + scrollSpeed[1] = tr("medium"); + scrollSpeed[2] = tr("fast"); + feedsWithNone[0] = tr("none"); + int i = 0; + for (std::vector<RssFeed>::iterator it = config.rssFeeds.begin(); it!=config.rssFeeds.end(); ++it) { + feeds[i] = it->name.c_str(); + feedsWithNone[i+1] = it->name.c_str(); + i++; + if (i==20) + break; + } + + Set(); +} + +void cNopacitySetupRssFeed::Set(void) { + int currentItem = Current(); + Clear(); + + Add(new cMenuEditBoolItem(tr("Display RSS Feed"), &tmpNopacityConfig->displayRSSFeed)); + if (tmpNopacityConfig->displayRSSFeed) { + Add(new cMenuEditIntItem(cString::sprintf("%s%s", *spacer, tr("Height of RSS Feed Line (Percent of OSD Height)")), &tmpNopacityConfig->rssFeedHeight, 3, 10)); + Add(new cMenuEditStraItem(cString::sprintf("%s%s", *spacer, tr("RSS Feed 1")), &tmpNopacityConfig->rssFeed[0], config.rssFeeds.size(), feeds)); + Add(new cMenuEditStraItem(cString::sprintf("%s%s", *spacer, tr("RSS Feed 2")), &tmpNopacityConfig->rssFeed[1], config.rssFeeds.size()+1, feedsWithNone)); + Add(new cMenuEditStraItem(cString::sprintf("%s%s", *spacer, tr("RSS Feed 3")), &tmpNopacityConfig->rssFeed[2], config.rssFeeds.size()+1, feedsWithNone)); + Add(new cMenuEditStraItem(cString::sprintf("%s%s", *spacer, tr("RSS Feed 4")), &tmpNopacityConfig->rssFeed[3], config.rssFeeds.size()+1, feedsWithNone)); + Add(new cMenuEditStraItem(cString::sprintf("%s%s", *spacer, tr("RSS Feed 5")), &tmpNopacityConfig->rssFeed[4], config.rssFeeds.size()+1, feedsWithNone)); + Add(new cMenuEditStraItem(cString::sprintf("%s%s", *spacer, tr("Scrolling Speed")), &tmpNopacityConfig->rssScrollSpeed, 3, scrollSpeed)); + Add(new cMenuEditIntItem(cString::sprintf("%s%s", *spacer, tr("Scrolling Delay in s")), &tmpNopacityConfig->rssScrollDelay, 0, 3)); + Add(new cMenuEditIntItem(cString::sprintf("%s%s", *spacer, tr("Adjust Font Size")), &tmpNopacityConfig->fontRssFeed, -30, 30)); + } + SetCurrent(Get(currentItem)); + Display(); +}
\ No newline at end of file @@ -110,4 +110,13 @@ class cNopacitySetupVolumeDisplay : public cMenuSetupSubMenu { public: cNopacitySetupVolumeDisplay(cNopacityConfig *data); }; +class cNopacitySetupRssFeed : public cMenuSetupSubMenu { + protected: + const char *scrollSpeed[3]; + const char *feeds[20]; + const char *feedsWithNone[21]; + void Set(void); + public: + cNopacitySetupRssFeed(cNopacityConfig *data); +}; #endif //__NOPACITY_SETUP_H
\ No newline at end of file diff --git a/skinnopacity.c b/skinnopacity.c index de87064..0ca03ea 100644 --- a/skinnopacity.c +++ b/skinnopacity.c @@ -21,6 +21,7 @@ static const char *MAINMENUENTRY = "nOpacity"; class cPluginNopacity : public cPlugin { private: + cNopacity *nopacity; public: cPluginNopacity(void); virtual ~cPluginNopacity(); @@ -46,6 +47,7 @@ public: cPluginNopacity::cPluginNopacity(void) { + nopacity = NULL; } cPluginNopacity::~cPluginNopacity() @@ -107,7 +109,8 @@ bool cPluginNopacity::Start(void) return false; } else dsyslog("nopacity: TrueColor OSD found"); - return new cNopacity; + nopacity = new cNopacity; + return nopacity; } void cPluginNopacity::Stop(void) @@ -157,9 +160,18 @@ const char **cPluginNopacity::SVDRPHelpPages(void) return NULL; } -cString cPluginNopacity::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode) -{ - return NULL; +cString cPluginNopacity::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode) { + if (!strcasecmp(Command, "NEXTMESG")) { + ReplyCode = 250; + nopacity->svdrpSwitchMessage(); + return "Switched to next RSS Message"; + } else if (!strcasecmp(Command, "NEXTFEED")) { + ReplyCode = 250; + nopacity->svdrpSwitchRss(); + return "Switched to next RSS Feed"; + } + ReplyCode = 502; + return NULL; } VDRPLUGINCREATOR(cPluginNopacity); // Don't touch this! |