Fixed #136.
This commit is contained in:
parent
cbf2fbec8d
commit
631f225110
@ -44,7 +44,7 @@ on_success:
|
||||
- for /f "tokens=*" %%F in ('dir /b *.exe') do curl --upload-file %%F https://transfer.sh/%%F --silent >> ..\rssguard-wiki\Windows-development-builds.md
|
||||
- echo.>> ..\rssguard-wiki\Windows-development-builds.md
|
||||
- cd ..\rssguard-wiki
|
||||
- git pull origin master
|
||||
- git add *.*
|
||||
- git commit -m "New files."
|
||||
- git pull origin master
|
||||
- git push origin master
|
||||
|
@ -29,7 +29,7 @@ echo "\n" >> ./build-wiki/Mac-OS-X-development-builds.md
|
||||
cat ./build-wiki/Mac-OS-X-development-builds.md
|
||||
|
||||
cd ./build-wiki
|
||||
git pull origin master
|
||||
git add *.*
|
||||
git commit -m "New files."
|
||||
git pull origin master
|
||||
git push origin master
|
@ -2,6 +2,7 @@
|
||||
—————
|
||||
|
||||
Added:
|
||||
▪ Added support for arbitrary external tools (settings category "Web browser & e-mail & proxy") which can open URLs of selected messages. (#136)
|
||||
▪ 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)
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "gui/guiutilities.h"
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QProcess>
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include <windows.h>
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include <QScrollBar>
|
||||
#include <QTimer>
|
||||
#include <QMenu>
|
||||
#include <QFileIconProvider>
|
||||
#include <QProcess>
|
||||
|
||||
|
||||
MessagesView::MessagesView(QWidget* parent)
|
||||
@ -180,6 +182,28 @@ void MessagesView::initializeContextMenu() {
|
||||
}
|
||||
|
||||
m_contextMenu->clear();
|
||||
|
||||
QFileIconProvider icon_provider;
|
||||
QMenu* menu = new QMenu(tr("Open with external tool"), m_contextMenu);
|
||||
menu->setIcon(qApp->icons()->fromTheme(QSL("document-open")));
|
||||
|
||||
foreach (const QString& tool, qApp->settings()->value(GROUP(Browser), SETTING(Browser::ExternalTools)).toStringList()) {
|
||||
QAction* act_tool = new QAction(QFileInfo(tool).fileName(), menu);
|
||||
|
||||
act_tool->setIcon(icon_provider.icon(tool));
|
||||
act_tool->setToolTip(tool);
|
||||
menu->addAction(act_tool);
|
||||
|
||||
connect(act_tool, &QAction::triggered, this, &MessagesView::openSelectedMessagesWithExternalTool);
|
||||
}
|
||||
|
||||
if (menu->actions().isEmpty()) {
|
||||
QAction* act_not_tools = new QAction("No external tools activated");
|
||||
act_not_tools->setEnabled(false);
|
||||
menu->addAction(act_not_tools);
|
||||
}
|
||||
|
||||
m_contextMenu->addMenu(menu);
|
||||
m_contextMenu->addActions(QList<QAction*>() <<
|
||||
qApp->mainForm()->m_ui->m_actionSendMessageViaEmail <<
|
||||
qApp->mainForm()->m_ui->m_actionOpenSelectedSourceArticlesExternally <<
|
||||
@ -482,6 +506,25 @@ void MessagesView::filterMessages(MessagesModel::MessageHighlighter filter) {
|
||||
m_sourceModel->highlightMessages(filter);
|
||||
}
|
||||
|
||||
void MessagesView::openSelectedMessagesWithExternalTool() {
|
||||
QAction* sndr = qobject_cast<QAction*>(sender());
|
||||
|
||||
if (sndr != nullptr) {
|
||||
const QString& tool = sndr->toolTip();
|
||||
|
||||
foreach (const QModelIndex& index, selectionModel()->selectedRows()) {
|
||||
const QString& link = m_sourceModel->messageAt(m_proxyModel->mapToSource(index).row()).m_url;
|
||||
|
||||
if (!link.isEmpty()) {
|
||||
if (!QProcess::startDetached(tool, QStringList() << link)) {
|
||||
qApp->showGuiMessage(tr("Cannot run external tool"), tr("External tool '%1' could not be started."),
|
||||
QSystemTrayIcon::Critical);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessagesView::adjustColumns() {
|
||||
if (header()->count() > 0 && !m_columnsAdjusted) {
|
||||
m_columnsAdjusted = true;
|
||||
|
@ -77,6 +77,8 @@ class MessagesView : public QTreeView {
|
||||
void filterMessages(MessagesModel::MessageHighlighter filter);
|
||||
|
||||
private slots:
|
||||
void openSelectedMessagesWithExternalTool();
|
||||
|
||||
// Marks given indexes as selected.
|
||||
void reselectIndexes(const QModelIndexList& indexes);
|
||||
|
||||
|
@ -29,14 +29,18 @@
|
||||
SettingsBrowserMail::SettingsBrowserMail(Settings* settings, QWidget* parent)
|
||||
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsBrowserMail) {
|
||||
m_ui->setupUi(this);
|
||||
|
||||
GuiUtilities::setLabelAsNotice(*m_ui->label, false);
|
||||
GuiUtilities::setLabelAsNotice(*m_ui->m_lblExternalEmailInfo, false);
|
||||
GuiUtilities::setLabelAsNotice(*m_ui->m_lblProxyInfo, false);
|
||||
GuiUtilities::setLabelAsNotice(*m_ui->m_lblToolInfo, false);
|
||||
|
||||
#if defined(USE_WEBENGINE)
|
||||
m_ui->m_checkOpenLinksInExternal->setVisible(false);
|
||||
#else
|
||||
connect(m_ui->m_checkOpenLinksInExternal, &QCheckBox::stateChanged, this, &SettingsBrowserMail::dirtifySettings);
|
||||
#endif
|
||||
|
||||
connect(m_ui->m_cmbProxyType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||
&SettingsBrowserMail::dirtifySettings);
|
||||
connect(m_ui->m_txtProxyHost, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
|
||||
@ -58,6 +62,13 @@ SettingsBrowserMail::SettingsBrowserMail(Settings* settings, QWidget* parent)
|
||||
connect(m_ui->m_cmbExternalEmailPreset, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||
&SettingsBrowserMail::changeDefaultEmailArguments);
|
||||
connect(m_ui->m_btnExternalEmailExecutable, &QPushButton::clicked, this, &SettingsBrowserMail::selectEmailExecutable);
|
||||
connect(m_ui->m_btnAddTool, &QPushButton::clicked, this, &SettingsBrowserMail::dirtifySettings);
|
||||
connect(m_ui->m_btnDeleteTool, &QPushButton::clicked, this, &SettingsBrowserMail::dirtifySettings);
|
||||
connect(m_ui->m_btnAddTool, &QPushButton::clicked, this, &SettingsBrowserMail::addExternalTool);
|
||||
connect(m_ui->m_btnDeleteTool, &QPushButton::clicked, this, &SettingsBrowserMail::deleteSelectedExternalTool);
|
||||
connect(m_ui->m_listTools, &QListWidget::currentTextChanged, [this](const QString & current_text) {
|
||||
m_ui->m_btnDeleteTool->setEnabled(!current_text.isEmpty());
|
||||
});
|
||||
}
|
||||
|
||||
SettingsBrowserMail::~SettingsBrowserMail() {
|
||||
@ -110,6 +121,22 @@ void SettingsBrowserMail::onProxyTypeChanged(int index) {
|
||||
m_ui->m_lblProxyUsername->setEnabled(is_proxy_selected);
|
||||
}
|
||||
|
||||
QStringList SettingsBrowserMail::externalTools() const {
|
||||
QStringList list;
|
||||
|
||||
for (int i = 0; i < m_ui->m_listTools->count(); i++) {
|
||||
list.append(m_ui->m_listTools->item(i)->text());
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void SettingsBrowserMail::setExternalTools(const QStringList& list) {
|
||||
foreach (const QString& tool, list) {
|
||||
m_ui->m_listTools->addItem(tool);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsBrowserMail::changeDefaultEmailArguments(int index) {
|
||||
if (index != 0) {
|
||||
m_ui->m_txtExternalEmailArguments->setText(m_ui->m_cmbExternalEmailPreset->itemData(index).toString());
|
||||
@ -134,10 +161,12 @@ void SettingsBrowserMail::selectEmailExecutable() {
|
||||
|
||||
void SettingsBrowserMail::loadSettings() {
|
||||
onBeginLoadSettings();
|
||||
|
||||
#if !defined(USE_WEBENGINE)
|
||||
m_ui->m_checkOpenLinksInExternal->setChecked(settings()->value(GROUP(Browser),
|
||||
SETTING(Browser::OpenLinksInExternalBrowserRightAway)).toBool());
|
||||
#endif
|
||||
|
||||
// Load settings of web browser GUI.
|
||||
m_ui->m_cmbExternalBrowserPreset->addItem(tr("Opera 12 or older"), QSL("-nosession %1"));
|
||||
m_ui->m_txtExternalBrowserExecutable->setText(settings()->value(GROUP(Browser),
|
||||
@ -145,6 +174,7 @@ void SettingsBrowserMail::loadSettings() {
|
||||
m_ui->m_txtExternalBrowserArguments->setText(settings()->value(GROUP(Browser),
|
||||
SETTING(Browser::CustomExternalBrowserArguments)).toString());
|
||||
m_ui->m_grpCustomExternalBrowser->setChecked(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserEnabled)).toBool());
|
||||
|
||||
// Load settings of e-mail.
|
||||
m_ui->m_cmbExternalEmailPreset->addItem(tr("Mozilla Thunderbird"), QSL("-compose \"subject='%1',body='%2'\""));
|
||||
m_ui->m_txtExternalEmailExecutable->setText(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailExecutable)).toString());
|
||||
@ -154,6 +184,7 @@ void SettingsBrowserMail::loadSettings() {
|
||||
m_ui->m_cmbProxyType->addItem(tr("System proxy"), QNetworkProxy::DefaultProxy);
|
||||
m_ui->m_cmbProxyType->addItem(tr("Socks5"), QNetworkProxy::Socks5Proxy);
|
||||
m_ui->m_cmbProxyType->addItem(tr("Http"), QNetworkProxy::HttpProxy);
|
||||
|
||||
// Load the settings.
|
||||
QNetworkProxy::ProxyType selected_proxy_type = static_cast<QNetworkProxy::ProxyType>(settings()->value(GROUP(Proxy),
|
||||
SETTING(Proxy::Type)).toInt());
|
||||
@ -162,18 +193,23 @@ void SettingsBrowserMail::loadSettings() {
|
||||
m_ui->m_txtProxyUsername->setText(settings()->value(GROUP(Proxy), SETTING(Proxy::Username)).toString());
|
||||
m_ui->m_txtProxyPassword->setText(TextFactory::decrypt(settings()->value(GROUP(Proxy), SETTING(Proxy::Password)).toString()));
|
||||
m_ui->m_spinProxyPort->setValue(settings()->value(GROUP(Proxy), SETTING(Proxy::Port)).toInt());
|
||||
|
||||
setExternalTools(settings()->value(GROUP(Browser), SETTING(Browser::ExternalTools)).toStringList());
|
||||
onEndLoadSettings();
|
||||
}
|
||||
|
||||
void SettingsBrowserMail::saveSettings() {
|
||||
onBeginSaveSettings();
|
||||
|
||||
#if !defined(USE_WEBENGINE)
|
||||
settings()->setValue(GROUP(Browser), Browser::OpenLinksInExternalBrowserRightAway, m_ui->m_checkOpenLinksInExternal->isChecked());
|
||||
#endif
|
||||
|
||||
// Save settings of GUI of web browser.
|
||||
settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserEnabled, m_ui->m_grpCustomExternalBrowser->isChecked());
|
||||
settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserExecutable, m_ui->m_txtExternalBrowserExecutable->text());
|
||||
settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserArguments, m_ui->m_txtExternalBrowserArguments->text());
|
||||
|
||||
// Save settings of e-mail.
|
||||
settings()->setValue(GROUP(Browser), Browser::CustomExternalEmailExecutable, m_ui->m_txtExternalEmailExecutable->text());
|
||||
settings()->setValue(GROUP(Browser), Browser::CustomExternalEmailArguments, m_ui->m_txtExternalEmailArguments->text());
|
||||
@ -183,7 +219,32 @@ void SettingsBrowserMail::saveSettings() {
|
||||
settings()->setValue(GROUP(Proxy), Proxy::Username, m_ui->m_txtProxyUsername->text());
|
||||
settings()->setValue(GROUP(Proxy), Proxy::Password, TextFactory::encrypt(m_ui->m_txtProxyPassword->text()));
|
||||
settings()->setValue(GROUP(Proxy), Proxy::Port, m_ui->m_spinProxyPort->value());
|
||||
|
||||
settings()->setValue(GROUP(Browser), Browser::ExternalTools, externalTools());
|
||||
|
||||
// Reload settings for all network access managers.
|
||||
SilentNetworkAccessManager::instance()->loadSettings();
|
||||
onEndSaveSettings();
|
||||
}
|
||||
|
||||
void SettingsBrowserMail::addExternalTool() {
|
||||
QString executable_file = QFileDialog::getOpenFileName(this,
|
||||
tr("Select external tool"),
|
||||
qApp->homeFolder(),
|
||||
//: File filter for external tool selection dialog.
|
||||
#if defined(Q_OS_LINUX)
|
||||
tr("Executables (*)"));
|
||||
#else
|
||||
tr("Executables (*.*)"));
|
||||
#endif
|
||||
|
||||
if (!executable_file.isEmpty()) {
|
||||
m_ui->m_listTools->addItem(QDir::toNativeSeparators(executable_file));
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsBrowserMail::deleteSelectedExternalTool() {
|
||||
if (m_ui->m_listTools->currentRow() >= 0) {
|
||||
m_ui->m_listTools->takeItem(m_ui->m_listTools->currentRow());
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ class SettingsBrowserMail : public SettingsPanel {
|
||||
void saveSettings();
|
||||
|
||||
private slots:
|
||||
void addExternalTool();
|
||||
void deleteSelectedExternalTool();
|
||||
void changeDefaultBrowserArguments(int index);
|
||||
void selectBrowserExecutable();
|
||||
void changeDefaultEmailArguments(int index);
|
||||
@ -46,6 +48,9 @@ class SettingsBrowserMail : public SettingsPanel {
|
||||
void onProxyTypeChanged(int index);
|
||||
|
||||
private:
|
||||
QStringList externalTools() const;
|
||||
void setExternalTools(const QStringList& list);
|
||||
|
||||
Ui::SettingsBrowserMail* m_ui;
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>658</width>
|
||||
<height>200</height>
|
||||
<height>330</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
@ -229,6 +229,53 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>External tools</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="m_lblToolInfo">
|
||||
<property name="text">
|
||||
<string>On this page, you can setup a list of external tools which can open URLs of selected messages.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QPushButton" name="m_btnAddTool">
|
||||
<property name="text">
|
||||
<string>Add external tool</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="m_btnDeleteTool">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delete selected external tool</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QListWidget" name="m_listTools">
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="uniformItemSizes">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="m_tabProxy">
|
||||
<attribute name="title">
|
||||
<string>Proxy</string>
|
||||
|
@ -286,6 +286,8 @@ DVALUE(QString) Browser::CustomExternalEmailExecutableDef = QString();
|
||||
DKEY Browser::CustomExternalEmailArguments = "external_email_arguments";
|
||||
DVALUE(char*) Browser::CustomExternalEmailArgumentsDef = "";
|
||||
|
||||
DKEY Browser::ExternalTools = "external_tools";
|
||||
DVALUE(QStringList) Browser::ExternalToolsDef = QStringList();
|
||||
|
||||
// Categories.
|
||||
DKEY CategoriesExpandStates::ID = "categories_expand_states";
|
||||
|
@ -316,6 +316,9 @@ namespace Browser {
|
||||
KEY CustomExternalEmailExecutable;
|
||||
VALUE(QString) CustomExternalEmailExecutableDef;
|
||||
|
||||
KEY ExternalTools;
|
||||
VALUE(QStringList) ExternalToolsDef;
|
||||
|
||||
KEY CustomExternalEmailArguments;
|
||||
VALUE(char*) CustomExternalEmailArgumentsDef;
|
||||
}
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include <QMetaObject>
|
||||
#include <QMimeData>
|
||||
#include <QMetaEnum>
|
||||
#include <QProcess>
|
||||
#include <QSettings>
|
||||
#include <QDebug>
|
||||
|
||||
@ -47,6 +46,7 @@ DownloadItem::DownloadItem(QNetworkReply* reply, QWidget* parent) : QWidget(pare
|
||||
m_ui->setupUi(this);
|
||||
m_ui->m_btnTryAgain->hide();
|
||||
m_requestFileName = qApp->settings()->value(GROUP(Downloads), SETTING(Downloads::AlwaysPromptForFilename)).toBool();
|
||||
|
||||
connect(m_ui->m_btnStopDownload, &QToolButton::clicked, this, &DownloadItem::stop);
|
||||
connect(m_ui->m_btnOpenFile, &QToolButton::clicked, this, &DownloadItem::openFile);
|
||||
connect(m_ui->m_btnTryAgain, &QToolButton::clicked, this, &DownloadItem::tryAgain);
|
||||
@ -69,15 +69,18 @@ void DownloadItem::init() {
|
||||
m_ui->m_btnOpenFolder->setEnabled(false);
|
||||
m_url = m_reply->url();
|
||||
m_reply->setParent(this);
|
||||
|
||||
connect(m_reply, &QNetworkReply::readyRead, this, &DownloadItem::downloadReadyRead);
|
||||
connect(m_reply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error), this, &DownloadItem::error);
|
||||
connect(m_reply, &QNetworkReply::downloadProgress, this, &DownloadItem::downloadProgress);
|
||||
connect(m_reply, &QNetworkReply::metaDataChanged, this, &DownloadItem::metaDataChanged);
|
||||
connect(m_reply, &QNetworkReply::finished, this, &DownloadItem::finished);
|
||||
|
||||
// Reset info.
|
||||
m_ui->m_lblInfoDownload->clear();
|
||||
m_ui->m_progressDownload->setValue(0);
|
||||
getFileName();
|
||||
|
||||
// Start timer for the download estimation.
|
||||
m_downloadTime.start();
|
||||
|
||||
@ -119,6 +122,7 @@ void DownloadItem::getFileName() {
|
||||
}
|
||||
|
||||
m_output.setFileName(chosen_filename);
|
||||
|
||||
// Check file path for saving.
|
||||
const QDir save_dir = QFileInfo(m_output.fileName()).dir();
|
||||
|
||||
@ -275,6 +279,7 @@ void DownloadItem::downloadReadyRead() {
|
||||
|
||||
void DownloadItem::error(QNetworkReply::NetworkError code) {
|
||||
Q_UNUSED(code)
|
||||
|
||||
m_ui->m_lblInfoDownload->setText(tr("Error: %1").arg(m_reply->errorString()));
|
||||
m_ui->m_btnTryAgain->setEnabled(true);
|
||||
m_ui->m_btnTryAgain->setVisible(true);
|
||||
@ -511,6 +516,7 @@ void DownloadManager::addItem(DownloadItem* item) {
|
||||
connect(item, &DownloadItem::statusChanged, this, static_cast<void (DownloadManager::*)()>(&DownloadManager::updateRow));
|
||||
connect(item, &DownloadItem::progress, this, &DownloadManager::itemProgress);
|
||||
connect(item, &DownloadItem::downloadFinished, this, &DownloadManager::itemFinished);
|
||||
|
||||
const int row = m_downloads.count();
|
||||
m_model->beginInsertRows(QModelIndex(), row, row);
|
||||
m_downloads.append(item);
|
||||
@ -519,6 +525,7 @@ void DownloadManager::addItem(DownloadItem* item) {
|
||||
QIcon icon = style()->standardIcon(QStyle::SP_FileIcon);
|
||||
item->m_ui->m_lblFileIcon->setPixmap(icon.pixmap(DOWNLOADER_ICON_SIZE, DOWNLOADER_ICON_SIZE));
|
||||
m_ui->m_viewDownloads->setRowHeight(row, item->sizeHint().height());
|
||||
|
||||
// Just in case of download finishes before it is actually added.
|
||||
updateRow(item);
|
||||
}
|
||||
@ -572,6 +579,7 @@ void DownloadManager::updateRow(DownloadItem* item) {
|
||||
item->m_ui->m_lblFileIcon->setPixmap(icon.pixmap(DOWNLOADER_ICON_SIZE, DOWNLOADER_ICON_SIZE));
|
||||
int old_height = m_ui->m_viewDownloads->rowHeight(row);
|
||||
m_ui->m_viewDownloads->setRowHeight(row, qMax(old_height, item->minimumSizeHint().height()));
|
||||
|
||||
// Remove the item if:
|
||||
// a) It is not downloading and private browsing is enabled.
|
||||
// OR
|
||||
|
Loading…
x
Reference in New Issue
Block a user