aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Moore <moorekou@gmail.com>2016-05-31 15:49:42 -0400
committerKen Moore <moorekou@gmail.com>2016-05-31 15:49:42 -0400
commit0e378ef4f087a04e4cc3643eb533f2e59e1a9061 (patch)
tree5d25faa30ee9b4aadd37c6d0dea67880c68d035d
parentAdd a note to the OS-detect.pri file that the OS and LINUX_DISTRO variables s... (diff)
downloadlumina-0e378ef4f087a04e4cc3643eb533f2e59e1a9061.tar.gz
lumina-0e378ef4f087a04e4cc3643eb533f2e59e1a9061.tar.bz2
lumina-0e378ef4f087a04e4cc3643eb533f2e59e1a9061.zip
Add the beginnings of a new desktop plugin: rssreader
This is a simple RSS reader for the desktop. (Not finished yet - but getting close).
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/NewDP.h3
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/desktop-plugins.pri11
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.cpp186
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.h66
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.ui523
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.cpp101
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.h86
7 files changed, 973 insertions, 3 deletions
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/NewDP.h b/src-qt5/core/lumina-desktop/desktop-plugins/NewDP.h
index a12341bb..bbb0539b 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/NewDP.h
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/NewDP.h
@@ -22,6 +22,7 @@
#include "systemmonitor/MonitorWidget.h"
//#include "quickcontainer/QuickDPlugin.h"
//#include "messagecenter/MessageCenter.h"
+#include "rssfeeder/RSSFeedPlugin.h"
class NewDP{
public:
@@ -48,6 +49,8 @@ public:
//plug = new MessageCenterPlugin(parent, plugin);
//}else if(plugin.section("---",0,0).startsWith("quick-") && LUtils::validQuickPlugin(plugin.section("---",0,0)) ){
//plug = new QuickDPlugin(parent, plugin);
+ }else if(plugin.section("---",0,0)=="rssfeeder"){
+ plug = new RSSFeedPlugin(parent, plugin);
}else{
qWarning() << "Invalid Desktop Plugin:"<<plugin << " -- Ignored";
}
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/desktop-plugins.pri b/src-qt5/core/lumina-desktop/desktop-plugins/desktop-plugins.pri
index 5a631b52..e39c594e 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/desktop-plugins.pri
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/desktop-plugins.pri
@@ -2,7 +2,9 @@ SOURCES += $$PWD/applauncher/AppLauncherPlugin.cpp \
$$PWD/desktopview/DesktopViewPlugin.cpp \
$$PWD/notepad/NotepadPlugin.cpp \
$$PWD/audioplayer/PlayerWidget.cpp \
- $$PWD/systemmonitor/MonitorWidget.cpp
+ $$PWD/systemmonitor/MonitorWidget.cpp \
+ $$PWD/rssfeeder/RSSFeedPlugin.cpp \
+ $$PWD/rssfeeder/RSSObjects.cpp
# $$PWD/messagecenter/MessageCenter.cpp
HEADERS += $$PWD/calendar/CalendarPlugin.h \
@@ -11,9 +13,12 @@ HEADERS += $$PWD/calendar/CalendarPlugin.h \
$$PWD/desktopview/DesktopViewPlugin.h \
$$PWD/notepad/NotepadPlugin.h \
$$PWD/audioplayer/PlayerWidget.h \
- $$PWD/systemmonitor/MonitorWidget.h
+ $$PWD/systemmonitor/MonitorWidget.h \
+ $$PWD/rssfeeder/RSSFeedPlugin.h \
+ $$PWD/rssfeeder/RSSObjects.h
# $$PWD/quickcontainer/QuickDPlugin.h
# $$PWD/messagecenter/MessageCenter.h
FORMS += $$PWD/audioplayer/PlayerWidget.ui \
- $$PWD/systemmonitor/MonitorWidget.ui \ No newline at end of file
+ $$PWD/systemmonitor/MonitorWidget.ui \
+ $$PWD/rssfeeder/RSSFeedPlugin.ui
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.cpp b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.cpp
new file mode 100644
index 00000000..d4a9aa44
--- /dev/null
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.cpp
@@ -0,0 +1,186 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "RSSFeedPlugin.h"
+#include "ui_RSSFeedPlugin.h"
+
+#include <LuminaXDG.h>
+#include "LSession.h"
+#include <LuminaUtils.h>
+#include <QDir>
+#include <QFileDialog>
+#include <QInputDialog>
+#include <QtConcurrent>
+
+RSSFeedPlugin::RSSFeedPlugin(QWidget* parent, QString ID) : LDPlugin(parent, ID), ui(new Ui::RSSFeedPlugin()){
+ ui->setupUi(this);
+ //Load the global settings
+ setprefix = "rssreader/"; //this structure/prefix should be used for *all* plugins of this type
+
+ //Create the options menu
+ optionsMenu = new QMenu(this);
+ ui->tool_options->setMenu(optionsMenu);
+ //Setup any signal/slot connections
+ connect(ui->push_back1, SIGNAL(clicked()), this, SLOT(backToFeeds()) );
+ connect(ui->push_back2, SIGNAL(clicked()), this, SLOT(backToFeeds()) );
+ connect(ui->push_back3, SIGNAL(clicked()), this, SLOT(backToFeeds()) );
+ connect(ui->push_save_settings, SIGNAL(clicked()), this, SLOT(saveSettings()) );
+
+ updateOptionsMenu();
+ QTimer::singleShot(0,this, SLOT(loadIcons()) );
+ //qDebug() << " - Done with init";
+}
+
+RSSFeedPlugin::~RSSFeedPlugin(){
+
+}
+
+//================
+// PRIVATE
+//================
+void RSSFeedPlugin::updateOptionsMenu(){
+ optionsMenu->clear();
+ optionsMenu->addAction(LXDG::findIcon("list-add",""), tr("Add RSS Feed"), this, SLOT(openFeedNew()) );
+ optionsMenu->addAction(LXDG::findIcon("help-about",""), tr("View Feed Details"), this, SLOT(openFeedInfo()) );
+ optionsMenu->addAction(LXDG::findIcon("configure",""), tr("Settings"), this, SLOT(openSettings()) );
+ optionsMenu->addSeparator();
+ optionsMenu->addAction(LXDG::findIcon("download",""), tr("Update Feeds Now"), this, SLOT(resync()) );
+}
+
+//Simplification functions for loading feed info onto widgets
+void RSSFeedPlugin::updateFeed(QString ID){
+
+}
+
+void RSSFeedPlugin::updateFeedInfo(QString ID){
+
+}
+
+//================
+// PRIVATE SLOTS
+//================
+void RSSFeedPlugin::loadIcons(){
+ ui->tool_options->setIcon( LXDG::findIcon("configure","") );
+ ui->tool_gotosite->setIcon( LXDG::findIcon("applications-internet","") );
+ ui->push_back1->setIcon( LXDG::findIcon("go-previous","") );
+ ui->push_back2->setIcon( LXDG::findIcon("go-previous","") );
+ ui->push_back3->setIcon( LXDG::findIcon("go-previous","") );
+ ui->push_rm_feed->setIcon( LXDG::findIcon("list-remove","") );
+ ui->push_add_url->setIcon( LXDG::findIcon("list-add","") );
+ ui->push_save_settings->setIcon( LXDG::findIcon("document-save","") );
+}
+
+//GUI slots
+// - Page management
+void RSSFeedPlugin::backToFeeds(){
+ ui->stackedWidget->setCurrentWidget(ui->page_feed);
+}
+
+void RSSFeedPlugin::openFeedInfo(){
+ ui->stackedWidget->setCurrentWidget(ui->page_feed_info);
+
+}
+
+void RSSFeedPlugin::openFeedNew(){
+ ui->line_new_url->setText("");
+ ui->stackedWidget->setCurrentWidget(ui->page_new_feed);
+}
+
+void RSSFeedPlugin::openSettings(){
+ //Sync the widget with the current settings
+ QSettings *set = LSession::handle()->DesktopPluginSettings();
+
+ ui->check_manual_sync->setChecked( set->value(setprefix+"manual_sync_only", false).toBool() );
+ int DI = set->value(setprefix+"default_interval_minutes", 60).toInt();
+ if(DI<1){ DI = 60; }
+ if( (DI%60) == 0 ){DI = DI/60; ui->combo_sync_units->setCurrentIndex(1); } //hourly setting
+ else{ ui->combo_sync_units->setCurrentIndex(1); } //minutes setting
+ ui->spin_synctime->setValue(DI);
+
+ //Now show the page
+ ui->stackedWidget->setCurrentWidget(ui->page_settings);
+}
+
+// - Feed Management
+void RSSFeedPlugin::addNewFeed(){
+ if(ui->line_new_url->text().isEmpty()){ return; } //nothing to add
+ //Validate the URL
+ QUrl url(ui->line_new_url->text());
+ if(!url.isValid()){
+ ui->line_new_url->setFocus();
+ return;
+ }
+
+ //Set this URL as the current selection
+ ui->combo_feed->setWhatsThis(url.toString()); //hidden field - will trigger an update in a moment
+ //Add the URL to the backend
+
+ UpdateFeedList(); //now re-load the feeds which are available
+
+ //Now go back to the main page
+ backToFeeds();
+}
+
+void RSSFeedPlugin::removeFeed(){
+ QString ID = ui->page_feed_info->whatsThis();
+ if(ID.isEmpty()){ return; }
+ //Remove from the RSS feed object
+
+ //Update the feed list
+ UpdateFeedList(); //now re-load the feeds which are available
+ //Now go back to the main page
+ backToFeeds();
+}
+
+// - Feed Interactions
+void RSSFeedPlugin::currentFeedChanged(){
+ QString ID = ui->combo_feed->currentData().toString();
+ if(ID.isEmpty()){ return; } //no feed selected
+}
+
+void RSSFeedPlugin::openFeedPage(){ //Open main website for feed
+ QString ID = ui->combo_feed->currentData().toString();
+ //Find the data associated with this feed
+ QString url;
+
+ //Now launch the browser
+ if(!url.isEmpty()){
+ QProcess::startDetached("lumina-open \""+url+"\"");
+ }
+}
+
+void RSSFeedPlugin::saveSettings(){
+ QSettings *set = LSession::handle()->DesktopPluginSettings();
+ set->setValue(setprefix+"manual_sync_only", ui->check_manual_sync->isChecked() );
+ int DI = ui->spin_synctime->value();
+ if(ui->combo_sync_units->currentIndex()==1){ DI = DI*60; } //convert from hours to minutes
+ set->setValue(setprefix+"default_interval_minutes", DI);
+ set->sync();
+ //Now prod the feed object that something changed
+
+ //Now go back to the feeds
+ backToFeeds();
+}
+
+//Feed Object interactions
+void RSSFeedPlugin::UpdateFeedList(){
+
+}
+
+void RSSFeedPlugin::RSSItemChanged(QString ID){
+
+}
+//==================
+// PUBLIC SLOTS
+//==================
+void RSSFeedPlugin::LocaleChange(){
+ ui->retranslateUi(this);
+ updateOptionsMenu();
+}
+void RSSFeedPlugin::ThemeChange(){
+ QTimer::singleShot(0,this, SLOT(loadIcons()));
+ updateOptionsMenu();
+}
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.h b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.h
new file mode 100644
index 00000000..a29e5ec1
--- /dev/null
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.h
@@ -0,0 +1,66 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// This plugin is a simple RSS feed reader for the desktop
+//===========================================
+#ifndef _LUMINA_DESKTOP_RSS_FEEDER_PLUGIN_H
+#define _LUMINA_DESKTOP_RSS_FEEDER_PLUGIN_H
+
+#include <QTimer>
+#include "../LDPlugin.h"
+
+namespace Ui{
+ class RSSFeedPlugin;
+};
+
+class RSSFeedPlugin : public LDPlugin{
+ Q_OBJECT
+public:
+ RSSFeedPlugin(QWidget* parent, QString ID);
+ ~RSSFeedPlugin();
+
+ virtual QSize defaultPluginSize(){
+ // The returned QSize is in grid points (typically 100 or 200 pixels square)
+ return QSize(3,3);
+ }
+private:
+ Ui::RSSFeedPlugin *ui;
+ QMenu *optionsMenu;
+ QString setprefix; //settings prefix
+
+ void updateOptionsMenu();
+
+ //Simplification functions for loading feed info onto widgets
+ void updateFeed(QString ID);
+ void updateFeedInfo(QString ID);
+
+private slots:
+ void loadIcons();
+
+ //GUI slots
+ // - Page management
+ void backToFeeds();
+ void openFeedInfo();
+ void openFeedNew();
+ void openSettings();
+ // - Feed Management
+ void addNewFeed(); // the "add" button (current url in widget on page)
+ void removeFeed(); // the "remove" button (current feed for page)
+ // - Feed Interactions
+ void currentFeedChanged();
+ void openFeedPage(); //Open the website in a browser
+ void saveSettings();
+
+ //Feed Object interactions
+ void UpdateFeedList();
+ void RSSItemChanged(QString ID);
+
+public slots:
+ void LocaleChange();
+ void ThemeChange();
+
+};
+#endif
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.ui b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.ui
new file mode 100644
index 00000000..d9972473
--- /dev/null
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.ui
@@ -0,0 +1,523 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>RSSFeedPlugin</class>
+ <widget class="QWidget" name="RSSFeedPlugin">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>238</width>
+ <height>278</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>2</number>
+ </property>
+ <property name="bottomMargin">
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="QStackedWidget" name="stackedWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="page_feed">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QComboBox" name="combo_feed"/>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tool_options">
+ <property name="toolTip">
+ <string>View Options</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="popupMode">
+ <enum>QToolButton::InstantPopup</enum>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_lastupdate">
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tool_gotosite">
+ <property name="toolTip">
+ <string>Open Website</string>
+ </property>
+ <property name="text">
+ <string>More</string>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ <property name="arrowType">
+ <enum>Qt::NoArrow</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTextEdit" name="text_feed">
+ <property name="undoRedoEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="html">
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page_feed_info">
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>5</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QPushButton" name="push_back1">
+ <property name="text">
+ <string>Back to Feeds</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Feed Information</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QScrollArea" name="scroll_feed_info">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents_2">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>228</width>
+ <height>178</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <item>
+ <widget class="QPushButton" name="push_rm_feed">
+ <property name="text">
+ <string>Remove Feed</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page_new_feed">
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QPushButton" name="push_back2">
+ <property name="text">
+ <string>Back to Feeds</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>New Feed Subscription</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_6">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>2</number>
+ </property>
+ <property name="bottomMargin">
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>RSS URL</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="line_new_url"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="push_add_url">
+ <property name="text">
+ <string>Add to Feeds</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page_settings">
+ <layout class="QVBoxLayout" name="verticalLayout_7">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
+ <widget class="QPushButton" name="push_back3">
+ <property name="text">
+ <string>Back to Feeds</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Feed Reader Settings</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_8">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>2</number>
+ </property>
+ <property name="bottomMargin">
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="check_manual_sync">
+ <property name="text">
+ <string>Manual Sync Only</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_4">
+ <property name="toolTip">
+ <string>Some RSS feeds may request custom update intervals instead of using this setting</string>
+ </property>
+ <property name="title">
+ <string>Default Sync Interval</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_7">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>2</number>
+ </property>
+ <property name="bottomMargin">
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="spin_synctime">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>60</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="combo_sync_units">
+ <property name="currentText">
+ <string>Hour(s)</string>
+ </property>
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>Minutes</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Hour(s)</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_9">
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="push_save_settings">
+ <property name="text">
+ <string>Save Settings</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.cpp b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.cpp
new file mode 100644
index 00000000..45a6bfeb
--- /dev/null
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.cpp
@@ -0,0 +1,101 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "RSSObjects.h"
+#include <QNetworkRequest>
+#include <QXmlStreamReader>
+
+//============
+// PUBLIC
+//============
+RSSReader::RSSReader(QObject *parent) : QObject(parent){
+ NMAN = new QNetworkAccessManager(this);
+}
+
+RSSReader::~RSSReader(){
+
+}
+
+//Information retrieval
+QStringList RSSReader::channels(){
+ return QStringList( data.keys() );
+}
+
+Rsschannel RSSReader::dataForID(QString ID){
+
+}
+
+//Initial setup
+void RSSReader::addUrls(){
+
+}
+
+void RSSReader::removeUrl(QString ID){
+
+}
+
+//=================
+// PUBLIC SLOTS
+//=================
+void RSSReader::syncNow(){
+
+}
+
+//=================
+// PRIVATE
+//=================
+void RSSchannel::requestRSS(QString url){
+ NMAN->get( QNetworkRequest( QUrl(url) ) );
+}
+
+//RSS parsing functions
+RSSchannel RSSReader::readRSS(QIODevice *device){
+ QXmlStreamReader xml(device);
+ RSSchannel rssinfo;
+ if(xml.readNextStartElement()){
+ if(xml.name() = "rss" && xml.attributes().value("version" =="2.0")){
+ while(xml.readNextStartElement()){
+ if(xml.name()=="channel"){ rssinfo = readRSSChannel(&xml); }
+ }
+ }
+ }
+ return rssinfo;
+}
+RSSchannel RSSReader::readRSSChannel(QXmlStreamReader *rss){
+ RSSchannel info;
+ while(rss.readNextStartElement()){
+ if(rss.name()=="item"){ info.items << readRSSItem(rss); }
+ else if(rss.name()=="title"){ info.title = rss.readElementText(); }
+ else if(rss.name()=="link"){ info.link = rss.readElementText(); }
+ else if(rss.name()=="description"){ info.description = rss.readElementText(); }
+ else if(rss.name()=="lastBuildDate"){ info.lastBuildDate = RSSDateTime(rss.readElementText()); }
+ else if(rss.name()=="pubDate"){ info.lastPubDate = RSSDateTime(rss.readElementText()); }
+ else if(rss.name()=="image"){ info.link = rss.readElementText(); }
+ else if(rss.name()=="guid"){ info.guid = rss.readElementText(); }
+ //else if(rss.name()=="skipHours"){ info.link = rss.readElementText(); }
+ //else if(rss.name()=="skipDays"){ info.link = rss.readElementText(); }
+ else if(rss.name()=="ttl"){ info.timetolive = rss.readElementText().toInt(); }
+ }
+ return info;
+}
+RSSitem RSSReader::readRSSItem(QXmlStreamReader *rss){
+
+}
+
+QDateTime RSSReader::RSSDateTime(QString datetime){
+
+}
+
+//=================
+// PRIVATE SLOTS
+//=================
+void RSSReader::replyFinished(QNetworkReply *reply){
+ RSSchannel info = ReadRSS(reply); //QNetworkReply can be used as QIODevice
+ reply->deleteLater(); //clean up
+ //Validate the info and announce any changes
+
+
+}
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.h b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.h
new file mode 100644
index 00000000..a1cffc3f
--- /dev/null
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.h
@@ -0,0 +1,86 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#ifndef _LUMINA_DESKTOP_RSS_READER_PLUGIN_OBJECT_H
+#define _LUMINA_DESKTOP_RSS_READER_PLUGIN_OBJECT_H
+
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QString>
+#include <QDateTime>
+#include <QList>
+#include <QIcon>
+
+struct RSSitem{
+ //Required Fields
+ QString title, link, description;
+
+ //Optional Fields
+ QString comments_url, author_email, author, guid;
+ QDateTime pubdate; //when the item was published
+ //IGNORED INFO from RSS2 spec: "category", "source", "enclosure"
+};
+
+struct RSSchannel{
+ //Required fields
+ QString title, link, description;
+
+ //Optional Fields
+ QDateTime lastBuildDate, lastPubDate; //last build/publish dates
+ // - channel refresh information
+ int timetolive; //in minutes - time until next sync should be performed
+ //QList<int> skiphours;
+ //QStringList skipdays;
+ // - icon info
+ QIcon icon;
+ QString iconurl, icontitle, iconlink;
+ QSize iconsize;
+ //All items within this channel
+ QList<RSSitem> items;
+
+ //Optional RSS2 elements ignored:
+ // "cloud", "textInput", "rating", "language", "copyright", "managingEditor", "webMaster",
+ // "category", "generator", "docs"
+};
+
+class RSSReader : public QObject{
+ Q_OBJECT
+public:
+ RSSReader(QObject *parent);
+ ~RSSReader();
+
+ //Information retrieval
+ QStringList channels(); //returns all ID's
+ Rsschannel dataForID(QString ID);
+
+ //Initial setup
+ void addUrls();
+ void removeUrl(QString ID);
+
+public slots:
+ void syncNow(); //not generally needed
+
+private:
+ QHash<QString, RSSchannel> data; // ID/data
+ //Network request functions
+ QNetworkAccessManager *NMAN;
+ void requestRSS(QString url);
+
+ //RSS parsing functions
+ RSSchannel readRSS(QByteArray rss);
+ RSSchannel readRSSChannel(QXmlStreamReader *rss)
+ RSSitem readRSSItem(QXmlStreamReader *rss);
+ QDateTime RSSDateTime(QString datetime);
+
+private slots:
+ void replyFinished(QNetworkReply *reply);
+
+signals:
+ void rssChanged(QString); //ID
+ void newChannelsAvailable();
+};
+
+#endif
bgstack15