forked from qt-creator/qt-creator
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:
@@ -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 \
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user