Add button and bindings for striking through text
authorAlex McGrath <amk@amk.ie>
Thu, 1 Aug 2019 16:07:46 +0000 (17:07 +0100)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sat, 3 Oct 2020 14:40:08 +0000 (16:40 +0200)
This includes icons and a small regex fix from @digitalcircuit

17 files changed:
3rdparty/icons/breeze-dark/actions/16/format-text-strikethrough.svg [new file with mode: 0644]
3rdparty/icons/breeze-dark/actions/22/format-text-strikethrough.svg [new file with mode: 0644]
3rdparty/icons/breeze-dark/actions/24/format-text-strikethrough.svg [new file with mode: 0644]
3rdparty/icons/breeze/actions/16/format-text-strikethrough.svg [new file with mode: 0644]
3rdparty/icons/breeze/actions/22/format-text-strikethrough.svg [new file with mode: 0644]
3rdparty/icons/breeze/actions/24/format-text-strikethrough.svg [new file with mode: 0644]
3rdparty/icons/oxygen/16x16/actions/format-text-strikethrough.png [new file with mode: 0644]
3rdparty/icons/oxygen/22x22/actions/format-text-strikethrough.png [new file with mode: 0644]
3rdparty/icons/oxygen/32x32/actions/format-text-strikethrough.png [new file with mode: 0644]
3rdparty/icons/oxygen/48x48/actions/format-text-strikethrough.png [new file with mode: 0644]
data/stylesheets/m4yer.qss
src/qtui/inputwidget.cpp
src/qtui/inputwidget.h
src/qtui/inputwidget.ui
src/qtui/mainwin.cpp
src/qtui/mainwin.h
src/uisupport/multilineedit.cpp

diff --git a/3rdparty/icons/breeze-dark/actions/16/format-text-strikethrough.svg b/3rdparty/icons/breeze-dark/actions/16/format-text-strikethrough.svg
new file mode 100644 (file)
index 0000000..e5f4aab
--- /dev/null
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#eff0f1;
+      }
+      </style>
+  </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none" 
+       d="M 8.28125 2 C 5.87276 1.9779 2.98125 3.61871 4.59375 7.3125 L 10.25 7.3125 C 1.25 5.0625 8.75114 -0.1875 10.28125 5.8125 L 11 5.8125 L 11 3.75 C 10.9887 2.625 9.72635 2.01328 8.28125 2 z M 2 8 L 2 8.75 L 2 9 L 14 9 L 14 8.75 L 14 8 L 2 8 z M 8.75 9.5 C 12.71497 13.43247 6.77502 14.69352 5 10.25 L 4.25 10.25 L 4.25 12.5 C 4.39332 14.38685 13.25 15.5 11.75 9.5 L 8.75 9.5 z "
+     class="ColorScheme-Text"
+     />
+</svg>
diff --git a/3rdparty/icons/breeze-dark/actions/22/format-text-strikethrough.svg b/3rdparty/icons/breeze-dark/actions/22/format-text-strikethrough.svg
new file mode 100644 (file)
index 0000000..24903dd
--- /dev/null
@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#eff0f1;
+      }
+      </style>
+  </defs>
+ <path 
+    style="fill:currentColor;fill-opacity:1;stroke:none" 
+    d="M 11.367188 3 C 8.1558629 2.9704971 4.2894531 5.1569693 6.4394531 10.082031 L 14 10.082031 C 1.999998 7.0820318 12.000924 0.08203135 14.041016 8.0820312 L 15 8.0820312 L 15 5.3339844 C 14.984965 3.8339844 13.29398 3.0177018 11.367188 3 z M 3 11 L 3 12 L 19 12 L 19 11 L 3 11 z M 12 12.998047 C 17.286623 18.241347 9.3666873 19.922747 7 13.998047 L 6 13.998047 L 6 16.998047 C 6.1910979 19.513847 18 20.998047 16 12.998047 L 12 12.998047 z "
+    class="ColorScheme-Text"
+    />  
+</svg>
diff --git a/3rdparty/icons/breeze-dark/actions/24/format-text-strikethrough.svg b/3rdparty/icons/breeze-dark/actions/24/format-text-strikethrough.svg
new file mode 100644 (file)
index 0000000..865f401
--- /dev/null
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#eff0f1;
+      }
+      </style>
+  </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none" 
+     d="M 12.367188 4 C 9.1558624 3.9704971 5.2894531 6.1569696 7.4394531 11.082031 L 15 11.082031 C 2.999998 8.082032 13.000924 1.0820314 15.041016 9.0820312 L 16 9.0820312 L 16 6.3339844 C 15.984965 4.8339844 14.293979 4.0177018 12.367188 4 z M 4 12 L 4 13 L 20 13 L 20 12 L 4 12 z M 13 13.998047 C 18.286623 19.241347 10.366687 20.922747 8 14.998047 L 7 14.998047 L 7 17.998047 C 7.1910979 20.513847 19 21.998047 17 13.998047 L 13 13.998047 z "
+     class="ColorScheme-Text"
+     />
+</svg>
diff --git a/3rdparty/icons/breeze/actions/16/format-text-strikethrough.svg b/3rdparty/icons/breeze/actions/16/format-text-strikethrough.svg
new file mode 100644 (file)
index 0000000..752b962
--- /dev/null
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#232629;
+      }
+      </style>
+  </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none" 
+       d="M 8.28125 2 C 5.87276 1.9779 2.98125 3.61871 4.59375 7.3125 L 10.25 7.3125 C 1.25 5.0625 8.75114 -0.1875 10.28125 5.8125 L 11 5.8125 L 11 3.75 C 10.9887 2.625 9.72635 2.01328 8.28125 2 z M 2 8 L 2 8.75 L 2 9 L 14 9 L 14 8.75 L 14 8 L 2 8 z M 8.75 9.5 C 12.71497 13.43247 6.77502 14.69352 5 10.25 L 4.25 10.25 L 4.25 12.5 C 4.39332 14.38685 13.25 15.5 11.75 9.5 L 8.75 9.5 z "
+     class="ColorScheme-Text"
+     />
+</svg>
diff --git a/3rdparty/icons/breeze/actions/22/format-text-strikethrough.svg b/3rdparty/icons/breeze/actions/22/format-text-strikethrough.svg
new file mode 100644 (file)
index 0000000..7f0cfc4
--- /dev/null
@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#232629;
+      }
+      </style>
+  </defs>
+ <path 
+    style="fill:currentColor;fill-opacity:1;stroke:none" 
+    d="M 11.367188 3 C 8.1558629 2.9704971 4.2894531 5.1569693 6.4394531 10.082031 L 14 10.082031 C 1.999998 7.0820318 12.000924 0.08203135 14.041016 8.0820312 L 15 8.0820312 L 15 5.3339844 C 14.984965 3.8339844 13.29398 3.0177018 11.367188 3 z M 3 11 L 3 12 L 19 12 L 19 11 L 3 11 z M 12 12.998047 C 17.286623 18.241347 9.3666873 19.922747 7 13.998047 L 6 13.998047 L 6 16.998047 C 6.1910979 19.513847 18 20.998047 16 12.998047 L 12 12.998047 z "
+    class="ColorScheme-Text"
+    />  
+</svg>
diff --git a/3rdparty/icons/breeze/actions/24/format-text-strikethrough.svg b/3rdparty/icons/breeze/actions/24/format-text-strikethrough.svg
new file mode 100644 (file)
index 0000000..27b4f30
--- /dev/null
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#232629;
+      }
+      </style>
+  </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none" 
+     d="M 12.367188 4 C 9.1558624 3.9704971 5.2894531 6.1569696 7.4394531 11.082031 L 15 11.082031 C 2.999998 8.082032 13.000924 1.0820314 15.041016 9.0820312 L 16 9.0820312 L 16 6.3339844 C 15.984965 4.8339844 14.293979 4.0177018 12.367188 4 z M 4 12 L 4 13 L 20 13 L 20 12 L 4 12 z M 13 13.998047 C 18.286623 19.241347 10.366687 20.922747 8 14.998047 L 7 14.998047 L 7 17.998047 C 7.1910979 20.513847 19 21.998047 17 13.998047 L 13 13.998047 z "
+     class="ColorScheme-Text"
+     />
+</svg>
diff --git a/3rdparty/icons/oxygen/16x16/actions/format-text-strikethrough.png b/3rdparty/icons/oxygen/16x16/actions/format-text-strikethrough.png
new file mode 100644 (file)
index 0000000..f248ce0
Binary files /dev/null and b/3rdparty/icons/oxygen/16x16/actions/format-text-strikethrough.png differ
diff --git a/3rdparty/icons/oxygen/22x22/actions/format-text-strikethrough.png b/3rdparty/icons/oxygen/22x22/actions/format-text-strikethrough.png
new file mode 100644 (file)
index 0000000..3e25ced
Binary files /dev/null and b/3rdparty/icons/oxygen/22x22/actions/format-text-strikethrough.png differ
diff --git a/3rdparty/icons/oxygen/32x32/actions/format-text-strikethrough.png b/3rdparty/icons/oxygen/32x32/actions/format-text-strikethrough.png
new file mode 100644 (file)
index 0000000..d062ee7
Binary files /dev/null and b/3rdparty/icons/oxygen/32x32/actions/format-text-strikethrough.png differ
diff --git a/3rdparty/icons/oxygen/48x48/actions/format-text-strikethrough.png b/3rdparty/icons/oxygen/48x48/actions/format-text-strikethrough.png
new file mode 100644 (file)
index 0000000..88970f6
Binary files /dev/null and b/3rdparty/icons/oxygen/48x48/actions/format-text-strikethrough.png differ
index 163eff5..eb79149 100644 (file)
@@ -84,11 +84,13 @@ ChatLine[bg-color="0f"] { background: #c0c0c0; }
 ChatLine[format="bold"]      { font-weight: bold;}
 ChatLine[format="italic"]    { font-style: italic; }
 ChatLine[format="underline"] { font-style: underline; }
+ChatLine[format="strikethrough"] { font-style: strikethrough; }
 
     // for sender
     ChatLine[format="bold", sender="self"]      { foreground: #323232; font-weight: bold; }
     ChatLine[format="italic", sender="self"]    { foreground: #323232; font-style: italic; }
     ChatLine[format="underline", sender="self"] { foreground: #323232; font-style: underline; }
+    ChatLine[format="strikethrough", sender="self"] { foreground: #323232; font-style: strikethrough; }
 
 // ChatView message colors
 ChatLine#notice { foreground: #916409; }
index ad83716..6998672 100644 (file)
@@ -68,6 +68,7 @@ InputWidget::InputWidget(QWidget* parent)
     ui.boldButton->setIcon(icon::get("format-text-bold"));
     ui.italicButton->setIcon(icon::get("format-text-italic"));
     ui.underlineButton->setIcon(icon::get("format-text-underline"));
+    ui.strikethroughButton->setIcon(icon::get("format-text-strikethrough"));
     ui.clearButton->setIcon(icon::get("edit-clear"));
     ui.encryptionIconLabel->hide();
 
@@ -374,6 +375,11 @@ void InputWidget::toggleFormatUnderline()
     setFormatUnderline(!ui.underlineButton->isChecked());
 }
 
+void InputWidget::toggleFormatStrikethrough()
+{
+    setFormatStrikethrough(!ui.strikethroughButton->isChecked());
+}
+
 void InputWidget::clearFormat()
 {
     // Clear all formatting for selection (not global)
@@ -511,6 +517,7 @@ void InputWidget::setFormatClear(const bool global)
     QTextCharFormat fmt;
     fmt.setFontWeight(QFont::Normal);
     fmt.setFontUnderline(false);
+    fmt.setFontStrikeOut(false);
     fmt.setFontItalic(false);
     fmt.clearForeground();
     fmt.clearBackground();
@@ -525,6 +532,7 @@ void InputWidget::setFormatClear(const bool global)
     ui.boldButton->setChecked(false);
     ui.italicButton->setChecked(false);
     ui.underlineButton->setChecked(false);
+    ui.strikethroughButton->setChecked(false);
 }
 
 void InputWidget::setFormatBold(const bool bold)
@@ -557,6 +565,16 @@ void InputWidget::setFormatUnderline(const bool underline)
     ui.underlineButton->setChecked(underline);
 }
 
+void InputWidget::setFormatStrikethrough(const bool strike)
+{
+    // Apply formatting
+    QTextCharFormat fmt;
+    fmt.setFontStrikeOut(strike);
+    mergeFormatOnSelection(fmt);
+    // Make sure UI state follows
+    ui.strikethroughButton->setChecked(strike);
+}
+
 void InputWidget::mergeFormatOnSelection(const QTextCharFormat& format)
 {
     QTextCursor cursor = inputLine()->textCursor();
@@ -605,6 +623,11 @@ void InputWidget::on_underlineButton_clicked(bool checked)
     setFormatUnderline(checked);
 }
 
+void InputWidget::on_strikethroughButton_clicked(bool checked)
+{
+    setFormatStrikethrough(checked);
+}
+
 void InputWidget::on_italicButton_clicked(bool checked)
 {
     setFormatItalic(checked);
@@ -615,6 +638,7 @@ void InputWidget::fontChanged(const QFont& f)
     ui.boldButton->setChecked(f.bold());
     ui.italicButton->setChecked(f.italic());
     ui.underlineButton->setChecked(f.underline());
+    ui.strikethroughButton->setChecked(f.strikeOut());
 }
 
 void InputWidget::colorChosen(QAction* action)
index b6afaee..ad20959 100644 (file)
@@ -83,6 +83,13 @@ public slots:
      */
     void toggleFormatUnderline();
 
+    /**
+     * Toggle the striking of the selected or typed text
+     *
+     * striking becomes normal, and normal becomes underlined.
+     */
+    void toggleFormatStrikethrough();
+
     /**
      * Clear the formatting of the selected or typed text
      *
@@ -132,6 +139,7 @@ private slots:
     void on_boldButton_clicked(bool checked);
     void on_italicButton_clicked(bool checked);
     void on_underlineButton_clicked(bool checked);
+    void on_strikethroughButton_clicked(bool checked);
     void colorChosen(QAction* action);
     void colorHighlightChosen(QAction* action);
 
@@ -166,6 +174,13 @@ private:
      */
     void setFormatUnderline(const bool underline);
 
+    /**
+     * Sets the strikethrough of the selected or typed text
+     *
+     * @param strike If true, set text striked, otherwise set text normal
+     */
+    void setFormatStrikethrough(const bool strike);
+
     Ui::InputWidget ui;
 
     NetworkId _networkId;
index 24a2525..631aa75 100644 (file)
            </property>
           </widget>
          </item>
+         <item>
+          <widget class="QToolButton" name="strikethroughButton">
+           <property name="enabled">
+            <bool>true</bool>
+           </property>
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Maximum">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>26</width>
+             <height>24</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>16777215</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Strikethrough</string>
+           </property>
+           <property name="text">
+            <string/>
+           </property>
+           <property name="iconSize">
+            <size>
+             <width>16</width>
+             <height>16</height>
+            </size>
+           </property>
+           <property name="checkable">
+            <bool>true</bool>
+           </property>
+           <property name="checked">
+            <bool>false</bool>
+           </property>
+          </widget>
+         </item>
          <item>
           <widget class="QToolButton" name="textcolorButton">
            <property name="sizePolicy">
index dae5029..019216f 100644 (file)
@@ -466,7 +466,14 @@ void MainWin::setupActions()
                      coll,
                      this,
                      &MainWin::onFormatUnderlineTriggered,
-                     QKeySequence::Underline)}});
+                     QKeySequence::Underline)},
+         {"FormatStrikethrough",
+          new Action(icon::get("format-text-strikethrough"),
+                     tr("Toggle strikethrough"),
+                     coll,
+                     this,
+                     &MainWin::onFormatStrikethroughTriggered,
+                     QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_S))}});
 
     // Navigation
     coll = QtUi::actionCollection("Navigation", tr("Navigation"));
@@ -1834,6 +1841,15 @@ void MainWin::onFormatUnderlineTriggered()
     _inputWidget->toggleFormatUnderline();
 }
 
+void MainWin::onFormatStrikethroughTriggered()
+{
+    if (!_inputWidget)
+        return;
+
+    _inputWidget->toggleFormatStrikethrough();
+}
+
+
 void MainWin::onJumpHotBufferTriggered()
 {
     if (!_bufferHotList->rowCount())
index fbcd553..0ff2a36 100644 (file)
@@ -189,6 +189,13 @@ private slots:
      */
     void onFormatUnderlineTriggered();
 
+     /**
+     * Toggle the strikethrough of the input widget selected or typed text
+     *
+     * @seealso InputWidget::toggleFormatStrikethrough()
+     */
+    void onFormatStrikethroughTriggered();
+
     /**
      * Clear the formatting of the input widget selected or typed text
      *
index 1ecba10..1712cc6 100644 (file)
@@ -463,13 +463,13 @@ void MultiLineEdit::keyPressEvent(QKeyEvent* event)
 
 QString MultiLineEdit::convertRichtextToMircCodes()
 {
-    bool underline, bold, italic, color;
+    bool underline, bold, italic, color, strikethrough;
     QString mircText, mircFgColor, mircBgColor;
     QTextCursor cursor = textCursor();
     QTextCursor peekcursor = textCursor();
     cursor.movePosition(QTextCursor::Start);
 
-    underline = bold = italic = color = false;
+    underline = bold = italic = color = strikethrough = false;
 
     while (cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor)) {
         if (cursor.selectedText() == QString(QChar(QChar::LineSeparator))
@@ -490,6 +490,10 @@ QString MultiLineEdit::convertRichtextToMircCodes()
                 bold = false;
                 mircText.append('\x02');
             }
+            if (strikethrough) {
+                strikethrough = false;
+                mircText.append('\x1E');
+            }
             mircText.append('\n');
         }
         else {
@@ -505,6 +509,10 @@ QString MultiLineEdit::convertRichtextToMircCodes()
                 underline = true;
                 mircText.append('\x1f');
             }
+            if (!strikethrough && cursor.charFormat().fontStrikeOut()) {
+                strikethrough = true;
+                mircText.append('\x1E');
+            }
             if (!color && (cursor.charFormat().foreground().isOpaque() || cursor.charFormat().background().isOpaque())) {
                 color = true;
                 mircText.append('\x03');
@@ -542,6 +550,10 @@ QString MultiLineEdit::convertRichtextToMircCodes()
                     bold = false;
                     mircText.append('\x02');
                 }
+                if (strikethrough) {
+                    strikethrough = false;
+                    mircText.append('\x1E');
+                }
             }
         }
 
@@ -560,6 +572,9 @@ QString MultiLineEdit::convertRichtextToMircCodes()
     if (bold)
         mircText.append('\x02');
 
+    if (strikethrough)
+        mircText.append('\x1E');
+
     return mircText;
 }
 
@@ -572,6 +587,8 @@ bool MultiLineEdit::mircCodesChanged(QTextCursor& cursor, QTextCursor& peekcurso
         changed = true;
     if (cursor.charFormat().fontUnderline() != peekcursor.charFormat().fontUnderline())
         changed = true;
+    if (cursor.charFormat().fontStrikeOut() != peekcursor.charFormat().fontStrikeOut())
+        changed = true;
     if (cursor.charFormat().foreground().color() != peekcursor.charFormat().foreground().color())
         changed = true;
     if (cursor.charFormat().background().color() != peekcursor.charFormat().background().color())
@@ -582,7 +599,7 @@ bool MultiLineEdit::mircCodesChanged(QTextCursor& cursor, QTextCursor& peekcurso
 QString MultiLineEdit::convertMircCodesToHtml(const QString& text)
 {
     QStringList words;
-    QRegExp mircCode = QRegExp("(\ 2|\1d|\1f|\ 3)", Qt::CaseSensitive);
+    QRegExp mircCode = QRegExp("(\x02|\x1d|\x1f|\x03|\x1E)", Qt::CaseSensitive);
 
     int posLeft = 0;
     int posRight = 0;
@@ -623,6 +640,10 @@ QString MultiLineEdit::convertMircCodesToHtml(const QString& text)
             style.append(" text-decoration: underline;");
             words[i].replace('\x1f', "");
         }
+        if (words[i].contains('\x1E')) {
+            style.append(" text-decoration: line-through;");
+            words[i].replace('\x1E', "");
+        }
         if (words[i].contains('\x03')) {
             int pos = words[i].indexOf('\x03');
             int len = 3;