summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlouis <louis.braun@gmx.de>2013-04-07 10:39:42 +0200
committerlouis <louis.braun@gmx.de>2013-04-07 10:39:42 +0200
commitfba3191de71867e91eb51cde93136fcdda64c0ab (patch)
treee99221ec2c9a7dc612b7e818c4b544a0c1e65a1d
parent518e7e87332e2b53e9f3e5f9fc853abaec2b360f (diff)
downloadskin-nopacity-fba3191de71867e91eb51cde93136fcdda64c0ab.tar.gz
skin-nopacity-fba3191de71867e91eb51cde93136fcdda64c0ab.tar.bz2
Added RSS Feed support
-rw-r--r--HISTORY1
-rw-r--r--Makefile3
-rw-r--r--README49
-rw-r--r--conf/rssfeeds.conf4
-rw-r--r--config.c85
-rw-r--r--config.h15
-rw-r--r--displaymenu.c54
-rw-r--r--displaymenu.h5
-rw-r--r--displaymenuview.c58
-rw-r--r--displaymenuview.h11
-rw-r--r--icons/skinIcons/rss.pngbin0 -> 10661 bytes
-rw-r--r--menudetailview.c2
-rw-r--r--nopacity.c22
-rw-r--r--nopacity.h6
-rw-r--r--po/de_DE.po35
-rw-r--r--po/it_IT.po35
-rw-r--r--po/sk_SK.po35
-rw-r--r--rssreader.c254
-rw-r--r--rssreader.h58
-rw-r--r--setup.c52
-rw-r--r--setup.h9
-rw-r--r--skinnopacity.c20
22 files changed, 798 insertions, 15 deletions
diff --git a/HISTORY b/HISTORY
index b67dddd..4f32a5e 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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
diff --git a/Makefile b/Makefile
index e2c14ad..bb0d4a0 100644
--- a/Makefile
+++ b/Makefile
@@ -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):
diff --git a/README b/README
index 76c6b9d..9b0c73a 100644
--- a/README
+++ b/README
@@ -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
diff --git a/config.c b/config.c
index 1c4bb94..1fd5e30 100644
--- a/config.c
+++ b/config.c
@@ -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;
diff --git a/config.h b/config.h
index 7ec88d8..38e965a 100644
--- a/config.h
+++ b/config.h
@@ -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
new file mode 100644
index 0000000..b1c7bbe
--- /dev/null
+++ b/icons/skinIcons/rss.png
Binary files differ
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
+}
diff --git a/nopacity.c b/nopacity.c
index 63ea93f..80ac5e2 100644
--- a/nopacity.c
+++ b/nopacity.c
@@ -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
diff --git a/nopacity.h b/nopacity.h
index 8144ee0..8fb1ab5 100644
--- a/nopacity.h
+++ b/nopacity.h
@@ -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
diff --git a/setup.c b/setup.c
index 3cc4617..49c5e29 100644
--- a/setup.c
+++ b/setup.c
@@ -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
diff --git a/setup.h b/setup.h
index 051fa66..61598ea 100644
--- a/setup.h
+++ b/setup.h
@@ -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!