1 /***************************************************************************
2 * Copyright (C) 2005-2018 by the Quassel Project *
3 * devel@quassel-irc.org *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) version 3. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #include <QHeaderView>
22 #include <QMessageBox>
23 #include <QTableWidget>
26 #include "corehighlightsettingspage.h"
29 CoreHighlightSettingsPage::CoreHighlightSettingsPage(QWidget *parent)
30 : SettingsPage(tr("Interface"), tr("Remote Highlights"), parent)
34 setupRuleTable(ui.highlightTable);
35 setupRuleTable(ui.ignoredTable);
37 ui.highlightNicksComboBox->addItem(tr("All Nicks from Identity"), QVariant(HighlightRuleManager::AllNicks));
38 ui.highlightNicksComboBox->addItem(tr("Current Nick"), QVariant(HighlightRuleManager::CurrentNick));
39 ui.highlightNicksComboBox->addItem(tr("None"), QVariant(HighlightRuleManager::NoNick));
41 coreConnectionStateChanged(Client::isConnected()); // need a core connection!
42 connect(Client::instance(), SIGNAL(coreConnectionStateChanged(bool)), this, SLOT(coreConnectionStateChanged(bool)));
44 connect(ui.highlightAdd, SIGNAL(clicked(bool)), this, SLOT(addNewHighlightRow()));
45 connect(ui.highlightRemove, SIGNAL(clicked(bool)), this, SLOT(removeSelectedHighlightRows()));
46 connect(ui.highlightImport, SIGNAL(clicked(bool)), this, SLOT(importRules()));
48 connect(ui.ignoredAdd, SIGNAL(clicked(bool)), this, SLOT(addNewIgnoredRow()));
49 connect(ui.ignoredRemove, SIGNAL(clicked(bool)), this, SLOT(removeSelectedIgnoredRows()));
51 // TODO: search for a better signal (one that emits everytime a selection has been changed for one item)
52 connect(ui.highlightTable,
53 SIGNAL(itemClicked(QTableWidgetItem * )),
55 SLOT(selectHighlightRow(QTableWidgetItem * )));
56 connect(ui.ignoredTable,
57 SIGNAL(itemClicked(QTableWidgetItem * )),
59 SLOT(selectIgnoredRow(QTableWidgetItem * )));
61 // Update the "Case sensitive" checkbox
62 connect(ui.highlightNicksComboBox,
63 SIGNAL(currentIndexChanged(int)),
65 SLOT(highlightNicksChanged(int)));
67 connect(ui.highlightNicksComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged()));
68 connect(ui.nicksCaseSensitive, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
70 connect(ui.highlightAdd, SIGNAL(clicked()), this, SLOT(widgetHasChanged()));
71 connect(ui.highlightRemove, SIGNAL(clicked()), this, SLOT(widgetHasChanged()));
73 connect(ui.ignoredAdd, SIGNAL(clicked()), this, SLOT(widgetHasChanged()));
74 connect(ui.ignoredRemove, SIGNAL(clicked()), this, SLOT(widgetHasChanged()));
76 connect(ui.highlightTable,
77 SIGNAL(itemChanged(QTableWidgetItem * )),
79 SLOT(highlightTableChanged(QTableWidgetItem * )));
81 connect(ui.ignoredTable,
82 SIGNAL(itemChanged(QTableWidgetItem * )),
84 SLOT(ignoredTableChanged(QTableWidgetItem * )));
86 connect(Client::instance(), SIGNAL(connected()), this, SLOT(clientConnected()));
89 ui.coreUnsupportedIcon->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(16));
92 void CoreHighlightSettingsPage::coreConnectionStateChanged(bool state)
94 updateCoreSupportStatus(state);
103 void CoreHighlightSettingsPage::setupRuleTable(QTableWidget *table) const
105 table->verticalHeader()->hide();
106 table->setShowGrid(false);
108 table->horizontalHeaderItem(CoreHighlightSettingsPage::RegExColumn)->setToolTip(
109 tr("<b>RegEx</b>: This option determines if the highlight rule should be "
110 "interpreted as a <b>regular expression</b> or just as a keyword."));
111 table->horizontalHeaderItem(CoreHighlightSettingsPage::RegExColumn)->setWhatsThis(
112 table->horizontalHeaderItem(CoreHighlightSettingsPage::RegExColumn)->toolTip());
114 table->horizontalHeaderItem(CoreHighlightSettingsPage::CsColumn)->setToolTip(
115 tr("<b>CS</b>: This option determines if the highlight rule should be interpreted "
116 "<b>case sensitive</b>."));
117 table->horizontalHeaderItem(CoreHighlightSettingsPage::CsColumn)->setWhatsThis(
118 table->horizontalHeaderItem(CoreHighlightSettingsPage::CsColumn)->toolTip());
120 table->horizontalHeaderItem(CoreHighlightSettingsPage::ChanColumn)->setToolTip(
121 tr("<p><b>Channel</b>: Semicolon separated list of channel names.</p>"
122 "<p><i>Example:</i><br />"
123 "<i>#quassel*; #foobar; !#quasseldroid</i><br />"
124 "would match on #foobar and on any channel starting with <i>#quassel</i> except "
125 "for <i>#quasseldroid</i><br />"
126 "<p>If only inverted names are specified, it will match anything except for "
127 "what's specified (implicit wildcard).</p>"
128 "<p><i>Example:</i><br />"
129 "<i>!#quassel*; !#foobar</i><br />"
130 "would match anything except for #foobar or any channel starting with "
131 "<i>#quassel</i></p>"));
132 table->horizontalHeaderItem(CoreHighlightSettingsPage::ChanColumn)->setWhatsThis(
133 table->horizontalHeaderItem(CoreHighlightSettingsPage::ChanColumn)->toolTip());
135 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
136 table->horizontalHeader()->setResizeMode(CoreHighlightSettingsPage::EnableColumn, QHeaderView::ResizeToContents);
137 table->horizontalHeader()->setResizeMode(CoreHighlightSettingsPage::NameColumn, QHeaderView::Stretch);
138 table->horizontalHeader()->setResizeMode(CoreHighlightSettingsPage::RegExColumn, QHeaderView::ResizeToContents);
139 table->horizontalHeader()->setResizeMode(CoreHighlightSettingsPage::CsColumn, QHeaderView::ResizeToContents);
140 table->horizontalHeader()->setResizeMode(CoreHighlightSettingsPage::ChanColumn, QHeaderView::ResizeToContents);
142 table->horizontalHeader()->setSectionResizeMode(CoreHighlightSettingsPage::EnableColumn, QHeaderView::ResizeToContents);
143 table->horizontalHeader()->setSectionResizeMode(CoreHighlightSettingsPage::NameColumn, QHeaderView::Stretch);
144 table->horizontalHeader()->setSectionResizeMode(CoreHighlightSettingsPage::RegExColumn, QHeaderView::ResizeToContents);
145 table->horizontalHeader()->setSectionResizeMode(CoreHighlightSettingsPage::CsColumn, QHeaderView::ResizeToContents);
146 table->horizontalHeader()->setSectionResizeMode(CoreHighlightSettingsPage::ChanColumn, QHeaderView::ResizeToContents);
150 void CoreHighlightSettingsPage::updateCoreSupportStatus(bool state)
152 // Assume connected state as enforced by the settings page UI
153 if (!state || Client::isCoreFeatureEnabled(Quassel::Feature::CoreSideHighlights)) {
154 // Either disconnected or core supports highlights, enable highlight configuration and hide
155 // warning. Don't show the warning needlessly when disconnected.
156 ui.highlightsConfigWidget->setEnabled(true);
157 ui.coreUnsupportedWidget->setVisible(false);
159 // Core does not support highlights, show warning and disable highlight configuration
160 ui.highlightsConfigWidget->setEnabled(false);
161 ui.coreUnsupportedWidget->setVisible(true);
165 void CoreHighlightSettingsPage::clientConnected()
167 connect(Client::highlightRuleManager(), SIGNAL(updated()), SLOT(revert()));
170 void CoreHighlightSettingsPage::revert()
175 setChangedState(false);
179 bool CoreHighlightSettingsPage::hasDefaults() const
184 void CoreHighlightSettingsPage::defaults()
186 int highlightNickType = HighlightRuleManager::HighlightNickType::CurrentNick;
187 int defaultIndex = ui.highlightNicksComboBox->findData(QVariant(highlightNickType));
188 ui.highlightNicksComboBox->setCurrentIndex(defaultIndex);
189 ui.nicksCaseSensitive->setChecked(false);
190 emptyHighlightTable();
196 void CoreHighlightSettingsPage::addNewHighlightRow(bool enable, const QString &name, bool regex, bool cs,
197 const QString &sender, const QString &chanName, bool self)
199 ui.highlightTable->setRowCount(ui.highlightTable->rowCount() + 1);
201 auto *nameItem = new QTableWidgetItem(name);
203 auto *regexItem = new QTableWidgetItem("");
205 regexItem->setCheckState(Qt::Checked);
207 regexItem->setCheckState(Qt::Unchecked);
208 regexItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
210 auto *csItem = new QTableWidgetItem("");
212 csItem->setCheckState(Qt::Checked);
214 csItem->setCheckState(Qt::Unchecked);
215 csItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
217 auto *enableItem = new QTableWidgetItem("");
219 enableItem->setCheckState(Qt::Checked);
221 enableItem->setCheckState(Qt::Unchecked);
222 enableItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
224 auto *chanNameItem = new QTableWidgetItem(chanName);
226 auto *senderItem = new QTableWidgetItem(sender);
228 enableItem->setToolTip(tr("Enable/disable this rule"));
229 nameItem->setToolTip(tr("Phrase to match"));
230 regexItem->setToolTip(
231 tr("<b>RegEx</b>: This option determines if the highlight rule should be "
232 "interpreted as a <b>regular expression</b> or just as a keyword."));
234 tr("<b>CS</b>: This option determines if the highlight rule should be interpreted "
235 "<b>case sensitive</b>."));
236 senderItem->setToolTip(
237 tr("<b>Sender</b>: This option specifies which sender to match. Leave blank to "
238 "match any nickname."));
239 chanNameItem->setToolTip(
240 tr("<p><b>Channel</b>: Semicolon separated list of channel names.</p>"
241 "<p><i>Example:</i><br />"
242 "<i>#quassel*; #foobar; !#quasseldroid</i><br />"
243 "would match on #foobar and on any channel starting with <i>#quassel</i> except "
244 "for <i>#quasseldroid</i><br />"
245 "<p>If only inverted names are specified, it will match anything except for "
246 "what's specified (implicit wildcard).</p>"
247 "<p><i>Example:</i><br />"
248 "<i>!#quassel*; !#foobar</i><br />"
249 "would match anything except for #foobar or any channel starting with "
250 "<i>#quassel</i></p>"));
252 int lastRow = ui.highlightTable->rowCount() - 1;
253 ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::NameColumn, nameItem);
254 ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::RegExColumn, regexItem);
255 ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::CsColumn, csItem);
256 ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::EnableColumn, enableItem);
257 ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::SenderColumn, senderItem);
258 ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::ChanColumn, chanNameItem);
261 ui.highlightTable->setCurrentItem(nameItem);
263 highlightList << HighlightRuleManager::HighlightRule(name, regex, cs, enable, false, sender, chanName);
266 void CoreHighlightSettingsPage::addNewIgnoredRow(bool enable, const QString &name, bool regex, bool cs,
267 const QString &sender, const QString &chanName, bool self)
269 ui.ignoredTable->setRowCount(ui.ignoredTable->rowCount() + 1);
271 auto *nameItem = new QTableWidgetItem(name);
273 auto *regexItem = new QTableWidgetItem("");
275 regexItem->setCheckState(Qt::Checked);
277 regexItem->setCheckState(Qt::Unchecked);
278 regexItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
280 auto *csItem = new QTableWidgetItem("");
282 csItem->setCheckState(Qt::Checked);
284 csItem->setCheckState(Qt::Unchecked);
285 csItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
287 auto *enableItem = new QTableWidgetItem("");
289 enableItem->setCheckState(Qt::Checked);
291 enableItem->setCheckState(Qt::Unchecked);
292 enableItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
294 auto *chanNameItem = new QTableWidgetItem(chanName);
296 auto *senderItem = new QTableWidgetItem(sender);
298 enableItem->setToolTip(tr("Enable/disable this rule"));
299 nameItem->setToolTip(tr("Phrase to match"));
300 regexItem->setToolTip(
301 tr("<b>RegEx</b>: This option determines if the highlight rule should be "
302 "interpreted as a <b>regular expression</b> or just as a keyword."));
304 tr("<b>CS</b>: This option determines if the highlight rule should be interpreted "
305 "<b>case sensitive</b>."));
306 senderItem->setToolTip(
307 tr("<b>Sender</b>: This option specifies which sender nicknames match. Leave "
308 "blank to match any nickname."));
309 chanNameItem->setToolTip(
310 tr("<p><b>Channel</b>: Semicolon separated list of channel names.</p>"
311 "<p><i>Example:</i><br />"
312 "<i>#quassel*; #foobar; !#quasseldroid</i><br />"
313 "would match on #foobar and on any channel starting with <i>#quassel</i> except "
314 "for <i>#quasseldroid</i><br />"
315 "<p>If only inverted names are specified, it will match anything except for "
316 "what's specified (implicit wildcard).</p>"
317 "<p><i>Example:</i><br />"
318 "<i>!#quassel*; !#foobar</i><br />"
319 "would match anything except for #foobar or any channel starting with "
320 "<i>#quassel</i></p>"));
322 int lastRow = ui.ignoredTable->rowCount() - 1;
323 ui.ignoredTable->setItem(lastRow, CoreHighlightSettingsPage::NameColumn, nameItem);
324 ui.ignoredTable->setItem(lastRow, CoreHighlightSettingsPage::RegExColumn, regexItem);
325 ui.ignoredTable->setItem(lastRow, CoreHighlightSettingsPage::CsColumn, csItem);
326 ui.ignoredTable->setItem(lastRow, CoreHighlightSettingsPage::EnableColumn, enableItem);
327 ui.ignoredTable->setItem(lastRow, CoreHighlightSettingsPage::SenderColumn, senderItem);
328 ui.ignoredTable->setItem(lastRow, CoreHighlightSettingsPage::ChanColumn, chanNameItem);
331 ui.ignoredTable->setCurrentItem(nameItem);
333 ignoredList << HighlightRuleManager::HighlightRule(name, regex, cs, enable, true, sender, chanName);
336 void CoreHighlightSettingsPage::removeSelectedHighlightRows()
338 QList<int> selectedRows;
339 QList<QTableWidgetItem *> selectedItemList = ui.highlightTable->selectedItems();
340 for (auto selectedItem : selectedItemList) {
341 selectedRows.append(selectedItem->row());
343 qSort(selectedRows.begin(), selectedRows.end(), qGreater<int>());
345 for (auto row : selectedRows) {
346 if (row != lastRow) {
347 ui.highlightTable->removeRow(row);
348 highlightList.removeAt(row);
354 void CoreHighlightSettingsPage::removeSelectedIgnoredRows()
356 QList<int> selectedRows;
357 QList<QTableWidgetItem *> selectedItemList = ui.ignoredTable->selectedItems();
358 for (auto selectedItem : selectedItemList) {
359 selectedRows.append(selectedItem->row());
361 qSort(selectedRows.begin(), selectedRows.end(), qGreater<int>());
363 for (auto row : selectedRows) {
364 if (row != lastRow) {
365 ui.ignoredTable->removeRow(row);
366 ignoredList.removeAt(row);
372 void CoreHighlightSettingsPage::highlightNicksChanged(const int index) {
373 // Only allow toggling "Case sensitive" when a nickname will be highlighted
374 auto highlightNickType = ui.highlightNicksComboBox->itemData(index).value<int>();
375 ui.nicksCaseSensitive->setEnabled(highlightNickType != HighlightRuleManager::NoNick);
378 void CoreHighlightSettingsPage::selectHighlightRow(QTableWidgetItem *item)
380 int row = item->row();
381 bool selected = item->isSelected();
383 ->setRangeSelected(QTableWidgetSelectionRange(row, 0, row, CoreHighlightSettingsPage::ColumnCount - 1),
387 void CoreHighlightSettingsPage::selectIgnoredRow(QTableWidgetItem *item)
389 int row = item->row();
390 bool selected = item->isSelected();
392 ->setRangeSelected(QTableWidgetSelectionRange(row, 0, row, CoreHighlightSettingsPage::ColumnCount - 1),
396 void CoreHighlightSettingsPage::emptyHighlightTable()
398 // ui.highlight and highlightList should have the same size, but just to make sure.
399 if (ui.highlightTable->rowCount() != highlightList.size()) {
400 qDebug() << "something is wrong: ui.highlight and highlightList don't have the same size!";
402 while (ui.highlightTable->rowCount()) {
403 ui.highlightTable->removeRow(0);
405 highlightList.clear();
408 void CoreHighlightSettingsPage::emptyIgnoredTable()
410 // ui.highlight and highlightList should have the same size, but just to make sure.
411 if (ui.ignoredTable->rowCount() != ignoredList.size()) {
412 qDebug() << "something is wrong: ui.highlight and highlightList don't have the same size!";
414 while (ui.ignoredTable->rowCount()) {
415 ui.ignoredTable->removeRow(0);
420 void CoreHighlightSettingsPage::highlightTableChanged(QTableWidgetItem *item)
422 if (item->row() + 1 > highlightList.size())
425 auto highlightRule = highlightList.value(item->row());
428 switch (item->column()) {
429 case CoreHighlightSettingsPage::EnableColumn:
430 highlightRule.isEnabled = (item->checkState() == Qt::Checked);
432 case CoreHighlightSettingsPage::NameColumn:
433 if (item->text() == "")
434 item->setText(tr("this shouldn't be empty"));
435 highlightRule.name = item->text();
437 case CoreHighlightSettingsPage::RegExColumn:
438 highlightRule.isRegEx = (item->checkState() == Qt::Checked);
440 case CoreHighlightSettingsPage::CsColumn:
441 highlightRule.isCaseSensitive = (item->checkState() == Qt::Checked);
443 case CoreHighlightSettingsPage::SenderColumn:
444 if (!item->text().isEmpty() && item->text().trimmed().isEmpty())
446 highlightRule.sender = item->text();
448 case CoreHighlightSettingsPage::ChanColumn:
449 if (!item->text().isEmpty() && item->text().trimmed().isEmpty())
451 highlightRule.chanName = item->text();
454 highlightList[item->row()] = highlightRule;
455 emit widgetHasChanged();
458 void CoreHighlightSettingsPage::ignoredTableChanged(QTableWidgetItem *item)
460 if (item->row() + 1 > ignoredList.size())
463 auto ignoredRule = ignoredList.value(item->row());
466 switch (item->column()) {
467 case CoreHighlightSettingsPage::EnableColumn:
468 ignoredRule.isEnabled = (item->checkState() == Qt::Checked);
470 case CoreHighlightSettingsPage::NameColumn:
471 if (item->text() == "")
472 item->setText(tr("this shouldn't be empty"));
473 ignoredRule.name = item->text();
475 case CoreHighlightSettingsPage::RegExColumn:
476 ignoredRule.isRegEx = (item->checkState() == Qt::Checked);
478 case CoreHighlightSettingsPage::CsColumn:
479 ignoredRule.isCaseSensitive = (item->checkState() == Qt::Checked);
481 case CoreHighlightSettingsPage::SenderColumn:
482 if (!item->text().isEmpty() && item->text().trimmed().isEmpty())
484 ignoredRule.sender = item->text();
486 case CoreHighlightSettingsPage::ChanColumn:
487 if (!item->text().isEmpty() && item->text().trimmed().isEmpty())
489 ignoredRule.chanName = item->text();
492 ignoredList[item->row()] = ignoredRule;
493 emit widgetHasChanged();
496 void CoreHighlightSettingsPage::load()
498 emptyHighlightTable();
501 auto ruleManager = Client::highlightRuleManager();
503 for (auto &rule : ruleManager->highlightRuleList()) {
504 if (rule.isInverse) {
505 addNewIgnoredRow(rule.isEnabled,
508 rule.isCaseSensitive,
513 addNewHighlightRow(rule.isEnabled, rule.name, rule.isRegEx, rule.isCaseSensitive, rule.sender,
518 int highlightNickType = ruleManager->highlightNick();
519 ui.highlightNicksComboBox->setCurrentIndex(ui.highlightNicksComboBox->findData(QVariant(highlightNickType)));
520 // Trigger the initial update of nicksCaseSensitive being enabled or not
521 highlightNicksChanged(ui.highlightNicksComboBox->currentIndex());
522 ui.nicksCaseSensitive->setChecked(ruleManager->nicksCaseSensitive());
524 setChangedState(false);
531 void CoreHighlightSettingsPage::save()
539 auto ruleManager = Client::highlightRuleManager();
540 if (ruleManager == nullptr)
543 auto clonedManager = HighlightRuleManager();
544 clonedManager.fromVariantMap(ruleManager->toVariantMap());
545 clonedManager.clear();
547 for (auto &rule : highlightList) {
548 clonedManager.addHighlightRule(rule.name, rule.isRegEx, rule.isCaseSensitive, rule.isEnabled, false,
549 rule.sender, rule.chanName);
552 for (auto &rule : ignoredList) {
553 clonedManager.addHighlightRule(rule.name, rule.isRegEx, rule.isCaseSensitive, rule.isEnabled, true,
554 rule.sender, rule.chanName);
557 auto highlightNickType = ui.highlightNicksComboBox->itemData(ui.highlightNicksComboBox->currentIndex()).value<int>();
559 clonedManager.setHighlightNick(HighlightRuleManager::HighlightNickType(highlightNickType));
560 clonedManager.setNicksCaseSensitive(ui.nicksCaseSensitive->isChecked());
562 ruleManager->requestUpdate(clonedManager.toVariantMap());
563 setChangedState(false);
567 void CoreHighlightSettingsPage::widgetHasChanged()
569 setChangedState(true);
572 void CoreHighlightSettingsPage::on_coreUnsupportedDetails_clicked()
574 // Re-use translations of "Local Highlights" as this is a word-for-word reference, forcing all
575 // spaces to non-breaking
576 const QString localHighlightsName = tr("Local Highlights").replace(" ", " ");
578 const QString remoteHighlightsMsgText =
579 QString("<p><b>%1</b></p></br><p>%2</p></br><p>%3</p>"
580 ).arg(tr("Your Quassel core is too old to support remote highlights"),
581 tr("You need a Quassel core v0.13.0 or newer to configure remote "
583 tr("You can still configure highlights for this device only in "
584 "<i>%1</i>.").arg(localHighlightsName));
586 QMessageBox::warning(this,
587 tr("Remote Highlights unsupported"),
588 remoteHighlightsMsgText);
591 void CoreHighlightSettingsPage::importRules() {
592 NotificationSettings notificationSettings;
594 auto clonedManager = HighlightRuleManager();
595 clonedManager.fromVariantMap(Client::highlightRuleManager()->toVariantMap());
597 for (const auto &variant : notificationSettings.highlightList()) {
598 auto highlightRule = variant.toMap();
600 clonedManager.addHighlightRule(
601 highlightRule["Name"].toString(),
602 highlightRule["RegEx"].toBool(),
603 highlightRule["CS"].toBool(),
604 highlightRule["Enable"].toBool(),
607 highlightRule["Channel"].toString()
611 Client::highlightRuleManager()->requestUpdate(clonedManager.toVariantMap());
612 setChangedState(false);
616 bool CoreHighlightSettingsPage::isSelectable() const {
617 return Client::isConnected();
618 // We check for Quassel::Feature::CoreSideHighlights when loading this page, allowing us to show
619 // a friendly error message.