Commit bf75cfa9 authored by Ahmad Samir's avatar Ahmad Samir
Browse files

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 923f8d14. 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:
parent 9d188aac
......@@ -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
......
......@@ -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()));
......
......@@ -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;
}
......@@ -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
......
......@@ -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)
......
......@@ -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();
......
......@@ -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">&lt;html&gt;&lt;head/&gt;&lt;body&gt;
&lt;p&gt;The text editor command that will be used to open a file starting at the specified line and column.&lt;/p&gt;
&lt;p&gt;PATH, LINE and COLUMN are palceholders that will be replaced by the actual path to the file, line number and column number respectively.&lt;/p&gt;
&lt;p&gt;If PATH and LINE aren't specified in the command, the file will be opened with the system default text editor.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;/usr/bin/kate PATH:LINE:COMLUMN&lt;/p&gt;
&lt;p&gt;/usr/bin/gedit +LINE:COLUMN PATH&lt;/p&gt;
&lt;/body&gt;&lt;/html&gt;</string>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
</sizepolicy>
</property>
</widget>
</item>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment