Fixed #132, fixed #6.

This commit is contained in:
Martin Rotter 2017-09-10 10:40:33 +02:00
parent dbdddb8729
commit 0a8aea5558
9 changed files with 165 additions and 34 deletions

View file

@ -3,6 +3,8 @@
Added: Added:
▪ Standard account is now automatically added if RSS Guard is started with empty database. ▪ 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:
▪ Fixed build on some Unit-like operating systems. ▪ Fixed build on some Unit-like operating systems.

View file

@ -65,25 +65,31 @@ FormMain::FormMain(QWidget* parent, Qt::WindowFlags f)
: QMainWindow(parent, f), m_ui(new Ui::FormMain) { : QMainWindow(parent, f), m_ui(new Ui::FormMain) {
m_ui->setupUi(this); m_ui->setupUi(this);
qApp->setMainForm(this); qApp->setMainForm(this);
#if defined (USE_WEBENGINE) #if defined (USE_WEBENGINE)
m_ui->m_menuWebBrowserTabs->addAction(AdBlockManager::instance()->adBlockIcon()); m_ui->m_menuWebBrowserTabs->addAction(AdBlockManager::instance()->adBlockIcon());
m_ui->m_menuWebBrowserTabs->addAction(qApp->web()->engineSettingsAction()); m_ui->m_menuWebBrowserTabs->addAction(qApp->web()->engineSettingsAction());
#endif #endif
// Add these actions to the list of actions of the main window. // Add these actions to the list of actions of the main window.
// This allows to use actions via shortcuts // This allows to use actions via shortcuts
// even if main menu is not visible. // even if main menu is not visible.
addActions(qApp->userActions()); addActions(qApp->userActions());
setStatusBar(m_statusBar = new StatusBar(this)); setStatusBar(m_statusBar = new StatusBar(this));
// Prepare main window and tabs. // Prepare main window and tabs.
prepareMenus(); prepareMenus();
// Prepare tabs. // Prepare tabs.
tabWidget()->feedMessageViewer()->feedsToolBar()->loadSavedActions(); tabWidget()->feedMessageViewer()->feedsToolBar()->loadSavedActions();
tabWidget()->feedMessageViewer()->messagesToolBar()->loadSavedActions(); tabWidget()->feedMessageViewer()->messagesToolBar()->loadSavedActions();
// Establish connections.
// Establish connections.
createConnections(); createConnections();
updateMessageButtonsAvailability(); updateMessageButtonsAvailability();
updateFeedButtonsAvailability(); updateFeedButtonsAvailability();
// Setup some appearance of the window.
// Setup some appearance of the window.
setupIcons(); setupIcons();
loadSize(); loadSize();
m_statusBar->loadSavedActions(); m_statusBar->loadSavedActions();
@ -107,9 +113,11 @@ StatusBar* FormMain::statusBar() const {
void FormMain::showDbCleanupAssistant() { void FormMain::showDbCleanupAssistant() {
if (qApp->feedUpdateLock()->tryLock()) { if (qApp->feedUpdateLock()->tryLock()) {
QScopedPointer<FormDatabaseCleanup> form_pointer(new FormDatabaseCleanup(this)); FormDatabaseCleanup form(new FormDatabaseCleanup(this));
form_pointer.data()->setCleaner(qApp->feedReader()->databaseCleaner()); form.setCleaner(qApp->feedReader()->databaseCleaner());
form_pointer.data()->exec(); form.exec();
// Reload needed stuff.
qApp->feedUpdateLock()->unlock(); qApp->feedUpdateLock()->unlock();
tabWidget()->feedMessageViewer()->messagesView()->reloadSelections(); tabWidget()->feedMessageViewer()->messagesView()->reloadSelections();
qApp->feedReader()->feedsModel()->reloadCountsOfWholeModel(); qApp->feedReader()->feedsModel()->reloadCountsOfWholeModel();
@ -130,21 +138,26 @@ QList<QAction*> FormMain::allActions() const {
actions << m_ui->m_actionBackupDatabaseSettings; actions << m_ui->m_actionBackupDatabaseSettings;
actions << m_ui->m_actionRestart; actions << m_ui->m_actionRestart;
actions << m_ui->m_actionQuit; actions << m_ui->m_actionQuit;
#if !defined(Q_OS_MAC) #if !defined(Q_OS_MAC)
actions << m_ui->m_actionFullscreen; actions << m_ui->m_actionFullscreen;
#endif #endif
actions << m_ui->m_actionAboutGuard; actions << m_ui->m_actionAboutGuard;
actions << m_ui->m_actionSwitchFeedsList; actions << m_ui->m_actionSwitchFeedsList;
actions << m_ui->m_actionSwitchMainWindow; actions << m_ui->m_actionSwitchMainWindow;
#if !defined(Q_OS_MAC) #if !defined(Q_OS_MAC)
actions << m_ui->m_actionSwitchMainMenu; actions << m_ui->m_actionSwitchMainMenu;
#endif #endif
actions << m_ui->m_actionSwitchToolBars; actions << m_ui->m_actionSwitchToolBars;
actions << m_ui->m_actionSwitchListHeaders; actions << m_ui->m_actionSwitchListHeaders;
actions << m_ui->m_actionSwitchStatusBar; actions << m_ui->m_actionSwitchStatusBar;
actions << m_ui->m_actionSwitchMessageListOrientation; actions << m_ui->m_actionSwitchMessageListOrientation;
// Add feeds/messages actions. actions << m_ui->m_actionTabsNext;
actions << m_ui->m_actionOpenSelectedSourceArticlesExternally; actions << m_ui->m_actionTabsPrevious;
actions << m_ui->m_actionOpenSelectedSourceArticlesExternally;
actions << m_ui->m_actionOpenSelectedMessagesInternally; actions << m_ui->m_actionOpenSelectedMessagesInternally;
actions << m_ui->m_actionMarkAllItemsRead; actions << m_ui->m_actionMarkAllItemsRead;
actions << m_ui->m_actionMarkSelectedItemsAsRead; actions << m_ui->m_actionMarkSelectedItemsAsRead;
@ -174,9 +187,11 @@ QList<QAction*> FormMain::allActions() const {
actions << m_ui->m_actionSelectPreviousMessage; actions << m_ui->m_actionSelectPreviousMessage;
actions << m_ui->m_actionSelectNextUnreadMessage; actions << m_ui->m_actionSelectNextUnreadMessage;
actions << m_ui->m_actionExpandCollapseItem; actions << m_ui->m_actionExpandCollapseItem;
#if defined(USE_WEBENGINE) #if defined(USE_WEBENGINE)
actions << m_ui->m_actionTabNewWebBrowser; actions << m_ui->m_actionTabNewWebBrowser;
#endif #endif
actions << m_ui->m_actionTabsCloseAll; actions << m_ui->m_actionTabsCloseAll;
actions << m_ui->m_actionTabsCloseAllExceptCurrent; actions << m_ui->m_actionTabsCloseAllExceptCurrent;
return actions; return actions;
@ -434,6 +449,7 @@ void FormMain::display() {
void FormMain::setupIcons() { void FormMain::setupIcons() {
IconFactory* icon_theme_factory = qApp->icons(); IconFactory* icon_theme_factory = qApp->icons();
// Setup icons of this main window. // Setup icons of this main window.
m_ui->m_actionDownloadManager->setIcon(icon_theme_factory->fromTheme(QSL("emblem-downloads"))); m_ui->m_actionDownloadManager->setIcon(icon_theme_factory->fromTheme(QSL("emblem-downloads")));
m_ui->m_actionSettings->setIcon(icon_theme_factory->fromTheme(QSL("document-properties"))); m_ui->m_actionSettings->setIcon(icon_theme_factory->fromTheme(QSL("document-properties")));
@ -447,6 +463,7 @@ void FormMain::setupIcons() {
m_ui->m_actionRestoreDatabaseSettings->setIcon(icon_theme_factory->fromTheme(QSL("document-import"))); 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_actionDonate->setIcon(icon_theme_factory->fromTheme(QSL("applications-office")));
m_ui->m_actionDisplayWiki->setIcon(icon_theme_factory->fromTheme(QSL("applications-science"))); m_ui->m_actionDisplayWiki->setIcon(icon_theme_factory->fromTheme(QSL("applications-science")));
// View. // View.
m_ui->m_actionSwitchMainWindow->setIcon(icon_theme_factory->fromTheme(QSL("window-close"))); m_ui->m_actionSwitchMainWindow->setIcon(icon_theme_factory->fromTheme(QSL("window-close")));
m_ui->m_actionFullscreen->setIcon(icon_theme_factory->fromTheme(QSL("view-fullscreen"))); m_ui->m_actionFullscreen->setIcon(icon_theme_factory->fromTheme(QSL("view-fullscreen")));
@ -457,6 +474,7 @@ void FormMain::setupIcons() {
m_ui->m_actionSwitchStatusBar->setIcon(icon_theme_factory->fromTheme(QSL("dialog-information"))); 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_actionSwitchMessageListOrientation->setIcon(icon_theme_factory->fromTheme(QSL("view-restore")));
m_ui->m_menuShowHide->setIcon(icon_theme_factory->fromTheme(QSL("view-restore"))); m_ui->m_menuShowHide->setIcon(icon_theme_factory->fromTheme(QSL("view-restore")));
// Feeds/messages. // Feeds/messages.
m_ui->m_menuAddItem->setIcon(icon_theme_factory->fromTheme(QSL("list-add"))); m_ui->m_menuAddItem->setIcon(icon_theme_factory->fromTheme(QSL("list-add")));
m_ui->m_actionStopRunningItemsUpdate->setIcon(icon_theme_factory->fromTheme(QSL("process-stop"))); m_ui->m_actionStopRunningItemsUpdate->setIcon(icon_theme_factory->fromTheme(QSL("process-stop")));
@ -492,11 +510,15 @@ void FormMain::setupIcons() {
m_ui->m_actionServiceDelete->setIcon(icon_theme_factory->fromTheme(QSL("list-remove"))); 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_actionAddFeedIntoSelectedAccount->setIcon(icon_theme_factory->fromTheme(QSL("application-rss+xml")));
m_ui->m_actionAddCategoryIntoSelectedAccount->setIcon(icon_theme_factory->fromTheme(QSL("folder"))); m_ui->m_actionAddCategoryIntoSelectedAccount->setIcon(icon_theme_factory->fromTheme(QSL("folder")));
// Tabs & web browser. // Tabs & web browser.
m_ui->m_actionTabNewWebBrowser->setIcon(icon_theme_factory->fromTheme(QSL("tab-new"))); 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_actionTabsCloseAll->setIcon(icon_theme_factory->fromTheme(QSL("window-close")));
m_ui->m_actionTabsCloseAllExceptCurrent->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(); m_ui->m_tabWidget->setupIcons();
} }
@ -566,24 +588,28 @@ void FormMain::createConnections() {
connect(m_ui->m_menuAccounts, &QMenu::aboutToShow, this, &FormMain::updateAccountsMenu); 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_actionServiceDelete, &QAction::triggered, m_ui->m_actionDeleteSelectedItem, &QAction::triggered);
connect(m_ui->m_actionServiceEdit, &QAction::triggered, m_ui->m_actionEditSelectedItem, &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_actionBackupDatabaseSettings, &QAction::triggered, this, &FormMain::backupDatabaseSettings);
connect(m_ui->m_actionRestoreDatabaseSettings, &QAction::triggered, this, &FormMain::restoreDatabaseSettings); connect(m_ui->m_actionRestoreDatabaseSettings, &QAction::triggered, this, &FormMain::restoreDatabaseSettings);
connect(m_ui->m_actionQuit, &QAction::triggered, qApp, &Application::quit); connect(m_ui->m_actionQuit, &QAction::triggered, qApp, &Application::quit);
connect(m_ui->m_actionServiceAdd, &QAction::triggered, this, &FormMain::showAddAccountDialog); connect(m_ui->m_actionServiceAdd, &QAction::triggered, this, &FormMain::showAddAccountDialog);
connect(m_ui->m_actionRestart, &QAction::triggered, qApp, &Application::restart); 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_actionFullscreen, &QAction::toggled, this, &FormMain::switchFullscreenMode);
connect(m_ui->m_actionSwitchMainMenu, &QAction::toggled, m_ui->m_menuBar, &QMenuBar::setVisible); 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_actionSwitchMainWindow, &QAction::triggered, this, &FormMain::switchVisibility);
connect(m_ui->m_actionSwitchStatusBar, &QAction::toggled, statusBar(), &StatusBar::setVisible); connect(m_ui->m_actionSwitchStatusBar, &QAction::toggled, statusBar(), &StatusBar::setVisible);
// Menu "Tools" connections.
// Menu "Tools" connections.
connect(m_ui->m_actionSettings, &QAction::triggered, [this]() { connect(m_ui->m_actionSettings, &QAction::triggered, [this]() {
FormSettings(*this).exec(); FormSettings(*this).exec();
}); });
connect(m_ui->m_actionDownloadManager, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::showDownloadManager); connect(m_ui->m_actionDownloadManager, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::showDownloadManager);
connect(m_ui->m_actionCleanupDatabase, &QAction::triggered, this, &FormMain::showDbCleanupAssistant); connect(m_ui->m_actionCleanupDatabase, &QAction::triggered, this, &FormMain::showDbCleanupAssistant);
// Menu "Help" connections.
// Menu "Help" connections.
connect(m_ui->m_actionAboutGuard, &QAction::triggered, [this]() { connect(m_ui->m_actionAboutGuard, &QAction::triggered, [this]() {
FormAbout(this).exec(); FormAbout(this).exec();
}); });
@ -593,7 +619,10 @@ void FormMain::createConnections() {
connect(m_ui->m_actionReportBug, &QAction::triggered, this, &FormMain::reportABug); connect(m_ui->m_actionReportBug, &QAction::triggered, this, &FormMain::reportABug);
connect(m_ui->m_actionDonate, &QAction::triggered, this, &FormMain::donate); connect(m_ui->m_actionDonate, &QAction::triggered, this, &FormMain::donate);
connect(m_ui->m_actionDisplayWiki, &QAction::triggered, this, &FormMain::showWiki); 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_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_actionTabsCloseAll, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::closeAllTabs);
connect(m_ui->m_actionTabNewWebBrowser, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::addEmptyBrowser); connect(m_ui->m_actionTabNewWebBrowser, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::addEmptyBrowser);
@ -607,7 +636,8 @@ void FormMain::createConnections() {
connect(qApp->feedReader(), &FeedReader::feedUpdatesStarted, this, &FormMain::onFeedUpdatesStarted); connect(qApp->feedReader(), &FeedReader::feedUpdatesStarted, this, &FormMain::onFeedUpdatesStarted);
connect(qApp->feedReader(), &FeedReader::feedUpdatesProgress, this, &FormMain::onFeedUpdatesProgress); connect(qApp->feedReader(), &FeedReader::feedUpdatesProgress, this, &FormMain::onFeedUpdatesProgress);
connect(qApp->feedReader(), &FeedReader::feedUpdatesFinished, this, &FormMain::onFeedUpdatesFinished); connect(qApp->feedReader(), &FeedReader::feedUpdatesFinished, this, &FormMain::onFeedUpdatesFinished);
// Toolbar forwardings.
// Toolbar forwardings.
connect(m_ui->m_actionAddFeedIntoSelectedAccount, &QAction::triggered, connect(m_ui->m_actionAddFeedIntoSelectedAccount, &QAction::triggered,
tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::addFeedIntoSelectedAccount); tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::addFeedIntoSelectedAccount);
connect(m_ui->m_actionAddCategoryIntoSelectedAccount, &QAction::triggered, connect(m_ui->m_actionAddCategoryIntoSelectedAccount, &QAction::triggered,
@ -653,7 +683,7 @@ void FormMain::createConnections() {
connect(m_ui->m_actionSwitchFeedsList, &QAction::triggered, connect(m_ui->m_actionSwitchFeedsList, &QAction::triggered,
tabWidget()->feedMessageViewer(), &FeedMessageViewer::switchFeedComponentVisibility); tabWidget()->feedMessageViewer(), &FeedMessageViewer::switchFeedComponentVisibility);
connect(m_ui->m_actionSelectNextItem, 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, connect(m_ui->m_actionSwitchToolBars, &QAction::toggled,
tabWidget()->feedMessageViewer(), &FeedMessageViewer::setToolBarsEnabled); tabWidget()->feedMessageViewer(), &FeedMessageViewer::setToolBarsEnabled);
connect(m_ui->m_actionSwitchListHeaders, &QAction::toggled, connect(m_ui->m_actionSwitchListHeaders, &QAction::toggled,
@ -663,7 +693,7 @@ void FormMain::createConnections() {
connect(m_ui->m_actionSelectNextMessage, connect(m_ui->m_actionSelectNextMessage,
&QAction::triggered, tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::selectNextItem); &QAction::triggered, tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::selectNextItem);
connect(m_ui->m_actionSelectNextUnreadMessage, connect(m_ui->m_actionSelectNextUnreadMessage,
&QAction::triggered, tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::selectNextUnreadItem); &QAction::triggered, tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::selectNextUnreadItem);
connect(m_ui->m_actionSelectPreviousMessage, connect(m_ui->m_actionSelectPreviousMessage,
&QAction::triggered, tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::selectPreviousItem); &QAction::triggered, tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::selectPreviousItem);
connect(m_ui->m_actionSwitchMessageListOrientation, &QAction::triggered, connect(m_ui->m_actionSwitchMessageListOrientation, &QAction::triggered,

View file

@ -165,8 +165,12 @@
<string>Web browser &amp;&amp; tabs</string> <string>Web browser &amp;&amp; tabs</string>
</property> </property>
<addaction name="m_actionTabNewWebBrowser"/> <addaction name="m_actionTabNewWebBrowser"/>
<addaction name="separator"/>
<addaction name="m_actionTabsCloseAll"/> <addaction name="m_actionTabsCloseAll"/>
<addaction name="m_actionTabsCloseAllExceptCurrent"/> <addaction name="m_actionTabsCloseAllExceptCurrent"/>
<addaction name="separator"/>
<addaction name="m_actionTabsNext"/>
<addaction name="m_actionTabsPrevious"/>
</widget> </widget>
<addaction name="m_menuFile"/> <addaction name="m_menuFile"/>
<addaction name="m_menuView"/> <addaction name="m_menuView"/>
@ -721,6 +725,16 @@
<string>Close all tabs except current</string> <string>Close all tabs except current</string>
</property> </property>
</action> </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> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View file

@ -206,6 +206,8 @@ void FeedMessageViewer::createConnections() {
#endif #endif
// If user selects feeds, load their messages. // If user selects feeds, load their messages.
connect(m_feedsView, &FeedsView::itemSelected, m_messagesView, &MessagesView::loadItem); 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 // State of many messages is changed, then we need
// to reload selections. // to reload selections.
connect(m_feedsView->sourceModel(), &FeedsModel::reloadMessageListRequested, connect(m_feedsView->sourceModel(), &FeedsModel::reloadMessageListRequested,

View file

@ -49,16 +49,19 @@ FeedsView::FeedsView(QWidget* parent)
m_contextMenuEmptySpace(nullptr), m_contextMenuEmptySpace(nullptr),
m_contextMenuOtherItems(nullptr) { m_contextMenuOtherItems(nullptr) {
setObjectName(QSL("FeedsView")); setObjectName(QSL("FeedsView"));
// Allocate models. // Allocate models.
m_sourceModel = qApp->feedReader()->feedsModel(); m_sourceModel = qApp->feedReader()->feedsModel();
m_proxyModel = qApp->feedReader()->feedsProxyModel(); m_proxyModel = qApp->feedReader()->feedsProxyModel();
// Connections.
// Connections.
connect(m_sourceModel, &FeedsModel::requireItemValidationAfterDragDrop, this, &FeedsView::validateItemAfterDragDrop); connect(m_sourceModel, &FeedsModel::requireItemValidationAfterDragDrop, this, &FeedsView::validateItemAfterDragDrop);
connect(m_sourceModel, &FeedsModel::itemExpandRequested, this, &FeedsView::onItemExpandRequested); connect(m_sourceModel, &FeedsModel::itemExpandRequested, this, &FeedsView::onItemExpandRequested);
connect(m_sourceModel, &FeedsModel::itemExpandStateSaveRequested, this, &FeedsView::onItemExpandStateSaveRequested); connect(m_sourceModel, &FeedsModel::itemExpandStateSaveRequested, this, &FeedsView::onItemExpandStateSaveRequested);
connect(header(), &QHeaderView::sortIndicatorChanged, this, &FeedsView::saveSortState); connect(header(), &QHeaderView::sortIndicatorChanged, this, &FeedsView::saveSortState);
connect(m_proxyModel, &FeedsProxyModel::expandAfterFilterIn, this, &FeedsView::expandItemDelayed); connect(m_proxyModel, &FeedsProxyModel::expandAfterFilterIn, this, &FeedsView::expandItemDelayed);
setModel(m_proxyModel);
setModel(m_proxyModel);
setupAppearance(); setupAppearance();
} }
@ -346,7 +349,70 @@ void FeedsView::selectPreviousItem() {
if (index_previous.isValid()) { if (index_previous.isValid()) {
setCurrentIndex(index_previous); setCurrentIndex(index_previous);
setFocus(); 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() { void FeedsView::switchVisibility() {
@ -354,8 +420,7 @@ void FeedsView::switchVisibility() {
} }
void FeedsView::expandItemDelayed(const QModelIndex& idx) { void FeedsView::expandItemDelayed(const QModelIndex& idx) {
QTimer::singleShot(100, this, [ = ] { QTimer::singleShot(100, this, [ = ] {
// TODO: Z nastavení.
setExpanded(m_proxyModel->mapFromSource(idx), true); setExpanded(m_proxyModel->mapFromSource(idx), true);
}); });
} }
@ -445,6 +510,9 @@ void FeedsView::setupAppearance() {
// Setup column resize strategies. // Setup column resize strategies.
header()->setSectionResizeMode(FDS_MODEL_TITLE_INDEX, QHeaderView::Stretch); header()->setSectionResizeMode(FDS_MODEL_TITLE_INDEX, QHeaderView::Stretch);
header()->setSectionResizeMode(FDS_MODEL_COUNTS_INDEX, QHeaderView::ResizeToContents); header()->setSectionResizeMode(FDS_MODEL_COUNTS_INDEX, QHeaderView::ResizeToContents);
header()->setStretchLastSection(false);
header()->setSortIndicatorShown(false);
setUniformRowHeights(true); setUniformRowHeights(true);
setAnimated(true); setAnimated(true);
setSortingEnabled(true); setSortingEnabled(true);
@ -460,8 +528,6 @@ void FeedsView::setupAppearance() {
setRootIsDecorated(false); setRootIsDecorated(false);
setSelectionMode(QAbstractItemView::SingleSelection); setSelectionMode(QAbstractItemView::SingleSelection);
setItemDelegate(new StyledItemDelegateWithoutFocus(this)); setItemDelegate(new StyledItemDelegateWithoutFocus(this));
header()->setStretchLastSection(false);
header()->setSortIndicatorShown(false);
} }
void FeedsView::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) { void FeedsView::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) {
@ -541,7 +607,6 @@ void FeedsView::onItemExpandRequested(const QList<RootItem*>& items, bool exp) {
foreach (const RootItem* item, items) { foreach (const RootItem* item, items) {
QModelIndex source_index = m_sourceModel->indexForItem(item); QModelIndex source_index = m_sourceModel->indexForItem(item);
QModelIndex proxy_index = m_proxyModel->mapFromSource(source_index); QModelIndex proxy_index = m_proxyModel->mapFromSource(source_index);
//setExpanded(proxy_index, !exp);
setExpanded(proxy_index, exp); setExpanded(proxy_index, exp);
} }
} }

View file

@ -90,26 +90,20 @@ class FeedsView : public QTreeView {
void selectNextItem(); void selectNextItem();
void selectPreviousItem(); void selectPreviousItem();
void selectNextUnreadItem();
// Switches visibility of the widget. // Switches visibility of the widget.
void switchVisibility(); void switchVisibility();
signals: signals:
// Emitted if user selects new feeds.
void itemSelected(RootItem* item); void itemSelected(RootItem* item);
void requestViewNextUnreadMessage();
// Requests opening of given messages in newspaper mode.
void openMessagesInNewspaperView(RootItem* root, const QList<Message>& messages); void openMessagesInNewspaperView(RootItem* root, const QList<Message>& messages);
protected: protected:
// Handle selections.
void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected); void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
// React on "Del" key.
void keyPressEvent(QKeyEvent* event); void keyPressEvent(QKeyEvent* event);
// Show custom context menu.
void contextMenuEvent(QContextMenuEvent* event); void contextMenuEvent(QContextMenuEvent* event);
void mouseDoubleClickEvent(QMouseEvent* event); void mouseDoubleClickEvent(QMouseEvent* event);
private slots: private slots:
@ -123,6 +117,9 @@ class FeedsView : public QTreeView {
void onItemExpandStateSaveRequested(RootItem* item); void onItemExpandStateSaveRequested(RootItem* item);
private: private:
QModelIndex nextPreviousUnreadItem(QModelIndex default_row);
QModelIndex nextUnreadItem(QModelIndex default_row);
// Initializes context menus. // Initializes context menus.
QMenu* initializeContextMenuCategories(RootItem* clicked_item); QMenu* initializeContextMenuCategories(RootItem* clicked_item);
QMenu* initializeContextMenuFeeds(RootItem* clicked_item); QMenu* initializeContextMenuFeeds(RootItem* clicked_item);

View file

@ -174,7 +174,7 @@ void MessagePreviewer::switchMessageImportance(bool checked) {
m_message.m_isImportant ? m_message.m_isImportant ?
RootItem::NotImportant : RootItem::NotImportant :
RootItem::Important))) { RootItem::Important))) {
DatabaseQueries::switchMessagesImportance(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings), DatabaseQueries::switchMessagesImportance(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings),
QStringList() << QString::number(m_message.m_id)); QStringList() << QString::number(m_message.m_id));
m_root->getParentServiceRoot()->onAfterSwitchMessageImportance(m_root.data(), m_root->getParentServiceRoot()->onAfterSwitchMessageImportance(m_root.data(),
QList<ImportanceChange>() << ImportanceChange(m_message, QList<ImportanceChange>() << ImportanceChange(m_message,

View file

@ -269,6 +269,24 @@ int TabWidget::addBrowser(bool move_after_current, bool make_active, const QUrl&
#endif #endif
} }
void TabWidget::gotoNextTab() {
if (currentIndex() == count() - 1) {
setCurrentIndex(0);
}
else {
setCurrentIndex(currentIndex() + 1);
}
}
void TabWidget::gotoPreviousTab() {
if (currentIndex() == 0) {
setCurrentIndex(count() - 1);
}
else {
setCurrentIndex(currentIndex() - 1);
}
}
void TabWidget::indentTabText(int index) { void TabWidget::indentTabText(int index) {
#if defined (Q_OS_MACOS) #if defined (Q_OS_MACOS)

View file

@ -113,6 +113,9 @@ class TabWidget : public QTabWidget {
// General method for adding WebBrowsers. // General method for adding WebBrowsers.
int addBrowser(bool move_after_current, bool make_active, const QUrl& initial_url = QUrl()); int addBrowser(bool move_after_current, bool make_active, const QUrl& initial_url = QUrl());
void gotoNextTab();
void gotoPreviousTab();
private slots: private slots:
// Fixes tabs indexes. // Fixes tabs indexes.
void fixContentsAfterMove(int from, int to); void fixContentsAfterMove(int from, int to);