aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Moore <moorekou@gmail.com>2016-06-02 11:25:21 -0400
committerKen Moore <moorekou@gmail.com>2016-06-02 11:25:21 -0400
commit5f5a1115789cce067f277476a6ab44e0d6c5c933 (patch)
treebe58be61c8c775edb7a8cc6593b922daff9ace93
parentGet the new RSS reader plugin mostly-functional. Add/remove feeds seems to wo... (diff)
downloadlumina-5f5a1115789cce067f277476a6ab44e0d6c5c933.tar.gz
lumina-5f5a1115789cce067f277476a6ab44e0d6c5c933.tar.bz2
lumina-5f5a1115789cce067f277476a6ab44e0d6c5c933.zip
Get the new RSS reader plugin all setup and fully-functional.
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.cpp87
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.h4
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.ui58
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.cpp37
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.h1
5 files changed, 148 insertions, 39 deletions
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.cpp b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.cpp
index 0bfc090e..4a1149ba 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.cpp
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.cpp
@@ -24,6 +24,9 @@ RSSFeedPlugin::RSSFeedPlugin(QWidget* parent, QString ID) : LDPlugin(parent, ID)
//Create the options menu
optionsMenu = new QMenu(this);
ui->tool_options->setMenu(optionsMenu);
+ presetMenu = new QMenu(this);
+ ui->tool_add_preset->setMenu(presetMenu);
+
//Setup any signal/slot connections
connect(ui->push_back1, SIGNAL(clicked()), this, SLOT(backToFeeds()) );
connect(ui->push_back2, SIGNAL(clicked()), this, SLOT(backToFeeds()) );
@@ -34,8 +37,12 @@ RSSFeedPlugin::RSSFeedPlugin(QWidget* parent, QString ID) : LDPlugin(parent, ID)
connect(ui->tool_gotosite, SIGNAL(clicked()), this, SLOT(openFeedPage()) );
connect(ui->push_rm_feed, SIGNAL(clicked()), this, SLOT(removeFeed()) );
connect(ui->push_add_url, SIGNAL(clicked()), this, SLOT(addNewFeed()) );
+ connect(ui->combo_feed, SIGNAL(currentIndexChanged(int)), this, SLOT(currentFeedChanged()) );
+
+ connect(presetMenu, SIGNAL(triggered(QAction*)), this, SLOT(loadPreset(QAction*)) );
+
updateOptionsMenu();
- QTimer::singleShot(0,this, SLOT(loadIcons()) );
+ QTimer::singleShot(0,this, SLOT(ThemeChange()) );
//qDebug() << " - Done with init";
QStringList feeds;
if( !LSession::handle()->DesktopPluginSettings()->contains(setprefix+"currentfeeds") ){
@@ -46,6 +53,7 @@ RSSFeedPlugin::RSSFeedPlugin(QWidget* parent, QString ID) : LDPlugin(parent, ID)
feeds = LSession::handle()->DesktopPluginSettings()->value(setprefix+"currentfeeds",QStringList()).toStringList();
}
RSS->addUrls(feeds);
+ backToFeeds(); //always load the first page
}
RSSFeedPlugin::~RSSFeedPlugin(){
@@ -62,15 +70,34 @@ void RSSFeedPlugin::updateOptionsMenu(){
optionsMenu->addAction(LXDG::findIcon("configure",""), tr("Settings"), this, SLOT(openSettings()) );
optionsMenu->addSeparator();
optionsMenu->addAction(LXDG::findIcon("download",""), tr("Update Feeds Now"), this, SLOT(resyncFeeds()) );
+
+ presetMenu->clear();
+ QAction *tmp = presetMenu->addAction( tr("Lumina Desktop RSS") );
+ tmp->setWhatsThis("http://lumina-desktop.org/?feed=rss2");
+ //Add any other feeds here as needed (TO-DO)
+
+}
+
+void RSSFeedPlugin::checkFeedNotify(){
+ bool notify = false;
+ for(int i=0; i<ui->combo_feed->count() && !notify; i++){
+ if( !ui->combo_feed->itemData(i, Qt::WhatsThisRole).toString().isEmpty()){ notify = true; }
+ }
+ QString style;
+ if(notify){ style = "QComboBox::down-arrow{ background-color: rgba(255,0,0,120); }"; }
+ ui->combo_feed->setStyleSheet(style);
}
//Simplification functions for loading feed info onto widgets
void RSSFeedPlugin::updateFeed(QString ID){
- //Save the datetime this feed was read
- LSession::handle()->DesktopPluginSettings()->setValue(setprefix+"feedReads/"+ID, QDateTime::currentDateTime() );
-
//Now clear/update the feed viewer (HTML)
ui->text_feed->clear();
+ if(ID.isEmpty()){ return; } //nothing to show
+
+ //Save the datetime this feed was read
+ LSession::handle()->DesktopPluginSettings()->setValue(setprefix+"feedReads/"+ID, QDateTime::currentDateTime() );
+ //Get the color to use for hyperlinks (need to specify in html)
+ QString color = ui->text_feed->palette().text().color().name(); //keep the hyperlinks the same color as the main text (different formatting still applies)
QString html;
RSSchannel data = RSS->dataForID(ID);
ui->label_lastupdate->setText( data.lastsync.toString(Qt::DefaultLocaleShortDate) );
@@ -78,8 +105,17 @@ void RSSFeedPlugin::updateFeed(QString ID){
// html.append("<ul style=\"margin-left: 3px;\">\n");
for(int i=0; i<data.items.length(); i++){
//html.append("<li>");
- html.append("<h3><a href=\""+data.items[i].link+"\">"+data.items[i].title+"</a></h3>");
- if(!data.items[i].pubdate.isNull()){html.append("<i>("+data.items[i].pubdate.toString(Qt::DefaultLocaleShortDate)+")</i><br>"); }
+ html.append("<h4><a href=\""+data.items[i].link+"\" style=\"color: "+color+";\">"+data.items[i].title+"</a></h4>");
+ if(!data.items[i].pubdate.isNull() || !data.items[i].author.isEmpty()){
+ html.append("<i>(");
+ if(!data.items[i].pubdate.isNull()){ html.append(data.items[i].pubdate.toString(Qt::DefaultLocaleShortDate)); }
+ if(!data.items[i].author.isEmpty()){
+ if(!html.endsWith("(")){ html.append(", "); } //spacing between date/author
+ if(!data.items[i].author_email.isEmpty()){ html.append("<a href=\"mailto:"+data.items[i].author_email+"\" style=\"color: "+color+";\">"+data.items[i].author+"</a>"); }
+ else{ html.append(data.items[i].author); }
+ }
+ html.append(")</i><br>");
+ }
html.append(data.items[i].description);
//html.append("</li>\n");
if(i+1 < data.items.length()){ html.append("<br>"); }
@@ -91,6 +127,23 @@ void RSSFeedPlugin::updateFeed(QString ID){
void RSSFeedPlugin::updateFeedInfo(QString ID){
ui->page_feed_info->setWhatsThis(ID);
+ ui->text_feed_info->clear();
+ if(ID.isEmpty()){ return; }
+ //Get the color to use for hyperlinks (need to specify in html)
+ QString color = ui->text_feed->palette().text().color().name(); //keep the hyperlinks the same color as the main text (different formatting still applies)
+ QString html;
+ RSSchannel data = RSS->dataForID(ID);
+ // - generate the html
+ // <a href=\""+LINK+"\" style=\"color: "+color+";\">"+TEXT+"</a>
+ html.append( QString(tr("Feed URL: %1")).arg("<a href=\""+data.originalURL+"\" style=\"color: "+color+";\">"+data.originalURL+"</a>") +"<br><hr>");
+ html.append( QString(tr("Title: %1")).arg(data.title) +"<br>");
+ html.append( QString(tr("Description: %1")).arg(data.description) +"<br>");
+ html.append( QString(tr("Website: %1")).arg("<a href=\""+data.link+"\" style=\"color: "+color+";\">"+data.link+"</a>") +"<br><hr>");
+ if(!data.lastBuildDate.isNull()){ html.append( QString(tr("Last Build Date: %1")).arg(data.lastBuildDate.toString(Qt::DefaultLocaleShortDate)) +"<br>"); }
+ html.append( QString(tr("Last Sync: %1")).arg(data.lastsync.toString(Qt::DefaultLocaleShortDate)) +"<br>");
+ html.append( QString(tr("Next Sync: %1")).arg(data.nextsync.toString(Qt::DefaultLocaleShortDate)) +"<br>");
+ // - load that html into the viewer
+ ui->text_feed_info->setHtml(html);
}
//================
@@ -105,6 +158,7 @@ void RSSFeedPlugin::loadIcons(){
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","") );
+ ui->tool_add_preset->setIcon( LXDG::findIcon("bookmark-new-list","") );
}
//GUI slots
@@ -165,15 +219,21 @@ void RSSFeedPlugin::addNewFeed(){
backToFeeds();
}
+void RSSFeedPlugin::loadPreset(QAction *act){
+ ui->line_new_url->setText( act->whatsThis() );
+}
+
void RSSFeedPlugin::removeFeed(){
QString ID = ui->page_feed_info->whatsThis();
if(ID.isEmpty()){ return; }
//Remove from the RSS feed object
+ RSSchannel info = RSS->dataForID(ID);
RSS->removeUrl(ID);
//Remove the URL from the settings file for next login
QStringList feeds = LSession::handle()->DesktopPluginSettings()->value(setprefix+"currentfeeds",QStringList()).toStringList();
- feeds.removeAll(ID);
+ feeds.removeAll(info.originalURL);
LSession::handle()->DesktopPluginSettings()->setValue(setprefix+"currentfeeds", feeds);
+ LSession::handle()->DesktopPluginSettings()->remove(setprefix+"feedReads/"+ID);
//Now go back to the main page
backToFeeds();
}
@@ -186,9 +246,10 @@ void RSSFeedPlugin::resyncFeeds(){
// - Feed Interactions
void RSSFeedPlugin::currentFeedChanged(){
QString ID = ui->combo_feed->currentData().toString();
- if(ID.isEmpty()){ return; } //no feed selected
- //Remove the "unread" color from the feed
+ //Remove the "unread" color/flag from the feed
ui->combo_feed->setItemData( ui->combo_feed->currentIndex(), QBrush(Qt::transparent) , Qt::BackgroundRole);
+ ui->combo_feed->setItemData( ui->combo_feed->currentIndex(), "", Qt::WhatsThisRole);
+ checkFeedNotify();
updateFeed(ID);
}
@@ -197,7 +258,7 @@ void RSSFeedPlugin::openFeedPage(){ //Open main website for feed
//Find the data associated with this feed
RSSchannel data = RSS->dataForID(ID);
QString url = data.link;
- qDebug() << "Open Feed Page:" << url;
+ //qDebug() << "Open Feed Page:" << url;
//Now launch the browser
if(!url.isEmpty()){
LSession::LaunchApplication("lumina-open \""+url+"\"");
@@ -254,6 +315,7 @@ void RSSFeedPlugin::UpdateFeedList(){
if(IDS.contains(activate)){
ui->combo_feed->setCurrentIndex( IDS.indexOf(activate) );
}
+ checkFeedNotify();
}
void RSSFeedPlugin::RSSItemChanged(QString ID){
@@ -269,12 +331,17 @@ void RSSFeedPlugin::RSSItemChanged(QString ID){
QColor color(Qt::transparent);
if( info.lastBuildDate > LSession::handle()->DesktopPluginSettings()->value(setprefix+"feedReads/"+ID,QDateTime()).toDateTime() ){
color = QColor(255,10,10,100); //semi-transparent red
+ ui->combo_feed->setItemData(i, "notify", Qt::WhatsThisRole);
+ }else{
+ ui->combo_feed->setItemData(i, "", Qt::WhatsThisRole);
}
ui->combo_feed->setItemData(i, QBrush(color) , Qt::BackgroundRole);
}
}
if(ID == ui->combo_feed->currentData().toString()){
currentFeedChanged(); //re-load the current feed
+ }else{
+ checkFeedNotify();
}
}
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.h b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.h
index ea6ee5e7..68b36760 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.h
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.h
@@ -30,11 +30,12 @@ public:
}
private:
Ui::RSSFeedPlugin *ui;
- QMenu *optionsMenu;
+ QMenu *optionsMenu, *presetMenu;
QString setprefix; //settings prefix
RSSReader *RSS;
void updateOptionsMenu();
+ void checkFeedNotify(); //check if unread feeds are available and change the styling a bit as needed
//Simplification functions for loading feed info onto widgets
void updateFeed(QString ID);
@@ -51,6 +52,7 @@ private slots:
void openSettings();
// - Feed Management
void addNewFeed(); // the "add" button (current url in widget on page)
+ void loadPreset(QAction*); //the add-preset menu
void removeFeed(); // the "remove" button (current feed for page)
void resyncFeeds();
// - Feed Interactions
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.ui b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.ui
index 7689e88b..45dac405 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.ui
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSFeedPlugin.ui
@@ -18,21 +18,21 @@
<number>0</number>
</property>
<property name="leftMargin">
- <number>2</number>
+ <number>3</number>
</property>
<property name="topMargin">
- <number>2</number>
+ <number>3</number>
</property>
<property name="rightMargin">
- <number>2</number>
+ <number>3</number>
</property>
<property name="bottomMargin">
- <number>2</number>
+ <number>3</number>
</property>
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
- <number>0</number>
+ <number>1</number>
</property>
<widget class="QWidget" name="page_feed">
<layout class="QVBoxLayout" name="verticalLayout_2">
@@ -153,6 +153,9 @@ p, li { white-space: pre-wrap; }
<property name="text">
<string>Back to Feeds</string>
</property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
</widget>
</item>
</layout>
@@ -185,23 +188,10 @@ p, li { white-space: pre-wrap; }
<number>0</number>
</property>
<item>
- <widget class="QScrollArea" name="scroll_feed_info">
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="widgetResizable">
+ <widget class="QTextBrowser" name="text_feed_info">
+ <property name="openExternalLinks">
<bool>true</bool>
</property>
- <widget class="QWidget" name="scrollAreaWidgetContents_2">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>100</width>
- <height>30</height>
- </rect>
- </property>
- </widget>
</widget>
</item>
</layout>
@@ -214,6 +204,9 @@ p, li { white-space: pre-wrap; }
<property name="text">
<string>Remove Feed</string>
</property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
</widget>
</item>
</layout>
@@ -244,6 +237,9 @@ p, li { white-space: pre-wrap; }
<property name="text">
<string>Back to Feeds</string>
</property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
</widget>
</item>
</layout>
@@ -289,7 +285,24 @@ p, li { white-space: pre-wrap; }
</widget>
</item>
<item>
- <widget class="QLineEdit" name="line_new_url"/>
+ <layout class="QHBoxLayout" name="horizontalLayout_10">
+ <item>
+ <widget class="QLineEdit" name="line_new_url"/>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tool_add_preset">
+ <property name="toolTip">
+ <string>Load a preset RSS Feed</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="popupMode">
+ <enum>QToolButton::InstantPopup</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
@@ -370,6 +383,9 @@ p, li { white-space: pre-wrap; }
<property name="text">
<string>Back to Feeds</string>
</property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
</widget>
</item>
</layout>
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.cpp b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.cpp
index f525d19c..5dbd614c 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.cpp
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.cpp
@@ -58,7 +58,9 @@ void RSSReader::addUrls(QStringList urls){
//Note: Make sure we get the complete URL form for accurate comparison later
QString url = QUrl(urls[i]).toString();
if(hash.contains(url)){ continue; } //already handled
- hash.insert(url, RSSchannel()); //put an empty struct into the hash for now
+ RSSchannel blank;
+ blank.originalURL = url;
+ hash.insert(url, blank); //put the empty struct into the hash for now
requestRSS(url); //startup the initial request for this url
}
emit newChannelsAvailable();
@@ -98,7 +100,6 @@ RSSchannel RSSReader::readRSS(QByteArray bytes){
QXmlStreamReader xml(bytes);
RSSchannel rssinfo;
//qDebug() << "Can Read XML Stream:" << !xml.hasError();
- if(xml.hasError()){ qDebug() << " - Error String:" << xml.errorString(); }
if(xml.readNextStartElement()){
//qDebug() << " - RSS Element:" << xml.name();
if(xml.name() == "rss" && xml.attributes().value("version") =="2.0"){
@@ -108,7 +109,7 @@ RSSchannel RSSReader::readRSS(QByteArray bytes){
}
}
}
- if(xml.hasError()){ qDebug() << " - Error String:" << xml.errorString(); }
+ if(xml.hasError()){ qDebug() << " - XML Read Error:" << xml.errorString() << "\n" << bytes; }
return rssinfo;
}
RSSchannel RSSReader::readRSSChannel(QXmlStreamReader *rss){
@@ -180,6 +181,28 @@ void RSSReader::replyFinished(QNetworkReply *reply){
//qDebug() << "Got Reply:" << url;
QByteArray data = reply->readAll();
outstandingURLS.removeAll(url);
+ if(data.isEmpty()){
+ qDebug() << "No data returned:" << url;
+ //see if the URL can be adjusted for known issues
+ bool handled = false;
+ QUrl redirecturl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
+ if(redirecturl.isValid() && (redirecturl.toString() != url )){
+ //New URL redirect - make the change and send a new request
+ QString newurl = redirecturl.toString();
+ qDebug() << " - Redirect to:" << newurl;
+ if(hash.contains(url) && !hash.contains(newurl)){
+ hash.insert(newurl, hash.take(url) ); //just move the data over to the new url
+ requestRSS(newurl);
+ emit newChannelsAvailable();
+ handled = true;
+ }
+ }
+ if(!handled && hash.contains(url) ){
+ emit rssChanged(url);
+ }
+ return;
+ }
+
if(!hash.contains(url)){
//qDebug() << " - hash does not contain URL!!";
//URL removed from list while a request was outstanding?
@@ -189,11 +212,10 @@ void RSSReader::replyFinished(QNetworkReply *reply){
if(hash[keys[i]].icon_url == url){
//Icon fetch response
RSSchannel info = hash[keys[i]];
- QByteArray bytes = reply->readAll();
- QImage img = QImage::fromData(bytes);
+ QImage img = QImage::fromData(data);
info.icon = QIcon( QPixmap::fromImage(img) );
- qDebug() << "Got Icon response:" << url << bytes;
- qDebug() << info.icon;
+ //qDebug() << "Got Icon response:" << url << data;
+ //qDebug() << info.icon;
hash.insert(keys[i], info); //insert back into the hash
emit rssChanged(keys[i]);
break;
@@ -214,6 +236,7 @@ void RSSReader::replyFinished(QNetworkReply *reply){
bool changed = (hash[url].lastBuildDate.isNull() || (hash[url].lastBuildDate < info.lastBuildDate) );
bool newinfo = false;
if(changed){ newinfo = hash[url].title.isEmpty(); } //no previous info from this URL
+ info.originalURL = hash[url].originalURL; //make sure this info gets preserved across updates
hash.insert(url, info);
if(newinfo){ emit newChannelsAvailable(); } //new channel
else if(changed){ emit rssChanged(url); } //update to existing channel
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.h b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.h
index 82ad9f86..91affc55 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.h
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssfeeder/RSSObjects.h
@@ -49,6 +49,7 @@ struct RSSchannel{
//Internal data for bookkeeping
QDateTime lastsync, nextsync;
+ QString originalURL; //in case it was redirected to some "fixed" url later
};
class RSSReader : public QObject{
bgstack15