cmake: avoid de-duplication of user's CXXFLAGS
[quassel.git] / src / qtui / settingspages / highlightsettingspage.cpp
index aed9ee5..53a1fd9 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-2016 by the Quassel Project                        *
+ *   Copyright (C) 2005-2022 by the Quassel Project                        *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
 
 #include "highlightsettingspage.h"
 
+#include <algorithm>
+
+#include <QHeaderView>
+#include <QMessageBox>
+
 #include "client.h"
+#include "icon.h"
 #include "qtui.h"
 #include "uisettings.h"
 
-#include <QHeaderView>
-
-HighlightSettingsPage::HighlightSettingsPage(QWidget *parent)
-    : SettingsPage(tr("Interface"), tr("Local Highlights"), parent)
+HighlightSettingsPage::HighlightSettingsPage(QWidget* parent)
+    : SettingsPage(tr("Interface"), tr("Legacy Highlights"),
+                   parent)
 {
     ui.setupUi(this);
     ui.highlightTable->verticalHeader()->hide();
     ui.highlightTable->setShowGrid(false);
 
-    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::RegExColumn)->setToolTip("<b>RegEx</b>: This option determines if the highlight rule should be interpreted as a <b>regular expression</b> or just as a keyword.");
-    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::RegExColumn)->setWhatsThis("<b>RegEx</b>: This option determines if the highlight rule should be interpreted as a <b>regular expression</b> or just as a keyword.");
+    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::EnableColumn)->setToolTip(tr("Enable/disable this rule"));
+    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::EnableColumn)
+        ->setWhatsThis(ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::EnableColumn)->toolTip());
+
+    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::NameColumn)->setToolTip(tr("Phrase to match"));
+    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::NameColumn)
+        ->setWhatsThis(ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::NameColumn)->toolTip());
+
+    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::RegExColumn)
+        ->setToolTip(tr("<b>RegEx</b>: This option determines if the highlight rule and <i>Channel</i> "
+                        "should be interpreted as <b>regular expressions</b> or just as keywords."));
+    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::RegExColumn)
+        ->setWhatsThis(ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::RegExColumn)->toolTip());
+
+    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::CsColumn)
+        ->setToolTip(tr("<b>CS</b>: This option determines if the highlight rule and <i>Channel</i> "
+                        "should be interpreted <b>case sensitive</b>."));
+    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::CsColumn)
+        ->setWhatsThis(ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::CsColumn)->toolTip());
+
+    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::ChanColumn)
+        ->setToolTip(tr("<p><b>Channel</b>: Semicolon separated list of channel/query names, leave "
+                        "blank to match any name.</p>"
+                        "<p><i>Example:</i><br />"
+                        "<i>#quassel*; #foobar; !#quasseldroid</i><br />"
+                        "would match on <i>#foobar</i> and any channel starting with <i>#quassel</i> "
+                        "except for <i>#quasseldroid</i><br />"
+                        "<p>If only inverted names are specified, it will match anything except for "
+                        "what's specified (implicit wildcard).</p>"
+                        "<p><i>Example:</i><br />"
+                        "<i>!#quassel*; !#foobar</i><br />"
+                        "would match anything except for <i>#foobar</i> or any channel starting with "
+                        "<i>#quassel</i></p>"));
+    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::ChanColumn)
+        ->setWhatsThis(ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::ChanColumn)->toolTip());
 
-    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::CsColumn)->setToolTip("<b>CS</b>: This option determines if the highlight rule should be interpreted <b>case sensitive</b>.");
-    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::CsColumn)->setWhatsThis("<b>CS</b>: This option determines if the highlight rule should be interpreted <b>case sensitive</b>.");
-
-    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::ChanColumn)->setToolTip("<b>Channel</b>: This regular expression determines for which <b>channels</b> the highlight rule works. Leave blank to match any channel. Put <b>!</b> in the beginning to negate. Case insensitive.");
-    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::ChanColumn)->setWhatsThis("<b>Channel</b>: This regular expression determines for which <b>channels</b> the highlight rule works. Leave blank to match any channel. Put <b>!</b> in the beginning to negate. Case insensitive.");
-
-#if QT_VERSION < 0x050000
-    ui.highlightTable->horizontalHeader()->setResizeMode(HighlightSettingsPage::NameColumn, QHeaderView::Stretch);
-    ui.highlightTable->horizontalHeader()->setResizeMode(HighlightSettingsPage::RegExColumn, QHeaderView::ResizeToContents);
-    ui.highlightTable->horizontalHeader()->setResizeMode(HighlightSettingsPage::CsColumn, QHeaderView::ResizeToContents);
-    ui.highlightTable->horizontalHeader()->setResizeMode(HighlightSettingsPage::EnableColumn, QHeaderView::ResizeToContents);
-    ui.highlightTable->horizontalHeader()->setResizeMode(HighlightSettingsPage::ChanColumn, QHeaderView::ResizeToContents);
-#else
     ui.highlightTable->horizontalHeader()->setSectionResizeMode(HighlightSettingsPage::NameColumn, QHeaderView::Stretch);
     ui.highlightTable->horizontalHeader()->setSectionResizeMode(HighlightSettingsPage::RegExColumn, QHeaderView::ResizeToContents);
     ui.highlightTable->horizontalHeader()->setSectionResizeMode(HighlightSettingsPage::CsColumn, QHeaderView::ResizeToContents);
     ui.highlightTable->horizontalHeader()->setSectionResizeMode(HighlightSettingsPage::EnableColumn, QHeaderView::ResizeToContents);
     ui.highlightTable->horizontalHeader()->setSectionResizeMode(HighlightSettingsPage::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 *)));
-}
 
+    // Information icon
+    ui.localHighlightsIcon->setPixmap(icon::get({"emblem-information", "dialog-information"}).pixmap(16));
+
+    connect(ui.add, &QAbstractButton::clicked, this, [this]() { addNewRow(); });
+    connect(ui.remove, &QAbstractButton::clicked, this, &HighlightSettingsPage::removeSelectedRows);
+    // TODO: search for a better signal (one that emits every time a selection has been changed for one item)
+    connect(ui.highlightTable, &QTableWidget::itemClicked, this, &HighlightSettingsPage::selectRow);
+
+    connect(ui.highlightAllNicks, &QAbstractButton::clicked, this, &HighlightSettingsPage::widgetHasChanged);
+    connect(ui.highlightCurrentNick, &QAbstractButton::clicked, this, &HighlightSettingsPage::widgetHasChanged);
+    connect(ui.highlightNoNick, &QAbstractButton::clicked, this, &HighlightSettingsPage::widgetHasChanged);
+    connect(ui.nicksCaseSensitive, &QAbstractButton::clicked, this, &HighlightSettingsPage::widgetHasChanged);
+    connect(ui.add, &QAbstractButton::clicked, this, &HighlightSettingsPage::widgetHasChanged);
+    connect(ui.remove, &QAbstractButton::clicked, this, &HighlightSettingsPage::widgetHasChanged);
+    connect(ui.highlightTable, &QTableWidget::itemChanged, this, &HighlightSettingsPage::tableChanged);
+}
 
 bool HighlightSettingsPage::hasDefaults() const
 {
     return true;
 }
 
-
 void HighlightSettingsPage::defaults()
 {
     ui.highlightNoNick->setChecked(true);
@@ -86,41 +111,59 @@ void HighlightSettingsPage::defaults()
     widgetHasChanged();
 }
 
-
 void HighlightSettingsPage::addNewRow(QString name, bool regex, bool cs, bool enable, QString chanName, bool self)
 {
-    ui.highlightTable->setRowCount(ui.highlightTable->rowCount()+1);
+    ui.highlightTable->setRowCount(ui.highlightTable->rowCount() + 1);
+
+    QTableWidgetItem* enableItem = new QTableWidgetItem("");
+    if (enable)
+        enableItem->setCheckState(Qt::Checked);
+    else
+        enableItem->setCheckState(Qt::Unchecked);
+    enableItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
 
-    QTableWidgetItem *nameItem = new QTableWidgetItem(name);
+    auto* nameItem = new QTableWidgetItem(name);
 
-    QTableWidgetItem *regexItem = new QTableWidgetItem("");
+    QTableWidgetItemregexItem = new QTableWidgetItem("");
     if (regex)
         regexItem->setCheckState(Qt::Checked);
     else
         regexItem->setCheckState(Qt::Unchecked);
-    regexItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
+    regexItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
 
-    QTableWidgetItem *csItem = new QTableWidgetItem("");
+    QTableWidgetItemcsItem = new QTableWidgetItem("");
     if (cs)
         csItem->setCheckState(Qt::Checked);
     else
         csItem->setCheckState(Qt::Unchecked);
-    csItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
-
-    QTableWidgetItem *enableItem = new QTableWidgetItem("");
-    if (enable)
-        enableItem->setCheckState(Qt::Checked);
-    else
-        enableItem->setCheckState(Qt::Unchecked);
-    enableItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
-
-    QTableWidgetItem *chanNameItem = new QTableWidgetItem(chanName);
-
-    int lastRow = ui.highlightTable->rowCount()-1;
+    csItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+
+    auto* chanNameItem = new QTableWidgetItem(chanName);
+
+    enableItem->setToolTip(tr("Enable/disable this rule"));
+    nameItem->setToolTip(tr("Phrase to match"));
+    regexItem->setToolTip(tr("<b>RegEx</b>: This option determines if the highlight rule and <i>Channel</i> "
+                             "should be interpreted as <b>regular expressions</b> or just as keywords."));
+    csItem->setToolTip(tr("<b>CS</b>: This option determines if the highlight rule and <i>Channel</i> "
+                          "should be interpreted <b>case sensitive</b>."));
+    chanNameItem->setToolTip(tr("<p><b>Channel</b>: Semicolon separated list of channel/query names, leave "
+                                "blank to match any name.</p>"
+                                "<p><i>Example:</i><br />"
+                                "<i>#quassel*; #foobar; !#quasseldroid</i><br />"
+                                "would match on <i>#foobar</i> and any channel starting with <i>#quassel</i> "
+                                "except for <i>#quasseldroid</i><br />"
+                                "<p>If only inverted names are specified, it will match anything except for "
+                                "what's specified (implicit wildcard).</p>"
+                                "<p><i>Example:</i><br />"
+                                "<i>!#quassel*; !#foobar</i><br />"
+                                "would match anything except for <i>#foobar</i> or any channel starting with "
+                                "<i>#quassel</i></p>"));
+
+    int lastRow = ui.highlightTable->rowCount() - 1;
+    ui.highlightTable->setItem(lastRow, HighlightSettingsPage::EnableColumn, enableItem);
     ui.highlightTable->setItem(lastRow, HighlightSettingsPage::NameColumn, nameItem);
     ui.highlightTable->setItem(lastRow, HighlightSettingsPage::RegExColumn, regexItem);
     ui.highlightTable->setItem(lastRow, HighlightSettingsPage::CsColumn, csItem);
-    ui.highlightTable->setItem(lastRow, HighlightSettingsPage::EnableColumn, enableItem);
     ui.highlightTable->setItem(lastRow, HighlightSettingsPage::ChanColumn, chanNameItem);
 
     if (!self)
@@ -136,17 +179,16 @@ void HighlightSettingsPage::addNewRow(QString name, bool regex, bool cs, bool en
     highlightList.append(highlightRule);
 }
 
-
 void HighlightSettingsPage::removeSelectedRows()
 {
     QList<int> selectedRows;
-    QList<QTableWidgetItem *> selectedItemList = ui.highlightTable->selectedItems();
-    foreach(QTableWidgetItem *selectedItem, selectedItemList) {
+    QList<QTableWidgetItem*> selectedItemList = ui.highlightTable->selectedItems();
+    foreach (QTableWidgetItem* selectedItem, selectedItemList) {
         selectedRows.append(selectedItem->row());
     }
-    qSort(selectedRows.begin(), selectedRows.end(), qGreater<int>());
+    std::sort(selectedRows.begin(), selectedRows.end(), std::greater<>());
     int lastRow = -1;
-    foreach(int row, selectedRows) {
+    foreach (int row, selectedRows) {
         if (row != lastRow) {
             ui.highlightTable->removeRow(row);
             highlightList.removeAt(row);
@@ -155,15 +197,13 @@ void HighlightSettingsPage::removeSelectedRows()
     }
 }
 
-
-void HighlightSettingsPage::selectRow(QTableWidgetItem *item)
+void HighlightSettingsPage::selectRow(QTableWidgetItem* item)
 {
     int row = item->row();
     bool selected = item->isSelected();
-    ui.highlightTable->setRangeSelected(QTableWidgetSelectionRange(row, 0, row, HighlightSettingsPage::ColumnCount-1), selected);
+    ui.highlightTable->setRangeSelected(QTableWidgetSelectionRange(row, 0, row, HighlightSettingsPage::ColumnCount - 1), selected);
 }
 
-
 void HighlightSettingsPage::emptyTable()
 {
     // ui.highlight and highlightList should have the same size, but just to make sure.
@@ -178,16 +218,17 @@ void HighlightSettingsPage::emptyTable()
     }
 }
 
-
-void HighlightSettingsPage::tableChanged(QTableWidgetItem *item)
+void HighlightSettingsPage::tableChanged(QTableWidgetItem* item)
 {
-    if (item->row()+1 > highlightList.size())
+    if (item->row() + 1 > highlightList.size())
         return;
 
     QVariantMap highlightRule = highlightList.value(item->row()).toMap();
 
-    switch (item->column())
-    {
+    switch (item->column()) {
+    case HighlightSettingsPage::EnableColumn:
+        highlightRule["Enable"] = (item->checkState() == Qt::Checked);
+        break;
     case HighlightSettingsPage::NameColumn:
         if (item->text() == "")
             item->setText(tr("this shouldn't be empty"));
@@ -199,9 +240,6 @@ void HighlightSettingsPage::tableChanged(QTableWidgetItem *item)
     case HighlightSettingsPage::CsColumn:
         highlightRule["CS"] = (item->checkState() == Qt::Checked);
         break;
-    case HighlightSettingsPage::EnableColumn:
-        highlightRule["Enable"] = (item->checkState() == Qt::Checked);
-        break;
     case HighlightSettingsPage::ChanColumn:
         if (!item->text().isEmpty() && item->text().trimmed().isEmpty())
             item->setText("");
@@ -212,6 +250,19 @@ void HighlightSettingsPage::tableChanged(QTableWidgetItem *item)
     emit widgetHasChanged();
 }
 
+void HighlightSettingsPage::on_localHighlightsDetails_clicked()
+{
+    // Discourage the use of local (legacy) highlights.  When not running in Monolithic mode, they
+    // need to be kept around for pre-0.13 cores.
+    QMessageBox::information(this,
+                             tr("Legacy Highlights vs. Highlights"),
+                             QString("<p><b>%1</b></p></br><p>%2</p></br><p>%3</p>")
+                             .arg(tr("Legacy Highlights are replaced by Highlights"),
+                                  tr("These highlights will keep working for now, but you should move to "
+                                     "the improved highlight rules when you can."),
+                                  tr("Configure the new style of highlights in <i>%1</i>.")
+                                  .arg(tr("Highlights"))));
+}
 
 void HighlightSettingsPage::load()
 {
@@ -219,7 +270,7 @@ void HighlightSettingsPage::load()
 
     emptyTable();
 
-    foreach(QVariant highlight, notificationSettings.highlightList()) {
+    foreach (QVariant highlight, notificationSettings.highlightList()) {
         QVariantMap highlightRule = highlight.toMap();
         QString name = highlightRule["Name"].toString();
         bool regex = highlightRule["RegEx"].toBool();
@@ -230,8 +281,7 @@ void HighlightSettingsPage::load()
         addNewRow(name, regex, cs, enable, chanName, true);
     }
 
-    switch (notificationSettings.highlightNick())
-    {
+    switch (notificationSettings.highlightNick()) {
     case NotificationSettings::NoNick:
         ui.highlightNoNick->setChecked(true);
         break;
@@ -247,7 +297,6 @@ void HighlightSettingsPage::load()
     setChangedState(false);
 }
 
-
 void HighlightSettingsPage::save()
 {
     NotificationSettings notificationSettings;
@@ -266,14 +315,13 @@ void HighlightSettingsPage::save()
     setChangedState(false);
 }
 
-
 void HighlightSettingsPage::widgetHasChanged()
 {
     bool changed = testHasChanged();
-    if (changed != hasChanged()) setChangedState(changed);
+    if (changed != hasChanged())
+        setChangedState(changed);
 }
 
-
 bool HighlightSettingsPage::testHasChanged()
 {
     NotificationSettings notificationSettings;