Changeset View
Changeset View
Standalone View
Standalone View
addons/externaltools/externaltools.cpp
- This file was added.
1 | /* | ||||
---|---|---|---|---|---|
2 | This file is part of the Kate text editor of the KDE project. | ||||
3 | | ||||
4 | This library is free software; you can redistribute it and/or | ||||
5 | modify it under the terms of the GNU Library General Public | ||||
6 | License version 2 as published by the Free Software Foundation. | ||||
7 | | ||||
8 | This library is distributed in the hope that it will be useful, | ||||
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
11 | Library General Public License for more details. | ||||
12 | | ||||
13 | You should have received a copy of the GNU Library General Public License | ||||
14 | along with this library; see the file COPYING.LIB. If not, write to | ||||
15 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||||
16 | Boston, MA 02110-1301, USA. | ||||
17 | | ||||
18 | --- | ||||
19 | Copyright (C) 2004, Anders Lund <anders@alweb.dk> | ||||
20 | Copyright (C) 2019 Dominik Haumann <dhaumann@kde.org> | ||||
21 | */ | ||||
22 | // TODO | ||||
23 | // Icons | ||||
24 | // Direct shortcut setting | ||||
25 | #include "externaltools.h" | ||||
26 | #include "kateexternaltool.h" | ||||
27 | #include "externaltoolsplugin.h" | ||||
28 | #include "katemacroexpander.h" | ||||
29 | #include "katetoolrunner.h" | ||||
30 | | ||||
31 | #include <KTextEditor/Document> | ||||
32 | #include <KTextEditor/Editor> | ||||
33 | #include <KTextEditor/View> | ||||
34 | | ||||
35 | #include <KActionCollection> | ||||
36 | #include <KConfig> | ||||
37 | #include <KConfigGroup> | ||||
38 | #include <KIconButton> | ||||
39 | #include <KIconLoader> | ||||
40 | #include <KMessageBox> | ||||
41 | #include <KMimeTypeChooser> | ||||
42 | #include <KSharedConfig> | ||||
43 | #include <KXMLGUIFactory> | ||||
44 | #include <KXmlGuiWindow> | ||||
45 | #include <QComboBox> | ||||
46 | #include <QLineEdit> | ||||
47 | #include <QListWidget> | ||||
48 | #include <QMenu> | ||||
49 | #include <QStandardPaths> | ||||
50 | | ||||
51 | #include <QBitmap> | ||||
52 | #include <QFile> | ||||
53 | #include <QGridLayout> | ||||
54 | #include <QLabel> | ||||
55 | #include <QObject> | ||||
56 | #include <QPushButton> | ||||
57 | #include <QRegularExpression> | ||||
58 | #include <QTextEdit> | ||||
59 | #include <QToolButton> | ||||
60 | | ||||
61 | #include <unistd.h> | ||||
62 | | ||||
63 | // BEGIN KateExternalToolsCommand | ||||
64 | KateExternalToolsCommand::KateExternalToolsCommand(KateExternalToolsPlugin* plugin) | ||||
65 | : KTextEditor::Command({/* FIXME */}) | ||||
66 | , m_plugin(plugin) | ||||
67 | { | ||||
68 | reload(); | ||||
69 | } | ||||
70 | | ||||
71 | // FIXME | ||||
72 | // const QStringList& KateExternalToolsCommand::cmds() | ||||
73 | // { | ||||
74 | // return m_list; | ||||
75 | // } | ||||
76 | | ||||
77 | void KateExternalToolsCommand::reload() | ||||
78 | { | ||||
79 | m_list.clear(); | ||||
80 | m_map.clear(); | ||||
81 | m_name.clear(); | ||||
82 | | ||||
83 | KConfig _config(QStringLiteral("externaltools"), KConfig::NoGlobals, QStandardPaths::ApplicationsLocation); | ||||
84 | KConfigGroup config(&_config, "Global"); | ||||
85 | const QStringList tools = config.readEntry("tools", QStringList()); | ||||
86 | | ||||
87 | for (QStringList::const_iterator it = tools.begin(); it != tools.end(); ++it) { | ||||
88 | if (*it == QStringLiteral("---")) | ||||
89 | continue; | ||||
90 | | ||||
91 | config = KConfigGroup(&_config, *it); | ||||
92 | | ||||
93 | KateExternalTool t; | ||||
94 | t.load(config); | ||||
95 | // FIXME test for a command name first! | ||||
96 | if (t.hasexec && (!t.cmdname.isEmpty())) { | ||||
97 | m_list.append(QStringLiteral("exttool-") + t.cmdname); | ||||
98 | m_map.insert(QStringLiteral("exttool-") + t.cmdname, t.actionName); | ||||
99 | m_name.insert(QStringLiteral("exttool-") + t.cmdname, t.name); | ||||
100 | } | ||||
101 | } | ||||
102 | } | ||||
103 | | ||||
104 | bool KateExternalToolsCommand::exec(KTextEditor::View* view, const QString& cmd, QString& msg, | ||||
105 | const KTextEditor::Range& range) | ||||
106 | { | ||||
107 | Q_UNUSED(msg) | ||||
108 | Q_UNUSED(range) | ||||
109 | | ||||
110 | auto wv = dynamic_cast<QWidget*>(view); | ||||
111 | if (!wv) { | ||||
112 | // qDebug()<<"KateExternalToolsCommand::exec: Could not get view widget"; | ||||
113 | return false; | ||||
114 | } | ||||
115 | | ||||
116 | // qDebug()<<"cmd="<<cmd.trimmed(); | ||||
117 | const QString actionName = m_map[cmd.trimmed()]; | ||||
118 | if (actionName.isEmpty()) | ||||
119 | return false; | ||||
120 | // qDebug()<<"actionName is not empty:"<<actionName; | ||||
121 | /* KateExternalToolsMenuAction *a = | ||||
122 | dynamic_cast<KateExternalToolsMenuAction*>(dmw->action("tools_external")); | ||||
123 | if (!a) return false;*/ | ||||
124 | KateExternalToolsPluginView* extview = m_plugin->extView(wv->window()); | ||||
125 | if (!extview) | ||||
126 | return false; | ||||
127 | if (!extview->externalTools) | ||||
128 | return false; | ||||
129 | // qDebug()<<"trying to find action"; | ||||
130 | QAction* a1 = extview->externalTools->actionCollection()->action(actionName); | ||||
131 | if (!a1) | ||||
132 | return false; | ||||
133 | // qDebug()<<"activating action"; | ||||
134 | a1->trigger(); | ||||
135 | return true; | ||||
136 | } | ||||
137 | | ||||
138 | bool KateExternalToolsCommand::help(KTextEditor::View*, const QString&, QString&) | ||||
139 | { | ||||
140 | return false; | ||||
141 | } | ||||
142 | // END KateExternalToolsCommand | ||||
143 | | ||||
144 | // BEGIN KateExternalToolAction | ||||
145 | KateExternalToolAction::KateExternalToolAction(QObject* parent, KateExternalTool* t) | ||||
146 | : QAction(QIcon::fromTheme(t->icon), t->name, parent) | ||||
147 | , tool(t) | ||||
148 | { | ||||
149 | setText(t->name); | ||||
150 | if (!t->icon.isEmpty()) | ||||
151 | setIcon(QIcon::fromTheme(t->icon)); | ||||
152 | | ||||
153 | connect(this, SIGNAL(triggered(bool)), SLOT(slotRun())); | ||||
154 | } | ||||
155 | | ||||
156 | KateExternalToolAction::~KateExternalToolAction() | ||||
157 | { | ||||
158 | delete (tool); | ||||
159 | } | ||||
160 | | ||||
161 | void KateExternalToolAction::slotRun() | ||||
162 | { | ||||
163 | // expand the macros in command if any, | ||||
164 | // and construct a command with an absolute path | ||||
165 | auto mw = qobject_cast<KTextEditor::MainWindow*>(parent()->parent()); | ||||
166 | | ||||
167 | // save documents if requested | ||||
168 | if (tool->saveMode == KateExternalTool::SaveMode::CurrentDocument) { | ||||
169 | mw->activeView()->document()->save(); | ||||
170 | } else if (tool->saveMode == KateExternalTool::SaveMode::AllDocuments) { | ||||
171 | foreach (KXMLGUIClient* client, mw->guiFactory()->clients()) { | ||||
172 | if (QAction* a = client->actionCollection()->action(QStringLiteral("file_save_all"))) { | ||||
173 | a->trigger(); | ||||
174 | break; | ||||
175 | } | ||||
176 | } | ||||
177 | } | ||||
178 | | ||||
179 | // copy tool | ||||
180 | auto copy = new KateExternalTool(*tool); | ||||
181 | | ||||
182 | MacroExpander macroExpander(mw->activeView()); | ||||
183 | if (!macroExpander.expandMacrosShellQuote(copy->arguments)) { | ||||
184 | KMessageBox::sorry(mw->activeView(), i18n("Failed to expand the arguments '%1'.", copy->arguments), i18n("Kate External Tools")); | ||||
185 | return; | ||||
186 | } | ||||
187 | | ||||
188 | if (!macroExpander.expandMacrosShellQuote(copy->workingDir)) { | ||||
189 | KMessageBox::sorry(mw->activeView(), i18n("Failed to expand the working directory '%1'.", copy->workingDir), i18n("Kate External Tools")); | ||||
190 | return; | ||||
191 | } | ||||
192 | | ||||
193 | // FIXME: The tool runner must live as long as the child process is running. | ||||
194 | // --> it must be allocated on the heap, and deleted with a ->deleteLater() call. | ||||
195 | KateToolRunner runner(copy); | ||||
196 | runner.run(); | ||||
197 | runner.waitForFinished(); | ||||
198 | } | ||||
199 | // END KateExternalToolAction | ||||
200 | | ||||
201 | // BEGIN KateExternalToolsMenuAction | ||||
202 | KateExternalToolsMenuAction::KateExternalToolsMenuAction(const QString& text, KActionCollection* collection, | ||||
203 | QObject* parent, KTextEditor::MainWindow* mw) | ||||
204 | : KActionMenu(text, parent) | ||||
205 | , mainwindow(mw) | ||||
206 | { | ||||
207 | | ||||
208 | m_actionCollection = collection; | ||||
209 | | ||||
210 | // connect to view changed... | ||||
211 | connect(mw, &KTextEditor::MainWindow::viewChanged, this, &KateExternalToolsMenuAction::slotViewChanged); | ||||
212 | | ||||
213 | reload(); | ||||
214 | } | ||||
215 | | ||||
216 | KateExternalToolsMenuAction::~KateExternalToolsMenuAction() | ||||
217 | { | ||||
218 | // kDebug() << "deleted KateExternalToolsMenuAction"; | ||||
219 | } | ||||
220 | | ||||
221 | void KateExternalToolsMenuAction::reload() | ||||
222 | { | ||||
223 | bool needs_readd = (m_actionCollection->takeAction(this) != nullptr); | ||||
224 | m_actionCollection->clear(); | ||||
225 | if (needs_readd) | ||||
226 | m_actionCollection->addAction(QStringLiteral("tools_external"), this); | ||||
227 | menu()->clear(); | ||||
228 | | ||||
229 | // load all the tools, and create a action for each of them | ||||
230 | KSharedConfig::Ptr pConfig = KSharedConfig::openConfig(QStringLiteral("externaltools"), KConfig::NoGlobals, | ||||
231 | QStandardPaths::ApplicationsLocation); | ||||
232 | KConfigGroup config(pConfig, "Global"); | ||||
233 | const QStringList tools = config.readEntry("tools", QStringList()); | ||||
234 | | ||||
235 | for (int i = 0; i < tools.size(); ++i) { | ||||
236 | const QString & toolSection = tools[i]; | ||||
237 | if (toolSection == QStringLiteral("---")) { | ||||
238 | menu()->addSeparator(); | ||||
239 | // a separator | ||||
240 | continue; | ||||
241 | } | ||||
242 | | ||||
243 | config = KConfigGroup(pConfig, toolSection); | ||||
244 | KateExternalTool* t = new KateExternalTool(); | ||||
245 | t->load(config); | ||||
246 | | ||||
247 | if (t->hasexec) { | ||||
248 | QAction* a = new KateExternalToolAction(this, t); | ||||
249 | m_actionCollection->addAction(t->actionName, a); | ||||
250 | addAction(a); | ||||
251 | } else | ||||
252 | delete t; | ||||
253 | } | ||||
254 | | ||||
255 | config = KConfigGroup(pConfig, "Shortcuts"); | ||||
256 | m_actionCollection->readSettings(&config); | ||||
257 | slotViewChanged(mainwindow->activeView()); | ||||
258 | } | ||||
259 | | ||||
260 | void KateExternalToolsMenuAction::slotViewChanged(KTextEditor::View* view) | ||||
261 | { | ||||
262 | // no active view, oh oh | ||||
263 | if (!view) { | ||||
264 | return; | ||||
265 | } | ||||
266 | | ||||
267 | // try to enable/disable to match current mime type | ||||
268 | KTextEditor::Document* doc = view->document(); | ||||
269 | if (doc) { | ||||
270 | const QString mimeType = doc->mimeType(); | ||||
271 | foreach (QAction* kaction, m_actionCollection->actions()) { | ||||
272 | KateExternalToolAction* action = dynamic_cast<KateExternalToolAction*>(kaction); | ||||
273 | if (action) { | ||||
274 | const QStringList l = action->tool->mimetypes; | ||||
275 | const bool b = (!l.count() || l.contains(mimeType)); | ||||
276 | action->setEnabled(b); | ||||
277 | } | ||||
278 | } | ||||
279 | } | ||||
280 | } | ||||
281 | // END KateExternalToolsMenuAction | ||||
282 | | ||||
283 | // BEGIN ToolItem | ||||
284 | /** | ||||
285 | * This is a QListBoxItem, that has a KateExternalTool. The text is the Name | ||||
286 | * of the tool. | ||||
287 | */ | ||||
288 | class ToolItem : public QListWidgetItem | ||||
289 | { | ||||
290 | public: | ||||
291 | ToolItem(QListWidget* lb, const QPixmap& icon, KateExternalTool* tool) | ||||
292 | : QListWidgetItem(icon, tool->name, lb) | ||||
293 | , tool(tool) | ||||
294 | { | ||||
295 | } | ||||
296 | | ||||
297 | ~ToolItem() {} | ||||
298 | | ||||
299 | KateExternalTool* tool; | ||||
300 | }; | ||||
301 | // END ToolItem | ||||
302 | | ||||
303 | // BEGIN KateExternalToolServiceEditor | ||||
304 | KateExternalToolServiceEditor::KateExternalToolServiceEditor(KateExternalTool* tool, QWidget* parent) | ||||
305 | : QDialog(parent) | ||||
306 | , tool(tool) | ||||
307 | { | ||||
308 | setWindowTitle(i18n("Edit External Tool")); | ||||
309 | | ||||
310 | ui = new Ui::ToolDialog(); | ||||
311 | ui->setupUi(this); | ||||
312 | ui->btnIcon->setIconSize(KIconLoader::SizeSmall); | ||||
313 | | ||||
314 | connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &KateExternalToolServiceEditor::slotOKClicked); | ||||
315 | connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); | ||||
316 | connect(ui->btnMimeType, &QToolButton::clicked, this, &KateExternalToolServiceEditor::showMTDlg); | ||||
317 | | ||||
318 | if (tool) { | ||||
319 | ui->edtName->setText(tool->name); | ||||
320 | if (!tool->icon.isEmpty()) | ||||
321 | ui->btnIcon->setIcon(tool->icon); | ||||
322 | | ||||
323 | ui->edtExecutable->setText(tool->executable); | ||||
324 | ui->edtArgs->setText(tool->arguments); | ||||
325 | ui->edtInput->setText(tool->input); | ||||
326 | ui->edtCommand->setText(tool->cmdname); | ||||
327 | ui->edtWorkingDir->setText(tool->workingDir); | ||||
328 | ui->edtMimeType->setText(tool->mimetypes.join(QStringLiteral("; "))); | ||||
329 | ui->cmbSave->setCurrentIndex(static_cast<int>(tool->saveMode)); | ||||
330 | ui->chkIncludeStderr->setChecked(tool->includeStderr); | ||||
331 | } | ||||
332 | } | ||||
333 | | ||||
334 | void KateExternalToolServiceEditor::slotOKClicked() | ||||
335 | { | ||||
336 | if (ui->edtName->text().isEmpty() || ui->edtExecutable->text().isEmpty()) { | ||||
337 | QMessageBox::information(this, i18n("External Tool"), i18n("You must specify at least a name and an executable")); | ||||
338 | return; | ||||
339 | } | ||||
340 | accept(); | ||||
341 | } | ||||
342 | | ||||
343 | void KateExternalToolServiceEditor::showMTDlg() | ||||
344 | { | ||||
345 | QString text = i18n("Select the MimeTypes for which to enable this tool."); | ||||
346 | QStringList list = ui->edtMimeType->text().split(QRegularExpression(QStringLiteral("\\s*;\\s*")), QString::SkipEmptyParts); | ||||
347 | KMimeTypeChooserDialog d(i18n("Select Mime Types"), text, list, QStringLiteral("text"), this); | ||||
348 | if (d.exec() == QDialog::Accepted) { | ||||
349 | ui->edtMimeType->setText(d.chooser()->mimeTypes().join(QStringLiteral(";"))); | ||||
350 | } | ||||
351 | } | ||||
352 | // END KateExternalToolServiceEditor | ||||
353 | | ||||
354 | // BEGIN KateExternalToolsConfigWidget | ||||
355 | KateExternalToolsConfigWidget::KateExternalToolsConfigWidget(QWidget* parent, KateExternalToolsPlugin* plugin) | ||||
356 | : KTextEditor::ConfigPage(parent) | ||||
357 | , m_plugin(plugin) | ||||
358 | { | ||||
359 | setupUi(this); | ||||
360 | | ||||
361 | btnMoveUp->setIcon(QIcon::fromTheme(QStringLiteral("go-up"))); | ||||
362 | btnMoveDown->setIcon(QIcon::fromTheme(QStringLiteral("go-down"))); | ||||
363 | | ||||
364 | connect(lbTools, &QListWidget::itemSelectionChanged, this, &KateExternalToolsConfigWidget::slotSelectionChanged); | ||||
365 | connect(lbTools, &QListWidget::itemDoubleClicked, this, &KateExternalToolsConfigWidget::slotEdit); | ||||
366 | connect(btnNew, &QPushButton::clicked, this, &KateExternalToolsConfigWidget::slotNew); | ||||
367 | connect(btnRemove, &QPushButton::clicked, this, &KateExternalToolsConfigWidget::slotRemove); | ||||
368 | connect(btnEdit, &QPushButton::clicked, this, &KateExternalToolsConfigWidget::slotEdit); | ||||
369 | connect(btnSeparator, &QPushButton::clicked, this, &KateExternalToolsConfigWidget::slotInsertSeparator); | ||||
370 | connect(btnMoveUp, &QPushButton::clicked, this, &KateExternalToolsConfigWidget::slotMoveUp); | ||||
371 | connect(btnMoveDown, &QPushButton::clicked, this, &KateExternalToolsConfigWidget::slotMoveDown); | ||||
372 | | ||||
373 | m_config = new KConfig(QStringLiteral("externaltools"), KConfig::NoGlobals, QStandardPaths::ApplicationsLocation); | ||||
374 | reset(); | ||||
375 | slotSelectionChanged(); | ||||
376 | } | ||||
377 | | ||||
378 | KateExternalToolsConfigWidget::~KateExternalToolsConfigWidget() | ||||
379 | { | ||||
380 | delete m_config; | ||||
381 | } | ||||
382 | | ||||
383 | QString KateExternalToolsConfigWidget::name() const | ||||
384 | { | ||||
385 | return i18n("External Tools"); | ||||
386 | } | ||||
387 | | ||||
388 | QString KateExternalToolsConfigWidget::fullName() const | ||||
389 | { | ||||
390 | return i18n("External Tools"); | ||||
391 | } | ||||
392 | | ||||
393 | QIcon KateExternalToolsConfigWidget::icon() const | ||||
394 | { | ||||
395 | return QIcon(); | ||||
396 | } | ||||
397 | | ||||
398 | void KateExternalToolsConfigWidget::reset() | ||||
399 | { | ||||
400 | // m_tools.clear(); | ||||
401 | lbTools->clear(); | ||||
402 | | ||||
403 | // load the files from a KConfig | ||||
404 | const QStringList tools = m_config->group("Global").readEntry("tools", QStringList()); | ||||
405 | | ||||
406 | for (int i = 0; i < tools.size(); ++i) { | ||||
407 | const QString & toolSection = tools[i]; | ||||
408 | if (toolSection == QStringLiteral("---")) { | ||||
409 | new QListWidgetItem(QStringLiteral("---"), lbTools); | ||||
410 | } else { | ||||
411 | KConfigGroup cg(m_config, toolSection); | ||||
412 | KateExternalTool* t = new KateExternalTool(); | ||||
413 | t->load(cg); | ||||
414 | | ||||
415 | if (t->hasexec) // we only show tools that are also in the menu. | ||||
416 | new ToolItem(lbTools, t->icon.isEmpty() ? blankIcon() : SmallIcon(t->icon), t); | ||||
417 | else | ||||
418 | delete t; | ||||
419 | } | ||||
420 | } | ||||
421 | m_changed = false; | ||||
422 | } | ||||
423 | | ||||
424 | QPixmap KateExternalToolsConfigWidget::blankIcon() | ||||
425 | { | ||||
426 | QPixmap pm(KIconLoader::SizeSmall, KIconLoader::SizeSmall); | ||||
427 | pm.fill(); | ||||
428 | pm.setMask(pm.createHeuristicMask()); | ||||
429 | return pm; | ||||
430 | } | ||||
431 | | ||||
432 | void KateExternalToolsConfigWidget::apply() | ||||
433 | { | ||||
434 | if (!m_changed) | ||||
435 | return; | ||||
436 | m_changed = false; | ||||
437 | | ||||
438 | QStringList tools; | ||||
439 | for (int i = 0; i < lbTools->count(); i++) { | ||||
440 | if (lbTools->item(i)->text() == QStringLiteral("---")) { | ||||
441 | tools << QStringLiteral("---"); | ||||
442 | continue; | ||||
443 | } | ||||
444 | const QString toolSection = QStringLiteral("Tool ") + QString::number(i); | ||||
445 | tools << toolSection; | ||||
446 | | ||||
447 | KConfigGroup cg(m_config, toolSection); | ||||
448 | KateExternalTool* t = static_cast<ToolItem*>(lbTools->item(i))->tool; | ||||
449 | t->save(cg); | ||||
450 | } | ||||
451 | | ||||
452 | m_config->group("Global").writeEntry("tools", tools); | ||||
453 | | ||||
454 | m_config->sync(); | ||||
455 | m_plugin->reload(); | ||||
456 | } | ||||
457 | | ||||
458 | void KateExternalToolsConfigWidget::slotSelectionChanged() | ||||
459 | { | ||||
460 | // update button state | ||||
461 | bool hs = lbTools->currentItem() != nullptr; | ||||
462 | btnEdit->setEnabled(hs && dynamic_cast<ToolItem*>(lbTools->currentItem())); | ||||
463 | btnRemove->setEnabled(hs); | ||||
464 | btnMoveUp->setEnabled((lbTools->currentRow() > 0) && hs); | ||||
465 | btnMoveDown->setEnabled((lbTools->currentRow() < (int)lbTools->count() - 1) && hs); | ||||
466 | } | ||||
467 | | ||||
468 | void KateExternalToolsConfigWidget::slotNew() | ||||
469 | { | ||||
470 | // display a editor, and if it is OK'd, create a new tool and | ||||
471 | // create a listbox item for it | ||||
472 | KateExternalToolServiceEditor editor(nullptr, this); | ||||
473 | | ||||
474 | if (editor.exec() == QDialog::Accepted) { | ||||
475 | KateExternalTool* t = new KateExternalTool(); | ||||
476 | t->name = editor.ui->edtName->text(); | ||||
477 | t->icon = editor.ui->btnIcon->icon(); | ||||
478 | t->executable = editor.ui->edtExecutable->text(); | ||||
479 | t->arguments = editor.ui->edtArgs->text(); | ||||
480 | t->input = editor.ui->edtInput->toPlainText(); | ||||
481 | t->workingDir = editor.ui->edtWorkingDir->text(); | ||||
482 | t->mimetypes = editor.ui->edtMimeType->text().split(QRegularExpression(QStringLiteral("\\s*;\\s*")), QString::SkipEmptyParts); | ||||
483 | t->saveMode = static_cast<KateExternalTool::SaveMode>(editor.ui->cmbSave->currentIndex()); | ||||
484 | t->includeStderr = editor.ui->chkIncludeStderr->isChecked(); | ||||
485 | | ||||
486 | // This is sticky, it does not change again, so that shortcuts sticks | ||||
487 | // TODO check for dups | ||||
488 | t->actionName = QStringLiteral("externaltool_") + QString(t->name).remove(QRegExp(QStringLiteral("\\W+"))); | ||||
489 | | ||||
490 | new ToolItem(lbTools, t->icon.isEmpty() ? blankIcon() : SmallIcon(t->icon), t); | ||||
491 | | ||||
492 | emit changed(); | ||||
493 | m_changed = true; | ||||
494 | } | ||||
495 | } | ||||
496 | | ||||
497 | void KateExternalToolsConfigWidget::slotRemove() | ||||
498 | { | ||||
499 | // add the tool action name to a list of removed items, | ||||
500 | // remove the current listbox item | ||||
501 | if (lbTools->currentRow() > -1) { | ||||
502 | ToolItem* i = dynamic_cast<ToolItem*>(lbTools->currentItem()); | ||||
503 | if (i) | ||||
504 | m_removed << i->tool->actionName; | ||||
505 | | ||||
506 | delete lbTools->takeItem(lbTools->currentRow()); | ||||
507 | emit changed(); | ||||
508 | m_changed = true; | ||||
509 | } | ||||
510 | } | ||||
511 | | ||||
512 | void KateExternalToolsConfigWidget::slotEdit() | ||||
513 | { | ||||
514 | if (!dynamic_cast<ToolItem*>(lbTools->currentItem())) | ||||
515 | return; | ||||
516 | // show the item in an editor | ||||
517 | KateExternalTool* t = static_cast<ToolItem*>(lbTools->currentItem())->tool; | ||||
518 | KateExternalToolServiceEditor editor(t, this); | ||||
519 | editor.resize(m_config->group("Editor").readEntry("Size", QSize())); | ||||
520 | if (editor.exec() /*== KDialog::Ok*/) { | ||||
521 | | ||||
522 | bool elementChanged = ((editor.ui->btnIcon->icon() != t->icon) || (editor.ui->edtName->text() != t->name)); | ||||
523 | | ||||
524 | t->name = editor.ui->edtName->text(); | ||||
525 | t->icon = editor.ui->btnIcon->icon(); | ||||
526 | t->executable = editor.ui->edtExecutable->text(); | ||||
527 | t->arguments = editor.ui->edtArgs->text(); | ||||
528 | t->input = editor.ui->edtInput->toPlainText(); | ||||
529 | t->cmdname = editor.ui->edtCommand->text(); | ||||
530 | t->workingDir = editor.ui->edtWorkingDir->text(); | ||||
531 | t->mimetypes = editor.ui->edtMimeType->text().split(QRegExp(QStringLiteral("\\s*;\\s*")), QString::SkipEmptyParts); | ||||
532 | t->saveMode = static_cast<KateExternalTool::SaveMode>(editor.ui->cmbSave->currentIndex()); | ||||
533 | t->includeStderr = editor.ui->chkIncludeStderr->isChecked(); | ||||
534 | | ||||
535 | // if the icon has changed or name changed, I have to renew the listbox item :S | ||||
536 | if (elementChanged) { | ||||
537 | int idx = lbTools->row(lbTools->currentItem()); | ||||
538 | delete lbTools->takeItem(idx); | ||||
539 | lbTools->insertItem(idx, new ToolItem(nullptr, t->icon.isEmpty() ? blankIcon() : SmallIcon(t->icon), t)); | ||||
540 | } | ||||
541 | | ||||
542 | emit changed(); | ||||
543 | m_changed = true; | ||||
544 | } | ||||
545 | | ||||
546 | m_config->group("Editor").writeEntry("Size", editor.size()); | ||||
547 | m_config->sync(); | ||||
548 | } | ||||
549 | | ||||
550 | void KateExternalToolsConfigWidget::slotInsertSeparator() | ||||
551 | { | ||||
552 | lbTools->insertItem(lbTools->currentRow() + 1, QStringLiteral("---")); | ||||
553 | emit changed(); | ||||
554 | m_changed = true; | ||||
555 | } | ||||
556 | | ||||
557 | void KateExternalToolsConfigWidget::slotMoveUp() | ||||
558 | { | ||||
559 | // move the current item in the listbox upwards if possible | ||||
560 | QListWidgetItem* item = lbTools->currentItem(); | ||||
561 | if (!item) | ||||
562 | return; | ||||
563 | | ||||
564 | int idx = lbTools->row(item); | ||||
565 | | ||||
566 | if (idx < 1) | ||||
567 | return; | ||||
568 | | ||||
569 | if (dynamic_cast<ToolItem*>(item)) { | ||||
570 | KateExternalTool* tool = static_cast<ToolItem*>(item)->tool; | ||||
571 | delete lbTools->takeItem(idx); | ||||
572 | lbTools->insertItem(idx - 1, | ||||
573 | new ToolItem(nullptr, tool->icon.isEmpty() ? blankIcon() : SmallIcon(tool->icon), tool)); | ||||
574 | } else // a separator! | ||||
575 | { | ||||
576 | delete lbTools->takeItem(idx); | ||||
577 | lbTools->insertItem(idx - 1, new QListWidgetItem(QStringLiteral("---"))); | ||||
578 | } | ||||
579 | | ||||
580 | lbTools->setCurrentRow(idx - 1); | ||||
581 | slotSelectionChanged(); | ||||
582 | emit changed(); | ||||
583 | m_changed = true; | ||||
584 | } | ||||
585 | | ||||
586 | void KateExternalToolsConfigWidget::slotMoveDown() | ||||
587 | { | ||||
588 | // move the current item in the listbox downwards if possible | ||||
589 | QListWidgetItem* item = lbTools->currentItem(); | ||||
590 | if (!item) | ||||
591 | return; | ||||
592 | | ||||
593 | int idx = lbTools->row(item); | ||||
594 | | ||||
595 | if (idx > lbTools->count() - 1) | ||||
596 | return; | ||||
597 | | ||||
598 | if (dynamic_cast<ToolItem*>(item)) { | ||||
599 | KateExternalTool* tool = static_cast<ToolItem*>(item)->tool; | ||||
600 | delete lbTools->takeItem(idx); | ||||
601 | lbTools->insertItem(idx + 1, | ||||
602 | new ToolItem(nullptr, tool->icon.isEmpty() ? blankIcon() : SmallIcon(tool->icon), tool)); | ||||
603 | } else // a separator! | ||||
604 | { | ||||
605 | delete lbTools->takeItem(idx); | ||||
606 | lbTools->insertItem(idx + 1, new QListWidgetItem(QStringLiteral("---"))); | ||||
607 | } | ||||
608 | | ||||
609 | lbTools->setCurrentRow(idx + 1); | ||||
610 | slotSelectionChanged(); | ||||
611 | emit changed(); | ||||
612 | m_changed = true; | ||||
613 | } | ||||
614 | // END KateExternalToolsConfigWidget | ||||
615 | | ||||
616 | ExternalToolRunner::ExternalToolRunner(KateExternalTool * tool) | ||||
617 | : m_tool(tool) | ||||
618 | { | ||||
619 | } | ||||
620 | | ||||
621 | ExternalToolRunner::~ExternalToolRunner() | ||||
622 | { | ||||
623 | } | ||||
624 | | ||||
625 | void ExternalToolRunner::run() | ||||
626 | { | ||||
627 | } | ||||
628 | | ||||
629 | // kate: space-indent on; indent-width 4; replace-tabs on; |