Skip to content

Commit

Permalink
Fixed #132, fixed #6.
Browse files Browse the repository at this point in the history
  • Loading branch information
martinrotter committed Sep 10, 2017
1 parent dbdddb8 commit 0a8aea5
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 34 deletions.
2 changes: 2 additions & 0 deletions resources/text/CHANGELOG
Expand Up @@ -3,6 +3,8 @@

Added:
▪ Standard account is now automatically added if RSS Guard is started with empty database.
▪ Menu action "Select next unread message" in "Messages" menu now works across all feeds, so user can navigate through all unread messages with a sigle keyboard shortcut. (#132, #6)
▪ Added two bindable menu actions (in menu "Web browser & tabs") which allow to cycle among tabs. (#6)

Fixed:
▪ Fixed build on some Unit-like operating systems.
Expand Down
62 changes: 46 additions & 16 deletions src/gui/dialogs/formmain.cpp
Expand Up @@ -65,25 +65,31 @@ FormMain::FormMain(QWidget* parent, Qt::WindowFlags f)
: QMainWindow(parent, f), m_ui(new Ui::FormMain) {
m_ui->setupUi(this);
qApp->setMainForm(this);

#if defined (USE_WEBENGINE)
m_ui->m_menuWebBrowserTabs->addAction(AdBlockManager::instance()->adBlockIcon());
m_ui->m_menuWebBrowserTabs->addAction(qApp->web()->engineSettingsAction());
#endif

// Add these actions to the list of actions of the main window.
// This allows to use actions via shortcuts
// even if main menu is not visible.
addActions(qApp->userActions());
setStatusBar(m_statusBar = new StatusBar(this));

// Prepare main window and tabs.
prepareMenus();

// Prepare tabs.
tabWidget()->feedMessageViewer()->feedsToolBar()->loadSavedActions();
tabWidget()->feedMessageViewer()->messagesToolBar()->loadSavedActions();
// Establish connections.

// Establish connections.
createConnections();
updateMessageButtonsAvailability();
updateFeedButtonsAvailability();
// Setup some appearance of the window.

// Setup some appearance of the window.
setupIcons();
loadSize();
m_statusBar->loadSavedActions();
Expand All @@ -107,9 +113,11 @@ StatusBar* FormMain::statusBar() const {

void FormMain::showDbCleanupAssistant() {
if (qApp->feedUpdateLock()->tryLock()) {
QScopedPointer<FormDatabaseCleanup> form_pointer(new FormDatabaseCleanup(this));
form_pointer.data()->setCleaner(qApp->feedReader()->databaseCleaner());
form_pointer.data()->exec();
FormDatabaseCleanup form(new FormDatabaseCleanup(this));
form.setCleaner(qApp->feedReader()->databaseCleaner());
form.exec();

// Reload needed stuff.
qApp->feedUpdateLock()->unlock();
tabWidget()->feedMessageViewer()->messagesView()->reloadSelections();
qApp->feedReader()->feedsModel()->reloadCountsOfWholeModel();
Expand All @@ -130,21 +138,26 @@ QList<QAction*> FormMain::allActions() const {
actions << m_ui->m_actionBackupDatabaseSettings;
actions << m_ui->m_actionRestart;
actions << m_ui->m_actionQuit;

#if !defined(Q_OS_MAC)
actions << m_ui->m_actionFullscreen;
#endif

actions << m_ui->m_actionAboutGuard;
actions << m_ui->m_actionSwitchFeedsList;
actions << m_ui->m_actionSwitchMainWindow;

#if !defined(Q_OS_MAC)
actions << m_ui->m_actionSwitchMainMenu;
#endif

actions << m_ui->m_actionSwitchToolBars;
actions << m_ui->m_actionSwitchListHeaders;
actions << m_ui->m_actionSwitchStatusBar;
actions << m_ui->m_actionSwitchMessageListOrientation;
// Add feeds/messages actions.
actions << m_ui->m_actionOpenSelectedSourceArticlesExternally;
actions << m_ui->m_actionTabsNext;
actions << m_ui->m_actionTabsPrevious;
actions << m_ui->m_actionOpenSelectedSourceArticlesExternally;
actions << m_ui->m_actionOpenSelectedMessagesInternally;
actions << m_ui->m_actionMarkAllItemsRead;
actions << m_ui->m_actionMarkSelectedItemsAsRead;
Expand Down Expand Up @@ -174,9 +187,11 @@ QList<QAction*> FormMain::allActions() const {
actions << m_ui->m_actionSelectPreviousMessage;
actions << m_ui->m_actionSelectNextUnreadMessage;
actions << m_ui->m_actionExpandCollapseItem;

#if defined(USE_WEBENGINE)
actions << m_ui->m_actionTabNewWebBrowser;
#endif

actions << m_ui->m_actionTabsCloseAll;
actions << m_ui->m_actionTabsCloseAllExceptCurrent;
return actions;
Expand Down Expand Up @@ -434,6 +449,7 @@ void FormMain::display() {

void FormMain::setupIcons() {
IconFactory* icon_theme_factory = qApp->icons();

// Setup icons of this main window.
m_ui->m_actionDownloadManager->setIcon(icon_theme_factory->fromTheme(QSL("emblem-downloads")));
m_ui->m_actionSettings->setIcon(icon_theme_factory->fromTheme(QSL("document-properties")));
Expand All @@ -447,6 +463,7 @@ void FormMain::setupIcons() {
m_ui->m_actionRestoreDatabaseSettings->setIcon(icon_theme_factory->fromTheme(QSL("document-import")));
m_ui->m_actionDonate->setIcon(icon_theme_factory->fromTheme(QSL("applications-office")));
m_ui->m_actionDisplayWiki->setIcon(icon_theme_factory->fromTheme(QSL("applications-science")));

// View.
m_ui->m_actionSwitchMainWindow->setIcon(icon_theme_factory->fromTheme(QSL("window-close")));
m_ui->m_actionFullscreen->setIcon(icon_theme_factory->fromTheme(QSL("view-fullscreen")));
Expand All @@ -457,6 +474,7 @@ void FormMain::setupIcons() {
m_ui->m_actionSwitchStatusBar->setIcon(icon_theme_factory->fromTheme(QSL("dialog-information")));
m_ui->m_actionSwitchMessageListOrientation->setIcon(icon_theme_factory->fromTheme(QSL("view-restore")));
m_ui->m_menuShowHide->setIcon(icon_theme_factory->fromTheme(QSL("view-restore")));

// Feeds/messages.
m_ui->m_menuAddItem->setIcon(icon_theme_factory->fromTheme(QSL("list-add")));
m_ui->m_actionStopRunningItemsUpdate->setIcon(icon_theme_factory->fromTheme(QSL("process-stop")));
Expand Down Expand Up @@ -492,11 +510,15 @@ void FormMain::setupIcons() {
m_ui->m_actionServiceDelete->setIcon(icon_theme_factory->fromTheme(QSL("list-remove")));
m_ui->m_actionAddFeedIntoSelectedAccount->setIcon(icon_theme_factory->fromTheme(QSL("application-rss+xml")));
m_ui->m_actionAddCategoryIntoSelectedAccount->setIcon(icon_theme_factory->fromTheme(QSL("folder")));

// Tabs & web browser.
m_ui->m_actionTabNewWebBrowser->setIcon(icon_theme_factory->fromTheme(QSL("tab-new")));
m_ui->m_actionTabsCloseAll->setIcon(icon_theme_factory->fromTheme(QSL("window-close")));
m_ui->m_actionTabsCloseAllExceptCurrent->setIcon(icon_theme_factory->fromTheme(QSL("window-close")));
// Setup icons on TabWidget too.
m_ui->m_actionTabsNext->setIcon(icon_theme_factory->fromTheme(QSL("go-next")));
m_ui->m_actionTabsPrevious->setIcon(icon_theme_factory->fromTheme(QSL("go-previous")));

// Setup icons on TabWidget too.
m_ui->m_tabWidget->setupIcons();
}

Expand Down Expand Up @@ -566,24 +588,28 @@ void FormMain::createConnections() {
connect(m_ui->m_menuAccounts, &QMenu::aboutToShow, this, &FormMain::updateAccountsMenu);
connect(m_ui->m_actionServiceDelete, &QAction::triggered, m_ui->m_actionDeleteSelectedItem, &QAction::triggered);
connect(m_ui->m_actionServiceEdit, &QAction::triggered, m_ui->m_actionEditSelectedItem, &QAction::triggered);
// Menu "File" connections.

// Menu "File" connections.
connect(m_ui->m_actionBackupDatabaseSettings, &QAction::triggered, this, &FormMain::backupDatabaseSettings);
connect(m_ui->m_actionRestoreDatabaseSettings, &QAction::triggered, this, &FormMain::restoreDatabaseSettings);
connect(m_ui->m_actionQuit, &QAction::triggered, qApp, &Application::quit);
connect(m_ui->m_actionServiceAdd, &QAction::triggered, this, &FormMain::showAddAccountDialog);
connect(m_ui->m_actionRestart, &QAction::triggered, qApp, &Application::restart);
// Menu "View" connections.

// Menu "View" connections.
connect(m_ui->m_actionFullscreen, &QAction::toggled, this, &FormMain::switchFullscreenMode);
connect(m_ui->m_actionSwitchMainMenu, &QAction::toggled, m_ui->m_menuBar, &QMenuBar::setVisible);
connect(m_ui->m_actionSwitchMainWindow, &QAction::triggered, this, &FormMain::switchVisibility);
connect(m_ui->m_actionSwitchStatusBar, &QAction::toggled, statusBar(), &StatusBar::setVisible);
// Menu "Tools" connections.

// Menu "Tools" connections.
connect(m_ui->m_actionSettings, &QAction::triggered, [this]() {
FormSettings(*this).exec();
});
connect(m_ui->m_actionDownloadManager, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::showDownloadManager);
connect(m_ui->m_actionCleanupDatabase, &QAction::triggered, this, &FormMain::showDbCleanupAssistant);
// Menu "Help" connections.

// Menu "Help" connections.
connect(m_ui->m_actionAboutGuard, &QAction::triggered, [this]() {
FormAbout(this).exec();
});
Expand All @@ -593,7 +619,10 @@ void FormMain::createConnections() {
connect(m_ui->m_actionReportBug, &QAction::triggered, this, &FormMain::reportABug);
connect(m_ui->m_actionDonate, &QAction::triggered, this, &FormMain::donate);
connect(m_ui->m_actionDisplayWiki, &QAction::triggered, this, &FormMain::showWiki);
// Tab widget connections.

// Tab widget connections.
connect(m_ui->m_actionTabsNext, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::gotoNextTab);
connect(m_ui->m_actionTabsPrevious, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::gotoPreviousTab);
connect(m_ui->m_actionTabsCloseAllExceptCurrent, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::closeAllTabsExceptCurrent);
connect(m_ui->m_actionTabsCloseAll, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::closeAllTabs);
connect(m_ui->m_actionTabNewWebBrowser, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::addEmptyBrowser);
Expand All @@ -607,7 +636,8 @@ void FormMain::createConnections() {
connect(qApp->feedReader(), &FeedReader::feedUpdatesStarted, this, &FormMain::onFeedUpdatesStarted);
connect(qApp->feedReader(), &FeedReader::feedUpdatesProgress, this, &FormMain::onFeedUpdatesProgress);
connect(qApp->feedReader(), &FeedReader::feedUpdatesFinished, this, &FormMain::onFeedUpdatesFinished);
// Toolbar forwardings.

// Toolbar forwardings.
connect(m_ui->m_actionAddFeedIntoSelectedAccount, &QAction::triggered,
tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::addFeedIntoSelectedAccount);
connect(m_ui->m_actionAddCategoryIntoSelectedAccount, &QAction::triggered,
Expand Down Expand Up @@ -653,7 +683,7 @@ void FormMain::createConnections() {
connect(m_ui->m_actionSwitchFeedsList, &QAction::triggered,
tabWidget()->feedMessageViewer(), &FeedMessageViewer::switchFeedComponentVisibility);
connect(m_ui->m_actionSelectNextItem,
&QAction::triggered, tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::selectNextItem);
&QAction::triggered, tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::selectNextItem);
connect(m_ui->m_actionSwitchToolBars, &QAction::toggled,
tabWidget()->feedMessageViewer(), &FeedMessageViewer::setToolBarsEnabled);
connect(m_ui->m_actionSwitchListHeaders, &QAction::toggled,
Expand All @@ -663,7 +693,7 @@ void FormMain::createConnections() {
connect(m_ui->m_actionSelectNextMessage,
&QAction::triggered, tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::selectNextItem);
connect(m_ui->m_actionSelectNextUnreadMessage,
&QAction::triggered, tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::selectNextUnreadItem);
&QAction::triggered, tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::selectNextUnreadItem);
connect(m_ui->m_actionSelectPreviousMessage,
&QAction::triggered, tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::selectPreviousItem);
connect(m_ui->m_actionSwitchMessageListOrientation, &QAction::triggered,
Expand Down
14 changes: 14 additions & 0 deletions src/gui/dialogs/formmain.ui
Expand Up @@ -165,8 +165,12 @@
<string>Web browser &amp;&amp; tabs</string>
</property>
<addaction name="m_actionTabNewWebBrowser"/>
<addaction name="separator"/>
<addaction name="m_actionTabsCloseAll"/>
<addaction name="m_actionTabsCloseAllExceptCurrent"/>
<addaction name="separator"/>
<addaction name="m_actionTabsNext"/>
<addaction name="m_actionTabsPrevious"/>
</widget>
<addaction name="m_menuFile"/>
<addaction name="m_menuView"/>
Expand Down Expand Up @@ -721,6 +725,16 @@
<string>Close all tabs except current</string>
</property>
</action>
<action name="m_actionTabsNext">
<property name="text">
<string>Go to &amp;next tab</string>
</property>
</action>
<action name="m_actionTabsPrevious">
<property name="text">
<string>Go to &amp;previous tab</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
Expand Down
2 changes: 2 additions & 0 deletions src/gui/feedmessageviewer.cpp
Expand Up @@ -206,6 +206,8 @@ void FeedMessageViewer::createConnections() {
#endif
// If user selects feeds, load their messages.
connect(m_feedsView, &FeedsView::itemSelected, m_messagesView, &MessagesView::loadItem);
connect(m_feedsView, &FeedsView::requestViewNextUnreadMessage, m_messagesView, &MessagesView::selectNextUnreadItem);

// State of many messages is changed, then we need
// to reload selections.
connect(m_feedsView->sourceModel(), &FeedsModel::reloadMessageListRequested,
Expand Down
81 changes: 73 additions & 8 deletions src/gui/feedsview.cpp
Expand Up @@ -49,16 +49,19 @@ FeedsView::FeedsView(QWidget* parent)
m_contextMenuEmptySpace(nullptr),
m_contextMenuOtherItems(nullptr) {
setObjectName(QSL("FeedsView"));

// Allocate models.
m_sourceModel = qApp->feedReader()->feedsModel();
m_proxyModel = qApp->feedReader()->feedsProxyModel();
// Connections.

// Connections.
connect(m_sourceModel, &FeedsModel::requireItemValidationAfterDragDrop, this, &FeedsView::validateItemAfterDragDrop);
connect(m_sourceModel, &FeedsModel::itemExpandRequested, this, &FeedsView::onItemExpandRequested);
connect(m_sourceModel, &FeedsModel::itemExpandStateSaveRequested, this, &FeedsView::onItemExpandStateSaveRequested);
connect(header(), &QHeaderView::sortIndicatorChanged, this, &FeedsView::saveSortState);
connect(m_proxyModel, &FeedsProxyModel::expandAfterFilterIn, this, &FeedsView::expandItemDelayed);
setModel(m_proxyModel);

setModel(m_proxyModel);
setupAppearance();
}

Expand Down Expand Up @@ -346,16 +349,78 @@ void FeedsView::selectPreviousItem() {
if (index_previous.isValid()) {
setCurrentIndex(index_previous);
setFocus();
}
}
}

void FeedsView::selectNextUnreadItem() {
QModelIndex next_unread_row;

if (currentIndex().isValid()) {
next_unread_row = nextPreviousUnreadItem(currentIndex());
}
else {
next_unread_row = nextPreviousUnreadItem(m_proxyModel->index(0, MSG_DB_READ_INDEX));
}

if (next_unread_row.isValid()) {
setCurrentIndex(next_unread_row);
emit requestViewNextUnreadMessage();
}
}

QModelIndex FeedsView::nextPreviousUnreadItem(QModelIndex default_row) {
const bool started_from_zero = default_row.row() == 0 && !default_row.parent().isValid();
QModelIndex next_index = nextUnreadItem(default_row);

// There is no next message, check previous.
if (!next_index.isValid() && !started_from_zero) {
next_index = nextUnreadItem(m_proxyModel->index(0, 0));
}

return next_index;
}

QModelIndex FeedsView::nextUnreadItem(QModelIndex default_row) {
default_row = m_proxyModel->index(default_row.row(), 0, default_row.parent());
const QModelIndex starting_row = default_row;

while (true) {
bool has_unread = m_sourceModel->itemForIndex(m_proxyModel->mapToSource(default_row))->countOfUnreadMessages() > 0;

if (has_unread) {
if (m_proxyModel->hasChildren(default_row)) {
// Current index has unread items, but is expandable, go to first child.
expand(default_row);
default_row = indexBelow(default_row);
continue;
}
else {
// We found unread feed, return it.
return default_row;
}
}
else {
QModelIndex next_row = indexBelow(default_row);

if (next_row == default_row || !next_row.isValid() || starting_row == next_row) {
// We came to last row probably.
break;
}
else {
default_row = next_row;
}
}
}

return QModelIndex();
}

void FeedsView::switchVisibility() {
setVisible(!isVisible());
}

void FeedsView::expandItemDelayed(const QModelIndex& idx) {
QTimer::singleShot(100, this, [ = ] {
// TODO: Z nastavení.
QTimer::singleShot(100, this, [ = ] {
setExpanded(m_proxyModel->mapFromSource(idx), true);
});
}
Expand Down Expand Up @@ -445,6 +510,9 @@ void FeedsView::setupAppearance() {
// Setup column resize strategies.
header()->setSectionResizeMode(FDS_MODEL_TITLE_INDEX, QHeaderView::Stretch);
header()->setSectionResizeMode(FDS_MODEL_COUNTS_INDEX, QHeaderView::ResizeToContents);
header()->setStretchLastSection(false);
header()->setSortIndicatorShown(false);

setUniformRowHeights(true);
setAnimated(true);
setSortingEnabled(true);
Expand All @@ -460,8 +528,6 @@ void FeedsView::setupAppearance() {
setRootIsDecorated(false);
setSelectionMode(QAbstractItemView::SingleSelection);
setItemDelegate(new StyledItemDelegateWithoutFocus(this));
header()->setStretchLastSection(false);
header()->setSortIndicatorShown(false);
}

void FeedsView::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) {
Expand Down Expand Up @@ -541,7 +607,6 @@ void FeedsView::onItemExpandRequested(const QList<RootItem*>& items, bool exp) {
foreach (const RootItem* item, items) {
QModelIndex source_index = m_sourceModel->indexForItem(item);
QModelIndex proxy_index = m_proxyModel->mapFromSource(source_index);
//setExpanded(proxy_index, !exp);
setExpanded(proxy_index, exp);
}
}

0 comments on commit 0a8aea5

Please sign in to comment.