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