External tools now support parameters.

This commit is contained in:
Martin Rotter 2017-09-11 11:51:23 +02:00
parent 659dd7d05b
commit 5b97260104
9 changed files with 237 additions and 30 deletions

View File

@ -188,8 +188,7 @@ win32 {
}
DISTFILES += resources/scripts/astyle/.astylerc \
resources/scripts/uncrustify/uncrustify.cfg \
resources/scripts/uncrustify/uncrustify.cfg
resources/scripts/uncrustify/uncrustify.cfg
MOC_DIR = $$OUT_PWD/moc
RCC_DIR = $$OUT_PWD/rcc
@ -340,7 +339,8 @@ HEADERS += src/core/feeddownloader.h \
src/core/messagesmodelsqllayer.h \
src/gui/treeviewcolumnsmenu.h \
src/services/abstract/labelsrootitem.h \
src/services/abstract/label.h
src/services/abstract/label.h \
src/miscellaneous/externaltool.h
SOURCES += src/core/feeddownloader.cpp \
src/core/feedsmodel.cpp \
@ -466,7 +466,8 @@ SOURCES += src/core/feeddownloader.cpp \
src/core/messagesmodelsqllayer.cpp \
src/gui/treeviewcolumnsmenu.cpp \
src/services/abstract/labelsrootitem.cpp \
src/services/abstract/label.cpp
src/services/abstract/label.cpp \
src/miscellaneous/externaltool.cpp
OBJECTIVE_SOURCES += src/miscellaneous/disablewindowtabbing.mm

View File

@ -84,6 +84,8 @@
#define GOOGLE_SUGGEST_URL "http://suggestqueries.google.com/complete/search?output=toolbar&hl=en&q=%1"
#define ENCRYPTION_FILE_NAME "key.private"
#define RELOAD_MODEL_BORDER_NUM 10
#define EXTERNAL_TOOL_SEPARATOR "###"
#define EXTERNAL_TOOL_PARAM_SEPARATOR "|||"
#define MAX_ZOOM_FACTOR 5.0f
#define MIN_ZOOM_FACTOR 0.25f

View File

@ -24,6 +24,7 @@
#include "network-web/networkfactory.h"
#include "network-web/webfactory.h"
#include "gui/dialogs/formmain.h"
#include "miscellaneous/externaltool.h"
#include "gui/messagebox.h"
#include "gui/treeviewcolumnsmenu.h"
#include "gui/styleditemdelegatewithoutfocus.h"
@ -187,11 +188,12 @@ void MessagesView::initializeContextMenu() {
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);
foreach (const ExternalTool& tool, ExternalTool::toolsFromSettings()) {
QAction* act_tool = new QAction(QFileInfo(tool.executable()).fileName(), menu);
act_tool->setIcon(icon_provider.icon(tool));
act_tool->setToolTip(tool);
act_tool->setIcon(icon_provider.icon(tool.executable()));
act_tool->setToolTip(tool.executable());
act_tool->setData(QVariant::fromValue(tool));
menu->addAction(act_tool);
connect(act_tool, &QAction::triggered, this, &MessagesView::openSelectedMessagesWithExternalTool);
@ -510,13 +512,13 @@ void MessagesView::openSelectedMessagesWithExternalTool() {
QAction* sndr = qobject_cast<QAction*>(sender());
if (sndr != nullptr) {
const QString& tool = sndr->toolTip();
auto tool = sndr->data().value<ExternalTool>();
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)) {
if (!QProcess::startDetached(tool.executable(), QStringList() << tool.parameters() << link)) {
qApp->showGuiMessage(tr("Cannot run external tool"), tr("External tool '%1' could not be started."),
QSystemTrayIcon::Critical);
}

View File

@ -21,13 +21,15 @@
#include "miscellaneous/application.h"
#include "miscellaneous/textfactory.h"
#include "gui/guiutilities.h"
#include "miscellaneous/externaltool.h"
#include <QNetworkProxy>
#include <QFileDialog>
#include <QInputDialog>
SettingsBrowserMail::SettingsBrowserMail(Settings* settings, QWidget* parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsBrowserMail) {
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsBrowserMail) {
m_ui->setupUi(this);
GuiUtilities::setLabelAsNotice(*m_ui->label, false);
@ -41,6 +43,9 @@ SettingsBrowserMail::SettingsBrowserMail(Settings* settings, QWidget* parent)
connect(m_ui->m_checkOpenLinksInExternal, &QCheckBox::stateChanged, this, &SettingsBrowserMail::dirtifySettings);
#endif
m_ui->m_listTools->setHeaderLabels(QStringList() << tr("Executable") << tr("Parameters"));
m_ui->m_listTools->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
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);
@ -66,8 +71,10 @@ SettingsBrowserMail::SettingsBrowserMail(Settings* settings, QWidget* parent)
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());
connect(m_ui->m_listTools, &QTreeWidget::currentItemChanged, [this](QTreeWidgetItem * current, QTreeWidgetItem * previous) {
Q_UNUSED(previous)
m_ui->m_btnDeleteTool->setEnabled(current != nullptr);
});
}
@ -121,19 +128,23 @@ void SettingsBrowserMail::onProxyTypeChanged(int index) {
m_ui->m_lblProxyUsername->setEnabled(is_proxy_selected);
}
QStringList SettingsBrowserMail::externalTools() const {
QStringList list;
QList<ExternalTool> SettingsBrowserMail::externalTools() const {
QList<ExternalTool> list;
for (int i = 0; i < m_ui->m_listTools->count(); i++) {
list.append(m_ui->m_listTools->item(i)->text());
for (int i = 0; i < m_ui->m_listTools->topLevelItemCount(); i++) {
list.append(m_ui->m_listTools->topLevelItem(i)->data(0, Qt::UserRole).value<ExternalTool>());
}
return list;
}
void SettingsBrowserMail::setExternalTools(const QStringList& list) {
foreach (const QString& tool, list) {
m_ui->m_listTools->addItem(tool);
void SettingsBrowserMail::setExternalTools(const QList<ExternalTool>& list) {
foreach (const ExternalTool& tool, list) {
QTreeWidgetItem* item = new QTreeWidgetItem(m_ui->m_listTools,
QStringList() << tool.executable() << tool.parameters());
item->setData(0, Qt::UserRole, QVariant::fromValue(tool));
m_ui->m_listTools->addTopLevelItem(item);
}
}
@ -194,7 +205,7 @@ void SettingsBrowserMail::loadSettings() {
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());
setExternalTools(ExternalTool::toolsFromSettings());
onEndLoadSettings();
}
@ -220,7 +231,9 @@ void SettingsBrowserMail::saveSettings() {
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());
auto tools = externalTools();
ExternalTool::setToolsToSettings(tools);
// Reload settings for all network access managers.
SilentNetworkAccessManager::instance()->loadSettings();
@ -239,12 +252,23 @@ void SettingsBrowserMail::addExternalTool() {
#endif
if (!executable_file.isEmpty()) {
m_ui->m_listTools->addItem(QDir::toNativeSeparators(executable_file));
executable_file = QDir::toNativeSeparators(executable_file);
bool ok;
QString parameters = QInputDialog::getText(this, tr("Enter parameters"),
tr("Enter (optional) parameters separated by single space to send to executable when opening URLs."),
QLineEdit::Normal, QString(), &ok);
if (ok) {
QTreeWidgetItem* item = new QTreeWidgetItem(m_ui->m_listTools,
QStringList() << QDir::toNativeSeparators(executable_file) << parameters);
item->setData(0, Qt::UserRole, QVariant::fromValue(ExternalTool(executable_file, parameters.split(QSL(" ")))));
m_ui->m_listTools->addTopLevelItem(item);
}
}
}
void SettingsBrowserMail::deleteSelectedExternalTool() {
if (m_ui->m_listTools->currentRow() >= 0) {
m_ui->m_listTools->takeItem(m_ui->m_listTools->currentRow());
if (!m_ui->m_listTools->selectedItems().isEmpty()) {
m_ui->m_listTools->takeTopLevelItem(m_ui->m_listTools->indexOfTopLevelItem(m_ui->m_listTools->selectedItems().first()));
}
}

View File

@ -20,6 +20,7 @@
#include "gui/settings/settingspanel.h"
#include "miscellaneous/externaltool.h"
#include "ui_settingsbrowsermail.h"
@ -34,7 +35,7 @@ class SettingsBrowserMail : public SettingsPanel {
return tr("Web browser & e-mail & proxy");
}
void loadSettings();
void loadSettings();
void saveSettings();
private slots:
@ -48,8 +49,8 @@ class SettingsBrowserMail : public SettingsPanel {
void onProxyTypeChanged(int index);
private:
QStringList externalTools() const;
void setExternalTools(const QStringList& list);
QList<ExternalTool> externalTools() const;
void setExternalTools(const QList<ExternalTool>& list);
Ui::SettingsBrowserMail* m_ui;
};

View File

@ -262,16 +262,30 @@
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QListWidget" name="m_listTools">
<widget class="QTreeWidget" name="m_listTools">
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="uniformItemSizes">
<property name="indentation">
<number>0</number>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
</layout>
@ -428,6 +442,29 @@
</item>
</layout>
</widget>
<tabstops>
<tabstop>m_txtProxyPassword</tabstop>
<tabstop>m_checkShowPassword</tabstop>
<tabstop>m_tabBrowserProxy</tabstop>
<tabstop>m_checkOpenLinksInExternal</tabstop>
<tabstop>m_grpCustomExternalBrowser</tabstop>
<tabstop>m_txtExternalBrowserExecutable</tabstop>
<tabstop>m_btnExternalBrowserExecutable</tabstop>
<tabstop>m_txtExternalBrowserArguments</tabstop>
<tabstop>m_cmbExternalBrowserPreset</tabstop>
<tabstop>m_grpCustomExternalEmail</tabstop>
<tabstop>m_txtExternalEmailExecutable</tabstop>
<tabstop>m_btnExternalEmailExecutable</tabstop>
<tabstop>m_txtExternalEmailArguments</tabstop>
<tabstop>m_cmbExternalEmailPreset</tabstop>
<tabstop>m_listTools</tabstop>
<tabstop>m_btnAddTool</tabstop>
<tabstop>m_btnDeleteTool</tabstop>
<tabstop>m_cmbProxyType</tabstop>
<tabstop>m_txtProxyHost</tabstop>
<tabstop>m_spinProxyPort</tabstop>
<tabstop>m_txtProxyUsername</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -26,6 +26,7 @@
ToolBarEditor::ToolBarEditor(QWidget* parent)
: QWidget(parent), m_ui(new Ui::ToolBarEditor) {
m_ui->setupUi(this);
// Create connections.
connect(m_ui->m_btnInsertSeparator, &QToolButton::clicked, this, &ToolBarEditor::insertSeparator);
connect(m_ui->m_btnInsertSpacer, &QToolButton::clicked, this, &ToolBarEditor::insertSpacer);
@ -56,6 +57,7 @@ ToolBarEditor::~ToolBarEditor() {
void ToolBarEditor::loadFromToolBar(BaseBar* tool_bar) {
m_toolBar = tool_bar;
QList<QAction*> activated_actions = m_toolBar->changeableActions();
QList<QAction*> available_actions = m_toolBar->availableActions();
loadEditor(activated_actions, available_actions);

View File

@ -0,0 +1,91 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
//
// RSS Guard is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// RSS Guard is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
#include "miscellaneous/externaltool.h"
#include "definitions/definitions.h"
#include "miscellaneous/application.h"
#include "exceptions/applicationexception.h"
#include <QObject>
#include <QDir>
void ExternalTool::sanitizeParameters() {
m_executable = QDir::toNativeSeparators(m_executable);
m_parameters.removeDuplicates();
m_parameters.removeAll(QString());
}
ExternalTool::ExternalTool() {
}
ExternalTool::ExternalTool(const ExternalTool& other) : ExternalTool(other.executable(), other.parameters()) {
}
ExternalTool::ExternalTool(const QString& executable, const QStringList& parameters)
: m_executable(executable), m_parameters(parameters) {
sanitizeParameters();
}
QString ExternalTool::toString() {
sanitizeParameters();
return m_executable + EXTERNAL_TOOL_SEPARATOR + m_parameters.join(EXTERNAL_TOOL_PARAM_SEPARATOR);
}
QString ExternalTool::executable() const {
return m_executable;
}
QStringList ExternalTool::parameters() const {
return m_parameters;
}
ExternalTool ExternalTool::fromString(const QString& str) {
QStringList outer = str.split(EXTERNAL_TOOL_SEPARATOR);
if (outer.size() != 2) {
throw ApplicationException(QObject::tr("Passed external tool representation is not valid."));
}
else {
const QString executable = outer.at(0);
const QStringList parameters = outer.at(1).split(EXTERNAL_TOOL_PARAM_SEPARATOR);
return ExternalTool(executable, parameters);
}
}
QList<ExternalTool> ExternalTool::toolsFromSettings() {
QStringList tools_encoded = qApp->settings()->value(GROUP(Browser), SETTING(Browser::ExternalTools)).toStringList();
QList<ExternalTool> tools;
foreach (const QString& tool_encoded, tools_encoded) {
tools.append(ExternalTool::fromString(tool_encoded));
}
return tools;
}
void ExternalTool::setToolsToSettings(QList<ExternalTool>& tools) {
QStringList encode;
foreach (ExternalTool tool, tools) {
encode.append(tool.toString());
}
qApp->settings()->setValue(GROUP(Browser), Browser::ExternalTools, encode);
}

View File

@ -0,0 +1,47 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
//
// RSS Guard is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// RSS Guard is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
#ifndef EXTERNALTOOL_H
#define EXTERNALTOOL_H
#include <QStringList>
#include <QMetaType>
class ExternalTool {
public:
explicit ExternalTool();
ExternalTool(const ExternalTool& other);
explicit ExternalTool(const QString& executable, const QStringList& parameters);
QString toString();
QString executable() const;
QStringList parameters() const;
static ExternalTool fromString(const QString& str);
static QList<ExternalTool> toolsFromSettings();
static void setToolsToSettings(QList<ExternalTool>& tools);
private:
QString m_executable;
QStringList m_parameters;
void sanitizeParameters();
};
Q_DECLARE_METATYPE(ExternalTool)
#endif // EXTERNALTOOL_H