From e269a87fc24964fbaac485d6a60f3c331ed321a6 Mon Sep 17 00:00:00 2001 From: louis Date: Mon, 8 Apr 2013 19:04:24 +0200 Subject: Added standalone RSS Feed --- HISTORY | 1 + README | 17 ++++++---- config.c | 8 ++++- config.h | 3 ++ nopacity.c | 48 +++++++++++++++++++++++++- nopacity.h | 2 ++ po/de_DE.po | 21 ++++++++++-- po/it_IT.po | 19 +++++++++-- po/sk_SK.po | 19 +++++++++-- rssreader.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- rssreader.h | 24 +++++++++++++ setup.c | 25 +++++++++----- setup.h | 1 + skinnopacity.c | 7 ++++ 14 files changed, 275 insertions(+), 25 deletions(-) diff --git a/HISTORY b/HISTORY index bcb7bcd..ef4beec 100644 --- a/HISTORY +++ b/HISTORY @@ -190,3 +190,4 @@ Version 0.1.1 - Fixed crash on initial startup with xine plugin as output device - Fixed crash / hang if menu is opened with small screen size - Background of ChannelDisplay configurable also to cover channel logo +- Added standalone RSS Feed diff --git a/README b/README index cf9ac20..94858ed 100644 --- a/README +++ b/README @@ -114,9 +114,11 @@ In this example, as a dirty hack just create a folder in your channel logo direc 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: +nOpacity supports the display of RSS Feeds in the VDR menu and standalone. Displaying the +RSS Feed in the VDR menu is disabled per default because on slow machines it could slow down +the VDR menu. If you like, enable it in the RSS Feed setup. +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 @@ -133,9 +135,12 @@ Each rss feed configured in this file can be selected in the plugin setup for th "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: +The standalone RSS Feed can be activated (and if active dectivated) with the svdrp command: + +svdrpsend plug skinnopacity STANDALONEFEED + +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 diff --git a/config.c b/config.c index 612915d..d795033 100644 --- a/config.c +++ b/config.c @@ -138,9 +138,12 @@ cNopacityConfig::cNopacityConfig() { fontDetailViewHeaderLarge = 0; fontEPGInfoWindow = 0; //RSS Feeds - displayRSSFeed = 1; + displayRSSFeed = 0; rssFeedHeight = 5; + rssFeedHeightStandalone = 7; fontRssFeed = 0; + fontRssFeedStandalone = 0; + rssFeedStandalonePos = 0; rssScrollDelay = 2; rssScrollSpeed = 1; rssFeed[0] = 0; @@ -404,6 +407,9 @@ bool cNopacityConfig::SetupParse(const char *Name, const char *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 if (strcmp(Name, "rssFeedHeightStandalone") == 0) rssFeedHeightStandalone = atoi(Value); + else if (strcmp(Name, "fontRssFeedStandalone") == 0) fontRssFeedStandalone = atoi(Value); + else if (strcmp(Name, "rssFeedStandalonePos") == 0) rssFeedStandalonePos = atoi(Value); else return false; return true; diff --git a/config.h b/config.h index 8b58dc7..dc6eeca 100644 --- a/config.h +++ b/config.h @@ -171,7 +171,10 @@ class cNopacityConfig { std::vector rssFeeds; int displayRSSFeed; int rssFeedHeight; + int rssFeedHeightStandalone; int fontRssFeed; + int fontRssFeedStandalone; + int rssFeedStandalonePos; int rssScrollDelay; int rssScrollSpeed; int rssScrollFrameTime; diff --git a/nopacity.c b/nopacity.c index 80ac5e2..5f95cdb 100644 --- a/nopacity.c +++ b/nopacity.c @@ -130,9 +130,9 @@ THEME_CLR(Theme, clrMessageBlend, CLR_TRANSBLACK); cNopacityConfig config; #include "setup.c" #include "imageloader.c" -#include "nopacity.h" #include "helpers.c" #include "rssreader.c" +#include "nopacity.h" #include "displaychannel.c" #include "textwindow.c" #include "timers.c" @@ -149,6 +149,7 @@ cNopacityConfig config; cNopacity::cNopacity(void) : cSkin("nOpacity", &::Theme) { displayMenu = NULL; + rssTicker = NULL; config.setDynamicValues(); config.loadRssFeeds(); } @@ -158,10 +159,18 @@ const char *cNopacity::Description(void) { } cSkinDisplayChannel *cNopacity::DisplayChannel(bool WithInfo) { + if (rssTicker) { + delete rssTicker; + rssTicker = NULL; + } return new cNopacityDisplayChannel(WithInfo); } cSkinDisplayMenu *cNopacity::DisplayMenu(void) { + if (rssTicker) { + delete rssTicker; + rssTicker = NULL; + } cNopacityDisplayMenu *menu = new cNopacityDisplayMenu; displayMenu = menu; menuActive = true; @@ -169,29 +178,66 @@ cSkinDisplayMenu *cNopacity::DisplayMenu(void) { } cSkinDisplayReplay *cNopacity::DisplayReplay(bool ModeOnly) { + if (rssTicker) { + delete rssTicker; + rssTicker = NULL; + } return new cNopacityDisplayReplay(ModeOnly); } cSkinDisplayVolume *cNopacity::DisplayVolume(void) { + if (rssTicker) { + delete rssTicker; + rssTicker = NULL; + } return new cNopacityDisplayVolume; } cSkinDisplayTracks *cNopacity::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks) { + if (rssTicker) { + delete rssTicker; + rssTicker = NULL; + } return new cNopacityDisplayTracks(Title, NumTracks, Tracks); } cSkinDisplayMessage *cNopacity::DisplayMessage(void) { + if (rssTicker) { + delete rssTicker; + rssTicker = NULL; + } return new cNopacityDisplayMessage; } void cNopacity::svdrpSwitchRss(void) { if (menuActive) { displayMenu->SwitchNextRssFeed(); + } else if (rssTicker) { + rssTicker->SwitchNextRssFeed(); } } void cNopacity::svdrpSwitchMessage(void) { if (menuActive) { displayMenu->SwitchNextRssMessage(); + } else if (rssTicker) { + rssTicker->SwitchNextRssMessage(); + } +} + +bool cNopacity::svdrpToggleStandaloneRss(void) { + if (menuActive) + return false; + + if (!rssTicker) { + rssTicker = new cRssStandaloneTicker(); + rssTicker->SetFeed(config.rssFeeds[config.rssFeed[0]].name); + rssTicker->Start(); + return true; + } else { + delete rssTicker; + rssTicker = NULL; + return false; } + return false; } \ No newline at end of file diff --git a/nopacity.h b/nopacity.h index 8fb1ab5..cc49a43 100644 --- a/nopacity.h +++ b/nopacity.h @@ -9,6 +9,7 @@ class cNopacityDisplayMenu; class cNopacity : public cSkin { private: cNopacityDisplayMenu *displayMenu; + cRssStandaloneTicker *rssTicker; public: cNopacity(void); virtual const char *Description(void); @@ -20,5 +21,6 @@ public: virtual cSkinDisplayMessage *DisplayMessage(void); void svdrpSwitchRss(void); void svdrpSwitchMessage(void); + bool svdrpToggleStandaloneRss(void); }; #endif //__NOPACITY_H diff --git a/po/de_DE.po b/po/de_DE.po index e332809..2c6f3f0 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: \n" -"POT-Creation-Date: 2013-04-07 13:48+0200\n" +"POT-Creation-Date: 2013-04-08 18:48+0200\n" "PO-Revision-Date: 2012-11-11 17:49+0200\n" "Last-Translator: louis\n" "Language-Team: \n" @@ -410,12 +410,27 @@ msgstr "Höhe der Lautstärken Anzeige (% der OSD Höhe)" msgid "none" msgstr "keiner" -msgid "Display RSS Feed" -msgstr "RSS Feed anzeigen" +msgid "bottom" +msgstr "unten" + +msgid "top" +msgstr "oben" + +msgid "Display RSS Feed in Skin" +msgstr "RSS Feed im Skin anzeigen" msgid "Height of RSS Feed Line (Percent of OSD Height)" msgstr "Höhe des RSS Feeds (% der OSD Höhe)" +msgid "Height of standalone RSS Feed (Percent of OSD Height)" +msgstr "Höhe des Standalone RSS Feeds (% der OSD Höhe)" + +msgid "Adjust Font Size of standalone Feed" +msgstr "Schriftgröße des standalone Feeds anpassen" + +msgid "Standalone RSS Feed Position" +msgstr "Position des standalone Feeds" + msgid "RSS Feed 1" msgstr "RSS Feed 1" diff --git a/po/it_IT.po b/po/it_IT.po index 2f0f503..89fd7cd 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: \n" -"POT-Creation-Date: 2013-04-07 13:48+0200\n" +"POT-Creation-Date: 2013-04-08 18:48+0200\n" "PO-Revision-Date: 2013-03-19 22:56+0100\n" "Last-Translator: Diego Pierotto \n" "Language-Team: \n" @@ -413,12 +413,27 @@ msgstr "Altezza di Mostra volume (% altezza OSD)" msgid "none" msgstr "" -msgid "Display RSS Feed" +msgid "bottom" +msgstr "" + +msgid "top" +msgstr "" + +msgid "Display RSS Feed in Skin" msgstr "" msgid "Height of RSS Feed Line (Percent of OSD Height)" msgstr "" +msgid "Height of standalone RSS Feed (Percent of OSD Height)" +msgstr "" + +msgid "Adjust Font Size of standalone Feed" +msgstr "" + +msgid "Standalone RSS Feed Position" +msgstr "" + msgid "RSS Feed 1" msgstr "" diff --git a/po/sk_SK.po b/po/sk_SK.po index 39bfc61..d5d4912 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: \n" -"POT-Creation-Date: 2013-04-07 13:48+0200\n" +"POT-Creation-Date: 2013-04-08 18:48+0200\n" "PO-Revision-Date: 2013-03-12 15:59+0100\n" "Last-Translator: Milan Hrala \n" "Language-Team: \n" @@ -413,12 +413,27 @@ msgstr "" msgid "none" msgstr "" -msgid "Display RSS Feed" +msgid "bottom" +msgstr "" + +msgid "top" +msgstr "" + +msgid "Display RSS Feed in Skin" msgstr "" msgid "Height of RSS Feed Line (Percent of OSD Height)" msgstr "" +msgid "Height of standalone RSS Feed (Percent of OSD Height)" +msgstr "" + +msgid "Adjust Font Size of standalone Feed" +msgstr "" + +msgid "Standalone RSS Feed Position" +msgstr "" + msgid "RSS Feed 1" msgstr "" diff --git a/rssreader.c b/rssreader.c index d3ff151..ae9eef1 100644 --- a/rssreader.c +++ b/rssreader.c @@ -170,6 +170,7 @@ void cRssReader::DoSleep(int duration) { } void cRssReader::Action(void) { +esyslog("nopacity: feed %s", feedUrl.c_str()); int success = readRssURL(feedUrl.c_str()); if (success < 1) return; @@ -181,7 +182,7 @@ void cRssReader::Action(void) { return; } saveRss(); - +//debugRSS(); int numElements = rssElements.size(); int scrollDelay = config.rssScrollDelay * 1000; int drawPortX; @@ -252,3 +253,105 @@ void cRssReader::fadeInOut(bool fadeIn) { DoSleep(frameTime); } } + +void cRssReader::debugRSS(void) { + for (std::vector::iterator it = rssElements.begin(); it!=rssElements.end(); ++it) { + esyslog("nopacity: title %s", it->title.c_str()); + esyslog("nopacity: content %s", it->content.c_str()); + } + +} + +cRssStandaloneTicker::cRssStandaloneTicker(void) { + osdLeft = cOsd::OsdLeft(); + osdWidth = cOsd::OsdWidth(); + osdHeight = config.rssFeedHeightStandalone * cOsd::OsdHeight() / 100; + if (config.rssFeedStandalonePos == 0) + osdTop = cOsd::OsdHeight() - osdHeight - 5; + else + osdTop = cOsd::OsdTop() + 5; + + osd = CreateOsd(osdLeft, osdTop, osdWidth, osdHeight); + font = cFont::CreateFont(config.fontName, (osdHeight / 2) + 3 + config.fontRssFeedStandalone); + pixmapBackground = osd->CreatePixmap(1, cRect(0, 0, osdWidth, osdHeight)); + pixmapFeed = osd->CreatePixmap(2, cRect(0, 0, osdWidth, osdHeight)); + pixmapIcon = osd->CreatePixmap(3, cRect(0, 0, osdHeight, osdHeight)); + currentFeed = 0; +} + +cRssStandaloneTicker::~cRssStandaloneTicker() { + if (rssReader) { + rssReader->Stop(); + while (rssReader->Active()) + cCondWait::SleepMs(10); + delete rssReader; + rssReader = NULL; + } + osd->DestroyPixmap(pixmapFeed); + osd->DestroyPixmap(pixmapBackground); + osd->DestroyPixmap(pixmapIcon); + delete font; + delete osd; +} + +void cRssStandaloneTicker::SetFeed(std::string feedName) { + pixmapBackground->Fill(clrBlack); + pixmapFeed->Fill(clrTransparent); + pixmapIcon->Fill(clrTransparent); + + int feedNameLength = font->Width(feedName.c_str()); + labelWidth = 2 + osdHeight + 2 + feedNameLength + 6; + pixmapFeed->Fill(Theme.Color(clrMenuBorder)); + cImageLoader imgLoader; + imgLoader.DrawBackground(Theme.Color(clrMenuItemHigh), Theme.Color(clrMenuItemHighBlend), labelWidth, osdHeight - 4); + pixmapFeed->DrawImage(cPoint(2,2), imgLoader.GetImage()); + + imgLoader.DrawBackground(Theme.Color(clrMenuItem), Theme.Color(clrMenuItemBlend), osdWidth - labelWidth - 2, osdHeight - 4); + pixmapFeed->DrawImage(cPoint(labelWidth,2), imgLoader.GetImage()); + + pixmapFeed->DrawText(cPoint(osdHeight + 2, (osdHeight - font->Height()) / 2), feedName.c_str(), Theme.Color(clrMenuFontHeader), clrTransparent, font); + pixmapIcon->Fill(clrTransparent); + if (imgLoader.LoadIcon("skinIcons/rss", osdHeight-4)) { + cImage icon = imgLoader.GetImage(); + pixmapIcon->DrawImage(cPoint(2,2), icon); + } + + osd->Flush(); +} + +void cRssStandaloneTicker::Start(void) { + rssReader = new cRssReader(osd, font, cPoint(labelWidth,0), cPoint(osdWidth, osdHeight)); + rssReader->SetFeed(config.rssFeeds[config.rssFeed[currentFeed]].url); + rssReader->Start(); +} + +void cRssStandaloneTicker::SwitchNextRssMessage(void) { + if (rssReader) { + rssReader->SwitchNextMessage(); + } +} + +void cRssStandaloneTicker::SwitchNextRssFeed(void) { + 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); + SetFeed(config.rssFeeds[feedNum].name); + Start(); +} + +void cRssStandaloneTicker::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/rssreader.h b/rssreader.h index 44fe36a..86c7119 100644 --- a/rssreader.h +++ b/rssreader.h @@ -53,6 +53,30 @@ private: std::string separator; void DoSleep(int duration); bool switchToNextMessage; + void debugRSS(void); }; +class cRssStandaloneTicker { + public: + cRssStandaloneTicker(void); + ~cRssStandaloneTicker(); + void Start(void); + void SetFeed(std::string feedName); + void SwitchNextRssMessage(void); + void SwitchNextRssFeed(void); + private: + int osdLeft; + int osdTop; + int osdWidth; + int osdHeight; + cRssReader *rssReader; + cOsd *osd; + cPixmap *pixmapFeed; + cPixmap *pixmapBackground; + cPixmap *pixmapIcon; + cFont *font; + int labelWidth; + int currentFeed; + void SetNextFeed(void); +}; #endif //__NOPACITY_RSSREADER_H \ No newline at end of file diff --git a/setup.c b/setup.c index 43998de..85f67fa 100644 --- a/setup.c +++ b/setup.c @@ -202,6 +202,9 @@ void cNopacitySetup::Store(void) { SetupStore("fontRssFeed", config.fontRssFeed); SetupStore("rssScrollDelay", config.rssScrollDelay); SetupStore("rssScrollSpeed", config.rssScrollSpeed); + SetupStore("rssFeedHeightStandalone", config.rssFeedHeightStandalone); + SetupStore("fontRssFeedStandalone", config.fontRssFeedStandalone); + SetupStore("rssFeedStandalonePos", config.rssFeedStandalonePos); } //------------------------------------------------------------------------------------------------------------------ @@ -571,7 +574,8 @@ cNopacitySetupRssFeed::cNopacitySetupRssFeed(cNopacityConfig* data) : cMenuSetu if (i==20) break; } - + standalonePos[0] = tr("bottom"); + standalonePos[1] = tr("top"); Set(); } @@ -579,18 +583,21 @@ void cNopacitySetupRssFeed::Set(void) { int currentItem = Current(); Clear(); - Add(new cMenuEditBoolItem(tr("Display RSS Feed"), &tmpNopacityConfig->displayRSSFeed)); + Add(new cMenuEditBoolItem(tr("Display RSS Feed in Skin"), &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)); } + Add(new cMenuEditIntItem(tr("Height of standalone RSS Feed (Percent of OSD Height)"), &tmpNopacityConfig->rssFeedHeightStandalone, 3, 20)); + Add(new cMenuEditIntItem(tr("Adjust Font Size of standalone Feed"), &tmpNopacityConfig->fontRssFeedStandalone, -30, 30)); + Add(new cMenuEditStraItem(tr("Standalone RSS Feed Position"), &tmpNopacityConfig->rssFeedStandalonePos, 2, standalonePos)); + Add(new cMenuEditStraItem(tr("RSS Feed 1"), &tmpNopacityConfig->rssFeed[0], config.rssFeeds.size(), feeds)); + Add(new cMenuEditStraItem(tr("RSS Feed 2"), &tmpNopacityConfig->rssFeed[1], config.rssFeeds.size()+1, feedsWithNone)); + Add(new cMenuEditStraItem(tr("RSS Feed 3"), &tmpNopacityConfig->rssFeed[2], config.rssFeeds.size()+1, feedsWithNone)); + Add(new cMenuEditStraItem(tr("RSS Feed 4"), &tmpNopacityConfig->rssFeed[3], config.rssFeeds.size()+1, feedsWithNone)); + Add(new cMenuEditStraItem(tr("RSS Feed 5"), &tmpNopacityConfig->rssFeed[4], config.rssFeeds.size()+1, feedsWithNone)); + Add(new cMenuEditStraItem(tr("Scrolling Speed"), &tmpNopacityConfig->rssScrollSpeed, 3, scrollSpeed)); + Add(new cMenuEditIntItem(tr("Scrolling Delay in s"), &tmpNopacityConfig->rssScrollDelay, 0, 3)); SetCurrent(Get(currentItem)); Display(); } \ No newline at end of file diff --git a/setup.h b/setup.h index 93c5c14..c9ede08 100644 --- a/setup.h +++ b/setup.h @@ -116,6 +116,7 @@ class cNopacitySetupRssFeed : public cMenuSetupSubMenu { const char *scrollSpeed[3]; const char *feeds[20]; const char *feedsWithNone[21]; + const char *standalonePos[2]; void Set(void); public: cNopacitySetupRssFeed(cNopacityConfig *data); diff --git a/skinnopacity.c b/skinnopacity.c index 0ca03ea..f24b9a4 100644 --- a/skinnopacity.c +++ b/skinnopacity.c @@ -169,6 +169,13 @@ cString cPluginNopacity::SVDRPCommand(const char *Command, const char *Option, i ReplyCode = 250; nopacity->svdrpSwitchRss(); return "Switched to next RSS Feed"; + } else if (!strcasecmp(Command, "STANDALONEFEED")) { + ReplyCode = 250; + bool onOff = nopacity->svdrpToggleStandaloneRss(); + if (onOff) + return "Displaying standalone RSS Feed"; + else + return "Closing standalone RSS Feed"; } ReplyCode = 502; return NULL; -- cgit v1.2.3