client: Show when Remote Highlights unsupported
[quassel.git] / src / qtui / settingspages / corehighlightsettingspage.cpp
index 444afd1..644a902 100644 (file)
@@ -19,6 +19,7 @@
  ***************************************************************************/
 
 #include <QHeaderView>
+#include <QMessageBox>
 #include <QTableWidget>
 
 #include "client.h"
@@ -83,10 +84,14 @@ CoreHighlightSettingsPage::CoreHighlightSettingsPage(QWidget *parent)
             SLOT(ignoredTableChanged(QTableWidgetItem * )));
 
     connect(Client::instance(), SIGNAL(connected()), this, SLOT(clientConnected()));
+
+    // Warning icon
+    ui.coreUnsupportedIcon->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(16));
 }
 
 void CoreHighlightSettingsPage::coreConnectionStateChanged(bool state)
 {
+    updateCoreSupportStatus(state);
     setEnabled(state);
     if (state) {
         load();
@@ -101,19 +106,31 @@ void CoreHighlightSettingsPage::setupRuleTable(QTableWidget *table) const
     table->setShowGrid(false);
 
     table->horizontalHeaderItem(CoreHighlightSettingsPage::RegExColumn)->setToolTip(
-        tr("<b>RegEx</b>: This option determines if the highlight rule should be interpreted as a <b>regular expression</b> or just as a keyword."));
+                tr("<b>RegEx</b>: This option determines if the highlight rule should be "
+                   "interpreted as a <b>regular expression</b> or just as a keyword."));
     table->horizontalHeaderItem(CoreHighlightSettingsPage::RegExColumn)->setWhatsThis(
-        tr("<b>RegEx</b>: This option determines if the highlight rule should be interpreted as a <b>regular expression</b> or just as a keyword."));
+                table->horizontalHeaderItem(CoreHighlightSettingsPage::RegExColumn)->toolTip());
 
     table->horizontalHeaderItem(CoreHighlightSettingsPage::CsColumn)->setToolTip(
-        tr("<b>CS</b>: This option determines if the highlight rule should be interpreted <b>case sensitive</b>."));
+                tr("<b>CS</b>: This option determines if the highlight rule should be interpreted "
+                   "<b>case sensitive</b>."));
     table->horizontalHeaderItem(CoreHighlightSettingsPage::CsColumn)->setWhatsThis(
-        tr("<b>CS</b>: This option determines if the highlight rule should be interpreted <b>case sensitive</b>."));
+                table->horizontalHeaderItem(CoreHighlightSettingsPage::CsColumn)->toolTip());
 
     table->horizontalHeaderItem(CoreHighlightSettingsPage::ChanColumn)->setToolTip(
-        tr("<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."));
+                tr("<p><b>Channel</b>: Semicolon separated list of channel names.</p>"
+                   "<p><i>Example:</i><br />"
+                   "<i>#quassel*; #foobar; !#quasseldroid</i><br />"
+                   "would match on #foobar and on 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 #foobar or any channel starting with "
+                   "<i>#quassel</i></p>"));
     table->horizontalHeaderItem(CoreHighlightSettingsPage::ChanColumn)->setWhatsThis(
-        tr("<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."));
+                table->horizontalHeaderItem(CoreHighlightSettingsPage::ChanColumn)->toolTip());
 
 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
     table->horizontalHeader()->setResizeMode(CoreHighlightSettingsPage::EnableColumn, QHeaderView::ResizeToContents);
@@ -130,6 +147,21 @@ void CoreHighlightSettingsPage::setupRuleTable(QTableWidget *table) const
 #endif
 }
 
+void CoreHighlightSettingsPage::updateCoreSupportStatus(bool state)
+{
+    // Assume connected state as enforced by the settings page UI
+    if (!state || Client::isCoreFeatureEnabled(Quassel::Feature::CoreSideHighlights)) {
+        // Either disconnected or core supports highlights, enable highlight configuration and hide
+        // warning.  Don't show the warning needlessly when disconnected.
+        ui.highlightsConfigWidget->setEnabled(true);
+        ui.coreUnsupportedWidget->setVisible(false);
+    } else {
+        // Core does not support highlights, show warning and disable highlight configuration
+        ui.highlightsConfigWidget->setEnabled(false);
+        ui.coreUnsupportedWidget->setVisible(true);
+    }
+}
+
 void CoreHighlightSettingsPage::clientConnected()
 {
     connect(Client::highlightRuleManager(), SIGNAL(updated()), SLOT(revert()));
@@ -193,6 +225,30 @@ void CoreHighlightSettingsPage::addNewHighlightRow(bool enable, const QString &n
 
     auto *senderItem = new QTableWidgetItem(sender);
 
+    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 should be "
+                   "interpreted as a <b>regular expression</b> or just as a keyword."));
+    csItem->setToolTip(
+                tr("<b>CS</b>: This option determines if the highlight rule should be interpreted "
+                   "<b>case sensitive</b>."));
+    senderItem->setToolTip(
+                tr("<b>Sender</b>: This option specifies which sender to match.  Leave blank to "
+                   "match any nickname."));
+    chanNameItem->setToolTip(
+                tr("<p><b>Channel</b>: Semicolon separated list of channel names.</p>"
+                   "<p><i>Example:</i><br />"
+                   "<i>#quassel*; #foobar; !#quasseldroid</i><br />"
+                   "would match on #foobar and on 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 #foobar or any channel starting with "
+                   "<i>#quassel</i></p>"));
+
     int lastRow = ui.highlightTable->rowCount() - 1;
     ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::NameColumn, nameItem);
     ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::RegExColumn, regexItem);
@@ -239,6 +295,30 @@ void CoreHighlightSettingsPage::addNewIgnoredRow(bool enable, const QString &nam
 
     auto *senderItem = new QTableWidgetItem(sender);
 
+    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 should be "
+                   "interpreted as a <b>regular expression</b> or just as a keyword."));
+    csItem->setToolTip(
+                tr("<b>CS</b>: This option determines if the highlight rule should be interpreted "
+                   "<b>case sensitive</b>."));
+    senderItem->setToolTip(
+                tr("<b>Sender</b>: This option specifies which sender nicknames match.  Leave "
+                   "blank to match any nickname."));
+    chanNameItem->setToolTip(
+                tr("<p><b>Channel</b>: Semicolon separated list of channel names.</p>"
+                   "<p><i>Example:</i><br />"
+                   "<i>#quassel*; #foobar; !#quasseldroid</i><br />"
+                   "would match on #foobar and on 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 #foobar or any channel starting with "
+                   "<i>#quassel</i></p>"));
+
     int lastRow = ui.ignoredTable->rowCount() - 1;
     ui.ignoredTable->setItem(lastRow, CoreHighlightSettingsPage::NameColumn, nameItem);
     ui.ignoredTable->setItem(lastRow, CoreHighlightSettingsPage::RegExColumn, regexItem);
@@ -489,6 +569,25 @@ void CoreHighlightSettingsPage::widgetHasChanged()
     setChangedState(true);
 }
 
+void CoreHighlightSettingsPage::on_coreUnsupportedDetails_clicked()
+{
+    // Re-use translations of "Local Highlights" as this is a word-for-word reference, forcing all
+    // spaces to non-breaking
+    const QString localHighlightsName = tr("Local Highlights").replace(" ", "&nbsp;");
+
+    const QString remoteHighlightsMsgText =
+            QString("<p><b>%1</b></p></br><p>%2</p></br><p>%3</p>"
+                    ).arg(tr("Your Quassel core is too old to support remote highlights"),
+                          tr("You need a Quassel core v0.13.0 or newer to configure remote "
+                             "highlights."),
+                          tr("You can still configure highlights for this device only in "
+                             "<i>%1</i>.").arg(localHighlightsName));
+
+    QMessageBox::warning(this,
+                         tr("Remote Highlights unsupported"),
+                         remoteHighlightsMsgText);
+}
+
 void CoreHighlightSettingsPage::importRules() {
     NotificationSettings notificationSettings;
 
@@ -515,5 +614,7 @@ void CoreHighlightSettingsPage::importRules() {
 }
 
 bool CoreHighlightSettingsPage::isSelectable() const {
-    return Client::isConnected() && Client::isCoreFeatureEnabled(Quassel::Feature::CoreSideHighlights);
+    return Client::isConnected();
+    // We check for Quassel::Feature::CoreSideHighlights when loading this page, allowing us to show
+    // a friendly error message.
 }