client: Highest sender prefix mode, migrate, fix
authorShane Synan <digitalcircuit36939@gmail.com>
Thu, 14 Jun 2018 04:58:48 +0000 (23:58 -0500)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sat, 16 Jun 2018 19:20:42 +0000 (21:20 +0200)
Add a "Highest mode" for showing sender prefixes, to only show the
highest in a given situation.  This mimics most IRC clients,
including Quasseldroid, while still saving the full mode details
behind the scenes.

Switch the UI from a Checkbox to a ComboBox, with all the 'fun' of
enums in Qt.  (Tip: don't code when tired.)

Add settings migration to preserve "None" for people upgrading, so
they won't suddenly see changes.

NOTE:  0.13 master users will need to opt in to enable showing sender
prefixes again.  A migration could be added, but the checkbox has
never been in beta or stable...

Fix up the "enableSenderBrackets" fallback default to be false, as
per Quassel itself.

Fix the sender prefix feature check to use "SenderPrefixes" instead
of "CoreSideHighlights".

src/qtui/chatviewsettings.h
src/qtui/qtuiapplication.cpp
src/qtui/qtuistyle.cpp
src/qtui/qtuistyle.h
src/qtui/settingspages/chatviewsettingspage.cpp
src/qtui/settingspages/chatviewsettingspage.h
src/qtui/settingspages/chatviewsettingspage.ui
src/uisupport/uistyle.cpp
src/uisupport/uistyle.h

index 06fb547..1af1756 100644 (file)
@@ -22,6 +22,7 @@
 #define CHATVIEWSETTINGS_H
 
 #include "qtuisettings.h"
+#include "uistyle.h"
 
 class ChatScene;
 class ChatView;
@@ -74,11 +75,21 @@ public:
     inline void setTimestampFormatString(const QString &format) { setLocalValue("TimestampFormat", format); }
 
     /**
-     * Gets if prefixmodes are shown before sender names
+     * Gets how prefix modes are shown before sender names
      *
-     * @returns True if sender prefixmodes enabled, otherwise false
+     * @returns SenderPrefixMode of what format to use for showing sender prefix modes
      */
-    inline bool showSenderPrefixes() { return localValue("ShowSenderPrefixes", false).toBool(); }
+    inline UiStyle::SenderPrefixMode SenderPrefixDisplay() {
+        return static_cast<UiStyle::SenderPrefixMode>(
+                    localValue("SenderPrefixMode",
+                               QVariant::fromValue<UiStyle::SenderPrefixMode>(
+                                   UiStyle::SenderPrefixMode::HighestMode)).toInt());
+        // Cast the QVariant to an integer, then cast that to the enum class.
+        // .canConvert<UiStyle::SenderPrefixMode>() returned true, but
+        // .value<UiStyle::SenderPrefixMode>(); always gave the default value 0.
+        //
+        // There's probably a cleaner way of doing this.  I couldn't find it within 4 hours, so...
+    }
 
     /**
      * Gets if brackets are shown around sender names
index 43abf86..a16f66e 100644 (file)
@@ -28,6 +28,7 @@
 #  include <KStandardDirs>
 #endif
 
+#include "chatviewsettings.h"
 #include "client.h"
 #include "cliparser.h"
 #include "mainwin.h"
@@ -158,7 +159,7 @@ bool QtUiApplication::migrateSettings()
     //
     // NOTE:  If you increase the minor version, you MUST ALSO add new version upgrade logic in
     // applySettingsMigration()!  Otherwise, settings upgrades will fail.
-    const uint VERSION_MINOR_CURRENT = 8;
+    const uint VERSION_MINOR_CURRENT = 9;
     // Stored minor version
     uint versionMinor = s.versionMinor();
 
@@ -223,6 +224,25 @@ bool QtUiApplication::applySettingsMigration(QtUiSettings settings, const uint n
     // saved.  Exceptions will be noted below.
     // NOTE:  If you add new upgrade logic here, you MUST ALSO increase VERSION_MINOR_CURRENT in
     // migrateSettings()!  Otherwise, your upgrade logic won't ever be called.
+    case 9:
+    {
+        // New default changes: show highest sender prefix mode, if available
+
+        // --------
+        // ChatView settings
+        ChatViewSettings chatViewSettings;
+        const QString senderPrefixModeId = "SenderPrefixMode";
+        if (!chatViewSettings.valueExists(senderPrefixModeId)) {
+            // New default is HighestMode, preserve previous behavior by setting to NoModes
+            chatViewSettings.setValue(senderPrefixModeId,
+                                      static_cast<int>(UiStyle::SenderPrefixMode::NoModes));
+        }
+        // --------
+
+        // Migration complete!
+        return true;
+    }
+
     case 8:
     {
         // New default changes: RegEx checkbox now toggles Channel regular expressions, too
index 3a5b649..f8e56aa 100644 (file)
@@ -32,8 +32,8 @@ QtUiStyle::QtUiStyle(QObject *parent) : UiStyle(parent)
     updateUseCustomTimestampFormat();
     s.notify("TimestampFormat", this, SLOT(updateTimestampFormatString()));
     updateTimestampFormatString();
-    s.notify("ShowSenderPrefixes", this, SLOT(updateShowSenderPrefixes()));
-    updateShowSenderPrefixes();
+    s.notify("SenderPrefixMode", this, SLOT(updateSenderPrefixDisplay()));
+    updateSenderPrefixDisplay();
     s.notify("ShowSenderBrackets", this, SLOT(updateShowSenderBrackets()));
     updateShowSenderBrackets();
 
@@ -56,10 +56,10 @@ void QtUiStyle::updateTimestampFormatString()
     setTimestampFormatString(s.timestampFormatString());
 }
 
-void QtUiStyle::updateShowSenderPrefixes()
+void QtUiStyle::updateSenderPrefixDisplay()
 {
     ChatViewSettings s;
-    enableSenderPrefixes(s.showSenderPrefixes());
+    setSenderPrefixDisplay(s.SenderPrefixDisplay());
 }
 
 void QtUiStyle::updateShowSenderBrackets()
index 8a85d93..94549e5 100644 (file)
@@ -61,9 +61,9 @@ private slots:
     void updateTimestampFormatString();
     
     /**
-     * Updates knowledge of whether or not to show sender prefixmodes
+     * Updates knowledge of how to display sender prefix modes
      */
-    void updateShowSenderPrefixes();
+    void updateSenderPrefixDisplay();
 
     /**
      * Updates knowledge of whether or not to show sender brackets
index b3171ac..c3fd8ae 100644 (file)
  ***************************************************************************/
 
 #include "chatviewsettingspage.h"
+#include "chatviewsettings.h"
 #include "client.h"
 #include "qtui.h"
 #include "qtuistyle.h"
+#include "uistyle.h"
 
 ChatViewSettingsPage::ChatViewSettingsPage(QWidget *parent)
     : SettingsPage(tr("Interface"), tr("Chat View"), parent)
@@ -33,18 +35,42 @@ ChatViewSettingsPage::ChatViewSettingsPage(QWidget *parent)
     ui.showWebPreview->setEnabled(false);
 #endif
 
+    // Handle UI dependent on core feature flags here
     // FIXME remove with protocol v11
     if (!Client::isCoreFeatureEnabled(Quassel::Feature::SynchronizedMarkerLine)) {
         ui.autoMarkerLine->setEnabled(false);
         ui.autoMarkerLine->setChecked(true);
         ui.autoMarkerLine->setToolTip(tr("You need at least version 0.6 of Quassel Core to use this feature"));
     }
-    if (!Client::isCoreFeatureEnabled(Quassel::Feature::CoreSideHighlights)) {
-        ui.showSenderPrefixes->setEnabled(false);
-        ui.showSenderPrefixes->setToolTip(tr("You need at least version 0.13 of Quassel Core to use this feature"));
+    if (!Client::isCoreFeatureEnabled(Quassel::Feature::SenderPrefixes)) {
+        // Sender prefixes are not supported, disallow toggling
+        ui.senderPrefixComboBox->setEnabled(false);
+        // Split up the message to allow re-using translations:
+        // [Original tool-tip]
+        // [Bold 'does not support feature' message]
+        // [Specific version needed and feature details]
+        ui.senderPrefixComboBox->setToolTip(
+                    QString("<b>%2</b><br/>%3").arg(
+                        tr("Your Quassel core does not support this feature"),
+                        tr("You need a Quassel core v0.13.0 or newer in order to show sender "
+                           "modes before nicknames.")));
     }
-
     initAutoWidgets();
+    initSenderPrefixComboBox();
+}
+
+
+void ChatViewSettingsPage::initSenderPrefixComboBox()
+{
+    // Fill combobox with sender prefix modes
+    // Do not change ComboBox ordering without also adjusting chatviewsettingspage.ui "defaultValue"
+    // and UiStyle::SenderPrefixMode
+    ui.senderPrefixComboBox->addItem(tr("No modes"),
+                                     static_cast<int>(UiStyle::SenderPrefixMode::NoModes));
+    ui.senderPrefixComboBox->addItem(tr("Highest mode"),
+                                     static_cast<int>(UiStyle::SenderPrefixMode::HighestMode));
+    ui.senderPrefixComboBox->addItem(tr("All modes"),
+                                     static_cast<int>(UiStyle::SenderPrefixMode::AllModes));
 }
 
 
index b1ad4cd..a47db0e 100644 (file)
@@ -41,6 +41,11 @@ public slots:
 private:
     Ui::ChatViewSettingsPage ui;
 
+    /**
+     * Initialize the available options for sender prefixes
+     */
+    void initSenderPrefixComboBox();
+
     inline QString settingsKey() const { return QString("QtUi/ChatView/__default__"); }
 };
 
index 349d335..f0f1403 100644 (file)
     </widget>
    </item>
    <item>
-    <widget class="QCheckBox" name="showSenderPrefixes">
-     <property name="toolTip">
-      <string>Shows the modes of senders before their name (e.g. @, +)</string>
-     </property>
-     <property name="text">
-      <string>Show sendermodes in front of nicknames</string>
-     </property>
-     <property name="checked">
-      <bool>true</bool>
-     </property>
-     <property name="defaultValue" stdset="0">
-      <bool>true</bool>
-     </property>
-     <property name="settingsKey" stdset="0">
-      <string notr="true">ShowSenderPrefixes</string>
-     </property>
-    </widget>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Show sender modes before nicknames:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QComboBox" name="senderPrefixComboBox">
+       <property name="toolTip">
+        <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot;font-weight:400; font-style:normal;&quot;&gt;
+&lt;p&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Sender modes:&lt;/span&gt;&lt;/p&gt;
+&lt;p&gt;&lt;span style=&quot;text-decoration: underline;&quot;&gt;No modes:&lt;/span&gt; Don't show any modes&lt;br/&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Example:&lt;/span&gt; &amp;lt;nickname&amp;gt;&lt;/p&gt;
+&lt;p&gt;&lt;span style=&quot;text-decoration: underline;&quot;&gt;Highest mode:&lt;/span&gt; Show only the highest active mode&lt;br/&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Example:&lt;/span&gt; &amp;lt;@nickname&amp;gt;&lt;/p&gt;
+&lt;p&gt;&lt;span style=&quot;text-decoration: underline;&quot;&gt;All modes:&lt;/span&gt; Show all active modes&lt;br/&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Example:&lt;/span&gt; &amp;lt;@+nickname&amp;gt;&lt;/p&gt;
+&lt;/body&gt;&lt;/html&gt;</string>
+       </property>
+       <property name="defaultValue" stdset="0">
+        <bool>1</bool>
+       </property>
+       <property name="settingsKey" stdset="0">
+        <string notr="true">SenderPrefixMode</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
    </item>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout_3">
   <tabstop>customTimestampFormat</tabstop>
   <tabstop>timestampFormat</tabstop>
   <tabstop>showSenderBrackets</tabstop>
+  <tabstop>senderPrefixComboBox</tabstop>
   <tabstop>customChatViewFont</tabstop>
   <tabstop>showWebPreview</tabstop>
   <tabstop>autoMarkerLine</tabstop>
index d5345ec..d1c78cd 100644 (file)
@@ -36,7 +36,7 @@ QHash<QString, UiStyle::FormatType> UiStyle::_formatCodes;
 bool UiStyle::_useCustomTimestampFormat;       /// If true, use the custom timestamp format
 QString UiStyle::_timestampFormatString;       /// Timestamp format
 QString UiStyle::_systemTimestampFormatString; /// Cached copy of system locale timestamp format
-bool UiStyle::_showSenderPrefixes;             /// If true, show prefixmodes before sender names
+UiStyle::SenderPrefixMode UiStyle::_senderPrefixDisplay; /// Display of prefix modes before sender
 bool UiStyle::_showSenderBrackets;             /// If true, show brackets around sender names
 
 namespace {
@@ -100,8 +100,8 @@ UiStyle::UiStyle(QObject *parent)
     // in there.
     setUseCustomTimestampFormat(false);
     setTimestampFormatString(" hh:mm:ss");
-    enableSenderPrefixes(false);
-    enableSenderBrackets(true);
+    setSenderPrefixDisplay(UiStyle::SenderPrefixMode::HighestMode);
+    enableSenderBrackets(false);
 
     // BufferView / NickView settings
     UiStyleSettings s;
@@ -251,10 +251,10 @@ void UiStyle::setTimestampFormatString(const QString &format)
     }
 }
 
-void UiStyle::enableSenderPrefixes(bool enabled)
+void UiStyle::setSenderPrefixDisplay(UiStyle::SenderPrefixMode mode)
 {
-    if (_showSenderPrefixes != enabled) {
-        _showSenderPrefixes = enabled;
+    if (_senderPrefixDisplay != mode) {
+        _senderPrefixDisplay = mode;
     }
 }
 
@@ -1058,8 +1058,18 @@ QString UiStyle::StyledMessage::plainSender() const
 QString UiStyle::StyledMessage::decoratedSender() const
 {
     QString _senderPrefixes;
-    if (_showSenderPrefixes) {
+    switch (_senderPrefixDisplay) {
+    case UiStyle::SenderPrefixMode::AllModes:
+        // Show every available mode
         _senderPrefixes = senderPrefixes();
+        break;
+    case UiStyle::SenderPrefixMode::HighestMode:
+        // Show the highest available mode (left-most)
+        _senderPrefixes = senderPrefixes().left(1);
+        break;
+    case UiStyle::SenderPrefixMode::NoModes:
+        // Don't show any mode (already empty by default)
+        break;
     }
 
     switch (type()) {
index 899ab9a..008577d 100644 (file)
@@ -41,6 +41,7 @@
 class UiStyle : public QObject
 {
     Q_OBJECT
+    Q_ENUMS(SenderPrefixModes)
 
 public:
     UiStyle(QObject *parent = 0);
@@ -162,6 +163,15 @@ public:
         NumRoles // must be last!
     };
 
+    /// Display of sender prefix modes
+    enum class SenderPrefixMode {
+        NoModes = 0,      ///< Hide sender modes
+        HighestMode = 1,  ///< Show the highest active sender mode
+        AllModes = 2      ///< Show all active sender modes
+    };
+    // Do not change SenderPrefixMode numbering without also adjusting
+    // ChatViewSettingsPage::initSenderPrefixComboBox() and chatviewsettingspage.ui "defaultValue"
+
     struct Format {
         FormatType type;
         QColor foreground;
@@ -305,11 +315,11 @@ protected:
      */
     static void setTimestampFormatString(const QString &format);
     /**
-     * Updates the local setting cache of whether or not to show sender prefixmodes
+     * Updates the local setting cache of how to display sender prefix modes
      *
-     * @param[in] enabled  If true, sender prefixmodes are enabled, otherwise false.
+     * @param[in] mode  Display format for sender prefix modes
      */
-    static void enableSenderPrefixes(bool enabled);
+    static void setSenderPrefixDisplay(UiStyle::SenderPrefixMode mode);
 
     /**
      * Updates the local setting cache of whether or not to show sender brackets
@@ -335,7 +345,7 @@ private:
     static bool _useCustomTimestampFormat;        /// If true, use the custom timestamp format
     static QString _systemTimestampFormatString;  /// Cached copy of system locale timestamp format
     static QString _timestampFormatString;        /// Timestamp format string
-    static bool _showSenderPrefixes;              /// If true, show prefixmodes before sender names
+    static UiStyle::SenderPrefixMode _senderPrefixDisplay; /// Display of prefix modes before sender
     static bool _showSenderBrackets;              /// If true, show brackets around sender names
 
     QIcon _channelJoinedIcon;
@@ -413,3 +423,4 @@ QDataStream &operator>>(QDataStream &in, UiStyle::FormatList &formatList);
 
 Q_DECLARE_METATYPE(UiStyle::FormatList)
 Q_DECLARE_METATYPE(UiStyle::MessageLabel)
+Q_DECLARE_METATYPE(UiStyle::SenderPrefixMode)