From af39ec163d703852a8fa49dbf79c0ef694aa2e76 Mon Sep 17 00:00:00 2001 From: Janne Koschinski Date: Fri, 1 Sep 2017 05:11:45 +0200 Subject: [PATCH] Implement UI for core-side highlights --- src/client/client.cpp | 10 + src/client/client.h | 3 + src/common/highlightrulemanager.cpp | 6 + src/common/highlightrulemanager.h | 4 + src/qtui/mainwin.cpp | 2 + .../corehighlightsettingspage.cpp | 295 ++++++++++++++++++ .../settingspages/corehighlightsettingspage.h | 73 +++++ .../corehighlightsettingspage.ui | 162 ++++++++++ src/qtui/settingspages/settingspages.cmake | 1 + 9 files changed, 556 insertions(+) create mode 100644 src/qtui/settingspages/corehighlightsettingspage.cpp create mode 100644 src/qtui/settingspages/corehighlightsettingspage.h create mode 100644 src/qtui/settingspages/corehighlightsettingspage.ui diff --git a/src/client/client.cpp b/src/client/client.cpp index e89f907d..f5fb6bfd 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -420,6 +420,11 @@ void Client::setSyncedToCore() _ignoreListManager = new ClientIgnoreListManager(this); p->synchronize(ignoreListManager()); + // create Core-Side HighlightRuleManager + Q_ASSERT(!_highlightRuleManager); + _highlightRuleManager = new HighlightRuleManager(this); + p->synchronize(highlightRuleManager()); + // create TransferManager and DccConfig if core supports them Q_ASSERT(!_dccConfig); Q_ASSERT(!_transferManager); @@ -508,6 +513,11 @@ void Client::setDisconnectedFromCore() _ignoreListManager = 0; } + if (_highlightRuleManager) { + _highlightRuleManager->deleteLater(); + _highlightRuleManager = nullptr; + } + if (_transferManager) { _transferModel->setManager(nullptr); _transferManager->deleteLater(); diff --git a/src/client/client.h b/src/client/client.h index 4b83d909..6f261f57 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -23,6 +23,7 @@ #include #include +#include #include "bufferinfo.h" #include "coreaccount.h" @@ -122,6 +123,7 @@ public: static inline ClientUserInputHandler *inputHandler() { return instance()->_inputHandler; } static inline NetworkConfig *networkConfig() { return instance()->_networkConfig; } static inline ClientIgnoreListManager *ignoreListManager() { return instance()->_ignoreListManager; } + static inline HighlightRuleManager *highlightRuleManager() { return instance()->_highlightRuleManager; } static inline ClientTransferManager *transferManager() { return instance()->_transferManager; } static inline TransferModel *transferModel() { return instance()->_transferModel; } @@ -260,6 +262,7 @@ private: ClientUserInputHandler *_inputHandler; NetworkConfig *_networkConfig; ClientIgnoreListManager *_ignoreListManager; + HighlightRuleManager *_highlightRuleManager; ClientTransferManager *_transferManager; TransferModel *_transferModel; diff --git a/src/common/highlightrulemanager.cpp b/src/common/highlightrulemanager.cpp index 9f780f51..d18d8d63 100644 --- a/src/common/highlightrulemanager.cpp +++ b/src/common/highlightrulemanager.cpp @@ -33,6 +33,8 @@ HighlightRuleManager &HighlightRuleManager::operator=(const HighlightRuleManager SyncableObject::operator=(other); _highlightRuleList = other._highlightRuleList; + _nicksCaseSensitive = other._nicksCaseSensitive; + _highlightNick = other._highlightNick; return *this; } @@ -69,6 +71,8 @@ QVariantMap HighlightRuleManager::initHighlightRuleList() const highlightRuleListMap["isCaseSensitive"] = isCaseSensitive; highlightRuleListMap["isEnabled"] = isActive; highlightRuleListMap["channel"] = channel; + highlightRuleListMap["highlightNick"] = _highlightNick; + highlightRuleListMap["nicksCaseSensitive"] = _nicksCaseSensitive; return highlightRuleListMap; } @@ -93,6 +97,8 @@ void HighlightRuleManager::initSetHighlightRuleList(const QVariantMap &highlight _highlightRuleList << HighlightRule(name[i], isRegEx[i].toBool(), isCaseSensitive[i].toBool(), isActive[i].toBool(), channel[i]); } + _highlightNick = HighlightNickType(highlightRuleList["highlightNick"].toInt()); + _nicksCaseSensitive = highlightRuleList["nicksCaseSensitive"].toBool(); } void HighlightRuleManager::addHighlightRule(const QString &name, bool isRegEx, bool isCaseSensitive, bool isActive, diff --git a/src/common/highlightrulemanager.h b/src/common/highlightrulemanager.h index 02b1a223..5799e480 100644 --- a/src/common/highlightrulemanager.h +++ b/src/common/highlightrulemanager.h @@ -68,10 +68,14 @@ public: inline bool isEmpty() const { return _highlightRuleList.isEmpty(); } inline int count() const { return _highlightRuleList.count(); } inline void removeAt(int index) { _highlightRuleList.removeAt(index); } + inline void clear() { _highlightRuleList.clear(); } inline HighlightRule &operator[](int i) { return _highlightRuleList[i]; } inline const HighlightRule &operator[](int i) const { return _highlightRuleList.at(i); } inline const HighlightRuleList &highlightRuleList() const { return _highlightRuleList; } + inline HighlightNickType highlightNick() { return _highlightNick; } + inline bool nicksCaseSensitive() { return _nicksCaseSensitive; } + //! Check if a message matches the HighlightRule /** This method checks if a message matches the users highlight rules. * \param msg The Message that should be checked diff --git a/src/qtui/mainwin.cpp b/src/qtui/mainwin.cpp index 4495bfeb..d9c7cc36 100644 --- a/src/qtui/mainwin.cpp +++ b/src/qtui/mainwin.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #ifdef HAVE_KDE4 # include @@ -1442,6 +1443,7 @@ void MainWin::showSettingsDlg() dlg->registerSettingsPage(new SonnetSettingsPage(dlg)); #endif dlg->registerSettingsPage(new HighlightSettingsPage(dlg)); + dlg->registerSettingsPage(new CoreHighlightSettingsPage(dlg)); dlg->registerSettingsPage(new NotificationsSettingsPage(dlg)); dlg->registerSettingsPage(new BacklogSettingsPage(dlg)); diff --git a/src/qtui/settingspages/corehighlightsettingspage.cpp b/src/qtui/settingspages/corehighlightsettingspage.cpp new file mode 100644 index 00000000..bad2400a --- /dev/null +++ b/src/qtui/settingspages/corehighlightsettingspage.cpp @@ -0,0 +1,295 @@ +/*************************************************************************** + * Copyright (C) 2005-2016 by the Quassel Project * + * devel@quassel-irc.org * + * * + * This program 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 2 of the License, or * + * (at your option) version 3. * + * * + * This program 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 this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "corehighlightsettingspage.h" + +#include "qtui.h" +#include "uisettings.h" + +#include +#include + +CoreHighlightSettingsPage::CoreHighlightSettingsPage(QWidget *parent) + : SettingsPage(tr("Interface"), tr("Core-Side Highlights"), parent) +{ + ui.setupUi(this); + ui.highlightTable->verticalHeader()->hide(); + ui.highlightTable->setShowGrid(false); + + ui.highlightTable->horizontalHeaderItem(CoreHighlightSettingsPage::RegExColumn)->setToolTip("RegEx: This option determines if the highlight rule should be interpreted as a regular expression or just as a keyword."); + ui.highlightTable->horizontalHeaderItem(CoreHighlightSettingsPage::RegExColumn)->setWhatsThis("RegEx: This option determines if the highlight rule should be interpreted as a regular expression or just as a keyword."); + + ui.highlightTable->horizontalHeaderItem(CoreHighlightSettingsPage::CsColumn)->setToolTip("CS: This option determines if the highlight rule should be interpreted case sensitive."); + ui.highlightTable->horizontalHeaderItem(CoreHighlightSettingsPage::CsColumn)->setWhatsThis("CS: This option determines if the highlight rule should be interpreted case sensitive."); + + ui.highlightTable->horizontalHeaderItem(CoreHighlightSettingsPage::ChanColumn)->setToolTip("Channel: This regular expression determines for which channels the highlight rule works. Leave blank to match any channel. Put ! in the beginning to negate. Case insensitive."); + ui.highlightTable->horizontalHeaderItem(CoreHighlightSettingsPage::ChanColumn)->setWhatsThis("Channel: This regular expression determines for which channels the highlight rule works. Leave blank to match any channel. Put ! in the beginning to negate. Case insensitive."); + +#if QT_VERSION < 0x050000 + ui.highlightTable->horizontalHeader()->setResizeMode(CoreHighlightSettingsPage::NameColumn, QHeaderView::Stretch); + ui.highlightTable->horizontalHeader()->setResizeMode(CoreHighlightSettingsPage::RegExColumn, QHeaderView::ResizeToContents); + ui.highlightTable->horizontalHeader()->setResizeMode(CoreHighlightSettingsPage::CsColumn, QHeaderView::ResizeToContents); + ui.highlightTable->horizontalHeader()->setResizeMode(CoreHighlightSettingsPage::EnableColumn, QHeaderView::ResizeToContents); + ui.highlightTable->horizontalHeader()->setResizeMode(CoreHighlightSettingsPage::ChanColumn, QHeaderView::ResizeToContents); +#else + ui.highlightTable->horizontalHeader()->setSectionResizeMode(CoreHighlightSettingsPage::NameColumn, QHeaderView::Stretch); + ui.highlightTable->horizontalHeader()->setSectionResizeMode(CoreHighlightSettingsPage::RegExColumn, QHeaderView::ResizeToContents); + ui.highlightTable->horizontalHeader()->setSectionResizeMode(CoreHighlightSettingsPage::CsColumn, QHeaderView::ResizeToContents); + ui.highlightTable->horizontalHeader()->setSectionResizeMode(CoreHighlightSettingsPage::EnableColumn, QHeaderView::ResizeToContents); + ui.highlightTable->horizontalHeader()->setSectionResizeMode(CoreHighlightSettingsPage::ChanColumn, QHeaderView::ResizeToContents); +#endif + + connect(ui.add, SIGNAL(clicked(bool)), this, SLOT(addNewRow())); + connect(ui.remove, SIGNAL(clicked(bool)), this, SLOT(removeSelectedRows())); + //TODO: search for a better signal (one that emits everytime a selection has been changed for one item) + connect(ui.highlightTable, SIGNAL(itemClicked(QTableWidgetItem *)), this, SLOT(selectRow(QTableWidgetItem *))); + + connect(ui.highlightAllNicks, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); + connect(ui.highlightCurrentNick, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); + connect(ui.highlightNoNick, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); + connect(ui.nicksCaseSensitive, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); + connect(ui.add, SIGNAL(clicked()), this, SLOT(widgetHasChanged())); + connect(ui.remove, SIGNAL(clicked()), this, SLOT(widgetHasChanged())); + connect(ui.highlightTable, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(tableChanged(QTableWidgetItem *))); + + connect(Client::instance(), SIGNAL(connected()), this, SLOT(clientConnected())); +} + +void CoreHighlightSettingsPage::clientConnected() +{ + connect(Client::highlightRuleManager(), SIGNAL(updated()), SLOT(revert())); +} + + +void CoreHighlightSettingsPage::revert() +{ + qWarning() << "revert()"; + + if (!hasChanged()) + return; + + setChangedState(false); + load(); +} + + +bool CoreHighlightSettingsPage::hasDefaults() const +{ + return true; +} + + +void CoreHighlightSettingsPage::defaults() +{ + ui.highlightCurrentNick->setChecked(true); + ui.nicksCaseSensitive->setChecked(false); + emptyTable(); + + widgetHasChanged(); +} + + +void CoreHighlightSettingsPage::addNewRow(QString name, bool regex, bool cs, bool enable, QString chanName, bool self) +{ + ui.highlightTable->setRowCount(ui.highlightTable->rowCount()+1); + + auto *nameItem = new QTableWidgetItem(name); + + auto *regexItem = new QTableWidgetItem(""); + if (regex) + regexItem->setCheckState(Qt::Checked); + else + regexItem->setCheckState(Qt::Unchecked); + regexItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable); + + auto *csItem = new QTableWidgetItem(""); + if (cs) + csItem->setCheckState(Qt::Checked); + else + csItem->setCheckState(Qt::Unchecked); + csItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable); + + auto *enableItem = new QTableWidgetItem(""); + if (enable) + enableItem->setCheckState(Qt::Checked); + else + enableItem->setCheckState(Qt::Unchecked); + enableItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable); + + auto *chanNameItem = new QTableWidgetItem(chanName); + + int lastRow = ui.highlightTable->rowCount()-1; + ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::NameColumn, nameItem); + ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::RegExColumn, regexItem); + ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::CsColumn, csItem); + ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::EnableColumn, enableItem); + ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::ChanColumn, chanNameItem); + + if (!self) + ui.highlightTable->setCurrentItem(nameItem); + + highlightList << HighlightRuleManager::HighlightRule(name, regex, cs, enable, chanName); +} + + +void CoreHighlightSettingsPage::removeSelectedRows() +{ + QList selectedRows; + QList selectedItemList = ui.highlightTable->selectedItems(); + foreach(QTableWidgetItem *selectedItem, selectedItemList) { + selectedRows.append(selectedItem->row()); + } + qSort(selectedRows.begin(), selectedRows.end(), qGreater()); + int lastRow = -1; + foreach(int row, selectedRows) { + if (row != lastRow) { + ui.highlightTable->removeRow(row); + highlightList.removeAt(row); + } + lastRow = row; + } +} + + +void CoreHighlightSettingsPage::selectRow(QTableWidgetItem *item) +{ + int row = item->row(); + bool selected = item->isSelected(); + ui.highlightTable->setRangeSelected(QTableWidgetSelectionRange(row, 0, row, CoreHighlightSettingsPage::ColumnCount-1), selected); +} + + +void CoreHighlightSettingsPage::emptyTable() +{ + // ui.highlight and highlightList should have the same size, but just to make sure. + if (ui.highlightTable->rowCount() != highlightList.size()) { + qDebug() << "something is wrong: ui.highlight and highlightList don't have the same size!"; + } + while (ui.highlightTable->rowCount()) { + ui.highlightTable->removeRow(0); + } + while (highlightList.size()) { + highlightList.removeLast(); + } +} + + +void CoreHighlightSettingsPage::tableChanged(QTableWidgetItem *item) +{ + if (item->row()+1 > highlightList.size()) + return; + + auto highlightRule = highlightList.value(item->row()); + + + switch (item->column()) + { + case CoreHighlightSettingsPage::NameColumn: + if (item->text() == "") + item->setText(tr("this shouldn't be empty")); + highlightRule.name = item->text(); + break; + case CoreHighlightSettingsPage::RegExColumn: + highlightRule.isRegEx = (item->checkState() == Qt::Checked); + break; + case CoreHighlightSettingsPage::CsColumn: + highlightRule.isCaseSensitive = (item->checkState() == Qt::Checked); + break; + case CoreHighlightSettingsPage::EnableColumn: + highlightRule.isEnabled = (item->checkState() == Qt::Checked); + break; + case CoreHighlightSettingsPage::ChanColumn: + if (!item->text().isEmpty() && item->text().trimmed().isEmpty()) + item->setText(""); + highlightRule.chanName = item->text(); + break; + } + highlightList[item->row()] = highlightRule; + emit widgetHasChanged(); +} + + +void CoreHighlightSettingsPage::load() +{ + emptyTable(); + + auto ruleManager = Client::highlightRuleManager(); + for (HighlightRuleManager::HighlightRule rule : ruleManager->highlightRuleList()) { + addNewRow(rule.name, rule.isRegEx, rule.isCaseSensitive, rule.isEnabled, rule.chanName); + } + + switch (ruleManager->highlightNick()) + { + case HighlightRuleManager::NoNick: + ui.highlightNoNick->setChecked(true); + break; + case HighlightRuleManager::CurrentNick: + ui.highlightCurrentNick->setChecked(true); + break; + case HighlightRuleManager::AllNicks: + ui.highlightAllNicks->setChecked(true); + break; + } + ui.nicksCaseSensitive->setChecked(ruleManager->nicksCaseSensitive()); + + setChangedState(false); + _initialized = true; +} + +void CoreHighlightSettingsPage::save() +{ + if (!hasChanged()) + return; + + if (!_initialized) + return; + + auto ruleManager = Client::highlightRuleManager(); + if (ruleManager == nullptr) + return; + + auto clonedManager = HighlightRuleManager(); + clonedManager.fromVariantMap(ruleManager->toVariantMap()); + clonedManager.clear(); + + for (const HighlightRuleManager::HighlightRule &rule : highlightList) { + clonedManager.addHighlightRule(rule.name, rule.isRegEx, rule.isCaseSensitive, rule.isRegEx, rule.chanName); + } + + HighlightRuleManager::HighlightNickType highlightNickType = HighlightRuleManager::NoNick; + if (ui.highlightCurrentNick->isChecked()) + highlightNickType = HighlightRuleManager::CurrentNick; + if (ui.highlightAllNicks->isChecked()) + highlightNickType = HighlightRuleManager::AllNicks; + + + clonedManager.setHighlightNick(highlightNickType); + clonedManager.setNicksCaseSensitive(ui.nicksCaseSensitive->isChecked()); + + ruleManager->requestUpdate(clonedManager.toVariantMap()); + setChangedState(false); + load(); +} + + +void CoreHighlightSettingsPage::widgetHasChanged() +{ + setChangedState(true); +} \ No newline at end of file diff --git a/src/qtui/settingspages/corehighlightsettingspage.h b/src/qtui/settingspages/corehighlightsettingspage.h new file mode 100644 index 00000000..a411662e --- /dev/null +++ b/src/qtui/settingspages/corehighlightsettingspage.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2005-2016 by the Quassel Project * + * devel@quassel-irc.org * + * * + * This program 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 2 of the License, or * + * (at your option) version 3. * + * * + * This program 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 this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef _COREHIGHLIGHTSETTINGSPAGE_H_ +#define _COREHIGHLIGHTSETTINGSPAGE_H_ + +#include +#include +#include +#include + +#include "settingspage.h" +#include "ui_highlightsettingspage.h" + +class CoreHighlightSettingsPage : public SettingsPage +{ + Q_OBJECT + +public: + CoreHighlightSettingsPage(QWidget *parent = 0); + + bool hasDefaults() const; + +public slots: + void save(); + void load(); + void defaults(); + void revert(); + void clientConnected(); + +private slots: + void widgetHasChanged(); + void addNewRow(QString name = tr("highlight rule"), bool regex = false, bool cs = false, bool enable = true, QString chanName = "", bool self = false); + void removeSelectedRows(); + void selectRow(QTableWidgetItem *item); + void tableChanged(QTableWidgetItem *item); + +private: + Ui::CoreHighlightSettingsPage ui; + HighlightRuleManager::HighlightRuleList highlightList; + enum column { + NameColumn = 0, + RegExColumn = 1, + CsColumn = 2, + EnableColumn = 3, + ChanColumn = 4, + ColumnCount = 5 + }; + + void emptyTable(); + + bool _initialized; +}; + + +#endif diff --git a/src/qtui/settingspages/corehighlightsettingspage.ui b/src/qtui/settingspages/corehighlightsettingspage.ui new file mode 100644 index 00000000..42b60419 --- /dev/null +++ b/src/qtui/settingspages/corehighlightsettingspage.ui @@ -0,0 +1,162 @@ + + + CoreHighlightSettingsPage + + + + 0 + 0 + 438 + 404 + + + + Form + + + + + + Custom Highlights + + + + + + + + + + + + + Highlight + + + + + RegEx + + + + + CS + + + + + Enable + + + + + Channel + + + + + + + + 0 + + + 0 + + + + + Add + + + + + + + Remove + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Highlight Nicks + + + + + + All nicks from identity + + + + + + + Current nick + + + true + + + + + + + None + + + + + + + Case sensitive + + + true + + + + + + + + + + + + highlightNoNick + toggled(bool) + nicksCaseSensitive + setDisabled(bool) + + + 64 + 350 + + + 69 + 381 + + + + + diff --git a/src/qtui/settingspages/settingspages.cmake b/src/qtui/settingspages/settingspages.cmake index e0612410..f278982a 100644 --- a/src/qtui/settingspages/settingspages.cmake +++ b/src/qtui/settingspages/settingspages.cmake @@ -12,6 +12,7 @@ set(SETTINGSPAGES connection coreconnection coreaccount + corehighlight dcc highlight identities -- 2.20.1