From d768008d608c034fde1a38098dc857e9ab5799ff Mon Sep 17 00:00:00 2001
From: con <qtc-committer@nokia.com>
Date: Thu, 6 Jan 2011 18:26:09 +0100
Subject: [PATCH] Add a tools settings page and show the tools there.

No editing possible yet.
---
 src/plugins/coreplugin/coreplugin.pro         |  11 +-
 .../coreplugin/dialogs/externaltoolconfig.cpp | 112 +++++++++++
 .../coreplugin/dialogs/externaltoolconfig.h   |  72 +++++++
 .../coreplugin/dialogs/externaltoolconfig.ui  | 178 ++++++++++++++++++
 .../coreplugin/dialogs/settingsdialog.cpp     |  11 ++
 .../coreplugin/dialogs/settingsdialog.h       |   1 +
 src/plugins/coreplugin/externaltool.cpp       |  58 ++++--
 src/plugins/coreplugin/externaltool.h         |   8 +-
 src/plugins/coreplugin/mainwindow.cpp         |   6 +
 src/plugins/coreplugin/mainwindow.h           |   2 +
 src/plugins/coreplugin/toolsettings.cpp       |  98 ++++++++++
 src/plugins/coreplugin/toolsettings.h         |  68 +++++++
 12 files changed, 604 insertions(+), 21 deletions(-)
 create mode 100644 src/plugins/coreplugin/dialogs/externaltoolconfig.cpp
 create mode 100644 src/plugins/coreplugin/dialogs/externaltoolconfig.h
 create mode 100644 src/plugins/coreplugin/dialogs/externaltoolconfig.ui
 create mode 100644 src/plugins/coreplugin/toolsettings.cpp
 create mode 100644 src/plugins/coreplugin/toolsettings.h

diff --git a/src/plugins/coreplugin/coreplugin.pro b/src/plugins/coreplugin/coreplugin.pro
index 8c55a3d2221..a52122cf35d 100644
--- a/src/plugins/coreplugin/coreplugin.pro
+++ b/src/plugins/coreplugin/coreplugin.pro
@@ -88,7 +88,9 @@ SOURCES += mainwindow.cpp \
     navigationsubwidget.cpp \
     sidebarwidget.cpp \
     rssfetcher.cpp \
-    externaltool.cpp
+    externaltool.cpp \
+    dialogs/externaltoolconfig.cpp \
+    toolsettings.cpp
 
 HEADERS += mainwindow.h \
     editmode.h \
@@ -174,14 +176,17 @@ HEADERS += mainwindow.h \
     navigationsubwidget.h \
     sidebarwidget.h \
     rssfetcher.h \
-    externaltool.h
+    externaltool.h \
+    dialogs/externaltoolconfig.h \
+    toolsettings.h
 
 FORMS += dialogs/newdialog.ui \
     actionmanager/commandmappings.ui \
     dialogs/saveitemsdialog.ui \
     dialogs/openwithdialog.ui \
     editormanager/openeditorsview.ui \
-    generalsettings.ui
+    generalsettings.ui \
+    dialogs/externaltoolconfig.ui
 RESOURCES += core.qrc \
     fancyactionbar.qrc
 
diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp
new file mode 100644
index 00000000000..f95b0d8e0f4
--- /dev/null
+++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp
@@ -0,0 +1,112 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "externaltoolconfig.h"
+#include "ui_externaltoolconfig.h"
+
+#include <QtCore/QTextStream>
+
+using namespace Core::Internal;
+
+ExternalToolConfig::ExternalToolConfig(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::ExternalToolConfig)
+{
+    ui->setupUi(this);
+    connect(ui->toolTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
+            this, SLOT(showInfoForItem(QTreeWidgetItem*)));
+    showInfoForItem(0);
+}
+
+ExternalToolConfig::~ExternalToolConfig()
+{
+    delete ui;
+}
+
+QString ExternalToolConfig::searchKeywords() const
+{
+    QString keywords;
+    QTextStream(&keywords)
+            << ui->descriptionLabel->text()
+            << ui->executableLabel->text()
+            << ui->argumentsLabel->text()
+            << ui->workingDirectoryLabel->text()
+            << ui->outputLabel->text()
+            << ui->errorOutputLabel->text()
+            << ui->inputCheckbox->text();
+    return keywords;
+}
+
+void ExternalToolConfig::setTools(const QMap<QString, QList<ExternalTool *> > &tools)
+{
+    // TODO make copy of tools
+
+    QMapIterator<QString, QList<ExternalTool *> > categories(tools);
+    while (categories.hasNext()) {
+        categories.next();
+        QString name = (categories.key().isEmpty() ? tr("External Tools Menu") : categories.key());
+        QTreeWidgetItem *category = new QTreeWidgetItem(ui->toolTree, QStringList() << name);
+        foreach (ExternalTool *tool, categories.value()) {
+            QTreeWidgetItem *item = new QTreeWidgetItem(category, QStringList() << tool->displayName());
+            item->setData(0, Qt::UserRole, qVariantFromValue(tool));
+        }
+    }
+    ui->toolTree->expandAll();
+}
+
+void ExternalToolConfig::showInfoForItem(QTreeWidgetItem *item)
+{
+    ExternalTool *tool = 0;
+    if (item)
+        tool = item->data(0, Qt::UserRole).value<ExternalTool *>();
+    if (!tool) {
+        ui->description->setText(QString());
+        ui->executable->setPath(QString());
+        ui->arguments->setText(QString());
+        ui->workingDirectory->setPath(QString());
+        ui->inputText->setPlainText(QString());
+        ui->infoWidget->setEnabled(false);
+        return;
+    }
+    ui->infoWidget->setEnabled(true);
+    ui->description->setText(tool->description());
+    ui->executable->setPath(tool->executables().isEmpty() ? QString() : tool->executables().first());
+    ui->arguments->setText(tool->arguments());
+    ui->workingDirectory->setPath(tool->workingDirectory());
+    ui->outputBehavior->setCurrentIndex((int)tool->outputHandling());
+    ui->errorOutputBehavior->setCurrentIndex((int)tool->errorHandling());
+    ui->inputCheckbox->setChecked(!tool->input().isEmpty());
+    ui->inputText->setPlainText(tool->input());
+    ui->description->setCursorPosition(0);
+    ui->arguments->setCursorPosition(0);
+}
diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.h b/src/plugins/coreplugin/dialogs/externaltoolconfig.h
new file mode 100644
index 00000000000..a05eb4be728
--- /dev/null
+++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.h
@@ -0,0 +1,72 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef EXTERNALTOOLCONFIG_H
+#define EXTERNALTOOLCONFIG_H
+
+#include "coreplugin/externaltool.h"
+
+#include <QtGui/QWidget>
+#include <QtGui/QTreeWidgetItem>
+
+namespace Core {
+namespace Internal {
+
+namespace Ui {
+    class ExternalToolConfig;
+}
+
+class ExternalToolConfig : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit ExternalToolConfig(QWidget *parent = 0);
+    ~ExternalToolConfig();
+
+    void setTools(const QMap<QString, QList<ExternalTool *> > &tools);
+
+    QString searchKeywords() const;
+
+private slots:
+    void showInfoForItem(QTreeWidgetItem *item);
+
+private:
+    Ui::ExternalToolConfig *ui;
+};
+
+} // Internal
+} // Core
+
+
+#endif // EXTERNALTOOLCONFIG_H
diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.ui b/src/plugins/coreplugin/dialogs/externaltoolconfig.ui
new file mode 100644
index 00000000000..fb4b5e020d1
--- /dev/null
+++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.ui
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Core::Internal::ExternalToolConfig</class>
+ <widget class="QWidget" name="Core::Internal::ExternalToolConfig">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>725</width>
+    <height>468</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <item>
+    <widget class="QTreeWidget" name="toolTree">
+     <attribute name="headerVisible">
+      <bool>false</bool>
+     </attribute>
+     <column>
+      <property name="text">
+       <string notr="true">1</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+   <item>
+    <widget class="QWidget" name="infoWidget" native="true">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+       <horstretch>10</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <layout class="QFormLayout" name="formLayout">
+      <property name="fieldGrowthPolicy">
+       <enum>QFormLayout::ExpandingFieldsGrow</enum>
+      </property>
+      <property name="margin">
+       <number>0</number>
+      </property>
+      <item row="0" column="0">
+       <widget class="QLabel" name="descriptionLabel">
+        <property name="text">
+         <string>Description:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QLineEdit" name="description"/>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="executableLabel">
+        <property name="text">
+         <string>Executable:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="Utils::PathChooser" name="executable">
+        <property name="expectedKind">
+         <enum>Utils::PathChooser::ExistingCommand</enum>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0">
+       <widget class="QLabel" name="argumentsLabel">
+        <property name="text">
+         <string>Arguments:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QLineEdit" name="arguments"/>
+      </item>
+      <item row="3" column="0">
+       <widget class="QLabel" name="workingDirectoryLabel">
+        <property name="text">
+         <string>Working directory:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <widget class="Utils::PathChooser" name="workingDirectory"/>
+      </item>
+      <item row="4" column="0">
+       <widget class="QLabel" name="outputLabel">
+        <property name="text">
+         <string>Output:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="1">
+       <widget class="QComboBox" name="outputBehavior">
+        <item>
+         <property name="text">
+          <string>Ignore</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Show in pane</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Replace selection</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Reload document</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="5" column="0">
+       <widget class="QLabel" name="errorOutputLabel">
+        <property name="text">
+         <string>Error output:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="1">
+       <widget class="QComboBox" name="errorOutputBehavior">
+        <item>
+         <property name="text">
+          <string>Ignore</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Show in pane</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Replace selection</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Reload document</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="6" column="0">
+       <widget class="QCheckBox" name="inputCheckbox">
+        <property name="text">
+         <string>Input:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="6" column="1">
+       <widget class="QPlainTextEdit" name="inputText">
+        <property name="lineWrapMode">
+         <enum>QPlainTextEdit::NoWrap</enum>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>Utils::PathChooser</class>
+   <extends>QWidget</extends>
+   <header location="global">utils/pathchooser.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/src/plugins/coreplugin/dialogs/settingsdialog.cpp
index 478696255f9..e0c01749743 100644
--- a/src/plugins/coreplugin/dialogs/settingsdialog.cpp
+++ b/src/plugins/coreplugin/dialogs/settingsdialog.cpp
@@ -446,6 +446,15 @@ void SettingsDialog::ensureAllCategoryWidgets()
         ensureCategoryWidget(category);
 }
 
+void SettingsDialog::disconnectTabWidgets()
+{
+    foreach (Category *category, m_model->categories()) {
+        if (category->tabWidget)
+            disconnect(category->tabWidget, SIGNAL(currentChanged(int)),
+                    this, SLOT(currentTabChanged(int)));
+    }
+}
+
 void SettingsDialog::updateEnabledTabs(Category *category, const QString &searchText)
 {
     for (int i = 0; i < category->pages.size(); ++i) {
@@ -497,6 +506,7 @@ void SettingsDialog::filter(const QString &text)
 
 void SettingsDialog::accept()
 {
+    disconnectTabWidgets();
     m_applied = true;
     foreach (IOptionsPage *page, m_visitedPages)
         page->apply();
@@ -507,6 +517,7 @@ void SettingsDialog::accept()
 
 void SettingsDialog::reject()
 {
+    disconnectTabWidgets();
     foreach (IOptionsPage *page, m_pages)
         page->finish();
     done(QDialog::Rejected);
diff --git a/src/plugins/coreplugin/dialogs/settingsdialog.h b/src/plugins/coreplugin/dialogs/settingsdialog.h
index d0003da0c81..3d82aae6e19 100644
--- a/src/plugins/coreplugin/dialogs/settingsdialog.h
+++ b/src/plugins/coreplugin/dialogs/settingsdialog.h
@@ -99,6 +99,7 @@ private:
     void updateEnabledTabs(Category *category, const QString &searchText);
     void ensureCategoryWidget(Category *category);
     void ensureAllCategoryWidgets();
+    void disconnectTabWidgets();
 
     const QList<Core::IOptionsPage*> m_pages;
 
diff --git a/src/plugins/coreplugin/externaltool.cpp b/src/plugins/coreplugin/externaltool.cpp
index f1ad60023a1..c334362b7bb 100644
--- a/src/plugins/coreplugin/externaltool.cpp
+++ b/src/plugins/coreplugin/externaltool.cpp
@@ -84,6 +84,21 @@ ExternalTool::ExternalTool() :
 {
 }
 
+ExternalTool::ExternalTool(const ExternalTool *other)
+    : m_id(other->m_id),
+      m_description(other->m_description),
+      m_displayName(other->m_displayName),
+      m_displayCategory(other->m_displayCategory),
+      m_order(other->m_order),
+      m_executables(other->m_executables),
+      m_arguments(other->m_arguments),
+      m_input(other->m_input),
+      m_workingDirectory(other->m_workingDirectory),
+      m_outputHandling(other->m_outputHandling),
+      m_errorHandling(other->m_errorHandling)
+{
+}
+
 ExternalTool::~ExternalTool()
 {
 }
@@ -448,14 +463,20 @@ void ExternalToolManager::initialize()
 
     mtools->addMenu(mexternaltools, Constants::G_DEFAULT_THREE);
 
-    QMap<QString, QMultiMap<int, Command*> > categoryMenus;
+    QMap<QString, QMultiMap<int, ExternalTool*> > categoryMap;
     parseDirectory(m_core->userResourcePath() + QLatin1String("/externaltools"),
-                   &categoryMenus);
+                   &categoryMap);
     parseDirectory(m_core->resourcePath() + QLatin1String("/externaltools"),
-                   &categoryMenus, true);
+                   &categoryMap, true);
+
+    QMapIterator<QString, QMultiMap<int, ExternalTool*> > it(categoryMap);
+    while (it.hasNext()) {
+        it.next();
+        m_categoryMap.insert(it.key(), it.value().values());
+    }
 
     // add all the category menus, QMap is nicely sorted
-    QMapIterator<QString, QMultiMap<int, Command*> > it(categoryMenus);
+    it.toFront();
     while (it.hasNext()) {
         it.next();
         ActionContainer *container = 0;
@@ -466,18 +487,23 @@ void ExternalToolManager::initialize()
             mexternaltools->addMenu(container, Constants::G_DEFAULT_ONE);
             container->menu()->setTitle(it.key());
         }
-        foreach (Command *cmd, it.value().values()) {
+        foreach (ExternalTool *tool, it.value().values()) {
+            // tool action and command
+            QAction *action = new QAction(tool->displayName(), this);
+            action->setToolTip(tool->description());
+            action->setWhatsThis(tool->description());
+            action->setData(tool->id());
+            Command *cmd = am->registerAction(action, Id("Tools.External." + tool->id()), Context(Constants::C_GLOBAL));
+            connect(action, SIGNAL(triggered()), this, SLOT(menuActivated()));
             container->addAction(cmd, Constants::G_DEFAULT_TWO);
         }
     }
 }
 
-void ExternalToolManager::parseDirectory(const QString &directory, QMap<QString, QMultiMap<int, Command*> > *categoryMenus,
+void ExternalToolManager::parseDirectory(const QString &directory, QMap<QString, QMultiMap<int, ExternalTool*> > *categoryMenus,
                                          bool ignoreDuplicates)
 {
     QTC_ASSERT(categoryMenus, return);
-    ActionManager *am = m_core->actionManager();
-    Command *cmd;
     QDir dir(directory, QLatin1String("*.xml"), QDir::Unsorted, QDir::Files | QDir::Readable);
     foreach (const QFileInfo &info, dir.entryInfoList()) {
         QFile file(info.absoluteFilePath());
@@ -499,15 +525,7 @@ void ExternalToolManager::parseDirectory(const QString &directory, QMap<QString,
                 continue;
             }
             m_tools.insert(tool->id(), tool);
-
-            // tool action and command
-            QAction *action = new QAction(tool->displayName(), this);
-            action->setToolTip(tool->description());
-            action->setWhatsThis(tool->description());
-            action->setData(tool->id());
-            cmd = am->registerAction(action, Id("Tools.External." + tool->id()), Context(Constants::C_GLOBAL));
-            connect(action, SIGNAL(triggered()), this, SLOT(menuActivated()));
-            (*categoryMenus)[tool->displayCategory()].insert(tool->order(), cmd);
+            (*categoryMenus)[tool->displayCategory()].insert(tool->order(), tool);
         }
     }
 }
@@ -520,3 +538,9 @@ void ExternalToolManager::menuActivated()
     QTC_ASSERT(tool, return);
     new ExternalToolRunner(tool);
 }
+
+QMap<QString, QList<Internal::ExternalTool *> > ExternalToolManager::tools() const
+{
+    return m_categoryMap;
+}
+
diff --git a/src/plugins/coreplugin/externaltool.h b/src/plugins/coreplugin/externaltool.h
index 53b02b712a3..c6b2fb390af 100644
--- a/src/plugins/coreplugin/externaltool.h
+++ b/src/plugins/coreplugin/externaltool.h
@@ -58,6 +58,7 @@ public:
     };
 
     ExternalTool();
+    ExternalTool(const ExternalTool *other);
     ~ExternalTool();
 
     QString id() const;
@@ -131,6 +132,8 @@ public:
     ExternalToolManager(Core::ICore *core);
     ~ExternalToolManager();
 
+    QMap<QString, QList<Internal::ExternalTool *> > tools() const;
+
 signals:
     void replaceSelectionRequested(const QString &text);
 
@@ -139,12 +142,13 @@ private slots:
 
 private:
     void initialize();
-    void parseDirectory(const QString &directory, QMap<QString, QMultiMap<int, Command*> > *categoryMenus,
+    void parseDirectory(const QString &directory, QMap<QString, QMultiMap<int, Internal::ExternalTool*> > *categoryMenus,
                         bool ignoreDuplicates = false);
 
     static ExternalToolManager *m_instance;
     Core::ICore *m_core;
     QMap<QString, Internal::ExternalTool *> m_tools;
+    QMap<QString, QList<Internal::ExternalTool *> > m_categoryMap;
 
     // for sending the replaceSelectionRequested signal
     friend class Core::Internal::ExternalToolRunner;
@@ -152,4 +156,6 @@ private:
 
 } // Core
 
+Q_DECLARE_METATYPE(Core::Internal::ExternalTool *)
+
 #endif // EXTERNALTOOL_H
diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp
index 705baaf09fe..075a8baf662 100644
--- a/src/plugins/coreplugin/mainwindow.cpp
+++ b/src/plugins/coreplugin/mainwindow.cpp
@@ -39,6 +39,7 @@
 #include "coreconstants.h"
 #include "editormanager.h"
 #include "externaltool.h"
+#include "toolsettings.h"
 #include "fancytabwidget.h"
 #include "filemanager.h"
 #include "generalsettings.h"
@@ -148,6 +149,7 @@ MainWindow::MainWindow() :
     m_activeContext(0),
     m_generalSettings(new GeneralSettings),
     m_shortcutSettings(new ShortcutSettings),
+    m_toolSettings(new ToolSettings),
     m_systemEditor(new SystemEditor),
     m_focusToEditor(0),
     m_newAction(0),
@@ -251,6 +253,7 @@ MainWindow::~MainWindow()
     ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
     pm->removeObject(m_shortcutSettings);
     pm->removeObject(m_generalSettings);
+    pm->removeObject(m_toolSettings);
     pm->removeObject(m_systemEditor);
     delete m_messageManager;
     m_messageManager = 0;
@@ -258,6 +261,8 @@ MainWindow::~MainWindow()
     m_shortcutSettings = 0;
     delete m_generalSettings;
     m_generalSettings = 0;
+    delete m_toolSettings;
+    m_toolSettings = 0;
     delete m_systemEditor;
     m_systemEditor = 0;
     delete m_settings;
@@ -315,6 +320,7 @@ bool MainWindow::init(QString *errorMessage)
 
     pm->addObject(m_generalSettings);
     pm->addObject(m_shortcutSettings);
+    pm->addObject(m_toolSettings);
     pm->addObject(m_systemEditor);
 
 
diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h
index 22506fd78c3..159cf35a74d 100644
--- a/src/plugins/coreplugin/mainwindow.h
+++ b/src/plugins/coreplugin/mainwindow.h
@@ -76,6 +76,7 @@ class FancyTabWidget;
 class GeneralSettings;
 class ProgressManagerPrivate;
 class ShortcutSettings;
+class ToolSettings;
 class StatusBarManager;
 class VersionDialog;
 class SystemEditor;
@@ -210,6 +211,7 @@ private:
 
     GeneralSettings *m_generalSettings;
     ShortcutSettings *m_shortcutSettings;
+    ToolSettings *m_toolSettings;
     SystemEditor *m_systemEditor;
 
     // actions
diff --git a/src/plugins/coreplugin/toolsettings.cpp b/src/plugins/coreplugin/toolsettings.cpp
new file mode 100644
index 00000000000..019e46ad7fa
--- /dev/null
+++ b/src/plugins/coreplugin/toolsettings.cpp
@@ -0,0 +1,98 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "toolsettings.h"
+
+#include "externaltool.h"
+#include "coreconstants.h"
+
+#include <QtCore/QCoreApplication>
+
+using namespace Core;
+using namespace Core::Internal;
+
+ToolSettings::ToolSettings(QObject *parent) :
+    IOptionsPage(parent)
+{
+}
+
+QString ToolSettings::id() const
+{
+    return QLatin1String("G.ExternalTools");
+}
+
+
+QString ToolSettings::displayName() const
+{
+    return tr("External Tools");
+}
+
+
+QString ToolSettings::category() const
+{
+    return QLatin1String(Core::Constants::SETTINGS_CATEGORY_CORE);
+}
+
+
+QString ToolSettings::displayCategory() const
+{
+    return QCoreApplication::translate("Core", Core::Constants::SETTINGS_TR_CATEGORY_CORE);
+}
+
+
+QIcon ToolSettings::categoryIcon() const
+{
+    return QIcon(QLatin1String(Core::Constants::SETTINGS_CATEGORY_CORE_ICON));
+}
+
+
+bool ToolSettings::matches(const QString & searchKeyWord) const
+{
+    return m_searchKeywords.contains(searchKeyWord, Qt::CaseInsensitive);
+}
+
+QWidget *ToolSettings::createPage(QWidget *parent)
+{
+    m_widget = new ExternalToolConfig(parent);
+    m_widget->setTools(ExternalToolManager::instance()->tools());
+    if (m_searchKeywords.isEmpty()) {
+        m_searchKeywords = m_widget->searchKeywords();
+    }
+    return m_widget;
+}
+
+
+void ToolSettings::apply()
+{
+}
+
+
+void ToolSettings::finish()
+{
+}
diff --git a/src/plugins/coreplugin/toolsettings.h b/src/plugins/coreplugin/toolsettings.h
new file mode 100644
index 00000000000..5d19a6057f7
--- /dev/null
+++ b/src/plugins/coreplugin/toolsettings.h
@@ -0,0 +1,68 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef TOOLSETTINGS_H
+#define TOOLSETTINGS_H
+
+#include "dialogs/externaltoolconfig.h"
+
+#include "ioptionspage.h"
+
+#include <QtCore/QPointer>
+
+namespace Core {
+namespace Internal {
+
+class ToolSettings : public IOptionsPage
+{
+    Q_OBJECT
+public:
+    explicit ToolSettings(QObject *parent = 0);
+    ~ToolSettings() {}
+
+    QString id() const;
+    QString displayName() const;
+    QString category() const;
+    QString displayCategory() const;
+    QIcon categoryIcon() const;
+    bool matches(const QString & searchKeyWord) const;
+
+    QWidget *createPage(QWidget *parent);
+    void apply();
+    void finish();
+
+private:
+    QString m_searchKeywords;
+    QPointer<ExternalToolConfig> m_widget;
+};
+
+} // namespace Internal
+} // namespace Core
+
+#endif // TOOLSETTINGS_H
-- 
GitLab