[utilities/konsole] src: EditProfileDialog: add combobox to select custom text editor

Ahmad Samir null at kde.org
Sun Jan 3 02:37:22 GMT 2021


Git commit bf75cfa930ff18b0c276421e7709e3487477d8be by Ahmad Samir.
Committed on 02/01/2021 at 16:39.
Pushed by hindenburg into branch 'master'.

EditProfileDialog: add combobox to select custom text editor

The functionality to open a file at a certain line/column in a text editor
was added in commit 923f8d144a31be. Here some preset text editors are added
to make it easier to select your preferred text editor to use; the syntax
for each editor is hard-coded, however there is a "custom" entry in the
combobox where the user can set a different text editor (or a different
syntax).

This combobox is inspired by the "Code Navigation" menu in Heaptrack.

GUI:

M  +15   -0    src/Enumeration.h
M  +8    -7    src/filterHotSpots/FileFilterHotspot.cpp
M  +40   -2    src/profile/Profile.cpp
M  +25   -10   src/profile/Profile.h
M  +106  -4    src/widgets/EditProfileDialog.cpp
M  +2    -0    src/widgets/EditProfileDialog.h
M  +21   -12   src/widgets/EditProfileMousePage.ui

https://invent.kde.org/utilities/konsole/commit/bf75cfa930ff18b0c276421e7709e3487477d8be

diff --git a/src/Enumeration.h b/src/Enumeration.h
index 13eca850..9b64bb26 100644
--- a/src/Enumeration.h
+++ b/src/Enumeration.h
@@ -88,6 +88,21 @@ public:
         PasteFromClipboard = 1
     };
 
+    /**
+     * This enum describes the the text editor cmd used to open local text file URLs
+     * in Konsole, where line and column data are appended to the file URL, e.g.:
+     * /path/to/file:123:123
+     */
+    enum TextEditorCmd {
+        Kate = 0,
+        KWrite,
+        KDevelop,
+        QtCreator,
+        Gedit,
+        gVim,
+        CustomTextEditor,
+    };
+
     /**
      * This enum describes the different types of sounds and visual effects which
      * can be used to alert the user when a 'bell' occurs in the terminal
diff --git a/src/filterHotSpots/FileFilterHotspot.cpp b/src/filterHotSpots/FileFilterHotspot.cpp
index 5d71f703..bd16645e 100644
--- a/src/filterHotSpots/FileFilterHotspot.cpp
+++ b/src/filterHotSpots/FileFilterHotspot.cpp
@@ -74,24 +74,25 @@ void FileFilterHotSpot::activate(QObject *)
 
         Profile::Ptr profile = SessionManager::instance()->sessionProfile(_session);
         QString editorCmd = profile->textEditorCmd();
+        const int firstBlank = editorCmd.indexOf(QLatin1Char(' '));
+        const QString editorExecPath = QStandardPaths::findExecutable(editorCmd.mid(0, firstBlank));
 
-        // If the cmd is empty or PATH and LINE don't exist, then the command
-        // is malformed, ignore it and open with the default editor
         // TODO: show an error message to the user?
-        if (editorCmd.isEmpty()
-            || ! (editorCmd.contains(QLatin1String("PATH")) && editorCmd.contains(QLatin1String("LINE")))) {
+        if (editorCmd.isEmpty() || editorExecPath.isEmpty()
+            || !(editorCmd.contains(QLatin1String("PATH")) && editorCmd.contains(QLatin1String("LINE")))) {
             openUrl(path);
             return;
         }
 
+        // Substitute e.g. "kate" with full path, "/usr/bin/kate"
+        editorCmd.replace(0, firstBlank, editorExecPath);
+
+        editorCmd.replace(QLatin1String("PATH"), path);
         editorCmd.replace(QLatin1String("LINE"), match.captured(1));
 
         const QString col = match.captured(2);
-
         editorCmd.replace(QLatin1String("COLUMN"), !col.isEmpty() ? col : QLatin1String("0"));
 
-        editorCmd.replace(QLatin1String("PATH"), path);
-
         qCDebug(KonsoleDebug) << "editorCmd:" << editorCmd;
 
         KService::Ptr service(new KService(QString(), editorCmd, QString()));
diff --git a/src/profile/Profile.cpp b/src/profile/Profile.cpp
index 81dc0fe6..72834267 100644
--- a/src/profile/Profile.cpp
+++ b/src/profile/Profile.cpp
@@ -107,7 +107,8 @@ const Profile::PropertyInfo Profile::DefaultPropertyNames[] = {
     , { UnderlineLinksEnabled , "UnderlineLinksEnabled" , INTERACTION_GROUP , QVariant::Bool }
     , { UnderlineFilesEnabled , "UnderlineFilesEnabled" , INTERACTION_GROUP , QVariant::Bool }
     , { OpenLinksByDirectClickEnabled , "OpenLinksByDirectClickEnabled" , INTERACTION_GROUP , QVariant::Bool }
-    , { TextEditorCmd , "TextEditorCmd" , INTERACTION_GROUP , QVariant::String }
+    , { TextEditorCmd , "TextEditorCmd" , INTERACTION_GROUP , QVariant::Int }
+    , { TextEditorCmdCustom , "TextEditorCmdCustom" , INTERACTION_GROUP , QVariant::String }
     , { CtrlRequiredForDrag, "CtrlRequiredForDrag" , INTERACTION_GROUP , QVariant::Bool }
     , { DropUrlsAsText , "DropUrlsAsText" , INTERACTION_GROUP , QVariant::Bool }
     , { AutoCopySelectedText , "AutoCopySelectedText" , INTERACTION_GROUP , QVariant::Bool }
@@ -194,7 +195,10 @@ void Profile::useFallback()
     setProperty(UnderlineLinksEnabled, true);
     setProperty(UnderlineFilesEnabled, false);
     setProperty(OpenLinksByDirectClickEnabled, false);
-    setProperty(TextEditorCmd, QStringLiteral("/usr/bin/kate PATH:LINE:COLUMN"));
+
+    setProperty(TextEditorCmd, Enum::Kate);
+    setProperty(TextEditorCmdCustom, QStringLiteral("kate PATH:LINE:COLUMN"));
+
     setProperty(CtrlRequiredForDrag, true);
     setProperty(AutoCopySelectedText, false);
     setProperty(CopyTextAsHTML, true);
@@ -353,3 +357,37 @@ Profile::GroupPtr Profile::asGroup()
 {
     return Profile::GroupPtr(dynamic_cast<ProfileGroup *>(this));
 }
+
+QString Profile::textEditorCmd() const
+{
+    auto current = property<int>(Profile::TextEditorCmd);
+
+    QString editorCmd;
+    switch(current) {
+    case Enum::Kate:
+        editorCmd = QStringLiteral("kate PATH:LINE:COLUMN");
+        break;
+    case Enum::KWrite:
+        editorCmd = QStringLiteral("kwrite PATH:LINE:COLUMN");
+        break;
+    case Enum::KDevelop:
+        editorCmd = QStringLiteral("kdevelop PATH:LINE:COLUMN");
+        break;
+    case Enum::QtCreator:
+        editorCmd = QStringLiteral("qtcreator PATH:LINE:COLUMN");
+        break;
+    case Enum::Gedit:
+        editorCmd = QStringLiteral("gedit +LINE:COLUMN PATH");
+        break;
+    case Enum::gVim:
+        editorCmd = QStringLiteral("gvim +LINE PATH");
+        break;
+    case Enum::CustomTextEditor:
+        editorCmd = customTextEditorCmd();
+        break;
+    default:
+        break;
+    }
+
+    return editorCmd;
+}
diff --git a/src/profile/Profile.h b/src/profile/Profile.h
index 4d46a5ea..53e85767 100644
--- a/src/profile/Profile.h
+++ b/src/profile/Profile.h
@@ -201,16 +201,23 @@ public:
          * underlined when hovered by the mouse pointer.
          */
         UnderlineFilesEnabled,
+
         /**
-         * (QString) Text editor command used to open link/file URLs at a given line/column;
-         * it should include two placeholders, LINE and COLUMN, which will be
-         * replaced by the actual line and column numbers, respectively. This is needed as
-         * each text editor has its own command line options to specify line/column numbers
-         * when opening a text file. For example:
-         * "/usr/bin/kate --line LINE --column COLUMN"
-         * "/usr/bin/gedit +LINE:COLUMN"
+         * (Enum::TextEditorCmd) Text editor command used to open local
+         * text file URLs at a given line/column. There is a default list
+         * of editors that the user can select from, and a CustomTextEditor
+         * option if the user wants to use a different editor.
+         *
+         * See Enum::TextEditorCmd
         */
         TextEditorCmd,
+        /**
+         * (QString) This is the command string corresponding to Enum::CustomTextEditor.
+         *
+         * See TextEditorCmd and Enum::TextEditorCmd
+         */
+        TextEditorCmdCustom,
+
         /** (bool) If true, links can be opened by direct mouse click.*/
         OpenLinksByDirectClickEnabled,
         /** (bool) If true, control key must be pressed to click and drag selected text. */
@@ -608,10 +615,18 @@ public:
         return property<bool>(Profile::UnderlineFilesEnabled);
     }
 
-    /** Convenience method for property<QString>(Profile::TextEditorCmd) */
-    QString textEditorCmd() const
+    /**
+     * Returns the command line that will be used with the current text
+     * editor setting.
+     */
+    QString textEditorCmd() const;
+    /**
+     * Convenience method to get the text editor command corresponding to
+     * Enum::TextEditorCmdCustom.
+     */
+    QString customTextEditorCmd() const
     {
-        return property<QString>(Profile::TextEditorCmd);
+        return property<QString>(Profile::TextEditorCmdCustom);
     }
 
     bool autoCopySelectedText() const
diff --git a/src/widgets/EditProfileDialog.cpp b/src/widgets/EditProfileDialog.cpp
index 16d9910a..92ce6329 100644
--- a/src/widgets/EditProfileDialog.cpp
+++ b/src/widgets/EditProfileDialog.cpp
@@ -1706,10 +1706,6 @@ void EditProfileDialog::setupMousePage(const Profile::Ptr &profile)
 
     _mouseUi->openLinksByDirectClickButton->setEnabled(_mouseUi->underlineLinksButton->isChecked() || _mouseUi->underlineFilesButton->isChecked());
 
-    _mouseUi->textEditorCmdLineEdit->setText(profile->textEditorCmd());
-    connect(_mouseUi->textEditorCmdLineEdit, &QLineEdit::textChanged,
-            this, &Konsole::EditProfileDialog::textEditorCmdEditLineChanged);
-
     _mouseUi->enableMouseWheelZoomButton->setChecked(profile->mouseWheelZoomEnabled());
     connect(_mouseUi->enableMouseWheelZoomButton, &QCheckBox::toggled, this, &Konsole::EditProfileDialog::toggleMouseWheelZoom);
 
@@ -1721,6 +1717,112 @@ void EditProfileDialog::setupMousePage(const Profile::Ptr &profile)
     _mouseUi->linkEscapeSequenceTexts->setText(profile->escapedLinksSchema().join(QLatin1Char(';')));
     connect(_mouseUi->linkEscapeSequenceTexts, &QLineEdit::textChanged,
             this, &Konsole::EditProfileDialog::linkEscapeSequenceTextsChanged);
+
+    setTextEditorCombo(profile);
+}
+
+void EditProfileDialog::setTextEditorCombo(const Profile::Ptr &profile)
+{
+    std::array<Enum::TextEditorCmd, 7> editorsList = { Enum::Kate, Enum::KWrite,
+                                                       Enum::KDevelop, Enum::QtCreator,
+                                                       Enum::Gedit, Enum::gVim,
+                                                       Enum::CustomTextEditor };
+
+    auto *editorCombo = _mouseUi->textEditorCombo;
+
+    QStandardItemModel *model = static_cast<QStandardItemModel *>(editorCombo->model());
+    Q_ASSERT(model);
+
+    for (auto editor : editorsList) {
+        QString exec;
+        QString displayName;
+        QIcon icon;
+        switch(editor) {
+        case Enum::Kate:
+            exec = QStringLiteral("kate");
+            displayName = QStringLiteral("Kate");
+            icon = QIcon::fromTheme(exec);
+            break;
+        case Enum::KWrite:
+            exec = QStringLiteral("kwrite");
+            displayName = QStringLiteral("KWrite");
+            icon = QIcon::fromTheme(exec);
+            break;
+        case Enum::KDevelop:
+            exec = QStringLiteral("kdevelop");
+            displayName = QStringLiteral("KDevelop");
+            icon = QIcon::fromTheme(exec);
+            break;
+        case Enum::QtCreator:
+            exec = QStringLiteral("qtcreator");
+            displayName = QStringLiteral("Qt Creator");
+            icon = QIcon::fromTheme(exec);
+            break;
+        case Enum::Gedit:
+            exec = QStringLiteral("gedit");
+            displayName = QStringLiteral("Gedit");
+            QIcon::fromTheme(QStringLiteral("org.gnome.gedit"));
+            break;
+        case Enum::gVim:
+            exec = QStringLiteral("gvim");
+            displayName = QStringLiteral("gVim");
+            icon = QIcon::fromTheme(exec);
+            break;
+        case Enum::CustomTextEditor:
+            displayName = QStringLiteral("Custom");
+            icon = QIcon::fromTheme(QStringLiteral("system-run"));
+            break;
+        default:
+            break;
+        }
+
+        editorCombo->addItem(icon, displayName);
+
+        // For "CustomTextEditor" we don't check if the binary exists
+        const bool isAvailable = editor == Enum::CustomTextEditor
+                                 || !QStandardPaths::findExecutable(exec).isEmpty();
+        // Make un-available editors look disabled in the combobox
+        model->item(static_cast<int>(editor))->setEnabled(isAvailable);
+    }
+
+    const auto currentEditor = profile->property<int>(Profile::TextEditorCmd);
+    editorCombo->setCurrentIndex(currentEditor);
+
+    connect(editorCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
+            this, [this](const int index) {
+        updateTempProfileProperty(Profile::TextEditorCmd, index);
+        _mouseUi->textEditorCustomBtn->setEnabled(index == Enum::CustomTextEditor);
+    });
+
+    _mouseUi->textEditorCustomBtn->setEnabled(currentEditor == Enum::CustomTextEditor);
+    connect(_mouseUi->textEditorCustomBtn, &QAbstractButton::clicked,
+            this, [this, profile]() {
+        auto *dlg = new QInputDialog(static_cast<QWidget *>(this));
+        dlg->setLabelText(i18n("The format is e.g. 'eidtorExec PATH:LINE:COLUMN'\n\n"
+                               "PATH    will be replaced by the path to the text file\n"
+                               "LINE    will be replaced by the line number\n"
+                               "COLUMN  (optional) will be replaced by the column number\n"
+                               "Note: you will need to replace 'PATH:LINE:COLUMN' by the actual\n"
+                               "syntax the editor you want to use supports; e.g.:\n"
+                               "gedit +LINE:COLUMN PATH\n\n"
+                               "If PATH or LINE aren't present in the command, this setting\n"
+                               "will be ignored and the file will be opened by the default text\n"
+                               "editor."));
+        const QString cmd = profile->customTextEditorCmd();
+        dlg->setTextValue(cmd);
+        dlg->setAttribute(Qt::WA_DeleteOnClose);
+        dlg->setWindowTitle(i18n("Text Editor Custom Command"));
+
+        QFontMetrics fm(font());
+        const int width = qMin(fm.averageCharWidth() * cmd.size(), this->width());
+        dlg->resize(width, dlg->height());
+
+        connect(dlg, &QDialog::accepted, this, [this, dlg]() {
+            updateTempProfileProperty(Profile::TextEditorCmdCustom, dlg->textValue());
+        });
+
+        dlg->show();
+    });
 }
 
 void EditProfileDialog::setupAdvancedPage(const Profile::Ptr &profile)
diff --git a/src/widgets/EditProfileDialog.h b/src/widgets/EditProfileDialog.h
index 242b7b07..53d45ece 100644
--- a/src/widgets/EditProfileDialog.h
+++ b/src/widgets/EditProfileDialog.h
@@ -203,6 +203,8 @@ private Q_SLOTS:
     // apply the first previewed changes stored up by delayedPreview()
     void delayedPreviewActivate();
 
+    void setTextEditorCombo(const Profile::Ptr &profile);
+
     void toggleAllowLinkEscapeSequence(bool);
     void linkEscapeSequenceTextsChanged();
 
diff --git a/src/widgets/EditProfileMousePage.ui b/src/widgets/EditProfileMousePage.ui
index 4b7f66f0..f691140f 100644
--- a/src/widgets/EditProfileMousePage.ui
+++ b/src/widgets/EditProfileMousePage.ui
@@ -285,24 +285,33 @@
               <string>Text Editor Command: </string>
              </property>
              <property name="buddy">
-              <cstring>textEditorCmdLineEdit</cstring>
+              <cstring>textEditorCombo</cstring>
+             </property>
+             <property name="toolTip">
+              <string comment="@info:tooltip">Text editor to use when opening text file URLs at a given line/column.</string>
              </property>
             </widget>
            </item>
            <item>
-            <widget class="QLineEdit" name="textEditorCmdLineEdit">
+            <widget class="QComboBox" name="textEditorCombo">
+             <property name="sizePolicy">
+              <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+               <horstretch>1</horstretch>
+              </sizepolicy>
+             </property>
              <property name="toolTip">
-              <string comment="@info:tooltip">Command used to open a file PATH at LINE/COLUMN.</string>
+              <string comment="@info:tooltip">Text editor to use when opening text file URLs at a given line/column.</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QPushButton" name="textEditorCustomBtn">
+             <property name="text">
+              <string>Edit</string>
              </property>
-             <property name="whatsThis">
-              <string comment="@info:whatsthis"><html><head/><body>
-                  <p>The text editor command that will be used to open a file starting at the specified line and column.</p>
-                  <p>PATH, LINE and COLUMN are palceholders that will be replaced by the actual path to the file, line number and column number respectively.</p>
-                  <p>If PATH and LINE aren't specified in the command, the file will be opened with the system default text editor.</p>
-                  <p>For example:</p>
-                  <p>/usr/bin/kate PATH:LINE:COMLUMN</p>
-                  <p>/usr/bin/gedit +LINE:COLUMN PATH</p>
-                  </body></html></string>
+             <property name="sizePolicy">
+              <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+              </sizepolicy>
              </property>
             </widget>
            </item>



More information about the kde-doc-english mailing list