This commit is contained in:
Martin Rotter 2016-02-10 12:09:03 +01:00
parent 10a135d570
commit f76c4d0dec
10 changed files with 77 additions and 2 deletions

View File

@ -10,6 +10,7 @@ http://goo.gl/forms/GcvPYgS2a8
Added: Added:
▪ User is now able to delete TT-RSS feeds. (issue #151) ▪ User is now able to delete TT-RSS feeds. (issue #151)
▪ Added ability to stop running batch feed update. (issue #157)
Fixed: Fixed:

View File

@ -25,7 +25,7 @@
#include <QMetaType> #include <QMetaType>
FeedDownloader::FeedDownloader(QObject *parent) : QObject(parent) { FeedDownloader::FeedDownloader(QObject *parent) : QObject(parent), m_stopUpdate(false), m_isUpdateRunning(false) {
qRegisterMetaType<FeedDownloadResults>("FeedDownloadResults"); qRegisterMetaType<FeedDownloadResults>("FeedDownloadResults");
} }
@ -33,15 +33,29 @@ FeedDownloader::~FeedDownloader() {
qDebug("Destroying FeedDownloader instance."); qDebug("Destroying FeedDownloader instance.");
} }
bool FeedDownloader::isUpdateRunning() const {
return m_isUpdateRunning;
}
void FeedDownloader::updateFeeds(const QList<Feed*> &feeds) { void FeedDownloader::updateFeeds(const QList<Feed*> &feeds) {
qDebug().nospace() << "Performing feed updates in thread: \'" << QThread::currentThreadId() << "\'."; qDebug().nospace() << "Performing feed updates in thread: \'" << QThread::currentThreadId() << "\'.";
// It may be good to disable "stop" action when batch feed update
// starts.
m_isUpdateRunning = true;
m_stopUpdate = false;
// Job starts now. // Job starts now.
emit started(); emit started();
FeedDownloadResults results; FeedDownloadResults results;
for (int i = 0, total = feeds.size(); i < total; i++) { for (int i = 0, total = feeds.size(); i < total; i++) {
if (m_stopUpdate) {
qDebug("Stopping batch feed update now.");
break;
}
int updated_messages = feeds.at(i)->update(); int updated_messages = feeds.at(i)->update();
if (updated_messages > 0) { if (updated_messages > 0) {
@ -56,6 +70,10 @@ void FeedDownloader::updateFeeds(const QList<Feed*> &feeds) {
results.sort(); results.sort();
// Make sure that there is not "stop" action pending.
m_isUpdateRunning = false;
m_stopUpdate = false;
// Update of feeds has finished. // Update of feeds has finished.
// NOTE: This means that now "update lock" can be unlocked // NOTE: This means that now "update lock" can be unlocked
// and feeds can be added/edited/deleted and application // and feeds can be added/edited/deleted and application
@ -63,6 +81,10 @@ void FeedDownloader::updateFeeds(const QList<Feed*> &feeds) {
emit finished(results); emit finished(results);
} }
void FeedDownloader::stopRunningUpdate() {
m_stopUpdate = true;
}
FeedDownloadResults::FeedDownloadResults() : m_updatedFeeds(QList<QPair<QString,int> >()) { FeedDownloadResults::FeedDownloadResults() : m_updatedFeeds(QList<QPair<QString,int> >()) {
} }

View File

@ -53,6 +53,8 @@ class FeedDownloader : public QObject {
explicit FeedDownloader(QObject *parent = 0); explicit FeedDownloader(QObject *parent = 0);
virtual ~FeedDownloader(); virtual ~FeedDownloader();
bool isUpdateRunning() const;
public slots: public slots:
// Performs update of all feeds from the "feeds" parameter. // Performs update of all feeds from the "feeds" parameter.
// New messages are downloaded for each feed and they // New messages are downloaded for each feed and they
@ -60,6 +62,9 @@ class FeedDownloader : public QObject {
// Appropriate signals are emitted. // Appropriate signals are emitted.
void updateFeeds(const QList<Feed*> &feeds); void updateFeeds(const QList<Feed*> &feeds);
// Stops running update.
void stopRunningUpdate();
signals: signals:
// Emitted if feed updates started. // Emitted if feed updates started.
void started(); void started();
@ -73,6 +78,10 @@ class FeedDownloader : public QObject {
// and "total" number indicates total number of feeds // and "total" number indicates total number of feeds
// which were in the initial queue. // which were in the initial queue.
void progress(const Feed *feed, int current, int total); void progress(const Feed *feed, int current, int total);
private:
bool m_isUpdateRunning;
bool m_stopUpdate;
}; };
#endif // FEEDDOWNLOADER_H #endif // FEEDDOWNLOADER_H

View File

@ -157,6 +157,8 @@ void FeedsModel::updateFeeds(const QList<Feed*> &feeds) {
void FeedsModel::onFeedUpdatesStarted() { void FeedsModel::onFeedUpdatesStarted() {
//: Text display in status bar when feed update is started. //: Text display in status bar when feed update is started.
qApp->mainForm()->statusBar()->showProgressFeeds(0, tr("Feed update started")); qApp->mainForm()->statusBar()->showProgressFeeds(0, tr("Feed update started"));
emit feedsUpdateStarted();
} }
void FeedsModel::onFeedUpdatesProgress(const Feed *feed, int current, int total) { void FeedsModel::onFeedUpdatesProgress(const Feed *feed, int current, int total) {
@ -610,6 +612,10 @@ bool FeedsModel::hasAnyFeedNewMessages() const {
return false; return false;
} }
bool FeedsModel::isFeedUpdateRunning() const {
return m_feedDownloader != NULL && m_feedDownloader->isUpdateRunning();
}
void FeedsModel::reloadChangedLayout(QModelIndexList list) { void FeedsModel::reloadChangedLayout(QModelIndexList list) {
while (!list.isEmpty()) { while (!list.isEmpty()) {
QModelIndex indx = list.takeFirst(); QModelIndex indx = list.takeFirst();
@ -721,6 +727,12 @@ void FeedsModel::loadActivatedServiceAccounts() {
} }
} }
void FeedsModel::stopRunningFeedUpdate() {
if (m_feedDownloader != NULL) {
m_feedDownloader->stopRunningUpdate();
}
}
QList<Feed*> FeedsModel::feedsForIndex(const QModelIndex &index) const { QList<Feed*> FeedsModel::feedsForIndex(const QModelIndex &index) const {
return itemForIndex(index)->getSubTreeFeeds(); return itemForIndex(index)->getSubTreeFeeds();
} }

View File

@ -125,6 +125,8 @@ class FeedsModel : public QAbstractItemModel {
return m_rootItem; return m_rootItem;
} }
bool isFeedUpdateRunning() const;
// Resets global auto-update intervals according to settings // Resets global auto-update intervals according to settings
// and starts/stop the timer as needed. // and starts/stop the timer as needed.
void updateAutoUpdateStatus(); void updateAutoUpdateStatus();
@ -142,6 +144,8 @@ class FeedsModel : public QAbstractItemModel {
void loadActivatedServiceAccounts(); void loadActivatedServiceAccounts();
public slots: public slots:
void stopRunningFeedUpdate();
// Schedules all feeds from all accounts for update. // Schedules all feeds from all accounts for update.
void updateAllFeeds(); void updateAllFeeds();
@ -191,6 +195,8 @@ class FeedsModel : public QAbstractItemModel {
// Update of feeds is finished. // Update of feeds is finished.
void feedsUpdateFinished(); void feedsUpdateFinished();
void feedsUpdateStarted();
// Emitted when model requests update of some feeds. // Emitted when model requests update of some feeds.
void feedsUpdateRequested(QList<Feed*> feeds); void feedsUpdateRequested(QList<Feed*> feeds);

View File

@ -130,6 +130,7 @@ QList<QAction*> FormMain::allActions() const {
actions << m_ui->m_actionDeleteSelectedMessages; actions << m_ui->m_actionDeleteSelectedMessages;
actions << m_ui->m_actionUpdateAllItems; actions << m_ui->m_actionUpdateAllItems;
actions << m_ui->m_actionUpdateSelectedItems; actions << m_ui->m_actionUpdateSelectedItems;
actions << m_ui->m_actionStopRunningItemsUpdate;
actions << m_ui->m_actionEditSelectedItem; actions << m_ui->m_actionEditSelectedItem;
actions << m_ui->m_actionDeleteSelectedItem; actions << m_ui->m_actionDeleteSelectedItem;
actions << m_ui->m_actionServiceAdd; actions << m_ui->m_actionServiceAdd;
@ -372,6 +373,7 @@ void FormMain::setupIcons() {
// Feeds/messages. // Feeds/messages.
m_ui->m_menuAddItem->setIcon(icon_theme_factory->fromTheme(QSL("item-new"))); m_ui->m_menuAddItem->setIcon(icon_theme_factory->fromTheme(QSL("item-new")));
m_ui->m_actionStopRunningItemsUpdate->setIcon(icon_theme_factory->fromTheme(QSL("go-stop")));
m_ui->m_actionUpdateAllItems->setIcon(icon_theme_factory->fromTheme(QSL("item-update-all"))); m_ui->m_actionUpdateAllItems->setIcon(icon_theme_factory->fromTheme(QSL("item-update-all")));
m_ui->m_actionUpdateSelectedItems->setIcon(icon_theme_factory->fromTheme(QSL("item-update-selected"))); m_ui->m_actionUpdateSelectedItems->setIcon(icon_theme_factory->fromTheme(QSL("item-update-selected")));
m_ui->m_actionClearSelectedItems->setIcon(icon_theme_factory->fromTheme(QSL("mail-remove"))); m_ui->m_actionClearSelectedItems->setIcon(icon_theme_factory->fromTheme(QSL("mail-remove")));

View File

@ -135,6 +135,7 @@
</widget> </widget>
<addaction name="m_actionUpdateAllItems"/> <addaction name="m_actionUpdateAllItems"/>
<addaction name="m_actionUpdateSelectedItems"/> <addaction name="m_actionUpdateSelectedItems"/>
<addaction name="m_actionStopRunningItemsUpdate"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="m_menuAddItem"/> <addaction name="m_menuAddItem"/>
<addaction name="m_actionEditSelectedItem"/> <addaction name="m_actionEditSelectedItem"/>
@ -797,6 +798,14 @@
<string notr="true"/> <string notr="true"/>
</property> </property>
</action> </action>
<action name="m_actionStopRunningItemsUpdate">
<property name="text">
<string>Stop running update</string>
</property>
<property name="shortcut">
<string notr="true"/>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View File

@ -191,6 +191,7 @@ void FeedMessageViewer::updateMessageButtonsAvailability() {
} }
void FeedMessageViewer::updateFeedButtonsAvailability() { void FeedMessageViewer::updateFeedButtonsAvailability() {
const bool is_update_running = feedsView()->sourceModel()->isFeedUpdateRunning();
const bool critical_action_running = qApp->feedUpdateLock()->isLocked(); const bool critical_action_running = qApp->feedUpdateLock()->isLocked();
const RootItem *selected_item = feedsView()->selectedItem(); const RootItem *selected_item = feedsView()->selectedItem();
const bool anything_selected = selected_item != NULL; const bool anything_selected = selected_item != NULL;
@ -199,6 +200,7 @@ void FeedMessageViewer::updateFeedButtonsAvailability() {
const bool service_selected = anything_selected && selected_item->kind() == RootItemKind::ServiceRoot; const bool service_selected = anything_selected && selected_item->kind() == RootItemKind::ServiceRoot;
const FormMain *form_main = qApp->mainForm(); const FormMain *form_main = qApp->mainForm();
form_main->m_ui->m_actionStopRunningItemsUpdate->setEnabled(is_update_running);
form_main->m_ui->m_actionBackupDatabaseSettings->setEnabled(!critical_action_running); form_main->m_ui->m_actionBackupDatabaseSettings->setEnabled(!critical_action_running);
form_main->m_ui->m_actionCleanupDatabase->setEnabled(!critical_action_running); form_main->m_ui->m_actionCleanupDatabase->setEnabled(!critical_action_running);
form_main->m_ui->m_actionClearSelectedItems->setEnabled(anything_selected); form_main->m_ui->m_actionClearSelectedItems->setEnabled(anything_selected);
@ -245,6 +247,7 @@ void FeedMessageViewer::createConnections() {
// to reload selections. // to reload selections.
connect(m_feedsView->sourceModel(), SIGNAL(reloadMessageListRequested(bool)), m_messagesView, SLOT(reloadSelections(bool))); connect(m_feedsView->sourceModel(), SIGNAL(reloadMessageListRequested(bool)), m_messagesView, SLOT(reloadSelections(bool)));
connect(m_feedsView->sourceModel(), SIGNAL(feedsUpdateFinished()), this, SLOT(onFeedsUpdateFinished())); connect(m_feedsView->sourceModel(), SIGNAL(feedsUpdateFinished()), this, SLOT(onFeedsUpdateFinished()));
connect(m_feedsView->sourceModel(), SIGNAL(feedsUpdateStarted()), this, SLOT(onFeedsUpdateStarted()));
// Message openers. // Message openers.
connect(m_messagesView, SIGNAL(openLinkMiniBrowser(QString)), m_messagesBrowser, SLOT(navigateToUrl(QString))); connect(m_messagesView, SIGNAL(openLinkMiniBrowser(QString)), m_messagesBrowser, SLOT(navigateToUrl(QString)));
@ -294,6 +297,8 @@ void FeedMessageViewer::createConnections() {
SIGNAL(triggered()), m_feedsView, SLOT(updateSelectedItems())); SIGNAL(triggered()), m_feedsView, SLOT(updateSelectedItems()));
connect(form_main->m_ui->m_actionUpdateAllItems, connect(form_main->m_ui->m_actionUpdateAllItems,
SIGNAL(triggered()), m_feedsView, SLOT(updateAllItems())); SIGNAL(triggered()), m_feedsView, SLOT(updateAllItems()));
connect(form_main->m_ui->m_actionStopRunningItemsUpdate,
SIGNAL(triggered()), m_feedsView->sourceModel(), SLOT(stopRunningFeedUpdate()));
connect(form_main->m_ui->m_actionEditSelectedItem, connect(form_main->m_ui->m_actionEditSelectedItem,
SIGNAL(triggered()), m_feedsView, SLOT(editSelectedItem())); SIGNAL(triggered()), m_feedsView, SLOT(editSelectedItem()));
connect(form_main->m_ui->m_actionViewSelectedItemsNewspaperMode, connect(form_main->m_ui->m_actionViewSelectedItemsNewspaperMode,
@ -434,3 +439,10 @@ void FeedMessageViewer::refreshVisualProperties() {
void FeedMessageViewer::onFeedsUpdateFinished() { void FeedMessageViewer::onFeedsUpdateFinished() {
m_messagesView->reloadSelections(true); m_messagesView->reloadSelections(true);
} }
void FeedMessageViewer::onFeedsUpdateStarted() {
// Check only "Stop running update" button.
const bool is_update_running = feedsView()->sourceModel()->isFeedUpdateRunning();
qApp->mainForm()->m_ui->m_actionStopRunningItemsUpdate->setEnabled(is_update_running);
}

View File

@ -97,6 +97,8 @@ class FeedMessageViewer : public TabContent {
// Called when feed update finishes. // Called when feed update finishes.
void onFeedsUpdateFinished(); void onFeedsUpdateFinished();
void onFeedsUpdateStarted();
// Switches visibility of feed list and related // Switches visibility of feed list and related
// toolbar. // toolbar.
void switchFeedComponentVisibility(); void switchFeedComponentVisibility();

View File

@ -85,7 +85,7 @@ DKEY GUI::ToolbarStyle = "toolbar_style";
DVALUE(Qt::ToolButtonStyle) GUI::ToolbarStyleDef = Qt::ToolButtonIconOnly; DVALUE(Qt::ToolButtonStyle) GUI::ToolbarStyleDef = Qt::ToolButtonIconOnly;
DKEY GUI::FeedsToolbarActions = "feeds_toolbar"; DKEY GUI::FeedsToolbarActions = "feeds_toolbar";
DVALUE(char*) GUI::FeedsToolbarActionsDef = "m_actionUpdateAllItems,m_actionMarkAllItemsRead"; DVALUE(char*) GUI::FeedsToolbarActionsDef = "m_actionUpdateAllItems,m_actionStopRunningItemsUpdate,m_actionMarkAllItemsRead";
DKEY GUI::MainWindowInitialSize = "window_size"; DKEY GUI::MainWindowInitialSize = "window_size";
DKEY GUI::MainWindowInitialPosition = "window_position"; DKEY GUI::MainWindowInitialPosition = "window_position";