client: Fix lost unsaved highlights on Import
[quassel.git] / src / qtui / settingspages / corehighlightsettingspage.cpp
index 78805cf..9d2f155 100644 (file)
 
 #include "client.h"
 #include "corehighlightsettingspage.h"
+#include "icon.h"
 #include "qtui.h"
 
 CoreHighlightSettingsPage::CoreHighlightSettingsPage(QWidget *parent)
-    : SettingsPage(tr("Interface"), tr("Remote Highlights"), parent)
+    : SettingsPage(tr("Interface"),
+                   // In Monolithic mode, local highlights are replaced by remote highlights
+                   Quassel::runMode() == Quassel::Monolithic ?
+                       tr("Highlights") : tr("Remote Highlights"),
+                   parent)
 {
     ui.setupUi(this);
 
@@ -86,9 +91,27 @@ CoreHighlightSettingsPage::CoreHighlightSettingsPage(QWidget *parent)
     connect(Client::instance(), SIGNAL(connected()), this, SLOT(clientConnected()));
 
     // Warning icon
-    ui.coreUnsupportedIcon->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(16));
+    ui.coreUnsupportedIcon->setPixmap(icon::get("dialog-warning").pixmap(16));
+
+    // Set up client/monolithic remote highlights information
+    if (Quassel::runMode() == Quassel::Monolithic) {
+        // We're running in Monolithic mode, local highlights are considered legacy
+        ui.highlightImport->setText(tr("Import Legacy"));
+        ui.highlightImport->setToolTip(tr("Import highlight rules configured in <i>%1</i>.")
+                                       .arg(tr("Legacy Highlights").replace(" ", "&nbsp;")));
+        // Re-use translations of "Legacy Highlights" as this is a word-for-word reference, forcing
+        // all spaces to be non-breaking
+    } else {
+        // We're running in client/split mode, local highlights are distinguished from remote
+        ui.highlightImport->setText(tr("Import Local"));
+        ui.highlightImport->setToolTip(tr("Import highlight rules configured in <i>%1</i>.")
+                                       .arg(tr("Local Highlights").replace(" ", "&nbsp;")));
+        // Re-use translations of "Local Highlights" as this is a word-for-word reference, forcing
+        // all spaces to be non-breaking
+    }
 }
 
+
 void CoreHighlightSettingsPage::coreConnectionStateChanged(bool state)
 {
     updateCoreSupportStatus(state);
@@ -100,6 +123,7 @@ void CoreHighlightSettingsPage::coreConnectionStateChanged(bool state)
     }
 }
 
+
 void CoreHighlightSettingsPage::setupRuleTable(QTableWidget *table) const
 {
     table->verticalHeader()->hide();
@@ -175,6 +199,7 @@ void CoreHighlightSettingsPage::setupRuleTable(QTableWidget *table) const
 #endif
 }
 
+
 void CoreHighlightSettingsPage::updateCoreSupportStatus(bool state)
 {
     // Assume connected state as enforced by the settings page UI
@@ -190,11 +215,13 @@ void CoreHighlightSettingsPage::updateCoreSupportStatus(bool state)
     }
 }
 
+
 void CoreHighlightSettingsPage::clientConnected()
 {
     connect(Client::highlightRuleManager(), SIGNAL(updated()), SLOT(revert()));
 }
 
+
 void CoreHighlightSettingsPage::revert()
 {
     if (!hasChanged())
@@ -204,11 +231,13 @@ void CoreHighlightSettingsPage::revert()
     load();
 }
 
+
 bool CoreHighlightSettingsPage::hasDefaults() const
 {
     return true;
 }
 
+
 void CoreHighlightSettingsPage::defaults()
 {
     int highlightNickType = HighlightRuleManager::HighlightNickType::CurrentNick;
@@ -221,11 +250,16 @@ void CoreHighlightSettingsPage::defaults()
     widgetHasChanged();
 }
 
-void CoreHighlightSettingsPage::addNewHighlightRow(bool enable, const QString &name, bool regex, bool cs,
+
+void CoreHighlightSettingsPage::addNewHighlightRow(bool enable, int id, const QString &name, bool regex, bool cs,
                                                    const QString &sender, const QString &chanName, bool self)
 {
     ui.highlightTable->setRowCount(ui.highlightTable->rowCount() + 1);
 
+    if (id < 0) {
+        id = nextId();
+    }
+
     auto *nameItem = new QTableWidgetItem(name);
 
     auto *regexItem = new QTableWidgetItem("");
@@ -300,14 +334,19 @@ void CoreHighlightSettingsPage::addNewHighlightRow(bool enable, const QString &n
     if (!self)
         ui.highlightTable->setCurrentItem(nameItem);
 
-    highlightList << HighlightRuleManager::HighlightRule(name, regex, cs, enable, false, sender, chanName);
+    highlightList << HighlightRuleManager::HighlightRule(id, name, regex, cs, enable, false, sender, chanName);
 }
 
-void CoreHighlightSettingsPage::addNewIgnoredRow(bool enable, const QString &name, bool regex, bool cs,
+
+void CoreHighlightSettingsPage::addNewIgnoredRow(bool enable, int id, const QString &name, bool regex, bool cs,
                                                  const QString &sender, const QString &chanName, bool self)
 {
     ui.ignoredTable->setRowCount(ui.ignoredTable->rowCount() + 1);
 
+    if (id < 0) {
+        id = nextId();
+    }
+
     auto *nameItem = new QTableWidgetItem(name);
 
     auto *regexItem = new QTableWidgetItem("");
@@ -370,9 +409,10 @@ void CoreHighlightSettingsPage::addNewIgnoredRow(bool enable, const QString &nam
     if (!self)
         ui.ignoredTable->setCurrentItem(nameItem);
 
-    ignoredList << HighlightRuleManager::HighlightRule(name, regex, cs, enable, true, sender, chanName);
+    ignoredList << HighlightRuleManager::HighlightRule(id, name, regex, cs, enable, true, sender, chanName);
 }
 
+
 void CoreHighlightSettingsPage::removeSelectedHighlightRows()
 {
     QList<int> selectedRows;
@@ -391,6 +431,7 @@ void CoreHighlightSettingsPage::removeSelectedHighlightRows()
     }
 }
 
+
 void CoreHighlightSettingsPage::removeSelectedIgnoredRows()
 {
     QList<int> selectedRows;
@@ -409,12 +450,15 @@ void CoreHighlightSettingsPage::removeSelectedIgnoredRows()
     }
 }
 
-void CoreHighlightSettingsPage::highlightNicksChanged(const int index) {
+
+void CoreHighlightSettingsPage::highlightNicksChanged(const int index)
+{
     // Only allow toggling "Case sensitive" when a nickname will be highlighted
     auto highlightNickType = ui.highlightNicksComboBox->itemData(index).value<int>();
     ui.nicksCaseSensitive->setEnabled(highlightNickType != HighlightRuleManager::NoNick);
 }
 
+
 void CoreHighlightSettingsPage::selectHighlightRow(QTableWidgetItem *item)
 {
     int row = item->row();
@@ -424,6 +468,7 @@ void CoreHighlightSettingsPage::selectHighlightRow(QTableWidgetItem *item)
                            selected);
 }
 
+
 void CoreHighlightSettingsPage::selectIgnoredRow(QTableWidgetItem *item)
 {
     int row = item->row();
@@ -433,6 +478,7 @@ void CoreHighlightSettingsPage::selectIgnoredRow(QTableWidgetItem *item)
                            selected);
 }
 
+
 void CoreHighlightSettingsPage::emptyHighlightTable()
 {
     // ui.highlight and highlightList should have the same size, but just to make sure.
@@ -445,6 +491,7 @@ void CoreHighlightSettingsPage::emptyHighlightTable()
     highlightList.clear();
 }
 
+
 void CoreHighlightSettingsPage::emptyIgnoredTable()
 {
     // ui.highlight and highlightList should have the same size, but just to make sure.
@@ -457,6 +504,7 @@ void CoreHighlightSettingsPage::emptyIgnoredTable()
     ignoredList.clear();
 }
 
+
 void CoreHighlightSettingsPage::highlightTableChanged(QTableWidgetItem *item)
 {
     if (item->row() + 1 > highlightList.size())
@@ -495,6 +543,7 @@ void CoreHighlightSettingsPage::highlightTableChanged(QTableWidgetItem *item)
     emit widgetHasChanged();
 }
 
+
 void CoreHighlightSettingsPage::ignoredTableChanged(QTableWidgetItem *item)
 {
     if (item->row() + 1 > ignoredList.size())
@@ -533,6 +582,7 @@ void CoreHighlightSettingsPage::ignoredTableChanged(QTableWidgetItem *item)
     emit widgetHasChanged();
 }
 
+
 void CoreHighlightSettingsPage::load()
 {
     emptyHighlightTable();
@@ -543,6 +593,7 @@ void CoreHighlightSettingsPage::load()
         for (auto &rule : ruleManager->highlightRuleList()) {
             if (rule.isInverse) {
                 addNewIgnoredRow(rule.isEnabled,
+                                 rule.id,
                                  rule.name,
                                  rule.isRegEx,
                                  rule.isCaseSensitive,
@@ -550,7 +601,7 @@ void CoreHighlightSettingsPage::load()
                                  rule.chanName);
             }
             else {
-                addNewHighlightRow(rule.isEnabled, rule.name, rule.isRegEx, rule.isCaseSensitive, rule.sender,
+                addNewHighlightRow(rule.isEnabled, rule.id, rule.name, rule.isRegEx, rule.isCaseSensitive, rule.sender,
                                    rule.chanName);
             }
         }
@@ -568,6 +619,7 @@ void CoreHighlightSettingsPage::load()
     }
 }
 
+
 void CoreHighlightSettingsPage::save()
 {
     if (!hasChanged())
@@ -585,12 +637,12 @@ void CoreHighlightSettingsPage::save()
     clonedManager.clear();
 
     for (auto &rule : highlightList) {
-        clonedManager.addHighlightRule(rule.name, rule.isRegEx, rule.isCaseSensitive, rule.isEnabled, false,
+        clonedManager.addHighlightRule(rule.id, rule.name, rule.isRegEx, rule.isCaseSensitive, rule.isEnabled, false,
                                        rule.sender, rule.chanName);
     }
 
     for (auto &rule : ignoredList) {
-        clonedManager.addHighlightRule(rule.name, rule.isRegEx, rule.isCaseSensitive, rule.isEnabled, true,
+        clonedManager.addHighlightRule(rule.id, rule.name, rule.isRegEx, rule.isCaseSensitive, rule.isEnabled, true,
                                        rule.sender, rule.chanName);
     }
 
@@ -604,11 +656,32 @@ void CoreHighlightSettingsPage::save()
     load();
 }
 
+
+int CoreHighlightSettingsPage::nextId()
+{
+    int max = 0;
+    for (int i = 0; i < highlightList.count(); i++) {
+        int id = highlightList[i].id;
+        if (id > max) {
+            max = id;
+        }
+    }
+    for (int i = 0; i < ignoredList.count(); i++) {
+        int id = ignoredList[i].id;
+        if (id > max) {
+            max = id;
+        }
+    }
+    return max + 1;
+}
+
+
 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
@@ -628,36 +701,48 @@ void CoreHighlightSettingsPage::on_coreUnsupportedDetails_clicked()
                          remoteHighlightsMsgText);
 }
 
-void CoreHighlightSettingsPage::importRules() {
+
+void CoreHighlightSettingsPage::importRules()
+{
     NotificationSettings notificationSettings;
 
     const auto localHighlightList = notificationSettings.highlightList();
 
-    // 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;");
+    // Re-use translations of "Legacy/Local Highlights" as this is a word-for-word reference,
+    // forcing all spaces to non-breaking
+    QString localHighlightsName;
+    if (Quassel::runMode() == Quassel::Monolithic) {
+        localHighlightsName = tr("Legacy Highlights").replace(" ", "&nbsp;");
+    } else {
+        localHighlightsName = tr("Local Highlights").replace(" ", "&nbsp;");
+    }
 
     if (localHighlightList.count() == 0) {
         // No highlight rules exist to import, do nothing
         QMessageBox::information(this,
-                                 tr("No local highlights"),
+                                 tr("No highlights to import"),
                                  tr("No highlight rules in <i>%1</i>."
                                     ).arg(localHighlightsName));
         return;
     }
 
     int ret = QMessageBox::question(this,
-                                    tr("Import local highlights?"),
+                                    tr("Import highlights?"),
                                     tr("Import all highlight rules from <i>%1</i>?"
                                        ).arg(localHighlightsName),
                                     QMessageBox::Yes|QMessageBox::No,
                                     QMessageBox::No);
 
-    if (ret == QMessageBox::No) {
-        // Only two options, Yes or No, just return if No
+    if (ret != QMessageBox::Yes) {
+        // Only two options, Yes or No, return if not Yes
         return;
     }
 
+    if (hasChanged()) {
+        // Save existing changes first to avoid overwriting them
+        save();
+    }
+
     auto clonedManager = HighlightRuleManager();
     clonedManager.fromVariantMap(Client::highlightRuleManager()->toVariantMap());
 
@@ -665,6 +750,7 @@ void CoreHighlightSettingsPage::importRules() {
         auto highlightRule = variant.toMap();
 
         clonedManager.addHighlightRule(
+                clonedManager.nextId(),
                 highlightRule["Name"].toString(),
                 highlightRule["RegEx"].toBool(),
                 highlightRule["CS"].toBool(),
@@ -681,12 +767,14 @@ void CoreHighlightSettingsPage::importRules() {
 
     // Give a heads-up that all succeeded
     QMessageBox::information(this,
-                             tr("Imported local highlights"),
+                             tr("Imported highlights"),
                              tr("%1 highlight rules successfully imported."
                                 ).arg(QString::number(localHighlightList.count())));
 }
 
-bool CoreHighlightSettingsPage::isSelectable() const {
+
+bool CoreHighlightSettingsPage::isSelectable() const
+{
     return Client::isConnected();
     // We check for Quassel::Feature::CoreSideHighlights when loading this page, allowing us to show
     // a friendly error message.