Debugger: Rework debugger option page

Use Utils::TreeModel internally, simplify code.

Change-Id: Ie5c28519d5c23441fcd6b4fbff470cc70a92ee97
Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
hjk
2014-12-19 10:46:40 +01:00
committed by hjk
parent d9b3c99c1d
commit b9ef7b7b28
11 changed files with 400 additions and 840 deletions

View File

@@ -25,7 +25,6 @@ HEADERS += \
debuggerinternalconstants.h \ debuggerinternalconstants.h \
debuggeritem.h \ debuggeritem.h \
debuggeritemmanager.h \ debuggeritemmanager.h \
debuggeritemmodel.h \
debuggerdialogs.h \ debuggerdialogs.h \
debuggerengine.h \ debuggerengine.h \
debuggermainwindow.h \ debuggermainwindow.h \
@@ -84,7 +83,6 @@ SOURCES += \
debuggerengine.cpp \ debuggerengine.cpp \
debuggeritem.cpp \ debuggeritem.cpp \
debuggeritemmanager.cpp \ debuggeritemmanager.cpp \
debuggeritemmodel.cpp \
debuggermainwindow.cpp \ debuggermainwindow.cpp \
debuggerplugin.cpp \ debuggerplugin.cpp \
debuggerprotocol.cpp \ debuggerprotocol.cpp \

View File

@@ -41,7 +41,6 @@ QtcPlugin {
"debuggerinternalconstants.h", "debuggerinternalconstants.h",
"debuggeritem.cpp", "debuggeritem.h", "debuggeritem.cpp", "debuggeritem.h",
"debuggeritemmanager.cpp", "debuggeritemmanager.h", "debuggeritemmanager.cpp", "debuggeritemmanager.h",
"debuggeritemmodel.cpp", "debuggeritemmodel.h",
"debuggerkitconfigwidget.cpp", "debuggerkitconfigwidget.h", "debuggerkitconfigwidget.cpp", "debuggerkitconfigwidget.h",
"debuggerkitinformation.cpp", "debuggerkitinformation.h", "debuggerkitinformation.cpp", "debuggerkitinformation.h",
"debuggermainwindow.cpp", "debuggermainwindow.h", "debuggermainwindow.cpp", "debuggermainwindow.h",

View File

@@ -97,6 +97,7 @@ public:
QStringList abiNames() const; QStringList abiNames() const;
bool operator==(const DebuggerItem &other) const; bool operator==(const DebuggerItem &other) const;
bool operator!=(const DebuggerItem &other) const { return !operator==(other); }
private: private:
DebuggerItem(const QVariant &id); DebuggerItem(const QVariant &id);

View File

@@ -29,8 +29,6 @@
****************************************************************************/ ****************************************************************************/
#include "debuggeritemmanager.h" #include "debuggeritemmanager.h"
#include "debuggeritemmodel.h"
#include "debuggerkitinformation.h" #include "debuggerkitinformation.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -46,26 +44,36 @@
#include <QFileInfo> #include <QFileInfo>
#include <QProcess> #include <QProcess>
using namespace Core;
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
namespace Debugger { namespace Debugger {
static const char DEBUGGER_COUNT_KEY[] = "DebuggerItem.Count"; const char DEBUGGER_COUNT_KEY[] = "DebuggerItem.Count";
static const char DEBUGGER_DATA_KEY[] = "DebuggerItem."; const char DEBUGGER_DATA_KEY[] = "DebuggerItem.";
static const char DEBUGGER_LEGACY_FILENAME[] = "/qtcreator/profiles.xml"; const char DEBUGGER_LEGACY_FILENAME[] = "/qtcreator/profiles.xml";
static const char DEBUGGER_FILE_VERSION_KEY[] = "Version"; const char DEBUGGER_FILE_VERSION_KEY[] = "Version";
static const char DEBUGGER_FILENAME[] = "/qtcreator/debuggers.xml"; const char DEBUGGER_FILENAME[] = "/qtcreator/debuggers.xml";
namespace {
QList<DebuggerItem> m_debuggers;
PersistentSettingsWriter *m_writer = 0;
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// DebuggerItemManager // DebuggerItemManager
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
static DebuggerItemManager *m_instance = 0; static void addDebugger(const DebuggerItem &item)
{
QTC_ASSERT(item.id().isValid(), return);
m_debuggers.append(item);
}
static FileName userSettingsFileName() static FileName userSettingsFileName()
{ {
QFileInfo settingsLocation(Core::ICore::settings()->fileName()); QFileInfo settingsLocation(ICore::settings()->fileName());
return FileName::fromString(settingsLocation.absolutePath() + QLatin1String(DEBUGGER_FILENAME)); return FileName::fromString(settingsLocation.absolutePath() + QLatin1String(DEBUGGER_FILENAME));
} }
@@ -111,27 +119,15 @@ static void readDebuggers(const FileName &fileName, bool isSystem)
} }
} }
QList<DebuggerItem> DebuggerItemManager::m_debuggers; DebuggerItemManager::DebuggerItemManager()
PersistentSettingsWriter * DebuggerItemManager::m_writer = 0;
DebuggerItemManager::DebuggerItemManager(QObject *parent)
: QObject(parent)
{ {
m_instance = this;
m_writer = new PersistentSettingsWriter(userSettingsFileName(), QLatin1String("QtCreatorDebuggers")); m_writer = new PersistentSettingsWriter(userSettingsFileName(), QLatin1String("QtCreatorDebuggers"));
connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()), connect(ICore::instance(), &ICore::saveSettingsRequested,
this, SLOT(saveDebuggers())); this, &DebuggerItemManager::saveDebuggers);
}
DebuggerItemManager *DebuggerItemManager::instance()
{
return m_instance;
} }
DebuggerItemManager::~DebuggerItemManager() DebuggerItemManager::~DebuggerItemManager()
{ {
disconnect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()),
this, SLOT(saveDebuggers()));
delete m_writer; delete m_writer;
} }
@@ -270,14 +266,6 @@ void DebuggerItemManager::autoDetectGdbOrLldbDebuggers()
} }
} }
void DebuggerItemManager::readLegacyDebuggers()
{
QFileInfo systemLocation(Core::ICore::settings(QSettings::SystemScope)->fileName());
readLegacyDebuggers(FileName::fromString(systemLocation.absolutePath() + QLatin1String(DEBUGGER_LEGACY_FILENAME)));
QFileInfo userLocation(Core::ICore::settings()->fileName());
readLegacyDebuggers(FileName::fromString(userLocation.absolutePath() + QLatin1String(DEBUGGER_LEGACY_FILENAME)));
}
void DebuggerItemManager::readLegacyDebuggers(const FileName &file) void DebuggerItemManager::readLegacyDebuggers(const FileName &file)
{ {
PersistentSettingsReader reader; PersistentSettingsReader reader;
@@ -344,7 +332,7 @@ const DebuggerItem *DebuggerItemManager::findByEngineType(DebuggerEngineType eng
void DebuggerItemManager::restoreDebuggers() void DebuggerItemManager::restoreDebuggers()
{ {
// Read debuggers from SDK // Read debuggers from SDK
QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName()); QFileInfo systemSettingsFile(ICore::settings(QSettings::SystemScope)->fileName());
readDebuggers(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(DEBUGGER_FILENAME)), true); readDebuggers(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(DEBUGGER_FILENAME)), true);
// Read all debuggers from user file. // Read all debuggers from user file.
@@ -355,7 +343,10 @@ void DebuggerItemManager::restoreDebuggers()
autoDetectGdbOrLldbDebuggers(); autoDetectGdbOrLldbDebuggers();
// Add debuggers from pre-3.x profiles.xml // Add debuggers from pre-3.x profiles.xml
readLegacyDebuggers(); QFileInfo systemLocation(ICore::settings(QSettings::SystemScope)->fileName());
readLegacyDebuggers(FileName::fromString(systemLocation.absolutePath() + QLatin1String(DEBUGGER_LEGACY_FILENAME)));
QFileInfo userLocation(ICore::settings()->fileName());
readLegacyDebuggers(FileName::fromString(userLocation.absolutePath() + QLatin1String(DEBUGGER_LEGACY_FILENAME)));
} }
void DebuggerItemManager::saveDebuggers() void DebuggerItemManager::saveDebuggers()
@@ -375,7 +366,7 @@ void DebuggerItemManager::saveDebuggers()
} }
} }
data.insert(QLatin1String(DEBUGGER_COUNT_KEY), count); data.insert(QLatin1String(DEBUGGER_COUNT_KEY), count);
m_writer->save(data, Core::ICore::mainWindow()); m_writer->save(data, ICore::mainWindow());
// Do not save default debuggers as they are set by the SDK. // Do not save default debuggers as they are set by the SDK.
} }
@@ -393,44 +384,23 @@ QVariant DebuggerItemManager::registerDebugger(const DebuggerItem &item)
} }
} }
// If item already has an id, add it. Otherwise, create a new id. // If item already has an id, use it. Otherwise, create a new id.
if (item.id().isValid())
return addDebugger(item);
DebuggerItem di = item; DebuggerItem di = item;
if (!di.id().isValid())
di.createId(); di.createId();
return addDebugger(di);
addDebugger(di);
return di.id();
} }
void DebuggerItemManager::deregisterDebugger(const QVariant &id) void DebuggerItemManager::deregisterDebugger(const QVariant &id)
{ {
if (findById(id))
removeDebugger(id);
}
QVariant DebuggerItemManager::addDebugger(const DebuggerItem &item)
{
QTC_ASSERT(item.id().isValid(), return QVariant());
m_debuggers.append(item);
QVariant id = item.id();
emit m_instance->debuggerAdded(id);
return id;
}
void DebuggerItemManager::removeDebugger(const QVariant &id)
{
bool ok = false;
for (int i = 0, n = m_debuggers.size(); i != n; ++i) { for (int i = 0, n = m_debuggers.size(); i != n; ++i) {
if (m_debuggers.at(i).id() == id) { if (m_debuggers.at(i).id() == id) {
emit m_instance->aboutToRemoveDebugger(id);
m_debuggers.removeAt(i); m_debuggers.removeAt(i);
emit m_instance->debuggerRemoved(id);
ok = true;
break; break;
} }
} }
QTC_ASSERT(ok, return);
} }
QString DebuggerItemManager::uniqueDisplayName(const QString &base) QString DebuggerItemManager::uniqueDisplayName(const QString &base)
@@ -442,26 +412,18 @@ QString DebuggerItemManager::uniqueDisplayName(const QString &base)
return base; return base;
} }
void DebuggerItemManager::setItemData(const QVariant &id, const QString &displayName, const FileName &fileName) void DebuggerItemManager::updateOrAddDebugger(const DebuggerItem &treeItem)
{ {
for (int i = 0, n = m_debuggers.size(); i != n; ++i) { for (int i = 0, n = m_debuggers.size(); i != n; ++i) {
DebuggerItem &item = m_debuggers[i]; DebuggerItem &item = m_debuggers[i];
if (item.id() == id) { if (item.id() == treeItem.id()) {
bool changed = false; item = treeItem;
if (item.displayName() != displayName) { return;
item.setDisplayName(displayName);
changed = true;
}
if (item.command() != fileName) {
item.setCommand(fileName);
item.reinitializeFromFile();
changed = true;
}
if (changed)
emit m_instance->debuggerUpdated(id);
break;
}
} }
} }
// This is a new item.
addDebugger(treeItem);
}
} // namespace Debugger; } // namespace Debugger;

View File

@@ -33,35 +33,27 @@
#include "debugger_global.h" #include "debugger_global.h"
#include "debuggeritem.h" #include "debuggeritem.h"
#include "debuggeritemmodel.h"
#include <QList> #include <QList>
#include <QObject> #include <QObject>
#include <QString> #include <QString>
namespace Utils { class PersistentSettingsWriter; }
namespace Debugger { namespace Debugger {
namespace Internal { class DebuggerPlugin; }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// DebuggerItemManager // DebuggerItemManager
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
class DEBUGGER_EXPORT DebuggerItemManager : public QObject class DEBUGGER_EXPORT DebuggerItemManager : public QObject
{ {
Q_OBJECT
public: public:
static DebuggerItemManager *instance(); DebuggerItemManager();
~DebuggerItemManager(); ~DebuggerItemManager();
static QList<DebuggerItem> debuggers(); static QList<DebuggerItem> debuggers();
static QVariant registerDebugger(const DebuggerItem &item); static QVariant registerDebugger(const DebuggerItem &item);
static void deregisterDebugger(const QVariant &id); static void deregisterDebugger(const QVariant &id);
static void setItemData(const QVariant &id, const QString& displayName, const Utils::FileName &fileName);
static const DebuggerItem *findByCommand(const Utils::FileName &command); static const DebuggerItem *findByCommand(const Utils::FileName &command);
static const DebuggerItem *findById(const QVariant &id); static const DebuggerItem *findById(const QVariant &id);
@@ -70,30 +62,13 @@ public:
static void restoreDebuggers(); static void restoreDebuggers();
static QString uniqueDisplayName(const QString &base); static QString uniqueDisplayName(const QString &base);
static void removeDebugger(const QVariant &id); static void updateOrAddDebugger(const DebuggerItem &item);
static QVariant addDebugger(const DebuggerItem &item); static void saveDebuggers();
signals:
void debuggerAdded(const QVariant &id);
void aboutToRemoveDebugger(const QVariant &id);
void debuggerRemoved(const QVariant &id);
void debuggerUpdated(const QVariant &id);
public slots:
void saveDebuggers();
private: private:
explicit DebuggerItemManager(QObject *parent = 0);
static void autoDetectGdbOrLldbDebuggers(); static void autoDetectGdbOrLldbDebuggers();
static void autoDetectCdbDebuggers(); static void autoDetectCdbDebuggers();
static void readLegacyDebuggers();
static void readLegacyDebuggers(const Utils::FileName &file); static void readLegacyDebuggers(const Utils::FileName &file);
static Utils::PersistentSettingsWriter *m_writer;
static QList<DebuggerItem> m_debuggers;
friend class Internal::DebuggerItemModel;
friend class Internal::DebuggerPlugin; // Enable constrcutor for DebuggerPlugin
}; };
} // namespace Debugger } // namespace Debugger

View File

@@ -1,311 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://www.qt.io/licensing. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "debuggeritemmodel.h"
#include "debuggeritem.h"
#include "debuggeritemmanager.h"
#include <utils/qtcassert.h>
namespace Debugger {
namespace Internal {
const int AbiRole = Qt::UserRole + 2;
static QList<QStandardItem *> describeItem(const DebuggerItem &item)
{
QList<QStandardItem *> row;
row.append(new QStandardItem(item.displayName()));
row.append(new QStandardItem(item.command().toUserOutput()));
row.append(new QStandardItem(item.engineTypeName()));
row.at(0)->setData(item.id());
row.at(0)->setData(item.abiNames(), AbiRole);
row.at(0)->setEditable(false);
row.at(1)->setEditable(false);
row.at(1)->setData(item.toMap());
row.at(2)->setEditable(false);
row.at(2)->setData(static_cast<int>(item.engineType()));
row.at(0)->setSelectable(true);
row.at(1)->setSelectable(true);
row.at(2)->setSelectable(true);
return row;
}
static QList<QStandardItem *> createRow(const QString &display)
{
QList<QStandardItem *> row;
row.append(new QStandardItem(display));
row.append(new QStandardItem());
row.append(new QStandardItem());
row.at(0)->setEditable(false);
row.at(1)->setEditable(false);
row.at(2)->setEditable(false);
row.at(0)->setSelectable(false);
row.at(1)->setSelectable(false);
row.at(2)->setSelectable(false);
return row;
}
// --------------------------------------------------------------------------
// DebuggerItemModel
// --------------------------------------------------------------------------
DebuggerItemModel::DebuggerItemModel(QObject *parent)
: QStandardItemModel(parent)
{
setColumnCount(3);
QList<QStandardItem *> row = createRow(tr("Auto-detected"));
m_autoRoot = row.at(0);
appendRow(row);
row = createRow(tr("Manual"));
m_manualRoot = row.at(0);
appendRow(row);
foreach (const DebuggerItem &item, DebuggerItemManager::debuggers())
addDebuggerStandardItem(item, false);
QObject *manager = DebuggerItemManager::instance();
connect(manager, SIGNAL(debuggerAdded(QVariant)),
this, SLOT(onDebuggerAdded(QVariant)));
connect(manager, SIGNAL(debuggerUpdated(QVariant)),
this, SLOT(onDebuggerUpdate(QVariant)));
connect(manager, SIGNAL(debuggerRemoved(QVariant)),
this, SLOT(onDebuggerRemoval(QVariant)));
}
QVariant DebuggerItemModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
switch (section) {
case 0:
return tr("Name");
case 1:
return tr("Path");
case 2:
return tr("Type");
}
}
return QVariant();
}
bool DebuggerItemModel::addDebuggerStandardItem(const DebuggerItem &item, bool changed)
{
if (findStandardItemById(item.id()))
return false;
QList<QStandardItem *> row = describeItem(item);
foreach (QStandardItem *cell, row) {
QFont font = cell->font();
font.setBold(changed);
cell->setFont(font);
}
(item.isAutoDetected() ? m_autoRoot : m_manualRoot)->appendRow(row);
return true;
}
bool DebuggerItemModel::removeDebuggerStandardItem(const QVariant &id)
{
QStandardItem *sitem = findStandardItemById(id);
QTC_ASSERT(sitem, return false);
QStandardItem *parent = sitem->parent();
QTC_ASSERT(parent, return false);
// This will trigger a change of m_currentDebugger via changing the
// view selection.
parent->removeRow(sitem->row());
return true;
}
bool DebuggerItemModel::updateDebuggerStandardItem(const DebuggerItem &item, bool changed)
{
QStandardItem *sitem = findStandardItemById(item.id());
QTC_ASSERT(sitem, return false);
QStandardItem *parent = sitem->parent();
QTC_ASSERT(parent, return false);
// Do not mark items as changed if they actually are not:
const DebuggerItem *orig = DebuggerItemManager::findById(item.id());
if (orig && *orig == item)
changed = false;
int row = sitem->row();
QFont font = sitem->font();
font.setBold(changed);
parent->child(row, 0)->setData(item.displayName(), Qt::DisplayRole);
parent->child(row, 0)->setData(item.abiNames(), AbiRole);
parent->child(row, 0)->setFont(font);
parent->child(row, 1)->setData(item.command().toUserOutput(), Qt::DisplayRole);
parent->child(row, 1)->setFont(font);
parent->child(row, 2)->setData(item.engineTypeName(), Qt::DisplayRole);
parent->child(row, 2)->setData(static_cast<int>(item.engineType()));
parent->child(row, 2)->setFont(font);
return true;
}
DebuggerItem DebuggerItemModel::debuggerItem(QStandardItem *sitem) const
{
DebuggerItem item = DebuggerItem(QVariant());
if (sitem && sitem->parent()) {
item.setAutoDetected(sitem->parent() == m_autoRoot);
QStandardItem *i = sitem->parent()->child(sitem->row(), 0);
item.m_id = i->data();
item.setDisplayName(i->data(Qt::DisplayRole).toString());
QStringList abis = i->data(AbiRole).toStringList();
QList<ProjectExplorer::Abi> abiList;
foreach (const QString &abi, abis)
abiList << ProjectExplorer::Abi(abi);
item.setAbis(abiList);
i = sitem->parent()->child(sitem->row(), 1);
item.setCommand(Utils::FileName::fromUserInput(i->data(Qt::DisplayRole).toString()));
i = sitem->parent()->child(sitem->row(), 2);
item.setEngineType(static_cast<DebuggerEngineType>(i->data().toInt()));
}
return item;
}
QList<DebuggerItem> DebuggerItemModel::debuggerItems() const
{
QList<DebuggerItem> result;
for (int i = 0, n = m_autoRoot->rowCount(); i != n; ++i)
result << debuggerItem(m_autoRoot->child(i));
for (int i = 0, n = m_manualRoot->rowCount(); i != n; ++i)
result << debuggerItem(m_manualRoot->child(i));
return result;
}
QStandardItem *DebuggerItemModel::currentStandardItem() const
{
return findStandardItemById(m_currentDebugger);
}
QStandardItem *DebuggerItemModel::findStandardItemById(const QVariant &id) const
{
for (int i = 0, n = m_autoRoot->rowCount(); i != n; ++i) {
QStandardItem *sitem = m_autoRoot->child(i);
if (sitem->data() == id)
return sitem;
}
for (int i = 0, n = m_manualRoot->rowCount(); i != n; ++i) {
QStandardItem *sitem = m_manualRoot->child(i);
if (sitem->data() == id)
return sitem;
}
return 0;
}
QModelIndex DebuggerItemModel::currentIndex() const
{
QStandardItem *current = currentStandardItem();
return current ? current->index() : QModelIndex();
}
QModelIndex DebuggerItemModel::lastIndex() const
{
int n = m_manualRoot->rowCount();
QStandardItem *current = m_manualRoot->child(n - 1);
return current ? current->index() : QModelIndex();
}
void DebuggerItemModel::onDebuggerAdded(const QVariant &id)
{
const DebuggerItem *item = DebuggerItemManager::findById(id);
QTC_ASSERT(item, return);
if (!addDebuggerStandardItem(*item, false))
updateDebuggerStandardItem(*item, false); // already had it added, so just update it.
}
void DebuggerItemModel::onDebuggerUpdate(const QVariant &id)
{
const DebuggerItem *item = DebuggerItemManager::findById(id);
QTC_ASSERT(item, return);
updateDebuggerStandardItem(*item, false);
}
void DebuggerItemModel::onDebuggerRemoval(const QVariant &id)
{
removeDebuggerStandardItem(id);
}
void DebuggerItemModel::addDebugger(const DebuggerItem &item)
{
addDebuggerStandardItem(item, true);
}
void DebuggerItemModel::removeDebugger(const QVariant &id)
{
if (!removeDebuggerStandardItem(id)) // Nothing there!
return;
if (DebuggerItemManager::findById(id))
m_removedItems.append(id);
}
void DebuggerItemModel::updateDebugger(const DebuggerItem &item)
{
updateDebuggerStandardItem(item, true);
}
void DebuggerItemModel::apply()
{
foreach (const QVariant &id, m_removedItems)
DebuggerItemManager::deregisterDebugger(id);
foreach (const DebuggerItem &item, debuggerItems()) {
const DebuggerItem *managed = DebuggerItemManager::findById(item.id());
if (managed) {
if (*managed == item)
continue;
else
DebuggerItemManager::setItemData(item.id(), item.displayName(), item.command());
} else {
DebuggerItemManager::registerDebugger(item);
}
}
}
void DebuggerItemModel::setCurrentIndex(const QModelIndex &index)
{
QStandardItem *sit = itemFromIndex(index);
m_currentDebugger = sit ? sit->data() : QVariant();
}
DebuggerItem DebuggerItemModel::currentDebugger() const
{
return debuggerItem(currentStandardItem());
}
} // namespace Internal
} // namespace Debugger

View File

@@ -1,93 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://www.qt.io/licensing. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef DEBUGGER_DEBUGGERITEMMODEL_H
#define DEBUGGER_DEBUGGERITEMMODEL_H
#include "debuggeritem.h"
#include <QStandardItemModel>
#include <QVariant>
namespace Debugger {
namespace Internal {
// -----------------------------------------------------------------------
// DebuggerItemModel
//------------------------------------------------------------------------
class DebuggerItemModel : public QStandardItemModel
{
Q_OBJECT
public:
DebuggerItemModel(QObject *parent = 0);
QModelIndex currentIndex() const;
QModelIndex lastIndex() const;
void setCurrentIndex(const QModelIndex &index);
QVariant currentDebuggerId() const { return m_currentDebugger; }
DebuggerItem currentDebugger() const;
void addDebugger(const DebuggerItem &item);
void removeDebugger(const QVariant &id);
void updateDebugger(const DebuggerItem &item);
void apply();
private slots:
void onDebuggerAdded(const QVariant &id);
void onDebuggerUpdate(const QVariant &id);
void onDebuggerRemoval(const QVariant &id);
private:
QStandardItem *currentStandardItem() const;
QStandardItem *findStandardItemById(const QVariant &id) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
bool addDebuggerStandardItem(const DebuggerItem &item, bool changed);
bool removeDebuggerStandardItem(const QVariant &id);
bool updateDebuggerStandardItem(const DebuggerItem &item, bool changed);
DebuggerItem debuggerItem(QStandardItem *sitem) const;
QList<DebuggerItem> debuggerItems() const;
QVariant m_currentDebugger;
QStandardItem *m_autoRoot;
QStandardItem *m_manualRoot;
QStringList removed;
QList<QVariant> m_removedItems;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_DEBUGGERITEMMODEL_H

View File

@@ -31,7 +31,6 @@
#include "debuggerkitconfigwidget.h" #include "debuggerkitconfigwidget.h"
#include "debuggeritemmanager.h" #include "debuggeritemmanager.h"
#include "debuggeritemmodel.h"
#include "debuggerkitinformation.h" #include "debuggerkitinformation.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -64,8 +63,6 @@ using namespace ProjectExplorer;
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
class DebuggerItemConfigWidget;
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// DebuggerKitConfigWidget // DebuggerKitConfigWidget
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -88,14 +85,6 @@ DebuggerKitConfigWidget::DebuggerKitConfigWidget(Kit *workingCopy, const KitInfo
m_manageButton->setContentsMargins(0, 0, 0, 0); m_manageButton->setContentsMargins(0, 0, 0, 0);
connect(m_manageButton, &QAbstractButton::clicked, connect(m_manageButton, &QAbstractButton::clicked,
this, &DebuggerKitConfigWidget::manageDebuggers); this, &DebuggerKitConfigWidget::manageDebuggers);
DebuggerItemManager *manager = DebuggerItemManager::instance();
connect(manager, &DebuggerItemManager::debuggerAdded,
this, &DebuggerKitConfigWidget::onDebuggerAdded);
connect(manager, &DebuggerItemManager::debuggerUpdated,
this, &DebuggerKitConfigWidget::onDebuggerUpdated);
connect(manager, &DebuggerItemManager::debuggerRemoved,
this, &DebuggerKitConfigWidget::onDebuggerRemoved);
} }
DebuggerKitConfigWidget::~DebuggerKitConfigWidget() DebuggerKitConfigWidget::~DebuggerKitConfigWidget()
@@ -150,31 +139,6 @@ void DebuggerKitConfigWidget::currentDebuggerChanged(int)
m_kit->setValue(DebuggerKitInformation::id(), id); m_kit->setValue(DebuggerKitInformation::id(), id);
} }
void DebuggerKitConfigWidget::onDebuggerAdded(const QVariant &id)
{
const DebuggerItem *item = DebuggerItemManager::findById(id);
QTC_ASSERT(item, return);
m_comboBox->addItem(item->displayName(), id);
}
void DebuggerKitConfigWidget::onDebuggerUpdated(const QVariant &id)
{
const DebuggerItem *item = DebuggerItemManager::findById(id);
QTC_ASSERT(item, return);
const int pos = indexOf(id);
if (pos < 0)
return;
m_comboBox->setItemText(pos, item->displayName());
}
void DebuggerKitConfigWidget::onDebuggerRemoved(const QVariant &id)
{
if (const int pos = indexOf(id)) {
m_comboBox->removeItem(pos);
refresh();
}
}
int DebuggerKitConfigWidget::indexOf(const QVariant &id) int DebuggerKitConfigWidget::indexOf(const QVariant &id)
{ {
QTC_ASSERT(id.isValid(), return -1); QTC_ASSERT(id.isValid(), return -1);

View File

@@ -31,8 +31,6 @@
#ifndef DEBUGGER_DEBUGGERKITCONFIGWIDGET_H #ifndef DEBUGGER_DEBUGGERKITCONFIGWIDGET_H
#define DEBUGGER_DEBUGGERKITCONFIGWIDGET_H #define DEBUGGER_DEBUGGERKITCONFIGWIDGET_H
#include "debuggeritemmodel.h"
#include <coreplugin/dialogs/ioptionspage.h> #include <coreplugin/dialogs/ioptionspage.h>
#include <projectexplorer/kitconfigwidget.h> #include <projectexplorer/kitconfigwidget.h>
#include <projectexplorer/abi.h> #include <projectexplorer/abi.h>
@@ -72,14 +70,10 @@ public:
QWidget *buttonWidget() const; QWidget *buttonWidget() const;
QWidget *mainWidget() const; QWidget *mainWidget() const;
private slots: private:
void manageDebuggers(); void manageDebuggers();
void currentDebuggerChanged(int idx); void currentDebuggerChanged(int idx);
void onDebuggerAdded(const QVariant &id);
void onDebuggerUpdated(const QVariant &id);
void onDebuggerRemoved(const QVariant &id);
private:
int indexOf(const QVariant &id); int indexOf(const QVariant &id);
QVariant currentId() const; QVariant currentId() const;
void updateComboBox(const QVariant &id); void updateComboBox(const QVariant &id);

View File

@@ -29,15 +29,14 @@
****************************************************************************/ ****************************************************************************/
#include "debuggeroptionspage.h" #include "debuggeroptionspage.h"
#include "debuggeritemmanager.h" #include "debuggeritemmanager.h"
#include "debuggeritemmodel.h"
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <utils/detailswidget.h> #include <utils/detailswidget.h>
#include <utils/pathchooser.h> #include <utils/pathchooser.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/treemodel.h>
#include <utils/winutils.h> #include <utils/winutils.h>
#include <QFileInfo> #include <QFileInfo>
@@ -55,17 +54,193 @@ using namespace Utils;
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
static const char debuggingToolsWikiLinkC[] = "http://qt-project.org/wiki/Qt_Creator_Windows_Debugging"; const char debuggingToolsWikiLinkC[] = "http://qt-project.org/wiki/Qt_Creator_Windows_Debugging";
// --------------------------------------------------------------------------
// DebuggerTreeItem
// --------------------------------------------------------------------------
class DebuggerTreeItem : public TreeItem
{
public:
DebuggerTreeItem(const DebuggerItem &item, bool changed) : m_item(item), m_changed(changed) {}
int columnCount() const { return 3; }
QVariant data(int column, int role) const
{
switch (role) {
case Qt::DisplayRole:
switch (column) {
case 0: return m_item.displayName();
case 1: return m_item.command().toUserOutput();
case 2: return m_item.engineTypeName();
}
case Qt::FontRole: {
QFont font;
font.setBold(m_changed);
return font;
}
}
return QVariant();
}
DebuggerItem m_item;
bool m_changed;
};
// --------------------------------------------------------------------------
// DebuggerItemModel
// --------------------------------------------------------------------------
class DebuggerItemModel : public Utils::TreeModel
{
Q_DECLARE_TR_FUNCTIONS(Debugger::DebuggerOptionsPage)
public:
DebuggerItemModel();
QModelIndex lastIndex() const;
void setCurrentIndex(const QModelIndex &index);
DebuggerItem *currentDebugger() const;
void addDebugger(const DebuggerItem &item, bool changed);
void updateDebugger(const DebuggerItem &item);
void removeCurrentDebugger();
void apply();
private:
DebuggerTreeItem *findTreeItemById(const QVariant &id) const;
DebuggerTreeItem *m_currentTreeItem;
QStringList removed;
QList<QVariant> m_removedItems;
};
DebuggerItemModel::DebuggerItemModel()
: m_currentTreeItem(0)
{
auto root = new TreeItem(QStringList() << tr("Name") << tr("Location") << tr("Type"));
root->appendChild(new TreeItem(QStringList() << tr("Auto-detected") << QString() << QString()));
root->appendChild(new TreeItem(QStringList() << tr("Manual") << QString() << QString()));
setRootItem(root);
foreach (const DebuggerItem &item, DebuggerItemManager::debuggers())
addDebugger(item, false);
}
void DebuggerItemModel::addDebugger(const DebuggerItem &item, bool changed)
{
int group = item.isAutoDetected() ? 0 : 1;
appendItem(rootItem()->child(group), new DebuggerTreeItem(item, changed));
}
void DebuggerItemModel::updateDebugger(const DebuggerItem &item)
{
DebuggerTreeItem *treeItem = findTreeItemById(item.id());
QTC_ASSERT(treeItem, return);
TreeItem *parent = treeItem->parent();
QTC_ASSERT(parent, return);
const DebuggerItem *orig = DebuggerItemManager::findById(item.id());
treeItem->m_changed = !orig || *orig != item;
treeItem->m_item = item;
updateItem(treeItem); // Notify views.
}
DebuggerTreeItem *DebuggerItemModel::findTreeItemById(const QVariant &id) const
{
TreeItem *root = rootItem();
for (int k = 0; k < rootItem()->rowCount(); ++k) {
TreeItem *group = root->child(k);
for (int i = 0, n = group->rowCount(); i != n; ++i) {
DebuggerTreeItem *treeItem = static_cast<DebuggerTreeItem *>(group->child(i));
if (treeItem->m_item.m_id == id)
return treeItem;
}
}
return 0;
}
QModelIndex DebuggerItemModel::lastIndex() const
{
TreeItem *manualGroup = rootItem()->lastChild();
TreeItem *lastItem = manualGroup->lastChild();
return lastItem ? indexFromItem(lastItem) : QModelIndex();
}
DebuggerItem *DebuggerItemModel::currentDebugger() const
{
return m_currentTreeItem ? &m_currentTreeItem->m_item : 0;
}
void DebuggerItemModel::removeCurrentDebugger()
{
QTC_ASSERT(m_currentTreeItem, return);
QVariant id = m_currentTreeItem->m_item.id();
DebuggerTreeItem *treeItem = m_currentTreeItem;
m_currentTreeItem = 0;
removeItem(treeItem);
delete treeItem;
m_removedItems.append(id);
}
void DebuggerItemModel::apply()
{
foreach (const QVariant &id, m_removedItems)
DebuggerItemManager::deregisterDebugger(id);
TreeItem *root = rootItem();
for (int k = 0; k < rootItem()->rowCount(); ++k) {
TreeItem *group = root->child(k);
for (int i = 0, n = group->rowCount(); i != n; ++i) {
DebuggerTreeItem *treeItem = static_cast<DebuggerTreeItem *>(group->child(i));
treeItem->m_changed = false;
DebuggerItemManager::updateOrAddDebugger(treeItem->m_item);
}
}
}
void DebuggerItemModel::setCurrentIndex(const QModelIndex &index)
{
TreeItem *treeItem = itemFromIndex(index);
m_currentTreeItem = treeItem && treeItem->level() == 2 ? static_cast<DebuggerTreeItem *>(treeItem) : 0;
}
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// DebuggerItemConfigWidget // DebuggerItemConfigWidget
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
DebuggerItemConfigWidget::DebuggerItemConfigWidget(DebuggerItemModel *model) : class DebuggerItemConfigWidget : public QWidget
m_model(model)
{ {
QTC_CHECK(model); Q_DECLARE_TR_FUNCTIONS(Debugger::DebuggerOptionsPage)
public:
explicit DebuggerItemConfigWidget(DebuggerItemModel *model);
void load(const DebuggerItem *item);
void store() const;
private:
void binaryPathHasChanged();
DebuggerItem item() const;
void setAbis(const QStringList &abiNames);
DebuggerItemModel *m_model;
QLineEdit *m_displayNameLineEdit;
QLabel *m_cdbLabel;
QLineEdit *m_versionLabel;
PathChooser *m_binaryChooser;
QLineEdit *m_abis;
bool m_autodetected;
DebuggerEngineType m_engineType;
QVariant m_id;
};
DebuggerItemConfigWidget::DebuggerItemConfigWidget(DebuggerItemModel *model)
: m_model(model)
{
m_displayNameLineEdit = new QLineEdit(this); m_displayNameLineEdit = new QLineEdit(this);
m_binaryChooser = new PathChooser(this); m_binaryChooser = new PathChooser(this);
@@ -93,15 +268,15 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget(DebuggerItemModel *model) :
formLayout->addRow(new QLabel(tr("ABIs:")), m_abis); formLayout->addRow(new QLabel(tr("ABIs:")), m_abis);
formLayout->addRow(new QLabel(tr("Version:")), m_versionLabel); formLayout->addRow(new QLabel(tr("Version:")), m_versionLabel);
connect(m_binaryChooser, SIGNAL(changed(QString)), this, SLOT(binaryPathHasChanged())); connect(m_binaryChooser, &PathChooser::changed,
this, &DebuggerItemConfigWidget::binaryPathHasChanged);
connect(m_displayNameLineEdit, &QLineEdit::textChanged,
this, &DebuggerItemConfigWidget::store);
} }
DebuggerItem DebuggerItemConfigWidget::item() const DebuggerItem DebuggerItemConfigWidget::item() const
{ {
DebuggerItem item(m_id); DebuggerItem item(m_id);
if (m_id.isNull())
return item;
item.setDisplayName(m_displayNameLineEdit->text()); item.setDisplayName(m_displayNameLineEdit->text());
item.setCommand(m_binaryChooser->fileName()); item.setCommand(m_binaryChooser->fileName());
item.setAutoDetected(m_autodetected); item.setAutoDetected(m_autodetected);
@@ -117,12 +292,10 @@ DebuggerItem DebuggerItemConfigWidget::item() const
return item; return item;
} }
void DebuggerItemConfigWidget::store() const void DebuggerItemConfigWidget::store() const
{ {
DebuggerItem i = item(); if (!m_id.isNull())
if (i.isValid()) m_model->updateDebugger(item());
m_model->updateDebugger(i);
} }
void DebuggerItemConfigWidget::setAbis(const QStringList &abiNames) void DebuggerItemConfigWidget::setAbis(const QStringList &abiNames)
@@ -130,8 +303,51 @@ void DebuggerItemConfigWidget::setAbis(const QStringList &abiNames)
m_abis->setText(abiNames.join(QLatin1String(", "))); m_abis->setText(abiNames.join(QLatin1String(", ")));
} }
void DebuggerItemConfigWidget::handleCommandChange() void DebuggerItemConfigWidget::load(const DebuggerItem *item)
{ {
m_id = QVariant(); // reset Id to avoid intermediate signal handling
if (!item)
return;
// Set values:
m_autodetected = item->isAutoDetected();
m_displayNameLineEdit->setEnabled(!item->isAutoDetected());
m_displayNameLineEdit->setText(item->displayName());
m_binaryChooser->setReadOnly(item->isAutoDetected());
m_binaryChooser->setFileName(item->command());
QString text;
QString versionCommand;
if (item->engineType() == CdbEngineType) {
const bool is64bit = is64BitWindowsSystem();
const QString versionString = is64bit ? tr("64-bit version") : tr("32-bit version");
//: Label text for path configuration. %2 is "x-bit version".
text = tr("<html><body><p>Specify the path to the "
"<a href=\"%1\">Windows Console Debugger executable</a>"
" (%2) here.</p>""</body></html>").
arg(QLatin1String(debuggingToolsWikiLinkC), versionString);
versionCommand = QLatin1String("-version");
} else {
versionCommand = QLatin1String("--version");
}
m_cdbLabel->setText(text);
m_cdbLabel->setVisible(!text.isEmpty());
m_binaryChooser->setCommandVersionArguments(QStringList(versionCommand));
m_versionLabel->setText(item->version());
setAbis(item->abiNames());
m_engineType = item->engineType();
m_id = item->id();
}
void DebuggerItemConfigWidget::binaryPathHasChanged()
{
// Ignore change if this is no valid DebuggerItem
if (!m_id.isValid())
return;
// Use DebuggerItemManager as a cache: // Use DebuggerItemManager as a cache:
const DebuggerItem *existing const DebuggerItem *existing
= DebuggerItemManager::findByCommand(m_binaryChooser->fileName()); = DebuggerItemManager::findByCommand(m_binaryChooser->fileName());
@@ -153,65 +369,135 @@ void DebuggerItemConfigWidget::handleCommandChange()
m_engineType = NoEngineType; m_engineType = NoEngineType;
} }
} }
m_model->updateDebugger(item());
}
void DebuggerItemConfigWidget::setItem(const DebuggerItem &item)
{
store(); // store away the (changed) settings for future use
m_id = QVariant(); // reset Id to avoid intermediate signal handling
// Set values:
m_autodetected = item.isAutoDetected();
m_displayNameLineEdit->setEnabled(!item.isAutoDetected());
m_displayNameLineEdit->setText(item.displayName());
m_binaryChooser->setReadOnly(item.isAutoDetected());
m_binaryChooser->setFileName(item.command());
QString text;
QString versionCommand;
if (item.engineType() == CdbEngineType) {
const bool is64bit = is64BitWindowsSystem();
const QString versionString = is64bit ? tr("64-bit version") : tr("32-bit version");
//: Label text for path configuration. %2 is "x-bit version".
text = tr("<html><body><p>Specify the path to the "
"<a href=\"%1\">Windows Console Debugger executable</a>"
" (%2) here.</p>""</body></html>").
arg(QLatin1String(debuggingToolsWikiLinkC), versionString);
versionCommand = QLatin1String("-version");
} else {
versionCommand = QLatin1String("--version");
}
m_cdbLabel->setText(text);
m_cdbLabel->setVisible(!text.isEmpty());
m_binaryChooser->setCommandVersionArguments(QStringList(versionCommand));
m_versionLabel->setText(item.version());
setAbis(item.abiNames());
m_engineType = item.engineType();
m_id = item.id();
}
void DebuggerItemConfigWidget::apply()
{
DebuggerItem current = m_model->currentDebugger();
if (!current.isValid())
return; // Nothing was selected here.
store(); store();
setItem(item());
} }
void DebuggerItemConfigWidget::binaryPathHasChanged() // --------------------------------------------------------------------------
// DebuggerConfigWidget
// --------------------------------------------------------------------------
class DebuggerConfigWidget : public QWidget
{ {
// Ignore change if this is no valid DebuggerItem public:
if (!m_id.isValid()) DebuggerConfigWidget()
{
m_addButton = new QPushButton(tr("Add"), this);
m_cloneButton = new QPushButton(tr("Clone"), this);
m_cloneButton->setEnabled(false);
m_delButton = new QPushButton(tr("Remove"), this);
m_delButton->setEnabled(false);
m_container = new DetailsWidget(this);
m_container->setState(DetailsWidget::NoSummary);
m_container->setVisible(false);
m_debuggerView = new QTreeView(this);
m_debuggerView->setModel(&m_model);
m_debuggerView->setUniformRowHeights(true);
m_debuggerView->setRootIsDecorated(false);
m_debuggerView->setSelectionMode(QAbstractItemView::SingleSelection);
m_debuggerView->setSelectionBehavior(QAbstractItemView::SelectRows);
m_debuggerView->expandAll();
auto header = m_debuggerView->header();
header->setStretchLastSection(false);
header->setSectionResizeMode(0, QHeaderView::ResizeToContents);
header->setSectionResizeMode(1, QHeaderView::ResizeToContents);
header->setSectionResizeMode(2, QHeaderView::Stretch);
auto buttonLayout = new QVBoxLayout();
buttonLayout->setSpacing(6);
buttonLayout->setContentsMargins(0, 0, 0, 0);
buttonLayout->addWidget(m_addButton);
buttonLayout->addWidget(m_cloneButton);
buttonLayout->addWidget(m_delButton);
buttonLayout->addItem(new QSpacerItem(10, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
auto verticalLayout = new QVBoxLayout();
verticalLayout->addWidget(m_debuggerView);
verticalLayout->addWidget(m_container);
auto horizontalLayout = new QHBoxLayout(this);
horizontalLayout->addLayout(verticalLayout);
horizontalLayout->addLayout(buttonLayout);
connect(m_debuggerView->selectionModel(), &QItemSelectionModel::currentChanged,
this, &DebuggerConfigWidget::currentDebuggerChanged, Qt::QueuedConnection);
connect(m_addButton, &QAbstractButton::clicked,
this, &DebuggerConfigWidget::addDebugger, Qt::QueuedConnection);
connect(m_cloneButton, &QAbstractButton::clicked,
this, &DebuggerConfigWidget::cloneDebugger, Qt::QueuedConnection);
connect(m_delButton, &QAbstractButton::clicked,
this, &DebuggerConfigWidget::removeDebugger, Qt::QueuedConnection);
m_itemConfigWidget = new DebuggerItemConfigWidget(&m_model);
m_container->setWidget(m_itemConfigWidget);
}
void cloneDebugger();
void addDebugger();
void removeDebugger();
void currentDebuggerChanged(const QModelIndex &newCurrent);
void updateState();
DebuggerItemModel m_model;
QTreeView *m_debuggerView;
QPushButton *m_addButton;
QPushButton *m_cloneButton;
QPushButton *m_delButton;
DetailsWidget *m_container;
DebuggerItemConfigWidget *m_itemConfigWidget;
};
void DebuggerConfigWidget::cloneDebugger()
{
DebuggerItem *item = m_model.currentDebugger();
if (!item)
return; return;
handleCommandChange(); DebuggerItem newItem;
newItem.createId();
newItem.setAutoDetected(false);
newItem.setCommand(item->command());
newItem.setEngineType(item->engineType());
newItem.setAbis(item->abis());
newItem.setDisplayName(DebuggerItemManager::uniqueDisplayName(tr("Clone of %1").arg(item->displayName())));
newItem.setAutoDetected(false);
m_model.addDebugger(newItem, true);
m_debuggerView->setCurrentIndex(m_model.lastIndex());
}
void DebuggerConfigWidget::addDebugger()
{
DebuggerItem item;
item.createId();
item.setAutoDetected(false);
item.setEngineType(NoEngineType);
item.setDisplayName(DebuggerItemManager::uniqueDisplayName(tr("New Debugger")));
item.setAutoDetected(false);
m_model.addDebugger(item, true);
m_debuggerView->setCurrentIndex(m_model.lastIndex());
}
void DebuggerConfigWidget::removeDebugger()
{
m_model.removeCurrentDebugger();
m_debuggerView->setCurrentIndex(m_model.lastIndex());
}
void DebuggerConfigWidget::currentDebuggerChanged(const QModelIndex &newCurrent)
{
m_model.setCurrentIndex(newCurrent);
DebuggerItem *item = m_model.currentDebugger();
m_itemConfigWidget->load(item);
m_container->setVisible(item);
m_cloneButton->setEnabled(item && item->isValid() && item->canClone());
m_delButton->setEnabled(item && !item->isAutoDetected());
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -220,13 +506,6 @@ void DebuggerItemConfigWidget::binaryPathHasChanged()
DebuggerOptionsPage::DebuggerOptionsPage() DebuggerOptionsPage::DebuggerOptionsPage()
{ {
m_model = 0;
m_debuggerView = 0;
m_container = 0;
m_addButton = 0;
m_cloneButton = 0;
m_delButton = 0;
setId(ProjectExplorer::Constants::DEBUGGER_SETTINGS_PAGE_ID); setId(ProjectExplorer::Constants::DEBUGGER_SETTINGS_PAGE_ID);
setDisplayName(tr("Debuggers")); setDisplayName(tr("Debuggers"));
setCategory(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY); setCategory(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY);
@@ -237,160 +516,22 @@ DebuggerOptionsPage::DebuggerOptionsPage()
QWidget *DebuggerOptionsPage::widget() QWidget *DebuggerOptionsPage::widget()
{ {
if (!m_configWidget) { if (!m_configWidget)
m_configWidget = new QWidget; m_configWidget = new DebuggerConfigWidget;
m_addButton = new QPushButton(tr("Add"), m_configWidget);
m_cloneButton = new QPushButton(tr("Clone"), m_configWidget);
m_delButton = new QPushButton(tr("Remove"), m_configWidget);
m_container = new DetailsWidget(m_configWidget);
m_container->setState(DetailsWidget::NoSummary);
m_container->setVisible(false);
m_debuggerView = new QTreeView(m_configWidget);
m_model = new DebuggerItemModel(m_debuggerView);
m_debuggerView->setModel(m_model);
m_debuggerView->setUniformRowHeights(true);
m_debuggerView->setSelectionMode(QAbstractItemView::SingleSelection);
m_debuggerView->setSelectionBehavior(QAbstractItemView::SelectRows);
m_debuggerView->expandAll();
QHeaderView *header = m_debuggerView->header();
header->setStretchLastSection(false);
header->setSectionResizeMode(0, QHeaderView::ResizeToContents);
header->setSectionResizeMode(1, QHeaderView::ResizeToContents);
header->setSectionResizeMode(2, QHeaderView::Stretch);
QVBoxLayout *buttonLayout = new QVBoxLayout();
buttonLayout->setSpacing(6);
buttonLayout->setContentsMargins(0, 0, 0, 0);
buttonLayout->addWidget(m_addButton);
buttonLayout->addWidget(m_cloneButton);
buttonLayout->addWidget(m_delButton);
buttonLayout->addItem(new QSpacerItem(10, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
QVBoxLayout *verticalLayout = new QVBoxLayout();
verticalLayout->addWidget(m_debuggerView);
verticalLayout->addWidget(m_container);
QHBoxLayout *horizontalLayout = new QHBoxLayout(m_configWidget);
horizontalLayout->addLayout(verticalLayout);
horizontalLayout->addLayout(buttonLayout);
connect(m_debuggerView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this, SLOT(debuggerSelectionChanged()));
connect(m_addButton, SIGNAL(clicked()), this, SLOT(addDebugger()), Qt::QueuedConnection);
connect(m_cloneButton, SIGNAL(clicked()), this, SLOT(cloneDebugger()), Qt::QueuedConnection);
connect(m_delButton, SIGNAL(clicked()), this, SLOT(removeDebugger()), Qt::QueuedConnection);
m_itemConfigWidget = new DebuggerItemConfigWidget(m_model);
m_container->setWidget(m_itemConfigWidget);
updateState();
}
return m_configWidget; return m_configWidget;
} }
void DebuggerOptionsPage::apply() void DebuggerOptionsPage::apply()
{ {
m_itemConfigWidget->apply(); QTC_ASSERT(m_configWidget, return);
m_model->apply(); m_configWidget->m_itemConfigWidget->store();
} m_configWidget->m_model.apply();
void DebuggerOptionsPage::cloneDebugger()
{
DebuggerItem item = m_model->currentDebugger();
if (!item.isValid())
return;
DebuggerItem newItem;
newItem.createId();
newItem.setAutoDetected(false);
newItem.setCommand(item.command());
newItem.setEngineType(item.engineType());
newItem.setAbis(item.abis());
newItem.setDisplayName(DebuggerItemManager::uniqueDisplayName(tr("Clone of %1").arg(item.displayName())));
newItem.setAutoDetected(false);
m_model->addDebugger(newItem);
m_debuggerView->setCurrentIndex(m_model->lastIndex());
}
void DebuggerOptionsPage::addDebugger()
{
DebuggerItem item;
item.createId();
item.setAutoDetected(false);
item.setEngineType(NoEngineType);
item.setDisplayName(DebuggerItemManager::uniqueDisplayName(tr("New Debugger")));
item.setAutoDetected(false);
m_model->addDebugger(item);
m_debuggerView->setCurrentIndex(m_model->lastIndex());
}
void DebuggerOptionsPage::removeDebugger()
{
QVariant id = m_model->currentDebuggerId();
m_model->removeDebugger(id);
m_debuggerView->setCurrentIndex(m_model->lastIndex());
} }
void DebuggerOptionsPage::finish() void DebuggerOptionsPage::finish()
{ {
delete m_configWidget; delete m_configWidget;
m_configWidget = 0;
// Children of m_configWidget.
m_model = 0;
m_container = 0;
m_debuggerView = 0;
m_addButton = 0;
m_cloneButton = 0;
m_delButton = 0;
}
void DebuggerOptionsPage::debuggerSelectionChanged()
{
QTC_ASSERT(m_container, return);
QModelIndex mi = m_debuggerView->currentIndex();
mi = mi.sibling(mi.row(), 0);
m_model->setCurrentIndex(mi);
DebuggerItem item = m_model->currentDebugger();
m_itemConfigWidget->setItem(item);
m_container->setVisible(item.isValid());
updateState();
}
void DebuggerOptionsPage::debuggerModelChanged()
{
QTC_ASSERT(m_container, return);
QVariant id = m_model->currentDebuggerId();
const DebuggerItem *item = DebuggerItemManager::findById(id);
if (!item)
return;
m_itemConfigWidget->setItem(*item);
m_container->setVisible(m_model->currentDebuggerId().isValid());
m_debuggerView->setCurrentIndex(m_model->currentIndex());
updateState();
}
void DebuggerOptionsPage::updateState()
{
if (!m_cloneButton)
return;
DebuggerItem item = m_model->currentDebugger();
bool canCopy = item.isValid() && item.canClone();
bool canDelete = m_model->currentIndex().parent().isValid() && !item.isAutoDetected();
m_cloneButton->setEnabled(canCopy);
m_delButton->setEnabled(canDelete);
} }
} // namespace Internal } // namespace Internal

View File

@@ -31,73 +31,19 @@
#ifndef DEBUGGER_DEBUGGEROPTIONSPAGE_H #ifndef DEBUGGER_DEBUGGEROPTIONSPAGE_H
#define DEBUGGER_DEBUGGEROPTIONSPAGE_H #define DEBUGGER_DEBUGGEROPTIONSPAGE_H
#include "debuggeritem.h"
#include <coreplugin/dialogs/ioptionspage.h> #include <coreplugin/dialogs/ioptionspage.h>
#include <QCoreApplication>
#include <QPointer> #include <QPointer>
#include <QWidget>
QT_BEGIN_NAMESPACE
class QLabel;
class QLineEdit;
class QPushButton;
class QTreeView;
QT_END_NAMESPACE
namespace Utils {
class DetailsWidget;
class PathChooser;
} // namespace Utils
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
class DebuggerItemModel; class DebuggerConfigWidget;
class DebuggerItemConfigWidget;
class DebuggerKitConfigWidget;
// -----------------------------------------------------------------------
// DebuggerItemConfigWidget
// -----------------------------------------------------------------------
class DebuggerItemConfigWidget : public QWidget
{
Q_OBJECT
public:
explicit DebuggerItemConfigWidget(DebuggerItemModel *model);
void setItem(const DebuggerItem &item);
void apply();
private slots:
void binaryPathHasChanged();
private:
DebuggerItem item() const;
void store() const;
void setAbis(const QStringList &abiNames);
void handleCommandChange();
QLineEdit *m_displayNameLineEdit;
QLabel *m_cdbLabel;
QLineEdit *m_versionLabel;
Utils::PathChooser *m_binaryChooser;
QLineEdit *m_abis;
DebuggerItemModel *m_model;
bool m_autodetected;
DebuggerEngineType m_engineType;
QVariant m_id;
};
// --------------------------------------------------------------------------
// DebuggerOptionsPage
// --------------------------------------------------------------------------
class DebuggerOptionsPage : public Core::IOptionsPage class DebuggerOptionsPage : public Core::IOptionsPage
{ {
Q_OBJECT Q_DECLARE_TR_FUNCTIONS(Debugger::DebuggerOptionsPage)
public: public:
DebuggerOptionsPage(); DebuggerOptionsPage();
@@ -106,24 +52,8 @@ public:
void apply(); void apply();
void finish(); void finish();
private slots:
void debuggerSelectionChanged();
void debuggerModelChanged();
void updateState();
void cloneDebugger();
void addDebugger();
void removeDebugger();
private: private:
QPointer<QWidget> m_configWidget; QPointer<DebuggerConfigWidget> m_configWidget;
DebuggerItemModel *m_model;
DebuggerItemConfigWidget *m_itemConfigWidget;
QTreeView *m_debuggerView;
Utils::DetailsWidget *m_container;
QPushButton *m_addButton;
QPushButton *m_cloneButton;
QPushButton *m_delButton;
}; };
} // namespace Internal } // namespace Internal