From d339637701f6733de87e98b50d618aab06e0c5b0 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Date: Tue, 11 Sep 2012 14:03:08 +0200
Subject: [PATCH] Move debugger kit settings into a separate dialog.

Change the DebuggerKitConfigWidget to contain a display label
only. Add a Button with a menu for "Autodetect" and
"Edit...".

Change-Id: I8ec17966ef220c81fb8b145a61df4408d5950da9
Reviewed-by: Eike Ziller <eike.ziller@nokia.com>
---
 src/plugins/debugger/debuggerdialogs.cpp      |   2 +-
 .../debugger/debuggerkitconfigwidget.cpp      | 142 ++++++++++++------
 .../debugger/debuggerkitconfigwidget.h        |  51 +++++--
 .../debugger/debuggerkitinformation.cpp       |  11 +-
 src/plugins/debugger/debuggerkitinformation.h |   8 +-
 5 files changed, 148 insertions(+), 66 deletions(-)

diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp
index 50bd8e64384..0138704dabc 100644
--- a/src/plugins/debugger/debuggerdialogs.cpp
+++ b/src/plugins/debugger/debuggerdialogs.cpp
@@ -137,7 +137,7 @@ bool DebuggerKitChooser::kitMatches(const ProjectExplorer::Kit *k) const
 
 QString DebuggerKitChooser::kitToolTip(Kit *k) const
 {
-    return DebuggerKitInformation::userOutput(k);
+    return DebuggerKitInformation::userOutput(DebuggerKitInformation::debuggerItem(k));
 }
 
 ///////////////////////////////////////////////////////////////////////
diff --git a/src/plugins/debugger/debuggerkitconfigwidget.cpp b/src/plugins/debugger/debuggerkitconfigwidget.cpp
index 1c69314fa80..9ecd51b7aaa 100644
--- a/src/plugins/debugger/debuggerkitconfigwidget.cpp
+++ b/src/plugins/debugger/debuggerkitconfigwidget.cpp
@@ -45,10 +45,14 @@
 
 #include <QDesktopServices>
 #include <QHBoxLayout>
-#include <QPushButton>
 #include <QVBoxLayout>
+#include <QFormLayout>
 #include <QLabel>
 #include <QComboBox>
+#include <QMenu>
+#include <QAction>
+#include <QPushButton>
+#include <QDialogButtonBox>
 
 namespace Debugger {
 namespace Internal {
@@ -67,44 +71,30 @@ DebuggerKitConfigWidget::DebuggerKitConfigWidget(ProjectExplorer::Kit *k,
     ProjectExplorer::KitConfigWidget(parent),
     m_kit(k),
     m_info(ki),
-    m_comboBox(new QComboBox(this)),
+    m_dirty(false),
     m_label(new QLabel(this)),
-    m_chooser(new Utils::PathChooser(this))
+    m_button(new QPushButton(tr("Manage..."), this))
 {
     setToolTip(tr("The debugger to use for this kit."));
 
-    QVBoxLayout *layout = new QVBoxLayout(this);
+    QHBoxLayout *layout = new QHBoxLayout(this);
     layout->setMargin(0);
-
-    m_comboBox->addItem(DebuggerKitInformation::debuggerEngineName(GdbEngineType), QVariant(int(GdbEngineType)));
-    if (ProjectExplorer::Abi::hostAbi().os() == ProjectExplorer::Abi::WindowsOS) {
-        m_comboBox->addItem(DebuggerKitInformation::debuggerEngineName(CdbEngineType), QVariant(int(CdbEngineType)));
-    } else {
-        m_comboBox->addItem(DebuggerKitInformation::debuggerEngineName(LldbEngineType), QVariant(int(LldbEngineType)));
-    }
-    layout->addWidget(m_comboBox);
-
-    m_label->setTextInteractionFlags(Qt::TextBrowserInteraction);
-    m_label->setOpenExternalLinks(true);
     layout->addWidget(m_label);
 
-    m_chooser->setContentsMargins(0, 0, 0, 0);
-    m_chooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
-    m_chooser->insertButton(0, tr("Auto detect"), this, SLOT(autoDetectDebugger()));
-
-    layout->addWidget(m_chooser);
+    // ToolButton with Menu, defaulting to 'Autodetect'.
+    QMenu *buttonMenu = new QMenu(m_button);
+    QAction *autoDetectAction = buttonMenu->addAction(tr("Auto-detect"));
+    connect(autoDetectAction, SIGNAL(triggered()), this, SLOT(autoDetectDebugger()));
+    QAction *changeAction = buttonMenu->addAction(tr("Edit..."));
+    connect(changeAction, SIGNAL(triggered()), this, SLOT(showDialog()));
+    m_button->setMenu(buttonMenu);
 
     discard();
-    connect(m_chooser, SIGNAL(changed(QString)), this, SIGNAL(dirty()));
-    connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(dirty()));
-    connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(refreshLabel()));
 }
 
-void DebuggerKitConfigWidget::addToLayout(QGridLayout *layout, int row)
+QWidget *DebuggerKitConfigWidget::buttonWidget() const
 {
-    addLabel(layout, row);
-    layout->addWidget(this, row, WidgetColumn, 3 , 1);
-    addButtonWidget(layout, row + 2);
+       return m_button;
 }
 
 QString DebuggerKitConfigWidget::displayName() const
@@ -114,47 +104,99 @@ QString DebuggerKitConfigWidget::displayName() const
 
 void DebuggerKitConfigWidget::makeReadOnly()
 {
-    m_comboBox->setEnabled(false);
-    m_chooser->setEnabled(false);
+    m_button->setEnabled(false);
 }
 
 void DebuggerKitConfigWidget::apply()
 {
-    DebuggerKitInformation::setDebuggerItem(m_kit, DebuggerKitInformation::DebuggerItem(engineType(), fileName()));
+    DebuggerKitInformation::setDebuggerItem(m_kit, m_item);
+    m_dirty = false;
 }
 
 void DebuggerKitConfigWidget::discard()
 {
-    const DebuggerKitInformation::DebuggerItem item = DebuggerKitInformation::debuggerItem(m_kit);
-    setEngineType(item.engineType);
-    setFileName(item.binary);
+    doSetItem(DebuggerKitInformation::debuggerItem(m_kit));
+    m_dirty = false;
 }
 
-bool DebuggerKitConfigWidget::isDirty() const
+void DebuggerKitConfigWidget::autoDetectDebugger()
 {
-    const DebuggerKitInformation::DebuggerItem item = DebuggerKitInformation::debuggerItem(m_kit);
-    return item.engineType != engineType() || item.binary != fileName();
+    setItem(DebuggerKitInformation::autoDetectItem(m_kit));
 }
 
-QWidget *DebuggerKitConfigWidget::buttonWidget() const
+void DebuggerKitConfigWidget::doSetItem(const DebuggerKitInformation::DebuggerItem &item)
 {
-    return m_chooser->buttonAtIndex(1);
+    m_item = item;
+    m_label->setText(DebuggerKitInformation::userOutput(m_item));
 }
 
-void DebuggerKitConfigWidget::autoDetectDebugger()
+void DebuggerKitConfigWidget::setItem(const DebuggerKitInformation::DebuggerItem &item)
 {
-    const DebuggerKitInformation::DebuggerItem item = DebuggerKitInformation::autoDetectItem(m_kit);
-    setEngineType(item.engineType);
-    setFileName(item.binary);
+    if (m_item != item) {
+        m_dirty = true;
+        doSetItem(item);
+        emit dirty();
+    }
+}
+
+void DebuggerKitConfigWidget::showDialog()
+{
+    DebuggerKitConfigDialog dialog;
+    dialog.setWindowTitle(tr("Debugger for \"%1\"").arg(m_kit->displayName()));
+    dialog.setDebuggerItem(m_item);
+    if (dialog.exec() == QDialog::Accepted)
+        setItem(dialog.item());
 }
 
-DebuggerEngineType DebuggerKitConfigWidget::engineType() const
+// -----------------------------------------------------------------------
+// DebuggerKitConfigDialog:
+// -----------------------------------------------------------------------
+
+DebuggerKitConfigDialog::DebuggerKitConfigDialog(QWidget *parent)
+    : QDialog(parent)
+    , m_comboBox(new QComboBox(this))
+    , m_label(new QLabel(this))
+    , m_chooser(new Utils::PathChooser(this))
+{
+    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+    QVBoxLayout *layout = new QVBoxLayout(this);
+    QFormLayout *formLayout = new QFormLayout;
+    formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
+
+    m_comboBox->addItem(DebuggerKitInformation::debuggerEngineName(GdbEngineType), QVariant(int(GdbEngineType)));
+    if (ProjectExplorer::Abi::hostAbi().os() == ProjectExplorer::Abi::WindowsOS) {
+        m_comboBox->addItem(DebuggerKitInformation::debuggerEngineName(CdbEngineType), QVariant(int(CdbEngineType)));
+    } else {
+        m_comboBox->addItem(DebuggerKitInformation::debuggerEngineName(LldbEngineType), QVariant(int(LldbEngineType)));
+    }
+    connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(refreshLabel()));
+    QLabel *engineTypeLabel = new QLabel(tr("&Engine:"));
+    engineTypeLabel->setBuddy(m_comboBox);
+    formLayout->addRow(engineTypeLabel, m_comboBox);
+
+    m_label->setTextInteractionFlags(Qt::TextBrowserInteraction);
+    m_label->setOpenExternalLinks(true);
+    formLayout->addRow(m_label);
+
+    QLabel *binaryLabel = new QLabel(tr("&Binary:"));
+    m_chooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
+    binaryLabel->setBuddy(m_chooser);
+    formLayout->addRow(binaryLabel, m_chooser);
+    layout->addLayout(formLayout);
+
+    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
+    connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+    connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+    layout->addWidget(buttonBox);
+}
+
+DebuggerEngineType DebuggerKitConfigDialog::engineType() const
 {
     const int index = m_comboBox->currentIndex();
     return static_cast<DebuggerEngineType>(m_comboBox->itemData(index).toInt());
 }
 
-void DebuggerKitConfigWidget::setEngineType(DebuggerEngineType et)
+void DebuggerKitConfigDialog::setEngineType(DebuggerEngineType et)
 {
     const int size = m_comboBox->count();
     for (int i = 0; i < size; ++i) {
@@ -166,17 +208,17 @@ void DebuggerKitConfigWidget::setEngineType(DebuggerEngineType et)
     }
 }
 
-Utils::FileName DebuggerKitConfigWidget::fileName() const
+Utils::FileName DebuggerKitConfigDialog::fileName() const
 {
     return m_chooser->fileName();
 }
 
-void DebuggerKitConfigWidget::setFileName(const Utils::FileName &fn)
+void DebuggerKitConfigDialog::setFileName(const Utils::FileName &fn)
 {
     m_chooser->setFileName(fn);
 }
 
-void DebuggerKitConfigWidget::refreshLabel()
+void DebuggerKitConfigDialog::refreshLabel()
 {
     QString text;
     const DebuggerEngineType type = engineType();
@@ -205,5 +247,11 @@ void DebuggerKitConfigWidget::refreshLabel()
                                           QStringList(QLatin1String("--version")));
 }
 
+void DebuggerKitConfigDialog::setDebuggerItem(const DebuggerKitInformation::DebuggerItem &item)
+{
+    setEngineType(item.engineType);
+    setFileName(item.binary);
+}
+
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/debuggerkitconfigwidget.h b/src/plugins/debugger/debuggerkitconfigwidget.h
index 4884ff7bd76..735d02fd01f 100644
--- a/src/plugins/debugger/debuggerkitconfigwidget.h
+++ b/src/plugins/debugger/debuggerkitconfigwidget.h
@@ -33,10 +33,15 @@
 
 #include <projectexplorer/kitconfigwidget.h>
 
-#include "debuggerconstants.h"
+#include "debuggerkitinformation.h"
 
-QT_FORWARD_DECLARE_CLASS(QLabel)
-QT_FORWARD_DECLARE_CLASS(QComboBox)
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+class QLabel;
+class QComboBox;
+class QPushButton;
+QT_END_NAMESPACE
 
 namespace ProjectExplorer { class Kit; }
 namespace Utils {
@@ -67,23 +72,45 @@ public:
 
     void apply();
     void discard();
-    bool isDirty() const;
+    bool isDirty() const { return m_dirty; }
     QWidget *buttonWidget() const;
-    void addToLayout(QGridLayout *layout, int row);
-
-    DebuggerEngineType engineType() const;
-    void setEngineType(DebuggerEngineType et);
-
-    Utils::FileName fileName() const;
-    void setFileName(const Utils::FileName &fn);
 
 private slots:
     void autoDetectDebugger();
-    void refreshLabel();
+    void showDialog();
 
 private:
+    void setItem(const DebuggerKitInformation::DebuggerItem &item);
+    void doSetItem(const DebuggerKitInformation::DebuggerItem &item);
+
     ProjectExplorer::Kit *m_kit;
     const DebuggerKitInformation *m_info;
+    DebuggerKitInformation::DebuggerItem m_item;
+    bool m_dirty;
+    QLabel *m_label;
+    QPushButton *m_button;
+};
+
+class DebuggerKitConfigDialog : public QDialog
+{
+    Q_OBJECT
+public:
+    explicit DebuggerKitConfigDialog(QWidget *parent =  0);
+
+    void setDebuggerItem(const DebuggerKitInformation::DebuggerItem &item);
+    DebuggerKitInformation::DebuggerItem item() const
+        { return DebuggerKitInformation::DebuggerItem(engineType(), fileName()); }
+
+private slots:
+    void refreshLabel();
+
+private:
+    DebuggerEngineType engineType() const;
+    void setEngineType(DebuggerEngineType et);
+
+    Utils::FileName fileName() const;
+    void setFileName(const Utils::FileName &fn);
+
     QComboBox *m_comboBox;
     QLabel *m_label;
     Utils::PathChooser *m_chooser;
diff --git a/src/plugins/debugger/debuggerkitinformation.cpp b/src/plugins/debugger/debuggerkitinformation.cpp
index 75012379838..e1aa4d453f6 100644
--- a/src/plugins/debugger/debuggerkitinformation.cpp
+++ b/src/plugins/debugger/debuggerkitinformation.cpp
@@ -269,16 +269,17 @@ KitConfigWidget *DebuggerKitInformation::createConfigWidget(Kit *k) const
     return new Internal::DebuggerKitConfigWidget(k, this);
 }
 
-QString DebuggerKitInformation::userOutput(const ProjectExplorer::Kit *k)
+QString DebuggerKitInformation::userOutput(const DebuggerItem &item)
 {
-    const DebuggerItem item = DebuggerKitInformation::debuggerItem(k);
-    return tr("%1 using '%2'").arg(debuggerEngineName(item.engineType),
-                                   item.binary.toUserOutput());
+    const QString binary = item.binary.toUserOutput();
+    return binary.isEmpty() ?
+           tr("%1 <None>").arg(debuggerEngineName(item.engineType)) :
+           tr("%1 using '%2'").arg(debuggerEngineName(item.engineType), binary);
 }
 
 KitInformation::ItemList DebuggerKitInformation::toUserOutput(Kit *k) const
 {
-  return ItemList() << qMakePair(tr("Debugger"), DebuggerKitInformation::userOutput(k));
+    return ItemList() << qMakePair(tr("Debugger"), DebuggerKitInformation::userOutput(DebuggerKitInformation::debuggerItem(k)));
 }
 
 static const char engineTypeKeyC[] = "EngineType";
diff --git a/src/plugins/debugger/debuggerkitinformation.h b/src/plugins/debugger/debuggerkitinformation.h
index ceb119d08d5..d77ad8d6346 100644
--- a/src/plugins/debugger/debuggerkitinformation.h
+++ b/src/plugins/debugger/debuggerkitinformation.h
@@ -47,6 +47,7 @@ public:
     public:
         DebuggerItem();
         DebuggerItem(DebuggerEngineType engineType, const Utils::FileName &fn);
+        bool equals(const DebuggerItem &rhs) const { return engineType == rhs.engineType && binary == rhs.binary; }
 
         DebuggerEngineType engineType;
         Utils::FileName binary;
@@ -71,7 +72,7 @@ public:
     ProjectExplorer::KitConfigWidget *createConfigWidget(ProjectExplorer::Kit *k) const;
 
     ItemList toUserOutput(ProjectExplorer::Kit *k) const;
-    static QString userOutput(const ProjectExplorer::Kit *k);
+    static QString userOutput(const DebuggerItem &item);
 
     static DebuggerItem debuggerItem(const ProjectExplorer::Kit *p);
     static void setDebuggerItem(ProjectExplorer::Kit *p, const DebuggerItem &item);
@@ -93,6 +94,11 @@ private:
     static QVariant itemToVariant(const DebuggerItem &i);
 };
 
+inline bool operator==(const DebuggerKitInformation::DebuggerItem &i1, const DebuggerKitInformation::DebuggerItem &i2)
+    { return i1.equals(i2); }
+inline bool operator!=(const DebuggerKitInformation::DebuggerItem &i1, const DebuggerKitInformation::DebuggerItem &i2)
+    { return !i1.equals(i2); }
+
 } // namespace Debugger
 
 #endif // DEBUGGER_DEBUGGERKITINFORMATION_H
-- 
GitLab