Work on GUI for filters.

This commit is contained in:
Martin Rotter 2020-07-03 11:52:21 +02:00
parent c608210e3c
commit 8862b70638
6 changed files with 128 additions and 24 deletions

View File

@ -175,7 +175,7 @@ win32 {
lib.path = $$PREFIX lib.path = $$PREFIX
lib.CONFIG = no_check_exist lib.CONFIG = no_check_exist
clng.files = ../../resources/scripts/clang-format/clang-format.exe clng.files = ../../resources/scripts/clang-format
clng.path = $$PREFIX clng.path = $$PREFIX
INSTALLS += target lib clng INSTALLS += target lib clng

View File

@ -1,5 +1,6 @@
#include <QDateTime> #include <QDateTime>
#include <QJSEngine> #include <QJSEngine>
#include <QProcess>
// For license of this file, see <project-root-folder>/LICENSE.md. // For license of this file, see <project-root-folder>/LICENSE.md.
@ -8,6 +9,7 @@
#include "core/messagefilter.h" #include "core/messagefilter.h"
#include "exceptions/filteringexception.h" #include "exceptions/filteringexception.h"
#include "gui/guiutilities.h" #include "gui/guiutilities.h"
#include "gui/messagebox.h"
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
#include "miscellaneous/feedreader.h" #include "miscellaneous/feedreader.h"
#include "miscellaneous/iconfactory.h" #include "miscellaneous/iconfactory.h"
@ -21,8 +23,10 @@ FormMessageFiltersManager::FormMessageFiltersManager(FeedReader* reader, const Q
GuiUtilities::applyDialogProperties(*this, qApp->icons()->fromTheme(QSL("view-list-details"))); GuiUtilities::applyDialogProperties(*this, qApp->icons()->fromTheme(QSL("view-list-details")));
m_ui.m_treeFeeds->setModel(m_feedsModel);
m_ui.m_btnAddNew->setIcon(qApp->icons()->fromTheme(QSL("list-add"))); m_ui.m_btnAddNew->setIcon(qApp->icons()->fromTheme(QSL("list-add")));
m_ui.m_btnRemoveSelected->setIcon(qApp->icons()->fromTheme(QSL("list-remove"))); m_ui.m_btnRemoveSelected->setIcon(qApp->icons()->fromTheme(QSL("list-remove")));
m_ui.m_btnBeautify->setIcon(qApp->icons()->fromTheme(QSL("format-justify-fill")));
m_ui.m_btnTest->setIcon(qApp->icons()->fromTheme(QSL("media-playback-start"))); m_ui.m_btnTest->setIcon(qApp->icons()->fromTheme(QSL("media-playback-start")));
m_ui.m_btnDetailedHelp->setIcon(qApp->icons()->fromTheme(QSL("help-contents"))); m_ui.m_btnDetailedHelp->setIcon(qApp->icons()->fromTheme(QSL("help-contents")));
m_ui.m_txtScript->setFont(QFontDatabase::systemFont(QFontDatabase::SystemFont::FixedFont)); m_ui.m_txtScript->setFont(QFontDatabase::systemFont(QFontDatabase::SystemFont::FixedFont));
@ -37,9 +41,16 @@ FormMessageFiltersManager::FormMessageFiltersManager(FeedReader* reader, const Q
connect(m_ui.m_txtTitle, &QLineEdit::textChanged, this, &FormMessageFiltersManager::saveSelectedFilter); connect(m_ui.m_txtTitle, &QLineEdit::textChanged, this, &FormMessageFiltersManager::saveSelectedFilter);
connect(m_ui.m_txtScript, &QPlainTextEdit::textChanged, this, &FormMessageFiltersManager::saveSelectedFilter); connect(m_ui.m_txtScript, &QPlainTextEdit::textChanged, this, &FormMessageFiltersManager::saveSelectedFilter);
connect(m_ui.m_btnTest, &QPushButton::clicked, this, &FormMessageFiltersManager::testFilter); connect(m_ui.m_btnTest, &QPushButton::clicked, this, &FormMessageFiltersManager::testFilter);
connect(m_ui.m_btnBeautify, &QPushButton::clicked, this, &FormMessageFiltersManager::beautifyScript);
connect(m_ui.m_cmbAccounts, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [this]() {
// Load feeds/categories of the account and check marks.
loadSelectedAccount();
loadFilterFeedAssignments();
});
initializeTestingMessage(); initializeTestingMessage();
loadFilter(); loadFilter();
loadAccounts();
} }
FormMessageFiltersManager::~FormMessageFiltersManager() { FormMessageFiltersManager::~FormMessageFiltersManager() {
@ -56,7 +67,9 @@ MessageFilter* FormMessageFiltersManager::selectedFilter() const {
} }
ServiceRoot* FormMessageFiltersManager::selectedAccount() const { ServiceRoot* FormMessageFiltersManager::selectedAccount() const {
return nullptr; auto dat = m_ui.m_cmbAccounts->currentData(Qt::ItemDataRole::UserRole);
return dat.isNull() ? nullptr : dat.value<ServiceRoot*>();
} }
void FormMessageFiltersManager::addNewFilter() { void FormMessageFiltersManager::addNewFilter() {
@ -93,16 +106,9 @@ void FormMessageFiltersManager::loadFilter() {
auto* acc = selectedAccount(); auto* acc = selectedAccount();
showFilter(filter); showFilter(filter);
updateFeedAssignments(filter, acc);
} }
void FormMessageFiltersManager::testFilter() { void FormMessageFiltersManager::testFilter() {
// TODO: Add button to beautify JavaScript code, call clang-format and distribute
// it under windows. On other platforms, just try to call and raise messagebox
// error with "install clang-format" if not found.
// then call like this with qt process api.
// echo "script-code" | ./clang-format.exe --assume-filename="script.js" --style="Chromium"
// Perform per-message filtering. // Perform per-message filtering.
QJSEngine filter_engine; QJSEngine filter_engine;
QSqlDatabase database = qApp->database()->connection(metaObject()->className()); QSqlDatabase database = qApp->database()->connection(metaObject()->className());
@ -127,9 +133,9 @@ void FormMessageFiltersManager::testFilter() {
m_ui.m_txtErrors->setTextColor(decision == FilteringAction::Accept ? Qt::GlobalColor::darkGreen : Qt::GlobalColor::red); m_ui.m_txtErrors->setTextColor(decision == FilteringAction::Accept ? Qt::GlobalColor::darkGreen : Qt::GlobalColor::red);
QString answer = tr("Message will be %1.\n").arg(decision == FilteringAction::Accept QString answer = tr("Message will be %1.\n\n").arg(decision == FilteringAction::Accept
? tr("accepted") ? tr("ACCEPTED")
: tr("rejected")); : tr("REJECTED"));
answer += tr("Output (modified) message is:\n" answer += tr("Output (modified) message is:\n"
" Title = '%1'\n" " Title = '%1'\n"
@ -154,6 +160,13 @@ void FormMessageFiltersManager::testFilter() {
m_ui.m_tcMessage->setCurrentIndex(1); m_ui.m_tcMessage->setCurrentIndex(1);
} }
void FormMessageFiltersManager::loadSelectedAccount() {
m_feedsModel->setRootItem(selectedAccount(), false, true);
m_ui.m_treeFeeds->expandAll();
}
void FormMessageFiltersManager::loadFilterFeedAssignments() {}
void FormMessageFiltersManager::showFilter(MessageFilter* filter) { void FormMessageFiltersManager::showFilter(MessageFilter* filter) {
m_loadingFilter = true; m_loadingFilter = true;
@ -173,7 +186,61 @@ void FormMessageFiltersManager::showFilter(MessageFilter* filter) {
m_loadingFilter = false; m_loadingFilter = false;
} }
void FormMessageFiltersManager::updateFeedAssignments(MessageFilter* filter, ServiceRoot* account) {} void FormMessageFiltersManager::loadAccounts() {
for (auto* acc : m_accounts) {
m_ui.m_cmbAccounts->addItem(acc->icon(),
acc->title(),
QVariant::fromValue(acc));
}
}
void FormMessageFiltersManager::beautifyScript() {
QProcess proc_clang_format(this);
proc_clang_format.setInputChannelMode(QProcess::InputChannelMode::ManagedInputChannel);
proc_clang_format.setArguments({"--assume-filename=script.js", "--style=Chromium"});
#if defined (Q_OS_WIN)
proc_clang_format.setProgram(qApp->applicationDirPath() + QDir::separator() +
QSL("clang-format") + QDir::separator() +
QSL("clang-format.exe"));
#else
proc_clang_format.setProgram(QSL("clang-format"));
#endif
if (!proc_clang_format.open()) {
MessageBox::show(this, QMessageBox::Icon::Critical,
tr("Cannot find 'clang-format'"),
tr("Script was not beautified, because 'clang-format' tool was not found."));
return;
}
proc_clang_format.write(m_ui.m_txtScript->toPlainText().toUtf8());
proc_clang_format.closeWriteChannel();
if (proc_clang_format.waitForFinished(3000)) {
if (proc_clang_format.exitCode() == 0) {
auto script = proc_clang_format.readAllStandardOutput();
m_ui.m_txtScript->setPlainText(script);
}
else {
auto err = proc_clang_format.readAllStandardError();
MessageBox::show(this, QMessageBox::Icon::Critical,
tr("Error"),
tr("Script was not beautified, because 'clang-format' tool thrown error."),
QString(),
err);
}
}
else {
proc_clang_format.kill();
MessageBox::show(this, QMessageBox::Icon::Critical,
tr("Beautifier was running for too long time"),
tr("Script was not beautified, is 'clang-format' installed?"));
}
}
void FormMessageFiltersManager::initializeTestingMessage() { void FormMessageFiltersManager::initializeTestingMessage() {
m_ui.m_cbSampleImportant->setChecked(true); m_ui.m_cbSampleImportant->setChecked(true);

View File

@ -29,13 +29,18 @@ class FormMessageFiltersManager : public QDialog {
void loadFilter(); void loadFilter();
void testFilter(); void testFilter();
// Load feeds/categories tree.
void loadSelectedAccount();
// Load checkmarks according to already active assignments.
void loadFilterFeedAssignments();
// Display filter title/contents. // Display filter title/contents.
void showFilter(MessageFilter* filter); void showFilter(MessageFilter* filter);
// Load feeds/categories of the account, place checkmarks where filter is used.
void updateFeedAssignments(MessageFilter* filter, ServiceRoot* account);
private: private:
void loadAccounts();
void beautifyScript();
void initializeTestingMessage(); void initializeTestingMessage();
Message testingMessage() const; Message testingMessage() const;

View File

@ -44,7 +44,11 @@
</spacer> </spacer>
</item> </item>
<item row="0" column="0" colspan="3"> <item row="0" column="0" colspan="3">
<widget class="QListWidget" name="m_listFilters"/> <widget class="QListWidget" name="m_listFilters">
<property name="uniformItemSizes">
<bool>true</bool>
</property>
</widget>
</item> </item>
</layout> </layout>
</item> </item>
@ -56,12 +60,12 @@
<string>Account</string> <string>Account</string>
</property> </property>
<property name="buddy"> <property name="buddy">
<cstring>comboBox</cstring> <cstring>m_cmbAccounts</cstring>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QComboBox" name="comboBox"/> <widget class="QComboBox" name="m_cmbAccounts"/>
</item> </item>
<item row="1" column="0" colspan="2"> <item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_5"> <layout class="QHBoxLayout" name="horizontalLayout_5">
@ -73,6 +77,12 @@
<height>150</height> <height>150</height>
</size> </size>
</property> </property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget> </widget>
</item> </item>
<item> <item>
@ -339,7 +349,14 @@
<item> <item>
<widget class="QPushButton" name="m_btnTest"> <widget class="QPushButton" name="m_btnTest">
<property name="text"> <property name="text">
<string>&amp;Test the script</string> <string>&amp;Test!</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_btnBeautify">
<property name="text">
<string>&amp;Beautify!</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -387,13 +404,14 @@
<tabstop>m_listFilters</tabstop> <tabstop>m_listFilters</tabstop>
<tabstop>m_btnAddNew</tabstop> <tabstop>m_btnAddNew</tabstop>
<tabstop>m_btnRemoveSelected</tabstop> <tabstop>m_btnRemoveSelected</tabstop>
<tabstop>comboBox</tabstop> <tabstop>m_cmbAccounts</tabstop>
<tabstop>m_treeFeeds</tabstop> <tabstop>m_treeFeeds</tabstop>
<tabstop>pushButton</tabstop> <tabstop>pushButton</tabstop>
<tabstop>pushButton_2</tabstop> <tabstop>pushButton_2</tabstop>
<tabstop>m_txtTitle</tabstop> <tabstop>m_txtTitle</tabstop>
<tabstop>m_txtScript</tabstop> <tabstop>m_txtScript</tabstop>
<tabstop>m_btnTest</tabstop> <tabstop>m_btnTest</tabstop>
<tabstop>m_btnBeautify</tabstop>
<tabstop>m_btnDetailedHelp</tabstop> <tabstop>m_btnDetailedHelp</tabstop>
<tabstop>m_tcMessage</tabstop> <tabstop>m_tcMessage</tabstop>
<tabstop>m_cbSampleRead</tabstop> <tabstop>m_cbSampleRead</tabstop>

View File

@ -24,9 +24,20 @@ RootItem* AccountCheckModel::rootItem() const {
return m_rootItem; return m_rootItem;
} }
void AccountCheckModel::setRootItem(RootItem* root_item) { void AccountCheckModel::setRootItem(RootItem* root_item, bool delete_previous_root, bool with_layout_change) {
delete m_rootItem; if (with_layout_change) {
emit layoutAboutToBeChanged();
}
if (delete_previous_root && m_rootItem != nullptr) {
m_rootItem->deleteLater();
}
m_rootItem = root_item; m_rootItem = root_item;
if (with_layout_change) {
emit layoutChanged();
}
} }
void AccountCheckModel::checkAllItems() { void AccountCheckModel::checkAllItems() {
@ -163,6 +174,9 @@ QVariant AccountCheckModel::data(const QModelIndex& index, int role) const {
return ic.isNull() ? QVariant() : ic; return ic.isNull() ? QVariant() : ic;
} }
else if (role == Qt::EditRole) {
return QVariant::fromValue(item);
}
else if (role == Qt::DisplayRole) { else if (role == Qt::DisplayRole) {
switch (item->kind()) { switch (item->kind()) {
case RootItemKind::Category: case RootItemKind::Category:

View File

@ -37,7 +37,7 @@ class AccountCheckModel : public QAbstractItemModel {
// Root item manipulators. // Root item manipulators.
RootItem* rootItem() const; RootItem* rootItem() const;
void setRootItem(RootItem* root_item); void setRootItem(RootItem* root_item, bool delete_previous_root = true, bool with_layout_change = false);
public slots: public slots:
void checkAllItems(); void checkAllItems();