Auto-update code moved to model class.

This commit is contained in:
Martin Rotter 2015-07-29 07:59:00 +02:00
parent c2e6172d21
commit 17a558e47a
6 changed files with 99 additions and 92 deletions

View File

@ -25,6 +25,7 @@
#include "miscellaneous/textfactory.h"
#include "miscellaneous/databasefactory.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/mutex.h"
#include "gui/messagebox.h"
#include <QSqlError>
@ -33,12 +34,13 @@
#include <QPair>
#include <QStack>
#include <QMimeData>
#include <QTimer>
#include <algorithm>
FeedsModel::FeedsModel(QObject *parent)
: QAbstractItemModel(parent), m_recycleBin(new RecycleBin()) {
: QAbstractItemModel(parent), m_recycleBin(new RecycleBin()), m_autoUpdateTimer(new QTimer(this)) {
setObjectName(QSL("FeedsModel"));
// Create root item.
@ -58,7 +60,12 @@ FeedsModel::FeedsModel(QObject *parent)
m_tooltipData << /*: Feed list header "titles" column tooltip.*/ tr("Titles of feeds/categories.") <<
/*: Feed list header "counts" column tooltip.*/ tr("Counts of unread/all meesages.");
connect(m_autoUpdateTimer, SIGNAL(timeout()), this, SLOT(executeNextAutoUpdate()));
loadFromDatabase();
// Setup the timer.
updateAutoUpdateStatus();
}
FeedsModel::~FeedsModel() {
@ -68,6 +75,68 @@ FeedsModel::~FeedsModel() {
delete m_rootItem;
}
void FeedsModel::quit() {
if (m_autoUpdateTimer->isActive()) {
m_autoUpdateTimer->stop();
}
}
void FeedsModel::executeNextAutoUpdate() {
if (!qApp->feedUpdateLock()->tryLock()) {
qDebug("Delaying scheduled feed auto-updates for one minute due to another running update.");
// Cannot update, quit.
return;
}
// If global auto-update is enabled and its interval counter reached zero,
// then we need to restore it.
if (m_globalAutoUpdateEnabled && --m_globalAutoUpdateRemainingInterval < 0) {
// We should start next auto-update interval.
m_globalAutoUpdateRemainingInterval = m_globalAutoUpdateInitialInterval;
}
qDebug("Starting auto-update event, pass %d/%d.", m_globalAutoUpdateRemainingInterval, m_globalAutoUpdateInitialInterval);
// Pass needed interval data and lets the model decide which feeds
// should be updated in this pass.
QList<Feed*> feeds_for_update = feedsForScheduledUpdate(m_globalAutoUpdateEnabled && m_globalAutoUpdateRemainingInterval == 0);
qApp->feedUpdateLock()->unlock();
if (!feeds_for_update.isEmpty()) {
// Request update for given feeds.
emit feedsUpdateRequested(feeds_for_update);
// NOTE: OSD/bubble informing about performing
// of scheduled update can be shown now.
qApp->showGuiMessage(tr("Starting auto-update of some feeds"),
tr("I will auto-update %n feed(s).", 0, feeds_for_update.size()),
QSystemTrayIcon::Information);
}
}
void FeedsModel::updateAutoUpdateStatus() {
// Restore global intervals.
// NOTE: Specific per-feed interval are left intact.
m_globalAutoUpdateInitialInterval = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::AutoUpdateInterval)).toInt();
m_globalAutoUpdateRemainingInterval = m_globalAutoUpdateInitialInterval;
m_globalAutoUpdateEnabled = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::AutoUpdateEnabled)).toBool();
// Start global auto-update timer if it is not running yet.
// NOTE: The timer must run even if global auto-update
// is not enabled because user can still enable auto-update
// for individual feeds.
if (!m_autoUpdateTimer->isActive()) {
m_autoUpdateTimer->setInterval(AUTO_UPDATE_INTERVAL);
m_autoUpdateTimer->start();
qDebug("Auto-update timer started with interval %d.", m_autoUpdateTimer->interval());
}
else {
qDebug("Auto-update timer is already running.");
}
}
QMimeData *FeedsModel::mimeData(const QModelIndexList &indexes) const {
QMimeData *mime_data = new QMimeData();
QByteArray encoded_data;
@ -158,7 +227,7 @@ Qt::DropActions FeedsModel::supportedDropActions() const {
return Qt::MoveAction;
}
Qt::ItemFlags FeedsModel::flags(const QModelIndex &index) const {
Qt::ItemFlags FeedsModel::flags(const QModelIndex &index) const {
Qt::ItemFlags base_flags = QAbstractItemModel::flags(index);
RootItem *item_for_index = itemForIndex(index);
@ -249,7 +318,7 @@ int FeedsModel::rowCount(const QModelIndex &parent) const {
}
}
bool FeedsModel::removeItem(const QModelIndex &index) {
bool FeedsModel::removeItem(const QModelIndex &index) {
if (index.isValid()) {
QModelIndex parent_index = index.parent();
RootItem *deleting_item = itemForIndex(index);
@ -472,7 +541,7 @@ RecycleBin *FeedsModel::recycleBinForIndex(const QModelIndex &index) const {
}
}
QModelIndex FeedsModel::indexForItem(RootItem *item) const {
QModelIndex FeedsModel::indexForItem(RootItem *item) const {
if (item == NULL || item->kind() == RootItem::Root) {
// Root item lies on invalid index.
return QModelIndex();

View File

@ -30,6 +30,7 @@ class Category;
class Feed;
class RecycleBin;
class FeedsImportExportModel;
class QTimer;
typedef QList<QPair<int, Category*> > CategoryAssignment;
typedef QPair<int, Category*> CategoryAssignmentItem;
@ -155,6 +156,13 @@ class FeedsModel : public QAbstractItemModel {
// Access to recycle bin.
RecycleBin *recycleBin() const;
// Resets global auto-update intervals according to settings
// and starts/stop the timer as needed.
void updateAutoUpdateStatus();
// Does necessary job before quitting this component.
void quit();
public slots:
// Feeds operations.
bool markFeedsRead(const QList<Feed*> &feeds, int read);
@ -169,6 +177,10 @@ class FeedsModel : public QAbstractItemModel {
// NOTE: This reloads all parent valid indexes too.
void reloadChangedLayout(QModelIndexList list);
private slots:
// Is executed when next auto-update round could be done.
void executeNextAutoUpdate();
protected:
// Returns converted ids of given feeds
// which are suitable as IN clause for SQL queries.
@ -185,12 +197,21 @@ class FeedsModel : public QAbstractItemModel {
signals:
void requireItemValidationAfterDragDrop(const QModelIndex &source_index);
// Emitted when model requests update of some feeds.
void feedsUpdateRequested(const QList<Feed*> feeds);
private:
RootItem *m_rootItem;
RecycleBin *m_recycleBin;
QList<QString> m_headerData;
QList<QString> m_tooltipData;
QIcon m_countsIcon;
// Auto-update stuff.
QTimer *m_autoUpdateTimer;
bool m_globalAutoUpdateEnabled;
int m_globalAutoUpdateInitialInterval;
int m_globalAutoUpdateRemainingInterval;
};
#endif // FEEDSMODEL_H

View File

@ -291,7 +291,7 @@ void FormSettings::saveFeedsMessages() {
settings->setValue(GROUP(Messages), Messages::PreviewerFontStandard, m_ui->m_cmbMessageFontStandard->currentFont().family());
qApp->mainForm()->tabWidget()->feedMessageViewer()->loadMessageViewerFonts();
qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->updateAutoUpdateStatus();
qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->sourceModel()->updateAutoUpdateStatus();
qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->sourceModel()->reloadWholeLayout();
qApp->mainForm()->tabWidget()->feedMessageViewer()->messagesView()->sourceModel()->updateDateFormat();
qApp->mainForm()->tabWidget()->feedMessageViewer()->messagesView()->sourceModel()->reloadWholeLayout();

View File

@ -150,8 +150,8 @@ void FeedMessageViewer::loadMessageViewerFonts() {
}
void FeedMessageViewer::quit() {
// Quit the feeds view (stops auto-update timer etc.).
m_feedsView->quit();
// Quit the feeds model (stops auto-update timer etc.).
m_feedsView->sourceModel()->quit();
// Close worker threads.
if (m_feedDownloaderThread != NULL && m_feedDownloaderThread->isRunning()) {

View File

@ -46,8 +46,7 @@ FeedsView::FeedsView(QWidget *parent)
: QTreeView(parent),
m_contextMenuCategoriesFeeds(NULL),
m_contextMenuEmptySpace(NULL),
m_contextMenuRecycleBin(NULL),
m_autoUpdateTimer(new QTimer(this)) {
m_contextMenuRecycleBin(NULL) {
setObjectName(QSL("FeedsView"));
// Allocate models.
@ -56,53 +55,23 @@ FeedsView::FeedsView(QWidget *parent)
// Connections.
connect(m_sourceModel, SIGNAL(requireItemValidationAfterDragDrop(QModelIndex)), this, SLOT(validateItemAfterDragDrop(QModelIndex)));
connect(m_autoUpdateTimer, SIGNAL(timeout()), this, SLOT(executeNextAutoUpdate()));
connect(m_sourceModel, SIGNAL(feedsUpdateRequested(QList<Feed*>)), this, SIGNAL(feedsUpdateRequested(QList<Feed*>)));
connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(saveSortState(int,Qt::SortOrder)));
setModel(m_proxyModel);
setupAppearance();
// Setup the timer.
updateAutoUpdateStatus();
}
FeedsView::~FeedsView() {
qDebug("Destroying FeedsView instance.");
}
void FeedsView::quit() {
if (m_autoUpdateTimer->isActive()) {
m_autoUpdateTimer->stop();
}
}
void FeedsView::setSortingEnabled(bool enable) {
disconnect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(saveSortState(int,Qt::SortOrder)));
QTreeView::setSortingEnabled(enable);
connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(saveSortState(int,Qt::SortOrder)));
}
void FeedsView::updateAutoUpdateStatus() {
// Restore global intervals.
// NOTE: Specific per-feed interval are left intact.
m_globalAutoUpdateInitialInterval = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::AutoUpdateInterval)).toInt();
m_globalAutoUpdateRemainingInterval = m_globalAutoUpdateInitialInterval;
m_globalAutoUpdateEnabled = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::AutoUpdateEnabled)).toBool();
// Start global auto-update timer if it is not running yet.
// NOTE: The timer must run even if global auto-update
// is not enabled because user can still enable auto-update
// for individual feeds.
if (!m_autoUpdateTimer->isActive()) {
m_autoUpdateTimer->setInterval(AUTO_UPDATE_INTERVAL);
m_autoUpdateTimer->start();
qDebug("Auto-update timer started with interval %d.", m_autoUpdateTimer->interval());
}
else {
qDebug("Auto-update timer is already running.");
}
}
QList<Feed*> FeedsView::selectedFeeds() const {
QModelIndex current_index = currentIndex();
@ -188,42 +157,6 @@ void FeedsView::updateAllFeedsOnStartup() {
}
}
void FeedsView::executeNextAutoUpdate() {
if (!qApp->feedUpdateLock()->tryLock()) {
qDebug("Delaying scheduled feed auto-updates for one minute due to another running update.");
// Cannot update, quit.
return;
}
// If global auto-update is enabled and its interval counter reached zero,
// then we need to restore it.
if (m_globalAutoUpdateEnabled && --m_globalAutoUpdateRemainingInterval < 0) {
// We should start next auto-update interval.
m_globalAutoUpdateRemainingInterval = m_globalAutoUpdateInitialInterval;
}
qDebug("Starting auto-update event, pass %d/%d.", m_globalAutoUpdateRemainingInterval, m_globalAutoUpdateInitialInterval);
// Pass needed interval data and lets the model decide which feeds
// should be updated in this pass.
QList<Feed*> feeds_for_update = m_sourceModel->feedsForScheduledUpdate(m_globalAutoUpdateEnabled &&
m_globalAutoUpdateRemainingInterval == 0);
qApp->feedUpdateLock()->unlock();
if (!feeds_for_update.isEmpty()) {
// Request update for given feeds.
emit feedsUpdateRequested(feeds_for_update);
// NOTE: OSD/bubble informing about performing
// of scheduled update can be shown now.
qApp->showGuiMessage(tr("Starting auto-update of some feeds"),
tr("I will auto-update %n feed(s).", 0, feeds_for_update.size()),
QSystemTrayIcon::Information);
}
}
void FeedsView::setSelectedFeedsClearStatus(int clear) {
m_sourceModel->markFeedsDeleted(selectedFeeds(), clear, 0);
updateCountsOfSelectedFeeds(true);

View File

@ -49,14 +49,7 @@ class FeedsView : public QTreeView {
return m_sourceModel;
}
// Does necessary job before quitting this component.
void quit();
void setSortingEnabled(bool enable);
// Resets global auto-update intervals according to settings
// and starts/stop the timer as needed.
void updateAutoUpdateStatus();
// Returns list of selected/all feeds.
// NOTE: This is recursive method which returns all descendants.
@ -82,9 +75,6 @@ class FeedsView : public QTreeView {
void updateAllFeedsOnStartup();
void updateSelectedFeeds();
// Is executed when next auto-update round could be done.
void executeNextAutoUpdate();
// Feed read/unread manipulators.
void markSelectedFeedsReadStatus(int read);
void markSelectedFeedsRead();
@ -196,12 +186,6 @@ class FeedsView : public QTreeView {
FeedsModel *m_sourceModel;
FeedsProxyModel *m_proxyModel;
// Auto-update stuff.
QTimer *m_autoUpdateTimer;
bool m_globalAutoUpdateEnabled;
int m_globalAutoUpdateInitialInterval;
int m_globalAutoUpdateRemainingInterval;
};
#endif // FEEDSVIEW_H