Browse Source

- Major rewrite of rss grouping code because I did not like my first approach. It is not complete yet but it is far more clean and stable

adaptive-webui-19844
Christophe Dumez 15 years ago
parent
commit
48b14d1066
  1. 12
      src/FeedDownloader.h
  2. 94
      src/feedList.h
  3. 207
      src/rss.cpp
  4. 34
      src/rss.h
  5. 181
      src/rss_imp.cpp
  6. 5
      src/rss_imp.h

12
src/FeedDownloader.h

@ -353,7 +353,7 @@ protected slots:
if(!filters.hasFilter(new_name)) { if(!filters.hasFilter(new_name)) {
validated = true; validated = true;
} else { } else {
QMessageBox::critical(0, tr("Invalid filter name"), tr("This filter name is already in use.")); QMessageBox::warning(0, tr("Invalid filter name"), tr("This filter name is already in use."));
} }
}while(!validated); }while(!validated);
// Rename the filter // Rename the filter
@ -392,7 +392,7 @@ protected slots:
new_name = new_name.trimmed(); new_name = new_name.trimmed();
if(new_name.isEmpty()) { if(new_name.isEmpty()) {
// Cannot be left empty // Cannot be left empty
QMessageBox::critical(0, tr("Invalid filter name"), tr("The filter name cannot be left empty.")); QMessageBox::warning(0, tr("Invalid filter name"), tr("The filter name cannot be left empty."));
} else { } else {
validated = true; validated = true;
} }
@ -408,7 +408,7 @@ protected slots:
if(filter_name.isNull()) return; if(filter_name.isNull()) return;
if(filters.hasFilter(filter_name)) { if(filters.hasFilter(filter_name)) {
// Filter alread exists // Filter alread exists
QMessageBox::critical(0, tr("Invalid filter name"), tr("This filter name is already in use.")); QMessageBox::warning(0, tr("Invalid filter name"), tr("This filter name is already in use."));
} else { } else {
validated = true; validated = true;
} }
@ -430,7 +430,7 @@ protected slots:
if(selected_filter.isEmpty()) return; if(selected_filter.isEmpty()) return;
QString s = test_line->text().trimmed(); QString s = test_line->text().trimmed();
if(s.isEmpty()) { if(s.isEmpty()) {
QMessageBox::critical(0, tr("Filter testing error"), tr("Please specify a test torrent name.")); QMessageBox::warning(0, tr("Filter testing error"), tr("Please specify a test torrent name."));
return; return;
} }
// Get current filter // Get current filter
@ -455,7 +455,7 @@ protected slots:
filtersList->setCurrentItem(filtersList->item(0)); filtersList->setCurrentItem(filtersList->item(0));
QMessageBox::information(0, tr("Import successful"), tr("Filters import was successful.")); QMessageBox::information(0, tr("Import successful"), tr("Filters import was successful."));
} else { } else {
QMessageBox::critical(0, tr("Import failure"), tr("Filters could not be imported due to an I/O error.")); QMessageBox::warning(0, tr("Import failure"), tr("Filters could not be imported due to an I/O error."));
} }
} }
@ -472,7 +472,7 @@ protected slots:
if(filters.serialize(destination)) if(filters.serialize(destination))
QMessageBox::information(0, tr("Export successful"), tr("Filters export was successful.")); QMessageBox::information(0, tr("Export successful"), tr("Filters export was successful."));
else else
QMessageBox::critical(0, tr("Export failure"), tr("Filters could not be exported due to an I/O error.")); QMessageBox::warning(0, tr("Export failure"), tr("Filters could not be exported due to an I/O error."));
} }
}; };

94
src/feedList.h

@ -6,44 +6,83 @@
#include <QDropEvent> #include <QDropEvent>
#include <QDragMoveEvent> #include <QDragMoveEvent>
#include <QStringList> #include <QStringList>
#include <QHash>
#include <QUrl>
#include "rss.h" #include "rss.h"
class FeedList : public QTreeWidget { class FeedList : public QTreeWidget {
private: private:
RssManager *rssmanager; RssManager *rssmanager;
QHash<QTreeWidgetItem*, RssFile*> mapping;
QHash<QString, QTreeWidgetItem*> feeds_items;
QTreeWidgetItem* current_feed;
public: public:
FeedList(QWidget *parent, RssManager *rssmanager): QTreeWidget(parent), rssmanager(rssmanager) { FeedList(QWidget *parent, RssManager *rssmanager): QTreeWidget(parent), rssmanager(rssmanager) {
setContextMenuPolicy(Qt::CustomContextMenu); setContextMenuPolicy(Qt::CustomContextMenu);
setDragDropMode(QAbstractItemView::InternalMove); setDragDropMode(QAbstractItemView::InternalMove);
setSelectionMode(QAbstractItemView::ExtendedSelection); setSelectionMode(QAbstractItemView::ExtendedSelection);
setColumnCount(3); setColumnCount(1);
QTreeWidgetItem *___qtreewidgetitem = headerItem(); QTreeWidgetItem *___qtreewidgetitem = headerItem();
___qtreewidgetitem->setText(2, QApplication::translate("RSS", "type", 0, QApplication::UnicodeUTF8));
___qtreewidgetitem->setText(1, QApplication::translate("RSS", "url", 0, QApplication::UnicodeUTF8));
___qtreewidgetitem->setText(0, QApplication::translate("RSS", "RSS feeds", 0, QApplication::UnicodeUTF8)); ___qtreewidgetitem->setText(0, QApplication::translate("RSS", "RSS feeds", 0, QApplication::UnicodeUTF8));
// Hide second column (url) and third column (type) connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(updateCurrentFeed(QTreeWidgetItem*)));
hideColumn(1);
hideColumn(2);
} }
QStringList getItemPath(QTreeWidgetItem *item) const { void itemAdded(QTreeWidgetItem *item, RssFile* file) {
QStringList path; mapping[item] = file;
if(item) { if(file->getType() == RssFile::STREAM)
if(item->parent()) { feeds_items[file->getID()] = item;
path = getItemPath(item->parent()); }
}
Q_ASSERT(!item->text(1).isEmpty()); void itemRemoved(QTreeWidgetItem *item) {
path << item->text(1); RssFile* file = mapping.take(item);
} if(file->getType() == RssFile::STREAM)
return path; feeds_items.remove(file->getID());
}
bool hasFeed(QString url) {
return feeds_items.contains(QUrl(url).toString());
}
RssFile* getRSSItem(QTreeWidgetItem *item) {
return mapping[item];
}
RssFile* getCurrentRSSItem() {
return mapping[current_feed];
}
RssFile::FileType getItemType(QTreeWidgetItem *item) {
return mapping[item]->getType();
}
QString getItemID(QTreeWidgetItem *item) {
return mapping[item]->getID();
}
QTreeWidgetItem* getTreeItemFromUrl(QString url) const{
return feeds_items[url];
}
QTreeWidgetItem* currentItem() const {
return current_feed;
}
QTreeWidgetItem* currentFeed() const {
return current_feed;
}
protected slots:
void updateCurrentFeed(QTreeWidgetItem* new_item) {
if(getItemType(new_item) == RssFile::STREAM)
current_feed = new_item;
} }
protected: protected:
void dragMoveEvent(QDragMoveEvent * event) { void dragMoveEvent(QDragMoveEvent * event) {
QTreeWidgetItem *item = itemAt(event->pos()); QTreeWidgetItem *item = itemAt(event->pos());
if(item && rssmanager->getFile(getItemPath(item))->getType() != RssFile::FOLDER) if(item && getItemType(item) != RssFile::FOLDER)
event->ignore(); event->ignore();
else { else {
QTreeWidget::dragMoveEvent(event); QTreeWidget::dragMoveEvent(event);
@ -52,19 +91,20 @@ protected:
void dropEvent(QDropEvent *event) { void dropEvent(QDropEvent *event) {
qDebug("dropEvent"); qDebug("dropEvent");
QTreeWidgetItem *dest_item = itemAt(event->pos()); QTreeWidgetItem *dest_folder_item = itemAt(event->pos());
QStringList dest_folder_path = getItemPath(dest_item); RssFolder *dest_folder;
if(dest_folder_item)
dest_folder = (RssFolder*)getRSSItem(dest_folder_item);
else
dest_folder = rssmanager;
QList<QTreeWidgetItem *> src_items = selectedItems(); QList<QTreeWidgetItem *> src_items = selectedItems();
foreach(QTreeWidgetItem *src_item, src_items) { foreach(QTreeWidgetItem *src_item, src_items) {
QStringList src_path = getItemPath(src_item); RssFile *file = getRSSItem(src_item);
QStringList dest_path = dest_folder_path; rssmanager->moveFile(file, dest_folder);
dest_path << src_item->text(1);
qDebug("Moving file %s to %s", src_path.join("\\").toLocal8Bit().data(), dest_path.join("\\").toLocal8Bit().data());
rssmanager->moveFile(src_path, dest_path);
} }
QTreeWidget::dropEvent (event); QTreeWidget::dropEvent(event);
if(dest_item) if(dest_folder_item)
dest_item->setExpanded(true); dest_folder_item->setExpanded(true);
} }
}; };

207
src/rss.cpp

@ -30,6 +30,7 @@
#include "rss.h" #include "rss.h"
#include <QTimer> #include <QTimer>
#include <QUrl>
/** RssFolder **/ /** RssFolder **/
@ -56,15 +57,6 @@ RssFile::FileType RssFolder::getType() const {
return RssFile::FOLDER; return RssFile::FOLDER;
} }
QStringList RssFolder::getPath() const {
QStringList path;
if(parent) {
path = parent->getPath();
path.append(name);
}
return path;
}
void RssFolder::refreshAll(){ void RssFolder::refreshAll(){
qDebug("Refreshing all rss feeds"); qDebug("Refreshing all rss feeds");
QList<RssFile*> items = this->values(); QList<RssFile*> items = this->values();
@ -87,98 +79,52 @@ void RssFolder::refreshAll(){
} }
} }
void RssFolder::removeFile(QStringList full_path) { void RssFolder::removeFile(QString ID) {
QString name = full_path.last(); if(this->contains(ID))
if(full_path.size() == 1) { delete this->take(ID);
Q_ASSERT(this->contains(name));
delete this->take(name);
} else {
QString subfolder_name = full_path.takeFirst();
Q_ASSERT(this->contains(subfolder_name));
RssFolder *subfolder = (RssFolder*)this->value(subfolder_name);
subfolder->removeFile(full_path);
}
} }
RssFolder* RssFolder::addFolder(QStringList full_path) { RssFolder* RssFolder::addFolder(QString name) {
QString name = full_path.last(); RssFolder *subfolder;
if(full_path.size() == 1) { if(!this->contains(name)) {
Q_ASSERT(!this->contains(name)); subfolder = new RssFolder(this, rssmanager, BTSession, name);
RssFolder *subfolder = new RssFolder(this, rssmanager, BTSession, name);
(*this)[name] = subfolder; (*this)[name] = subfolder;
return subfolder;
} else { } else {
QString subfolder_name = full_path.takeFirst(); subfolder = (RssFolder*)this->value(name);
// Check if the subfolder exists and create it if it does not
if(!this->contains(subfolder_name)) {
qDebug("Creating subfolder %s which did not exist", subfolder_name.toLocal8Bit().data());
(*this)[subfolder_name] = new RssFolder(this, rssmanager, BTSession, subfolder_name);
}
Q_ASSERT(this->contains(subfolder_name));
RssFolder *subfolder = (RssFolder*)this->value(subfolder_name);
return subfolder->addFolder(full_path);
} }
return subfolder;
} }
RssStream* RssFolder::addStream(QStringList full_path) { RssStream* RssFolder::addStream(QString url) {
QString url = full_path.last(); Q_ASSERT(!this->contains(url));
if(full_path.size() == 1) { RssStream* stream = new RssStream(this, rssmanager, BTSession, url);
if(this->contains(url)){ (*this)[url] = stream;
qDebug("Not adding the Rss stream because it is already in the list"); refreshStream(url);
return 0; return stream;
} }
RssStream* stream = new RssStream(this, rssmanager, BTSession, url);
(*this)[url] = stream; // Refresh All Children
refresh(full_path); void RssFolder::refresh() {
return stream; foreach(RssFile *child, this->values()) {
} else { // Little optimization child->refresh() would work too
QString subfolder_name = full_path.takeFirst(); if(child->getType() == RssFile::STREAM)
// Check if the subfolder exists and create it if it does not refreshStream(child->getID());
if(!this->contains(subfolder_name)) { else
qDebug("Creating subfolder %s which did not exist", subfolder_name.toLocal8Bit().data()); child->refresh();
(*this)[subfolder_name] = new RssFolder(this, rssmanager, BTSession, subfolder_name);
}
Q_ASSERT(this->contains(subfolder_name));
RssFolder *subfolder = (RssFolder*)this->value(subfolder_name);
return subfolder->addStream(full_path);
}
}
void RssFolder::refresh(QStringList full_path) {
QString url = full_path.last();
if(full_path.size() == 1) {
qDebug("Refreshing feed: %s", url.toLocal8Bit().data());
Q_ASSERT(this->contains(url));
RssStream *stream = (RssStream*)this->value(url);
if(stream->isLoading()) return;
stream->setLoading(true);
downloader->downloadUrl(url);
if(!stream->hasCustomIcon()){
downloader->downloadUrl(stream->getIconUrl());
}else{
qDebug("No need to download this feed's icon, it was already downloaded");
}
} else {
QString subfolder_name = full_path.takeFirst();
Q_ASSERT(this->contains(subfolder_name));
RssFolder *subfolder = (RssFolder*)this->value(subfolder_name);
subfolder->refresh(full_path);
} }
} }
RssFile* RssFolder::getFile(QStringList full_path) const { void RssFolder::refreshStream(QString url) {
if(full_path.isEmpty()) return rssmanager; qDebug("Refreshing feed: %s", url.toLocal8Bit().data());
QString file_name = full_path.last(); Q_ASSERT(this->contains(url));
Q_ASSERT(!file_name.isEmpty()); RssStream *stream = (RssStream*)this->value(url);
if(full_path.size() == 1) { if(stream->isLoading()) return;
qDebug("getFile: %s from folder %s", file_name.toLocal8Bit().data(), name.toLocal8Bit().data()); stream->setLoading(true);
Q_ASSERT(this->contains(file_name)); downloader->downloadUrl(url);
return (*this)[file_name]; if(!stream->hasCustomIcon()){
} else { downloader->downloadUrl(stream->getIconUrl());
QString subfolder_name = full_path.takeFirst(); }else{
Q_ASSERT(this->contains(subfolder_name)); qDebug("No need to download this feed's icon, it was already downloaded");
RssFolder *subfolder = (RssFolder*)this->value(subfolder_name);
return subfolder->getFile(full_path);
} }
} }
@ -225,7 +171,7 @@ void RssFolder::processFinishedDownload(QString url, QString path) {
// this is more user friendly // this is more user friendly
if(stream->getName().isEmpty()){ if(stream->getName().isEmpty()){
if(!stream->getTitle().isEmpty()) if(!stream->getTitle().isEmpty())
stream->rename(QStringList(), stream->getTitle()); stream->rename(stream->getTitle());
} }
rssmanager->forwardFeedInfosChanged(url, stream->getName(), stream->getNbUnRead()); rssmanager->forwardFeedInfosChanged(url, stream->getName(), stream->getNbUnRead());
} }
@ -261,19 +207,13 @@ QString RssFolder::getName() const {
return name; return name;
} }
void RssFolder::rename(QStringList full_path, QString new_name) { void RssFolder::rename(QString new_name) {
if(full_path.size() == 1) { Q_ASSERT(parent->contains(new_name));
if(!parent->contains(new_name)) {
// Update parent
(*parent)[new_name] = parent->take(name);
// Actually rename
name = new_name; name = new_name;
} else {
QString child_name = full_path.takeFirst();
Q_ASSERT(this->contains(child_name));
RssFile *child = (RssFile*)this->value(child_name);
if(full_path.empty()) {
// Child is renamed, update QHash
Q_ASSERT(!this->contains(new_name));
(*this)[new_name] = this->take(child_name);
}
child->rename(full_path, new_name);
} }
} }
@ -297,16 +237,6 @@ QList<RssStream*> RssFolder::getAllFeeds() const {
return streams; return streams;
} }
void RssFolder::removeFileRef(RssFile* item) {
if(item->getType() == RssFile::STREAM) {
Q_ASSERT(this->contains(((RssStream*)item)->getUrl()));
this->remove(((RssStream*)item)->getUrl());
} else {
Q_ASSERT(this->contains(((RssFolder*)item)->getName()));
this->remove(((RssFolder*)item)->getName());
}
}
void RssFolder::addFile(RssFile * item) { void RssFolder::addFile(RssFile * item) {
if(item->getType() == RssFile::STREAM) { if(item->getType() == RssFile::STREAM) {
Q_ASSERT(!this->contains(((RssStream*)item)->getUrl())); Q_ASSERT(!this->contains(((RssStream*)item)->getUrl()));
@ -349,10 +279,17 @@ void RssManager::loadStreamList(){
foreach(QString s, streamsUrl){ foreach(QString s, streamsUrl){
QStringList path = s.split("\\"); QStringList path = s.split("\\");
if(path.empty()) continue; if(path.empty()) continue;
RssStream *stream = this->addStream(path); QString feed_url = path.takeLast();
// Create feed path (if it does not exists)
RssFolder * feed_parent = this;
foreach(QString folder_name, path) {
feed_parent = feed_parent->addFolder(folder_name);
}
// Create feed
RssStream *stream = feed_parent->addStream(feed_url);
QString alias = aliases.at(i); QString alias = aliases.at(i);
if(!alias.isEmpty()) { if(!alias.isEmpty()) {
stream->rename(QStringList(), alias); stream->rename(alias);
} }
++i; ++i;
} }
@ -367,29 +304,16 @@ void RssManager::forwardFeedIconChanged(QString url, QString icon_path) {
emit feedIconChanged(url, icon_path); emit feedIconChanged(url, icon_path);
} }
void RssManager::moveFile(QStringList old_path, QStringList new_path) { void RssManager::moveFile(RssFile* file, RssFolder* dest_folder) {
RssFile* item = getFile(old_path); RssFolder* src_folder = file->getParent();
RssFolder* src_folder = item->getParent();
QString new_name = new_path.takeLast();
RssFolder* dest_folder = (RssFolder*)getFile(new_path);
if(dest_folder != src_folder) { if(dest_folder != src_folder) {
// Copy to new Folder // Copy to new Folder
dest_folder->addFile(item); dest_folder->addFile(file);
// Remove reference in old folder // Remove reference in old folder
src_folder->removeFileRef(item); src_folder->remove(file->getID());
} else { } else {
qDebug("Nothing to move, same destination folder"); qDebug("Nothing to move, same destination folder");
} }
// Need to rename?
QString current_name;
if(item->getType() == RssFile::FOLDER)
current_name = item->getName();
else
current_name = ((RssStream*)item)->getUrl();
if(current_name != new_name) {
qDebug("Renaming file from %s to %s...", current_name.toLocal8Bit().data(), new_name.toLocal8Bit().data());
dest_folder->rename(item->getPath(), new_name);
}
} }
void RssManager::saveStreamList(){ void RssManager::saveStreamList(){
@ -413,9 +337,10 @@ void RssManager::saveStreamList(){
/** RssStream **/ /** RssStream **/
RssStream::RssStream(RssFolder* parent, RssManager *rssmanager, bittorrent *BTSession, QString _url): parent(parent), rssmanager(rssmanager), BTSession(BTSession), url(_url), alias(""), iconPath(":/Icons/rss16.png"), refreshed(false), downloadFailure(false), currently_loading(false) { RssStream::RssStream(RssFolder* parent, RssManager *rssmanager, bittorrent *BTSession, QString _url): parent(parent), rssmanager(rssmanager), BTSession(BTSession), alias(""), iconPath(":/Icons/rss16.png"), refreshed(false), downloadFailure(false), currently_loading(false) {
qDebug("RSSStream constructed"); qDebug("RSSStream constructed");
QSettings qBTRSS("qBittorrent", "qBittorrent-rss"); QSettings qBTRSS("qBittorrent", "qBittorrent-rss");
url = QUrl(_url).toString();
QHash<QString, QVariant> all_old_items = qBTRSS.value("old_items", QHash<QString, QVariant>()).toHash(); QHash<QString, QVariant> all_old_items = qBTRSS.value("old_items", QHash<QString, QVariant>()).toHash();
QVariantList old_items = all_old_items.value(url, QVariantList()).toList(); QVariantList old_items = all_old_items.value(url, QVariantList()).toList();
qDebug("Loading %d old items for feed %s", old_items.size(), getName().toLocal8Bit().data()); qDebug("Loading %d old items for feed %s", old_items.size(), getName().toLocal8Bit().data());
@ -454,15 +379,7 @@ RssFile::FileType RssStream::getType() const {
} }
void RssStream::refresh() { void RssStream::refresh() {
QStringList path; parent->refreshStream(url);
path << url;
parent->refresh(path);
}
QStringList RssStream::getPath() const {
QStringList path = parent->getPath();
path.append(url);
return path;
} }
// delete all the items saved // delete all the items saved
@ -491,7 +408,7 @@ QString RssStream::getTitle() const{
return title; return title;
} }
void RssStream::rename(QStringList, QString new_name){ void RssStream::rename(QString new_name){
qDebug("Renaming stream to %s", new_name.toLocal8Bit().data()); qDebug("Renaming stream to %s", new_name.toLocal8Bit().data());
alias = new_name; alias = new_name;
} }
@ -603,7 +520,7 @@ short RssStream::readDoc(const QDomDocument& doc) {
if (property.tagName() == "title") { if (property.tagName() == "title") {
title = property.text(); title = property.text();
if(alias==getUrl()) if(alias==getUrl())
rename(QStringList(), title); rename(title);
} }
else if (property.tagName() == "link") else if (property.tagName() == "link")
link = property.text(); link = property.text();

34
src/rss.h

@ -87,12 +87,21 @@ public:
virtual unsigned int getNbUnRead() const = 0; virtual unsigned int getNbUnRead() const = 0;
virtual FileType getType() const = 0; virtual FileType getType() const = 0;
virtual QStringList getPath() const = 0;
virtual QString getName() const = 0; virtual QString getName() const = 0;
virtual void rename(QStringList path, QString new_name) = 0; virtual QString getID() const = 0;
virtual void rename(QString new_name) = 0;
virtual void markAllAsRead() = 0; virtual void markAllAsRead() = 0;
virtual RssFolder* getParent() const = 0; virtual RssFolder* getParent() const = 0;
virtual void setParent(RssFolder*) = 0; virtual void setParent(RssFolder*) = 0;
virtual void refresh() = 0;
QStringList getPath() const {
QStringList path;
if(getParent()) {
path = ((RssFile*)getParent())->getPath();
path.append(getID());
}
return path;
}
}; };
// Item of a rss stream, single information // Item of a rss stream, single information
@ -394,13 +403,13 @@ public:
void setParent(RssFolder* _parent) { parent = _parent; } void setParent(RssFolder* _parent) { parent = _parent; }
FileType getType() const; FileType getType() const;
void refresh(); void refresh();
QStringList getPath() const; QString getID() const { return url; }
void removeAllItems(); void removeAllItems();
bool itemAlreadyExists(QString hash); bool itemAlreadyExists(QString hash);
void setLoading(bool val); void setLoading(bool val);
bool isLoading(); bool isLoading();
QString getTitle() const; QString getTitle() const;
void rename(QStringList path, QString _alias); void rename(QString _alias);
QString getName() const; QString getName() const;
QString getLink() const; QString getLink() const;
QString getUrl() const; QString getUrl() const;
@ -442,25 +451,24 @@ public:
void setParent(RssFolder* _parent) { parent = _parent; } void setParent(RssFolder* _parent) { parent = _parent; }
unsigned int getNbUnRead() const; unsigned int getNbUnRead() const;
FileType getType() const; FileType getType() const;
RssStream* addStream(QStringList full_path); RssStream* addStream(QString url);
RssFolder* addFolder(QStringList full_path); RssFolder* addFolder(QString name);
QList<RssStream*> findFeedsWithIcon(QString icon_url) const; QList<RssStream*> findFeedsWithIcon(QString icon_url) const;
unsigned int getNbFeeds() const; unsigned int getNbFeeds() const;
QList<RssFile*> getContent() const; QList<RssFile*> getContent() const;
RssFile* getFile(QStringList full_path) const;
QList<RssStream*> getAllFeeds() const; QList<RssStream*> getAllFeeds() const;
QString getName() const; QString getName() const;
QStringList getPath() const; QString getID() const { return name; }
public slots: public slots:
void refreshAll(); void refreshAll();
void removeFileRef(RssFile* item);
void addFile(RssFile * item); void addFile(RssFile * item);
void removeFile(QStringList full_path); void removeFile(QString ID);
void refresh(QStringList full_path); void refresh();
void refreshStream(QString url);
void processFinishedDownload(QString url, QString path); void processFinishedDownload(QString url, QString path);
void handleDownloadFailure(QString url, QString reason); void handleDownloadFailure(QString url, QString reason);
void rename(QStringList full_path, QString new_name); void rename(QString new_name);
void markAllAsRead(); void markAllAsRead();
}; };
@ -481,7 +489,7 @@ public slots:
void saveStreamList(); void saveStreamList();
void forwardFeedInfosChanged(QString url, QString aliasOrUrl, unsigned int nbUnread); void forwardFeedInfosChanged(QString url, QString aliasOrUrl, unsigned int nbUnread);
void forwardFeedIconChanged(QString url, QString icon_path); void forwardFeedIconChanged(QString url, QString icon_path);
void moveFile(QStringList old_path, QStringList new_path); void moveFile(RssFile* file, RssFolder* dest_folder);
public: public:
RssManager(bittorrent *BTSession); RssManager(bittorrent *BTSession);

181
src/rss_imp.cpp

@ -56,18 +56,20 @@ void RSSImp::displayRSSListMenu(const QPoint& pos){
myRSSListMenu.addSeparator(); myRSSListMenu.addSeparator();
if(selectedItems.size() == 1) { if(selectedItems.size() == 1) {
myRSSListMenu.addAction(actionRename); myRSSListMenu.addAction(actionRename);
RssFile *rss_item = rssmanager->getFile(listStreams->getItemPath(selectedItems.first())); myRSSListMenu.addAction(actionDelete);
if(rss_item->getType() == RssFile::FOLDER) myRSSListMenu.addSeparator();
if(listStreams->getItemType(selectedItems.first()) == RssFile::FOLDER)
myRSSListMenu.addAction(actionNew_folder); myRSSListMenu.addAction(actionNew_folder);
} }
myRSSListMenu.addAction(actionDelete); myRSSListMenu.addAction(actionNew_subscription);
myRSSListMenu.addSeparator(); if(listStreams->getItemType(selectedItems.first()) == RssFile::STREAM) {
myRSSListMenu.addAction(actionCopy_feed_URL);
if(selectedItems.size() == 1) {
myRSSListMenu.addSeparator(); myRSSListMenu.addSeparator();
myRSSListMenu.addAction(actionRSS_feed_downloader); myRSSListMenu.addAction(actionCopy_feed_URL);
if(selectedItems.size() == 1) {
myRSSListMenu.addSeparator();
myRSSListMenu.addAction(actionRSS_feed_downloader);
}
} }
}else{ }else{
myRSSListMenu.addAction(actionNew_subscription); myRSSListMenu.addAction(actionNew_subscription);
myRSSListMenu.addAction(actionNew_folder); myRSSListMenu.addAction(actionNew_folder);
@ -87,38 +89,29 @@ void RSSImp::displayItemsListMenu(const QPoint&){
myItemListMenu.exec(QCursor::pos()); myItemListMenu.exec(QCursor::pos());
} }
QStringList RSSImp::getCurrentFeedPath() const {
return listStreams->getItemPath(listStreams->currentItem());
}
RssFile::FileType RSSImp::getItemType(QTreeWidgetItem *item) const {
if(!item)
return RssFile::FOLDER;
return (RssFile::FileType)item->text(2).toInt();
}
void RSSImp::askNewFolder() { void RSSImp::askNewFolder() {
QStringList dest_path;
QTreeWidgetItem *parent_item = 0; QTreeWidgetItem *parent_item = 0;
RssFolder *rss_parent;
if(listStreams->selectedItems().size() > 0) { if(listStreams->selectedItems().size() > 0) {
parent_item = listStreams->selectedItems().at(0); parent_item = listStreams->selectedItems().at(0);
foreach(QString name, listStreams->getItemPath(parent_item)) { rss_parent = (RssFolder*)listStreams->getRSSItem(parent_item);
dest_path << name; Q_ASSERT(rss_parent->getType() == RssFile::FOLDER);
} } else {
rss_parent = rssmanager;
} }
bool ok; bool ok;
QString newFolder = QInputDialog::getText(this, tr("Please choose a folder name"), tr("Folder name:"), QLineEdit::Normal, tr("New folder"), &ok); QString new_name = QInputDialog::getText(this, tr("Please choose a folder name"), tr("Folder name:"), QLineEdit::Normal, tr("New folder"), &ok);
if(ok) { if(ok) {
dest_path << newFolder; RssFolder* new_folder = rss_parent->addFolder(new_name);
RssFolder* new_folder = rssmanager->addFolder(dest_path);
QTreeWidgetItem* folder_item; QTreeWidgetItem* folder_item;
if(parent_item) if(parent_item)
folder_item = new QTreeWidgetItem(parent_item); folder_item = new QTreeWidgetItem(parent_item);
else else
folder_item = new QTreeWidgetItem(listStreams); folder_item = new QTreeWidgetItem(listStreams);
// Notify TreeWidget
listStreams->itemAdded(folder_item, new_folder);
// Set Text
folder_item->setText(0, new_folder->getName() + QString::fromUtf8(" (0)")); folder_item->setText(0, new_folder->getName() + QString::fromUtf8(" (0)"));
folder_item->setText(1, new_folder->getName());
folder_item->setData(2,Qt::DisplayRole, QVariant((int)RssFile::FOLDER));
folder_item->setData(0,Qt::DecorationRole, QVariant(QIcon(":/Icons/oxygen/folder.png"))); folder_item->setData(0,Qt::DecorationRole, QVariant(QIcon(":/Icons/oxygen/folder.png")));
// Expand parent folder to display new folder // Expand parent folder to display new folder
if(parent_item) if(parent_item)
@ -129,12 +122,22 @@ void RSSImp::askNewFolder() {
// add a stream by a button // add a stream by a button
void RSSImp::on_newFeedButton_clicked() { void RSSImp::on_newFeedButton_clicked() {
QStringList dest_path; // Determine parent folder for new feed
QTreeWidgetItem *current_item = listStreams->currentItem(); QTreeWidgetItem *parent_item =0;
if(getItemType(current_item) != RssFile::FOLDER) QList<QTreeWidgetItem *> selected_items = listStreams->selectedItems();
dest_path = listStreams->getItemPath(current_item->parent()); if(!selected_items.empty())
else parent_item = selected_items.first();
dest_path = listStreams->getItemPath(current_item); RssFolder *rss_parent;
if(parent_item) {
RssFile* tmp = listStreams->getRSSItem(parent_item);
if(tmp->getType() == RssFile::FOLDER)
rss_parent = (RssFolder*)tmp;
else
rss_parent = tmp->getParent();
} else {
rss_parent = rssmanager;
}
// Ask for feed URL
bool ok; bool ok;
QString clip_txt = qApp->clipboard()->text(); QString clip_txt = qApp->clipboard()->text();
QString default_url = "http://"; QString default_url = "http://";
@ -145,19 +148,19 @@ void RSSImp::on_newFeedButton_clicked() {
if(ok) { if(ok) {
newUrl = newUrl.trimmed(); newUrl = newUrl.trimmed();
if(!newUrl.isEmpty()){ if(!newUrl.isEmpty()){
dest_path.append(newUrl); if(listStreams->hasFeed(newUrl)) {
RssStream *stream = rssmanager->addStream(dest_path);
if(stream == 0){
// Already existing
QMessageBox::warning(this, tr("qBittorrent"), QMessageBox::warning(this, tr("qBittorrent"),
tr("This rss feed is already in the list."), tr("This rss feed is already in the list."),
QMessageBox::Ok); QMessageBox::Ok);
return; return;
} }
RssStream *stream = rss_parent->addStream(newUrl);
// Create TreeWidget item
QTreeWidgetItem* item = new QTreeWidgetItem(listStreams); QTreeWidgetItem* item = new QTreeWidgetItem(listStreams);
// Notify TreeWidget
listStreams->itemAdded(item, stream);
// Set text
item->setText(0, stream->getName() + QString::fromUtf8(" (0)")); item->setText(0, stream->getName() + QString::fromUtf8(" (0)"));
item->setText(1, stream->getUrl());
item->setData(2,Qt::DisplayRole, QVariant((int)RssFile::STREAM));
item->setData(0,Qt::DecorationRole, QVariant(QIcon(":/Icons/loading.png"))); item->setData(0,Qt::DecorationRole, QVariant(QIcon(":/Icons/loading.png")));
if(listStreams->topLevelItemCount() == 1) if(listStreams->topLevelItemCount() == 1)
selectFirstFeed(); selectFirstFeed();
@ -171,17 +174,26 @@ void RSSImp::on_newFeedButton_clicked() {
void RSSImp::deleteSelectedItems() { void RSSImp::deleteSelectedItems() {
QList<QTreeWidgetItem*> selectedItems = listStreams->selectedItems(); QList<QTreeWidgetItem*> selectedItems = listStreams->selectedItems();
if(selectedItems.size() == 0) return; if(selectedItems.size() == 0) return;
if(!selectedItems.size()) return; int ret;
int ret = QMessageBox::question(this, tr("Are you sure? -- qBittorrent"), tr("Are you sure you want to delete this RSS feed from the list?"), if(selectedItems.size() > 1)
tr("&Yes"), tr("&No"), ret = QMessageBox::question(this, tr("Are you sure? -- qBittorrent"), tr("Are you sure you want to delete these elements from the list?"),
QString(), 0, 1); tr("&Yes"), tr("&No"),
QString(), 0, 1);
else
ret = QMessageBox::question(this, tr("Are you sure? -- qBittorrent"), tr("Are you sure you want to delete this element from the list?"),
tr("&Yes"), tr("&No"),
QString(), 0, 1);
if(!ret) { if(!ret) {
foreach(QTreeWidgetItem *item, selectedItems){ foreach(QTreeWidgetItem *item, selectedItems){
if(listStreams->currentItem() == item){ if(listStreams->currentFeed() == item){
textBrowser->clear(); textBrowser->clear();
listNews->clear(); listNews->clear();
} }
rssmanager->removeFile(listStreams->getItemPath(item)); RssFile *rss_item = listStreams->getRSSItem(item);
rss_item->getParent()->removeFile(rss_item->getID());
// Notify TreeWidget
listStreams->itemRemoved(item);
// Actually delete the item
delete item; delete item;
} }
rssmanager->saveStreamList(); rssmanager->saveStreamList();
@ -199,7 +211,7 @@ void RSSImp::on_updateAllButton_clicked() {
void RSSImp::downloadTorrent() { void RSSImp::downloadTorrent() {
QList<QListWidgetItem *> selected_items = listNews->selectedItems(); QList<QListWidgetItem *> selected_items = listNews->selectedItems();
foreach(const QListWidgetItem* item, selected_items) { foreach(const QListWidgetItem* item, selected_items) {
RssItem* news = ((RssStream*)rssmanager->getFile(getCurrentFeedPath()))->getItem(listNews->row(item)); RssItem* news = ((RssStream*)listStreams->getCurrentRSSItem())->getItem(listNews->row(item));
BTSession->downloadFromUrl(news->getTorrentUrl()); BTSession->downloadFromUrl(news->getTorrentUrl());
} }
} }
@ -208,7 +220,7 @@ void RSSImp::downloadTorrent() {
void RSSImp::openNewsUrl() { void RSSImp::openNewsUrl() {
QList<QListWidgetItem *> selected_items = listNews->selectedItems(); QList<QListWidgetItem *> selected_items = listNews->selectedItems();
foreach(const QListWidgetItem* item, selected_items) { foreach(const QListWidgetItem* item, selected_items) {
RssItem* news = ((RssStream*)rssmanager->getFile(getCurrentFeedPath()))->getItem(listNews->row(item)); RssItem* news = ((RssStream*)listStreams->getCurrentRSSItem())->getItem(listNews->row(item));
QString link = news->getLink(); QString link = news->getLink();
if(!link.isEmpty()) if(!link.isEmpty())
QDesktopServices::openUrl(QUrl(link)); QDesktopServices::openUrl(QUrl(link));
@ -220,16 +232,22 @@ void RSSImp::renameFiles() {
QList<QTreeWidgetItem*> selectedItems = listStreams->selectedItems(); QList<QTreeWidgetItem*> selectedItems = listStreams->selectedItems();
Q_ASSERT(selectedItems.size() == 1); Q_ASSERT(selectedItems.size() == 1);
QTreeWidgetItem *item = selectedItems.at(0); QTreeWidgetItem *item = selectedItems.at(0);
RssFile *rss_item = listStreams->getRSSItem(item);
bool ok; bool ok;
QString newName = QInputDialog::getText(this, tr("Please choose a new name for this RSS feed"), tr("New feed name:"), QLineEdit::Normal, rssmanager->getFile(listStreams->getItemPath(item))->getName(), &ok); QString newName;
do {
newName = QInputDialog::getText(this, tr("Please choose a new name for this RSS feed"), tr("New feed name:"), QLineEdit::Normal, listStreams->getRSSItem(item)->getName(), &ok);
// Check if name is already taken
if(ok && rss_item->getParent()->contains(newName)) {
QMessageBox::warning(0, tr("Name already in use"), tr("This name is already used by another item, please choose another one."));
ok = false;
}
}while(!ok);
if(ok) { if(ok) {
QStringList item_path = listStreams->getItemPath(item); // Rename item
rssmanager->rename(item_path, newName); rss_item->rename(newName);
item->setText(0, newName); // Update TreeWidget
if(rssmanager->getFile(item_path)->getType() == RssFile::FOLDER) { item->setText(0, newName+ QString(" (")+QString::number(rss_item->getNbUnRead())+QString(")"));
// If it is a folder, we must update second column too
item->setText(1, newName);
}
} }
} }
@ -238,8 +256,10 @@ void RSSImp::refreshSelectedStreams() {
QList<QTreeWidgetItem*> selectedItems = listStreams->selectedItems(); QList<QTreeWidgetItem*> selectedItems = listStreams->selectedItems();
QTreeWidgetItem* item; QTreeWidgetItem* item;
foreach(item, selectedItems){ foreach(item, selectedItems){
rssmanager->refresh(listStreams->getItemPath(item)); RssFile* file = listStreams->getRSSItem(item);
if(getItemType(item) == RssFile::STREAM) file->refresh();
// FIXME: Should recursively set icons for feeds in a folder
if(file->getType() == RssFile::STREAM)
item->setData(0,Qt::DecorationRole, QVariant(QIcon(":/Icons/loading.png"))); item->setData(0,Qt::DecorationRole, QVariant(QIcon(":/Icons/loading.png")));
} }
} }
@ -249,23 +269,23 @@ void RSSImp::copySelectedFeedsURL() {
QList<QTreeWidgetItem*> selectedItems = listStreams->selectedItems(); QList<QTreeWidgetItem*> selectedItems = listStreams->selectedItems();
QTreeWidgetItem* item; QTreeWidgetItem* item;
foreach(item, selectedItems){ foreach(item, selectedItems){
URLs << item->text(1); URLs << listStreams->getItemID(item);
} }
qApp->clipboard()->setText(URLs.join("\n")); qApp->clipboard()->setText(URLs.join("\n"));
} }
void RSSImp::showFeedDownloader() { void RSSImp::showFeedDownloader() {
QTreeWidgetItem* item = listStreams->selectedItems()[0]; QTreeWidgetItem* item = listStreams->selectedItems()[0];
RssFile* rss_item = rssmanager->getFile(listStreams->getItemPath(item)); RssFile* rss_item = listStreams->getRSSItem(item);
if(rss_item->getType() == RssFile::STREAM) if(rss_item->getType() == RssFile::STREAM)
new FeedDownloaderDlg(this, item->text(1), rss_item->getName(), BTSession); new FeedDownloaderDlg(this, listStreams->getItemID(item), rss_item->getName(), BTSession);
} }
void RSSImp::on_markReadButton_clicked() { void RSSImp::on_markReadButton_clicked() {
QList<QTreeWidgetItem*> selectedItems = listStreams->selectedItems(); QList<QTreeWidgetItem*> selectedItems = listStreams->selectedItems();
QTreeWidgetItem* item; QTreeWidgetItem* item;
foreach(item, selectedItems){ foreach(item, selectedItems){
RssFile *rss_item = rssmanager->getFile(listStreams->getItemPath(item)); RssFile *rss_item = listStreams->getRSSItem(item);
rss_item->markAllAsRead(); rss_item->markAllAsRead();
item->setData(0, Qt::DisplayRole, rss_item->getName()+ QString::fromUtf8(" (0)")); item->setData(0, Qt::DisplayRole, rss_item->getName()+ QString::fromUtf8(" (0)"));
} }
@ -287,14 +307,13 @@ void RSSImp::fillFeedsList(QTreeWidgetItem *parent, RssFolder *rss_parent) {
else else
item = new QTreeWidgetItem(parent); item = new QTreeWidgetItem(parent);
item->setData(0, Qt::DisplayRole, rss_child->getName()+ QString::fromUtf8(" (")+QString::number(rss_child->getNbUnRead(), 10)+QString(")")); item->setData(0, Qt::DisplayRole, rss_child->getName()+ QString::fromUtf8(" (")+QString::number(rss_child->getNbUnRead(), 10)+QString(")"));
// Notify TreeWidget of item addition
listStreams->itemAdded(item, rss_child);
// Set Icon
if(rss_child->getType() == RssFile::STREAM) { if(rss_child->getType() == RssFile::STREAM) {
item->setData(0,Qt::DecorationRole, QVariant(QIcon(QString::fromUtf8(":/Icons/loading.png")))); item->setData(0,Qt::DecorationRole, QVariant(QIcon(QString::fromUtf8(":/Icons/loading.png"))));
item->setData(1, Qt::DisplayRole, ((RssStream*)rss_child)->getUrl());
item->setData(2, Qt::DisplayRole, QVariant((int)rss_child->getType()));
} else { } else {
item->setData(0,Qt::DecorationRole, QVariant(QIcon(QString::fromUtf8(":/Icons/oxygen/folder.png")))); item->setData(0,Qt::DecorationRole, QVariant(QIcon(QString::fromUtf8(":/Icons/oxygen/folder.png"))));
item->setData(1, Qt::DisplayRole, ((RssFolder*)rss_child)->getName());
item->setData(2, Qt::DisplayRole, QVariant((int)rss_child->getType()));
// Recurvive call to load sub folders/files // Recurvive call to load sub folders/files
fillFeedsList(item, (RssFolder*)rss_child); fillFeedsList(item, (RssFolder*)rss_child);
} }
@ -307,14 +326,12 @@ void RSSImp::refreshNewsList(QTreeWidgetItem* item) {
listNews->clear(); listNews->clear();
return; return;
} }
qDebug("RefreshNewsList for item: %s", item->text(1).toLocal8Bit().data()); if(listStreams->getItemType(item) != RssFile::STREAM) {
qDebug("Item path: %s", listStreams->getItemPath(item).join("\\").toLocal8Bit().data());
RssFile *file = rssmanager->getFile(listStreams->getItemPath(item));
if(file->getType() != RssFile::STREAM) {
listNews->clear(); listNews->clear();
return; return;
} }
RssStream *stream = (RssStream*)file;
RssStream *stream = (RssStream*)listStreams->getRSSItem(item);
qDebug("Getting the list of news"); qDebug("Getting the list of news");
QList<RssItem*> news = stream->getNewsList(); QList<RssItem*> news = stream->getNewsList();
@ -333,14 +350,13 @@ void RSSImp::refreshNewsList(QTreeWidgetItem* item) {
} }
} }
qDebug("Added all news to the GUI"); qDebug("Added all news to the GUI");
//selectFirstNews();
qDebug("First news selected"); qDebug("First news selected");
} }
// display a news // display a news
void RSSImp::refreshTextBrowser(QListWidgetItem *item) { void RSSImp::refreshTextBrowser(QListWidgetItem *item) {
if(!item) return; if(!item) return;
RssStream *stream = (RssStream*)rssmanager->getFile(getCurrentFeedPath()); RssStream *stream = (RssStream*)listStreams->getCurrentRSSItem();
RssItem* article = stream->getItem(listNews->row(item)); RssItem* article = stream->getItem(listNews->row(item));
QString html; QString html;
html += "<div style='border: 2px solid red; margin-left: 5px; margin-right: 5px; margin-bottom: 5px;'>"; html += "<div style='border: 2px solid red; margin-left: 5px; margin-right: 5px; margin-bottom: 5px;'>";
@ -380,32 +396,19 @@ void RSSImp::restoreSlidersPosition() {
} }
} }
QTreeWidgetItem* RSSImp::getTreeItemFromUrl(QString url) const{
QList<QTreeWidgetItem*> items = listStreams->findItems(url, Qt::MatchExactly, 1);
Q_ASSERT(items.size() == 1);
return items.at(0);
}
void RSSImp::updateFeedIcon(QString url, QString icon_path){ void RSSImp::updateFeedIcon(QString url, QString icon_path){
QTreeWidgetItem *item = getTreeItemFromUrl(url); QTreeWidgetItem *item = listStreams->getTreeItemFromUrl(url);
item->setData(0,Qt::DecorationRole, QVariant(QIcon(icon_path))); item->setData(0,Qt::DecorationRole, QVariant(QIcon(icon_path)));
} }
void RSSImp::updateFeedNbNews(RssStream* stream){ void RSSImp::updateFeedNbNews(RssStream* stream){
QTreeWidgetItem *item = getTreeItemFromUrl(stream->getUrl()); QTreeWidgetItem *item = listStreams->getTreeItemFromUrl(stream->getUrl());
item->setText(0, stream->getName() + QString::fromUtf8(" (") + QString::number(stream->getNbUnRead(), 10)+ QString(")")); item->setText(0, stream->getName() + QString::fromUtf8(" (") + QString::number(stream->getNbUnRead(), 10)+ QString(")"));
} }
QString RSSImp::getCurrentFeedUrl() const {
QTreeWidgetItem *item = listStreams->currentItem();
if(item)
return item->text(1);
return QString::null;
}
void RSSImp::updateFeedInfos(QString url, QString aliasOrUrl, unsigned int nbUnread){ void RSSImp::updateFeedInfos(QString url, QString aliasOrUrl, unsigned int nbUnread){
QTreeWidgetItem *item = getTreeItemFromUrl(url); QTreeWidgetItem *item = listStreams->getTreeItemFromUrl(url);
RssStream *stream = (RssStream*)rssmanager->getFile(listStreams->getItemPath(item)); RssStream *stream = (RssStream*)listStreams->getRSSItem(item);
item->setText(0, aliasOrUrl + QString::fromUtf8(" (") + QString::number(nbUnread, 10)+ QString(")")); item->setText(0, aliasOrUrl + QString::fromUtf8(" (") + QString::number(nbUnread, 10)+ QString(")"));
item->setData(0,Qt::DecorationRole, QVariant(QIcon(stream->getIconPath()))); item->setData(0,Qt::DecorationRole, QVariant(QIcon(stream->getIconPath())));
// If the feed is selected, update the displayed news // If the feed is selected, update the displayed news

5
src/rss_imp.h

@ -76,11 +76,6 @@ protected slots:
public: public:
RSSImp(bittorrent *BTSession); RSSImp(bittorrent *BTSession);
~RSSImp(); ~RSSImp();
QTreeWidgetItem* getTreeItemFromUrl(QString url) const;
QString getCurrentFeedUrl() const;
QTreeWidgetItem* getItemFromPath(QStringList path) const;
QStringList getCurrentFeedPath() const;
RssFile::FileType getItemType(QTreeWidgetItem *item) const;
}; };

Loading…
Cancel
Save