diff --git a/CMakeLists.txt b/CMakeLists.txt index 5895bc31b..29e135e7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,13 +15,13 @@ # # "-DUSE_QT_5=ON" # Specifies which major Qt version to use. Qt 4 and Qt 5 are supported. -# If "OFF" is passed as an argument, then Qt 4 is used. +# If "OFF" is passed as an argument, then Qt 4 is used. Default is "OFF". # # Other information: +# - supports Windows, Linux, OS/2 (eComStation), # - Qt 4.7.3 and higher is required, # - resource compiler (windres.exe) is needed on MinGW, -# - resource compiler (rc.exe) is needed on OS/2, -# - supports Windows, Linux, OS/2 (eComStation). +# - resource compiler (rc.exe) is needed on OS/2. # # Authors and contributors: # - Martin Rotter (project leader) @@ -34,12 +34,14 @@ cmake_minimum_required(VERSION 2.8.11) # Setup basic variables. project(rssguard) set(APP_NAME "RSS Guard") -set(APP_UP_NAME "RSSGuard") set(APP_LOW_NAME "rssguard") set(APP_VERSION "2.0.0-prealpha-3") +set(FILE_VERSION "2,0,0,0") set(APP_AUTHOR "Martin Rotter") set(APP_URL "http://rssguard.sf.net") set(MINIMUM_QT_VERSION 4.7.3) +set(SOURCE_PACKAGE_SUFFIX "Source") +set(EXE_NAME ${APP_LOW_NAME}) option(USE_QT_5 "Use Qt 5 for building" ON) @@ -51,13 +53,6 @@ set(CMAKE_COLOR_MAKEFILE ON) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/resources/cmake ${CMAKE_MODULE_PATH}) set(CMAKE_INCLUDE_CURRENT_DIR ON) -# Setup name for executable file. -if(APPLE) - set(EXE_NAME ${APP_UP_NAME}) -else(APPLE) - set(EXE_NAME ${APP_LOW_NAME}) -endif(APPLE) - # Select which Qt version to use. if(${USE_QT_5}) message(STATUS "[${APP_LOW_NAME}] Using Qt 5 library for building.") @@ -159,14 +154,6 @@ endif(${USE_QT_5}) # Setup libraries. if(${USE_QT_5}) - #find_package(Qt5Sql) - #find_package(Qt5WebKit) - #find_package(Qt5WebKitWidgets) - #find_package(Qt5Widgets) - #find_package(Qt5Xml) - #find_package(Qt5XmlPatterns) - #find_package(Qt5Network) - #find_package(Qt5LinguistTools) find_package(Qt5 REQUIRED Sql WebKit WebKitWidgets Widgets Xml XmlPatterns Network LinguistTools) else(${USE_QT_5}) set(QT_MIN_VERSION ${MINIMUM_QT_VERSION}) @@ -490,7 +477,7 @@ set(CPACK_PACKAGE_NAME ${APP_LOW_NAME}) set(CPACK_PACKAGE_VERSION ${APP_VERSION}) set(CPACK_IGNORE_FILES "/resources/aur/;\\\\.psd$;/resources/deployment;/CVS/;/\\\\.svn/;/\\\\.git/;\\\\.swp$;/CMakeLists.txt.user;\\\\.#;/#;\\\\.tar.gz$;/CMakeFiles/;CMakeCache.txt;\\\\.qm$;/build/;\\\\.diff$;.DS_Store'") set(CPACK_SOURCE_GENERATOR "TGZ") -set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-src") +set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${SOURCE_PACKAGE_SUFFIX}") set(CPACK_SOURCE_IGNORE_FILES ${CPACK_IGNORE_FILES}) # Load packaging facilities. diff --git a/resources/executable_properties/rssguard_win.rc.in b/resources/executable_properties/rssguard_win.rc.in index 08ad6313f..86443e682 100644 --- a/resources/executable_properties/rssguard_win.rc.in +++ b/resources/executable_properties/rssguard_win.rc.in @@ -1,30 +1,33 @@ +// This is resource file for MS Windows platform. + + IDI_ICON1 ICON DISCARDABLE "@PROJECT_SOURCE_DIR@/resources/graphics/rssguard.ico" #include VS_VERSION_INFO VERSIONINFO -FILEVERSION 1,0,0,0 -PRODUCTVERSION 1,0,0,0 +FILEVERSION @FILE_VERSION@ +PRODUCTVERSION @FILE_VERSION@ BEGIN - BLOCK "StringFileInfo" + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" BEGIN - BLOCK "040904E4" - BEGIN - VALUE "CompanyName", "@APP_AUTHOR@" - VALUE "FileDescription", "@APP_NAME@" - VALUE "FileVersion", "@APP_VERSION@" - VALUE "InternalName", "@APP_AUTHOR@" - VALUE "LegalCopyright", "Copyright © 2011-2013 Martin Rotter" - VALUE "LegalTrademarks1", "Some rights reserved" - VALUE "LegalTrademarks2", "Some rights reserved" - VALUE "OriginalFilename", "@EXE_NAME@.exe" - VALUE "ProductName", "@APP_NAME@" - VALUE "ProductVersion", "@APP_VERSION@" - END + VALUE "CompanyName", "@APP_AUTHOR@" + VALUE "FileDescription", "@APP_NAME@" + VALUE "FileVersion", "@APP_VERSION@" + VALUE "InternalName", "@APP_AUTHOR@" + VALUE "LegalCopyright", "Copyright © 2011-2013 Martin Rotter" + VALUE "LegalTrademarks1", "Some rights reserved" + VALUE "LegalTrademarks2", "Some rights reserved" + VALUE "OriginalFilename", "@EXE_NAME@.exe" + VALUE "ProductName", "@APP_NAME@" + VALUE "ProductVersion", "@APP_VERSION@" END + END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1252 - END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END END diff --git a/src/gui/feedmessageviewer.cpp b/src/gui/feedmessageviewer.cpp index d1430c9bd..cccb88dce 100644 --- a/src/gui/feedmessageviewer.cpp +++ b/src/gui/feedmessageviewer.cpp @@ -51,8 +51,8 @@ void FeedMessageViewer::initialize() { QToolButton *update_button = new QToolButton(m_toolBar); update_button->setPopupMode(QToolButton::InstantPopup); update_button->setIcon(IconThemeFactory::getInstance()->fromTheme("view-refresh")); - update_button->setText(FormMain::getInstance()->m_ui->m_actionUpdateAllFeeds->text()); - update_button->setToolTip(FormMain::getInstance()->m_ui->m_actionUpdateAllFeeds->toolTip()); + update_button->setText(tr("Update selected/all feeds")); + update_button->setToolTip(tr("Select which feeds you want to update.")); QMenu *update_menu = new QMenu(tr("Feed update menu"), update_button); update_menu->addAction(FormMain::getInstance()->m_ui->m_actionUpdateAllFeeds); diff --git a/src/gui/formmain.cpp b/src/gui/formmain.cpp index 32f7b4ac1..76032d787 100644 --- a/src/gui/formmain.cpp +++ b/src/gui/formmain.cpp @@ -58,13 +58,33 @@ TabWidget *FormMain::getTabWidget() { QList FormMain::getActions() { QList actions; + + // Add basic actions. actions << m_ui->m_actionImport << m_ui->m_actionExport << m_ui->m_actionSettings << m_ui->m_actionQuit << - m_ui->m_actionFullscreen << m_ui->m_actionAboutGuard << - m_ui->m_actionAddBrowser << m_ui->m_actionCloseCurrentTab << + m_ui->m_actionFullscreen; + + // Add web browser actions + actions << m_ui->m_actionAddBrowser << m_ui->m_actionCloseCurrentTab << m_ui->m_actionCloseAllTabs; - return actions; + // Add feeds/messages actions. + actions << m_ui->m_actionOpenSelectedSourceArticlesExternally << + m_ui->m_actionOpenSelectedMessagesExternally << + m_ui->m_actionOpenSelectedMessagesInternally << + m_ui->m_actionMarkAllMessagesAsRead << + m_ui->m_actionMarkAllMessagesAsUnread << + m_ui->m_actionDeleteAllMessages << + m_ui->m_actionMarkSelectedMessagesAsRead << + m_ui->m_actionMarkSelectedMessagesAsUnread << + m_ui->m_actionSwitchImportanceOfSelectedMessages << + m_ui->m_actionDeleteSelectedMessages << + m_ui->m_actionUpdateAllFeeds << + m_ui->m_actionUpdateSelectedFeeds << + m_ui->m_actionEditSelectedFeed << + m_ui->m_actionDeleteSelectedFeeds; + + return actions; } void FormMain::prepareMenus() { @@ -125,7 +145,7 @@ void FormMain::display() { QtSingleApplication::alert(this); } -void FormMain::onCommitData(QSessionManager &manager) { +void FormMain::onCommitData(QSessionManager &manager) { qDebug("OS asked application to commit its data."); } @@ -166,7 +186,9 @@ void FormMain::setupIcons() { m_ui->m_actionMarkSelectedMessagesAsRead->setIcon(IconThemeFactory::getInstance()->fromTheme("mail-mark-read")); m_ui->m_actionMarkSelectedMessagesAsUnread->setIcon(IconThemeFactory::getInstance()->fromTheme("mail-mark-unread")); m_ui->m_actionSwitchImportanceOfSelectedMessages->setIcon(IconThemeFactory::getInstance()->fromTheme("mail-mark-important")); - + m_ui->m_actionOpenSelectedMessagesExternally->setIcon(IconThemeFactory::getInstance()->fromTheme("document-open")); + m_ui->m_actionOpenSelectedSourceArticlesExternally->setIcon(IconThemeFactory::getInstance()->fromTheme("document-open")); + m_ui->m_actionOpenSelectedMessagesInternally->setIcon(IconThemeFactory::getInstance()->fromTheme("document-open")); // Setup icons for underlying components: opened web browsers... foreach (WebBrowser *browser, WebBrowser::runningWebBrowsers()) { diff --git a/src/gui/formmain.h b/src/gui/formmain.h index cd9e9e589..bde361439 100644 --- a/src/gui/formmain.h +++ b/src/gui/formmain.h @@ -12,6 +12,7 @@ class FormMain : public QMainWindow { friend class TabWidget; friend class FeedMessageViewer; + friend class MessagesView; public: // Constructors and destructors. diff --git a/src/gui/formmain.ui b/src/gui/formmain.ui index 1ff581b36..ba94398da 100644 --- a/src/gui/formmain.ui +++ b/src/gui/formmain.ui @@ -48,7 +48,7 @@ 0 0 800 - 19 + 21 @@ -357,6 +357,36 @@ Add new feed. + + + Open selected messages in external browser + + + Open selected messages in external browser. + + + + + + + + Open selected messages in internal browser + + + Open selected messages in internal browser. + + + + + + + + Open selected source articles in external browser + + + Open selected source messages in external browser. + + diff --git a/src/gui/formsettings.cpp b/src/gui/formsettings.cpp index 540b20f78..34d86756d 100644 --- a/src/gui/formsettings.cpp +++ b/src/gui/formsettings.cpp @@ -125,18 +125,30 @@ void FormSettings::displayProxyPassword(int state) { bool FormSettings::doSaveCheck() { bool everything_ok = true; - QString resulting_information; + QStringList resulting_information; + QMessageBox msg_error(this); + // Setup indication of settings consistence. everything_ok &= m_ui->m_shortcuts->areShortcutsUnique(); if (!m_ui->m_shortcuts->areShortcutsUnique()) { - resulting_information = resulting_information.append(tr("Some keyboard shortcuts are not unique.\n")); +#if QT_VERSION >= 0x050000 + resulting_information.append(tr(" • some keyboard shortcuts are not unique")); +#else + resulting_information.append(trUtf8(" • some keyboard shortcuts are not unique")); +#endif } + // Setup dialog. + msg_error.setText(tr("Some critical settings are not set. You must fix these settings in order confirm new settings.")); + msg_error.setWindowTitle(tr("Cannot save settings")); + msg_error.setDetailedText(tr("List of errors:\n %1.").arg(resulting_information.join(",\n"))); + msg_error.setIcon(QMessageBox::Critical); + msg_error.setStandardButtons(QMessageBox::Ok); + msg_error.setDefaultButton(QMessageBox::Ok); + if (!everything_ok) { - QMessageBox::warning(this, - tr("Cannot save settings"), - resulting_information); + msg_error.exec(); } return everything_ok; @@ -494,6 +506,7 @@ void FormSettings::saveInterface() { QString original_icon_theme = IconThemeFactory::getInstance()->getCurrentIconTheme(); IconThemeFactory::getInstance()->setCurrentIconTheme(selected_icon_theme); + // Check if icon theme was changed. if (selected_icon_theme != original_icon_theme) { #if QT_VERSION >= 0x050000 m_changedDataTexts.append(tr(" • icon theme changed")); diff --git a/src/gui/formsettings.ui b/src/gui/formsettings.ui index cbf46ec57..f254c6940 100644 --- a/src/gui/formsettings.ui +++ b/src/gui/formsettings.ui @@ -6,7 +6,7 @@ 0 0 - 910 + 966 445 @@ -17,7 +17,7 @@ - 2 + 5 @@ -69,8 +69,8 @@ 0 0 - 666 - 399 + 100 + 30 @@ -147,8 +147,8 @@ 0 0 - 662 - 371 + 167 + 219 @@ -634,6 +634,7 @@ + @@ -663,7 +664,7 @@ false - 0 + -1 @@ -690,6 +691,11 @@ Web browser & proxy + + + Feeds & messages + + diff --git a/src/gui/messagesview.cpp b/src/gui/messagesview.cpp index 260181e5c..e3e1edf3d 100644 --- a/src/gui/messagesview.cpp +++ b/src/gui/messagesview.cpp @@ -1,13 +1,16 @@ #include #include #include +#include #include "gui/messagesview.h" #include "core/messagesproxymodel.h" #include "core/messagesmodel.h" +#include "gui/formmain.h" -MessagesView::MessagesView(QWidget *parent) : QTreeView(parent) { +MessagesView::MessagesView(QWidget *parent) + : QTreeView(parent), m_contextMenu(NULL) { m_proxyModel = new MessagesProxyModel(this); m_sourceModel = m_proxyModel->sourceModel(); @@ -98,6 +101,39 @@ void MessagesView::keyPressEvent(QKeyEvent *event) { QTreeView::keyPressEvent(event); } +void MessagesView::contextMenuEvent(QContextMenuEvent *event) { + QModelIndex clicked_index = indexAt(event->pos()); + + if (!clicked_index.isValid()) { + qDebug("Context menu for MessagesView will not be shown because " + "user clicked on invalid item."); + return; + } + + if (m_contextMenu == NULL) { + // Context menu is not initialized, initialize. + initializeContextMenu(); + } + + m_contextMenu->exec(event->globalPos()); +} + +void MessagesView::initializeContextMenu() { + m_contextMenu = new QMenu(tr("Context menu for messages"), this); + + connect(FormMain::getInstance()->m_ui->m_actionOpenSelectedMessagesExternally, + SIGNAL(triggered()), this, SLOT(openSelectedMessagesExternally())); + + m_contextMenu->addActions(QList() << + FormMain::getInstance()->m_ui->m_actionOpenSelectedSourceArticlesExternally << + FormMain::getInstance()->m_ui->m_actionOpenSelectedMessagesExternally << + FormMain::getInstance()->m_ui->m_actionOpenSelectedMessagesInternally << + FormMain::getInstance()->m_ui->m_actionMarkSelectedMessagesAsRead << + FormMain::getInstance()->m_ui->m_actionMarkSelectedMessagesAsUnread << + FormMain::getInstance()->m_ui->m_actionSwitchImportanceOfSelectedMessages << + FormMain::getInstance()->m_ui->m_actionDeleteSelectedMessages); +} + void MessagesView::mousePressEvent(QMouseEvent *event) { QTreeView::mousePressEvent(event); @@ -140,36 +176,49 @@ void MessagesView::currentChanged(const QModelIndex ¤t, QTreeView::currentChanged(current, previous); } +void MessagesView::openSelectedMessagesExternally() { + // TODO: otevÅ™e vybrane zpravy v externim prohlizeci +} + +void MessagesView::openSelectedSourceMessagesInternally() { + // TODO: otevre vybrane nactene zpravy v internch tabech +} + +void MessagesView::openSelectedTargetMessagesInternally() { + // TODO: otevre vybrane zpravy ze zdrojovych webz v internich tabech +} + void MessagesView::switchSelectedMessagesImportance() { - QModelIndex current_idx = selectionModel()->currentIndex(); - QModelIndex mapped_current_idx = m_proxyModel->mapToSource(current_idx); - QModelIndexList selected_idxs = selectionModel()->selectedRows(); - QModelIndexList mapped_idxs = m_proxyModel->mapListToSource(selected_idxs); + QModelIndex current_index = selectionModel()->currentIndex(); + QModelIndex mapped_current_index = m_proxyModel->mapToSource(current_index); + QModelIndexList selected_indexes = selectionModel()->selectedRows(); + QModelIndexList mapped_indexes = m_proxyModel->mapListToSource(selected_indexes); - m_sourceModel->switchBatchMessageImportance(mapped_idxs); + m_sourceModel->switchBatchMessageImportance(mapped_indexes); - selected_idxs.clear(); + selected_indexes.clear(); sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder()); - foreach (const QModelIndex &index, mapped_idxs) { - selected_idxs << m_proxyModel->mapFromSource(m_sourceModel->index(index.row(), + foreach (const QModelIndex &index, mapped_indexes) { + selected_indexes << m_proxyModel->mapFromSource(m_sourceModel->index(index.row(), index.column())); } - current_idx = m_proxyModel->mapFromSource(m_sourceModel->index(mapped_current_idx.row(), - mapped_current_idx.column())); + current_index = m_proxyModel->mapFromSource(m_sourceModel->index(mapped_current_index.row(), + mapped_current_index.column())); - setCurrentIndex(current_idx); - scrollTo(current_idx); - reselectIndexes(selected_idxs); + setCurrentIndex(current_index); + scrollTo(current_index); + reselectIndexes(selected_indexes); } void MessagesView::reselectIndexes(const QModelIndexList &indexes) { selectionModel()->clearSelection(); - foreach (const QModelIndex &idx, indexes) { - selectionModel()->select(idx, - QItemSelectionModel::Select | QItemSelectionModel::Rows); + foreach (const QModelIndex &index, indexes) { + selectionModel()->select(index, + QItemSelectionModel::Select | + QItemSelectionModel::Rows); } } diff --git a/src/gui/messagesview.h b/src/gui/messagesview.h index 9be91bcb6..e389544d4 100644 --- a/src/gui/messagesview.h +++ b/src/gui/messagesview.h @@ -24,6 +24,9 @@ class MessagesView : public QTreeView { public slots: // Message manipulators. + void openSelectedMessagesExternally(); + void openSelectedSourceMessagesInternally(); + void openSelectedTargetMessagesInternally(); void switchSelectedMessagesImportance(); void setAllMessagesRead(); @@ -31,7 +34,10 @@ class MessagesView : public QTreeView { void reselectIndexes(const QModelIndexList &indexes); protected: + void initializeContextMenu(); void setupAppearance(); + + void contextMenuEvent(QContextMenuEvent *event); void mousePressEvent(QMouseEvent *event); void keyPressEvent(QKeyEvent *event); void currentChanged(const QModelIndex ¤t, @@ -44,6 +50,8 @@ class MessagesView : public QTreeView { void currentMessageRemoved(); private: + QMenu *m_contextMenu; + MessagesProxyModel *m_proxyModel; MessagesModel *m_sourceModel; }; diff --git a/src/gui/webbrowser.cpp b/src/gui/webbrowser.cpp index 127c8c6c8..2f321b927 100644 --- a/src/gui/webbrowser.cpp +++ b/src/gui/webbrowser.cpp @@ -176,7 +176,7 @@ void WebBrowser::navigateToMessage(const Message &message) { tr("Written by ") + message.m_author, message.m_url, message.m_contents, - message.m_updated.toString(Qt::ISODate))); + message.m_updated.toString(Qt::DefaultLocaleLongDate))); } void WebBrowser::updateZoomGui() {