From 10b6b2936be180001b7618fadf8c69c70c3a2e3e Mon Sep 17 00:00:00 2001
From: con <qtc-committer@nokia.com>
Date: Thu, 9 Dec 2010 14:57:22 +0100
Subject: [PATCH] Make the "sort selection" tool do something.

* Handle <input> tag.
* Pass input to running process.
* Search for executable in path.
* Add "CurrentSelection" variable.

Remaining issue: ReplaceSelection output handling.
---
 share/qtcreator/externaltools/sort.xml        |  6 +--
 src/plugins/coreplugin/externaltool.cpp       | 42 +++++++++++++++----
 src/plugins/coreplugin/externaltool.h         |  4 ++
 src/plugins/texteditor/texteditorplugin.cpp   | 19 +++++++++
 src/plugins/texteditor/texteditorplugin.h     |  1 +
 .../externaltool/tst_externaltooltest.cpp     |  7 +++-
 6 files changed, 66 insertions(+), 13 deletions(-)

diff --git a/share/qtcreator/externaltools/sort.xml b/share/qtcreator/externaltools/sort.xml
index 6ed6bb93eaf..cf9e784ca15 100644
--- a/share/qtcreator/externaltools/sort.xml
+++ b/share/qtcreator/externaltools/sort.xml
@@ -32,11 +32,11 @@
 <externaltool id="sort">
     <description>Sorts the selected text</description>
     <description xml:lang="de">Sortiert den ausgewählten Text</description>
-    <displayname>Sort</displayname>
-    <displayname xml:lang="de">Sortieren</displayname>
+    <displayname>Sort Selection</displayname>
+    <displayname xml:lang="de">Selektion Sortieren</displayname>
     <category>Text</category>
     <category xml:lang="de">Text</category>
-    <executable output="replaceselection">
+    <executable output="showinpane" error="ignore">
         <path>sort</path>
         <input>%{CurrentSelection}</input>
         <workingdirectory>%{CurrentPath}</workingdirectory>
diff --git a/src/plugins/coreplugin/externaltool.cpp b/src/plugins/coreplugin/externaltool.cpp
index 1a446cbcc10..b6fa8bdbc1d 100644
--- a/src/plugins/coreplugin/externaltool.cpp
+++ b/src/plugins/coreplugin/externaltool.cpp
@@ -38,6 +38,7 @@
 #include <coreplugin/messagemanager.h>
 #include <utils/qtcassert.h>
 #include <utils/stringutils.h>
+#include <utils/environment.h>
 
 #include <QtCore/QXmlStreamReader>
 #include <QtCore/QDir>
@@ -60,6 +61,7 @@ namespace {
     const char * const kExecutable = "executable";
     const char * const kPath = "path";
     const char * const kArguments = "arguments";
+    const char * const kInput = "input";
     const char * const kWorkingDirectory = "workingdirectory";
 
     const char * const kXmlLang = "xml:lang";
@@ -120,6 +122,11 @@ QString ExternalTool::arguments() const
     return m_arguments;
 }
 
+QString ExternalTool::input() const
+{
+    return m_input;
+}
+
 QString ExternalTool::workingDirectory() const
 {
     return m_workingDirectory;
@@ -244,6 +251,12 @@ ExternalTool * ExternalTool::createFromXml(const QByteArray &xml, QString *error
                         break;
                     }
                     tool->m_arguments = reader.readElementText();
+                } else if (reader.name() == QLatin1String(kInput)) {
+                    if (!tool->m_input.isEmpty()) {
+                        reader.raiseError(QLatin1String("only one <input> element allowed"));
+                        break;
+                    }
+                    tool->m_input = reader.readElementText();
                 } else if (reader.name() == QLatin1String(kWorkingDirectory)) {
                     if (!tool->m_workingDirectory.isEmpty()) {
                         reader.raiseError(QLatin1String("only one <workingdirectory> element allowed"));
@@ -290,14 +303,10 @@ bool ExternalToolRunner::resolve()
         foreach (const QString &executable, m_tool->executables()) {
             QString resolved = Utils::expandMacros(executable,
                                                    Core::VariableManager::instance()->macroExpander());
-            QFileInfo info(resolved);
-            // TODO search in path
-            if (info.exists() && info.isExecutable()) {
-                m_resolvedExecutable = resolved;
-                break;
-            }
+            m_resolvedExecutable =
+                    Utils::Environment::systemEnvironment().searchInPath(resolved);
         }
-        if (m_resolvedExecutable.isNull())
+        if (m_resolvedExecutable.isEmpty())
             return false;
     }
     { // arguments
@@ -306,6 +315,10 @@ bool ExternalToolRunner::resolve()
         // TODO stupid, do it right
         m_resolvedArguments = resolved.split(QLatin1Char(' '), QString::SkipEmptyParts);
     }
+    { // input
+        m_resolvedInput = Utils::expandMacros(m_tool->input(),
+                                              Core::VariableManager::instance()->macroExpander());
+    }
     { // working directory
         m_resolvedWorkingDirectory = Utils::expandMacros(m_tool->workingDirectory(),
                                                Core::VariableManager::instance()->macroExpander());
@@ -321,17 +334,30 @@ void ExternalToolRunner::run()
     }
     m_process = new QProcess;
     // TODO error handling, finish reporting, reading output, etc
+    connect(m_process, SIGNAL(started()), this, SLOT(started()));
     connect(m_process, SIGNAL(finished(int)), this, SLOT(finished()));
     connect(m_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)));
     connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(readStandardOutput()));
     connect(m_process, SIGNAL(readyReadStandardError()), this, SLOT(readStandardError()));
     if (!m_resolvedWorkingDirectory.isEmpty())
         m_process->setWorkingDirectory(m_resolvedWorkingDirectory);
-    m_process->start(m_resolvedExecutable, m_resolvedArguments, QIODevice::ReadOnly);
+    ICore::instance()->messageManager()->printToOutputPane(
+                tr("Starting external tool '%1'").arg(m_resolvedExecutable), false);
+    m_process->start(m_resolvedExecutable, m_resolvedArguments, QIODevice::ReadWrite);
+}
+
+void ExternalToolRunner::started()
+{
+    if (!m_resolvedInput.isEmpty()) {
+        m_process->write(m_resolvedInput.toLocal8Bit());
+    }
+    m_process->closeWriteChannel();
 }
 
 void ExternalToolRunner::finished()
 {
+    ICore::instance()->messageManager()->printToOutputPane(
+                tr("'%1' finished").arg(m_resolvedExecutable), false);
     // TODO handle the ReplaceSelection and ReloadDocument flags
     m_process->deleteLater();
     deleteLater();
diff --git a/src/plugins/coreplugin/externaltool.h b/src/plugins/coreplugin/externaltool.h
index ffb1c8a491a..d89fcdd55c4 100644
--- a/src/plugins/coreplugin/externaltool.h
+++ b/src/plugins/coreplugin/externaltool.h
@@ -66,6 +66,7 @@ public:
 
     QStringList executables() const;
     QString arguments() const;
+    QString input() const;
     QString workingDirectory() const;
 
     static ExternalTool *createFromXml(const QByteArray &xml, QString *errorMessage = 0, const QString &locale = QString());
@@ -78,6 +79,7 @@ private:
     int m_order;
     QStringList m_executables;
     QString m_arguments;
+    QString m_input;
     QString m_workingDirectory;
     OutputHandling m_outputHandling;
     OutputHandling m_errorHandling;
@@ -90,6 +92,7 @@ public:
     ExternalToolRunner(const ExternalTool *tool);
 
 private slots:
+    void started();
     void finished();
     void error(QProcess::ProcessError error);
     void readStandardOutput();
@@ -102,6 +105,7 @@ private:
     const ExternalTool *m_tool;
     QString m_resolvedExecutable;
     QStringList m_resolvedArguments;
+    QString m_resolvedInput;
     QString m_resolvedWorkingDirectory;
     QProcess *m_process;
     QTextCodec *m_outputCodec;
diff --git a/src/plugins/texteditor/texteditorplugin.cpp b/src/plugins/texteditor/texteditorplugin.cpp
index cdf5f19cf07..bce94dd65a8 100644
--- a/src/plugins/texteditor/texteditorplugin.cpp
+++ b/src/plugins/texteditor/texteditorplugin.cpp
@@ -50,6 +50,7 @@
 #include <coreplugin/icore.h>
 #include <coreplugin/coreconstants.h>
 #include <coreplugin/mimedatabase.h>
+#include <coreplugin/variablemanager.h>
 #include <coreplugin/actionmanager/actionmanager.h>
 #include <coreplugin/actionmanager/command.h>
 #include <coreplugin/editormanager/editormanager.h>
@@ -175,6 +176,9 @@ void TextEditorPlugin::extensionsInitialized()
 
     addAutoReleasedObject(new FindInFiles(Find::SearchResultWindow::instance()));
     addAutoReleasedObject(new FindInCurrentFile(Find::SearchResultWindow::instance()));
+    connect(Core::VariableManager::instance(), SIGNAL(variableUpdateRequested(QString)),
+            this, SLOT(updateVariable(QString)));
+
 }
 
 void TextEditorPlugin::initializeEditor(PlainTextEditor *editor)
@@ -208,4 +212,19 @@ void TextEditorPlugin::updateSearchResultsFont(const FontSettings &settings)
                                                       settings.fontSize() * settings.fontZoom() / 100));
 }
 
+void TextEditorPlugin::updateVariable(const QString &variable)
+{
+    static const char * const kCurrentSelectionVar = "CurrentSelection";
+    if (variable == QLatin1String(kCurrentSelectionVar)) {
+        QString selectedText;
+        Core::IEditor *iface = Core::EditorManager::instance()->currentEditor();
+        ITextEditor *editor = qobject_cast<ITextEditor *>(iface);
+        if (editor) {
+            selectedText = editor->selectedText();
+            selectedText.replace(QChar::ParagraphSeparator, QLatin1String("\n"));
+        }
+        Core::VariableManager::instance()->insert(variable, selectedText);
+    }
+}
+
 Q_EXPORT_PLUGIN(TextEditorPlugin)
diff --git a/src/plugins/texteditor/texteditorplugin.h b/src/plugins/texteditor/texteditorplugin.h
index 979d32b8069..d79e1a07163 100644
--- a/src/plugins/texteditor/texteditorplugin.h
+++ b/src/plugins/texteditor/texteditorplugin.h
@@ -76,6 +76,7 @@ private slots:
     void invokeCompletion();
     void invokeQuickFix();
     void updateSearchResultsFont(const TextEditor::FontSettings &);
+    void updateVariable(const QString &variable);
 
 private:
     static TextEditorPlugin *m_instance;
diff --git a/tests/auto/externaltool/tst_externaltooltest.cpp b/tests/auto/externaltool/tst_externaltooltest.cpp
index 72f06982643..c21a6aece77 100644
--- a/tests/auto/externaltool/tst_externaltooltest.cpp
+++ b/tests/auto/externaltool/tst_externaltooltest.cpp
@@ -35,7 +35,7 @@ static const char * const TEST_XML2 =
 "    <category xml:lang=\"de\">Text</category>"
 "    <executable output=\"replaceselection\">"
 "        <path>sort</path>"
-"        <arguments>%{CurrentSelectionFilePath}</arguments>"
+"        <input>%{CurrentSelection}</input>"
 "        <workingdirectory>%{CurrentPath}</workingdirectory>"
 "    </executable>"
 "</externaltool>";
@@ -99,6 +99,7 @@ void ExternaltoolTest::testRead1()
     QCOMPARE(tool->executables().at(0), QString::fromLatin1("%{QT_INSTALL_BINS}/lupdate"));
     QCOMPARE(tool->executables().at(1), QString::fromLatin1("lupdate"));
     QCOMPARE(tool->arguments(), QString::fromLatin1("%{CurrentProjectFilePath}"));
+    QCOMPARE(tool->input(), QString());
     QCOMPARE(tool->workingDirectory(), QString::fromLatin1("%{CurrentProjectPath}"));
     QCOMPARE(tool->outputHandling(), ExternalTool::ShowInPane);
     QCOMPARE(tool->errorHandling(), ExternalTool::Ignore);
@@ -118,7 +119,8 @@ void ExternaltoolTest::testRead2()
     QCOMPARE(tool->order(), -1);
     QCOMPARE(tool->executables().size(), 1);
     QCOMPARE(tool->executables().at(0), QString::fromLatin1("sort"));
-    QCOMPARE(tool->arguments(), QString::fromLatin1("%{CurrentSelectionFilePath}"));
+    QCOMPARE(tool->arguments(), QString());
+    QCOMPARE(tool->input(), QString::fromLatin1("%{CurrentSelection}"));
     QCOMPARE(tool->workingDirectory(), QString::fromLatin1("%{CurrentPath}"));
     QCOMPARE(tool->outputHandling(), ExternalTool::ReplaceSelection);
     QCOMPARE(tool->errorHandling(), ExternalTool::ShowInPane);
@@ -139,6 +141,7 @@ void ExternaltoolTest::testRead3()
     QCOMPARE(tool->executables().size(), 1);
     QCOMPARE(tool->executables().at(0), QString::fromLatin1("xterm"));
     QVERIFY(tool->arguments().startsWith(QLatin1String("-geom %{")));
+    QCOMPARE(tool->input(), QString());
     QCOMPARE(tool->workingDirectory(), QString::fromLatin1("%{CurrentPath}"));
     QCOMPARE(tool->outputHandling(), ExternalTool::ReloadDocument);
     QCOMPARE(tool->errorHandling(), ExternalTool::ShowInPane);
-- 
GitLab