Debugger: Don't add invalid items during validation

Change-Id: I3b6427ec038d61ea3166880ae51292f87f7b861b
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
hjk
2013-09-03 12:31:28 +02:00
parent 48d1e8ebbf
commit cd17a0e400
8 changed files with 424 additions and 313 deletions

View File

@@ -265,6 +265,7 @@ static inline QSettings *userSettings()
|| lowerFile.startsWith(QLatin1String("toolchains.xml")) || lowerFile.startsWith(QLatin1String("toolchains.xml"))
|| lowerFile.startsWith(QLatin1String("qtversion.xml")) || lowerFile.startsWith(QLatin1String("qtversion.xml"))
|| lowerFile.startsWith(QLatin1String("devices.xml")) || lowerFile.startsWith(QLatin1String("devices.xml"))
|| lowerFile.startsWith(QLatin1String("debuggers.xml"))
|| lowerFile.startsWith(QLatin1String("qtcreator."))) || lowerFile.startsWith(QLatin1String("qtcreator.")))
QFile::copy(srcDir.absoluteFilePath(file), destDir.absoluteFilePath(file)); QFile::copy(srcDir.absoluteFilePath(file), destDir.absoluteFilePath(file));
if (file == QLatin1String("qtcreator")) if (file == QLatin1String("qtcreator"))

View File

@@ -788,7 +788,7 @@ void AndroidConfigurations::updateAutomaticKitList()
ToolChainKitInformation::setToolChain(newKit, tc); ToolChainKitInformation::setToolChain(newKit, tc);
QtSupport::QtKitInformation::setQtVersion(newKit, qt); QtSupport::QtKitInformation::setQtVersion(newKit, qt);
DeviceKitInformation::setDevice(newKit, device); DeviceKitInformation::setDevice(newKit, device);
Debugger::DebuggerKitInformation::setDebuggerItem(newKit, Debugger::DebuggerKitInformation::setDebugger(newKit,
Debugger::GdbEngineType, tc->suggestedDebugger()); Debugger::GdbEngineType, tc->suggestedDebugger());
AndroidGdbServerKitInformation::setGdbSever(newKit, tc->suggestedGdbServer()); AndroidGdbServerKitInformation::setGdbSever(newKit, tc->suggestedGdbServer());
newKit->makeSticky(); newKit->makeSticky();

View File

@@ -121,7 +121,7 @@ bool DebuggerKitChooser::kitMatches(const ProjectExplorer::Kit *k) const
QString DebuggerKitChooser::kitToolTip(Kit *k) const QString DebuggerKitChooser::kitToolTip(Kit *k) const
{ {
return DebuggerKitInformation::debuggerItem(k).userOutput(); return DebuggerKitInformation::displayString(k);
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////

View File

@@ -75,7 +75,10 @@ static const char DEFAULT_DEBUGGER_COUNT_KEY[] = "DefaultDebugger.Count";
static const char DEFAULT_DEBUGGER_ABI_KEY[] = "DefaultDebugger.Abi."; static const char DEFAULT_DEBUGGER_ABI_KEY[] = "DefaultDebugger.Abi.";
static const char DEFAULT_DEBUGGER_PATH_KEY[] = "DefaultDebugger.Path."; static const char DEFAULT_DEBUGGER_PATH_KEY[] = "DefaultDebugger.Path.";
static const char DEBUGGER_FILENAME[] = "/qtcreator/debuggers.xml"; static const char DEBUGGER_FILENAME[] = "/qtcreator/debuggers.xml";
static const char DEBUGGER_LEGACY_FILENAME[] = "/qtcreator/profiles.xml";
static const char DEBUGGER_INFORMATION_LEGACY[] = "Debugger.Information";
//static const char DEBUGGER_INFORMATION[] = "Debugger.InformationV3";
static const char DEBUGGER_INFORMATION[] = "Debugger.Information"; static const char DEBUGGER_INFORMATION[] = "Debugger.Information";
static const char DEBUGGER_INFORMATION_COMMAND[] = "Binary"; static const char DEBUGGER_INFORMATION_COMMAND[] = "Binary";
static const char DEBUGGER_INFORMATION_DISPLAYNAME[] = "DisplayName"; static const char DEBUGGER_INFORMATION_DISPLAYNAME[] = "DisplayName";
@@ -98,19 +101,38 @@ static DebuggerItemManager *theDebuggerItemManager()
// DebuggerItem // DebuggerItem
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
namespace Internal {
class DebuggerItem
{
public:
DebuggerItem();
bool canClone() const { return true; }
bool isValid() const { return engineType != NoEngineType; }
QString engineTypeName() const;
QVariantMap toMap() const;
void fromMap(const QVariantMap &data);
void reinitializeFromFile();
public:
QVariant id;
QString displayName;
DebuggerEngineType engineType;
Utils::FileName command;
bool isAutoDetected;
QList<ProjectExplorer::Abi> abis;
};
} // namespace Internal
DebuggerItem::DebuggerItem() DebuggerItem::DebuggerItem()
{ {
engineType = NoEngineType; engineType = NoEngineType;
isAutoDetected = false; isAutoDetected = false;
} }
bool DebuggerItem::looksLike(const DebuggerItem &rhs) const
{
return engineType == rhs.engineType
&& displayName == rhs.displayName
&& command == rhs.command;
}
QString DebuggerItem::engineTypeName() const QString DebuggerItem::engineTypeName() const
{ {
switch (engineType) { switch (engineType) {
@@ -163,15 +185,6 @@ void DebuggerItem::fromMap(const QVariantMap &data)
} }
} }
QString DebuggerItem::userOutput() const
{
const QString binary = command.toUserOutput();
const QString name = DebuggerKitInformation::tr("%1 Engine").arg(engineTypeName());
return binary.isEmpty() ? DebuggerKitInformation::tr("%1 <None>").arg(name)
: DebuggerKitInformation::tr("%1 using \"%2\"").arg(name, binary);
}
void DebuggerItem::reinitializeFromFile() void DebuggerItem::reinitializeFromFile()
{ {
QProcess proc; QProcess proc;
@@ -217,11 +230,12 @@ DebuggerKitInformation::DebuggerKitInformation()
QVariant DebuggerKitInformation::defaultValue(Kit *k) const QVariant DebuggerKitInformation::defaultValue(Kit *k) const
{ {
if (isValidDebugger(k)) { // This is only called from Kit::Kit()
DebuggerItem item = debuggerItem(k); // if (isValidDebugger(k)) {
return theDebuggerItemManager()->maybeAddDebugger(item, false); // DebuggerItem *item = DebuggerItemManager::debuggerFromKit(k);
} // QTC_ASSERT(item, return QVariant());
// return item->id;
// }
ToolChain *tc = ToolChainKitInformation::toolChain(k); ToolChain *tc = ToolChainKitInformation::toolChain(k);
return theDebuggerItemManager()->defaultDebugger(tc); return theDebuggerItemManager()->defaultDebugger(tc);
} }
@@ -241,25 +255,54 @@ enum DebuggerConfigurationErrors {
DebuggerNeedsAbsolutePath = 0x8 DebuggerNeedsAbsolutePath = 0x8
}; };
static QVariant debuggerPathOrId(const Kit *k)
{
QTC_ASSERT(k, return QString());
QVariant id = k->value(DEBUGGER_INFORMATION);
if (!id.isValid())
return id; // Invalid.
// With 3.0 we have:
// <value type="QString" key="Debugger.Information">{75ecf347-f221-44c3-b613-ea1d29929cd4}</value>
if (id.type() == QVariant::String)
return id;
// Before we had:
// <valuemap type="QVariantMap" key="Debugger.Information">
// <value type="QString" key="Binary">/data/dev/debugger/gdb-git/gdb/gdb</value>
// <value type="int" key="EngineType">1</value>
// </valuemap>
return id.toMap().value(QLatin1String("Binary"));
}
static unsigned debuggerConfigurationErrors(const Kit *k) static unsigned debuggerConfigurationErrors(const Kit *k)
{ {
unsigned result = 0; QTC_ASSERT(k, return NoDebugger);
const DebuggerItem item = DebuggerKitInformation::debuggerItem(k);
if (item.engineType == NoEngineType || item.command.isEmpty()) const DebuggerItem *item = DebuggerItemManager::debuggerFromKit(k);
if (!item)
return NoDebugger; return NoDebugger;
const QFileInfo fi = item.command.toFileInfo(); if (item->command.isEmpty())
return NoDebugger;
unsigned result = 0;
const QFileInfo fi = item->command.toFileInfo();
if (!fi.exists() || fi.isDir()) if (!fi.exists() || fi.isDir())
result |= DebuggerNotFound; result |= DebuggerNotFound;
else if (!fi.isExecutable()) else if (!fi.isExecutable())
result |= DebuggerNotExecutable; result |= DebuggerNotExecutable;
if (!fi.exists() || fi.isDir()) if (!fi.exists() || fi.isDir()) {
if (item->engineType == NoEngineType)
return NoDebugger;
// We need an absolute path to be able to locate Python on Windows. // We need an absolute path to be able to locate Python on Windows.
if (item.engineType == GdbEngineType) if (item->engineType == GdbEngineType)
if (const ToolChain *tc = ToolChainKitInformation::toolChain(k)) if (const ToolChain *tc = ToolChainKitInformation::toolChain(k))
if (tc->targetAbi().os() == Abi::WindowsOS && !fi.isAbsolute()) if (tc->targetAbi().os() == Abi::WindowsOS && !fi.isAbsolute())
result |= DebuggerNeedsAbsolutePath; result |= DebuggerNeedsAbsolutePath;
}
return result; return result;
} }
@@ -271,12 +314,14 @@ bool DebuggerKitInformation::isValidDebugger(const Kit *k)
QList<Task> DebuggerKitInformation::validateDebugger(const Kit *k) QList<Task> DebuggerKitInformation::validateDebugger(const Kit *k)
{ {
QList<Task> result; QList<Task> result;
const unsigned errors = debuggerConfigurationErrors(k);
const unsigned errors = debuggerConfigurationErrors(k);
if (!errors) if (!errors)
return result; return result;
const QString path = DebuggerKitInformation::debuggerCommand(k).toUserOutput(); QString path;
if (const DebuggerItem *item = DebuggerItemManager::debuggerFromKit(k))
path = item->command.toUserOutput();
const Core::Id id = ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM; const Core::Id id = ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM;
if (errors & NoDebugger) if (errors & NoDebugger)
@@ -304,62 +349,37 @@ KitConfigWidget *DebuggerKitInformation::createConfigWidget(Kit *k) const
KitInformation::ItemList DebuggerKitInformation::toUserOutput(const Kit *k) const KitInformation::ItemList DebuggerKitInformation::toUserOutput(const Kit *k) const
{ {
return ItemList() << qMakePair(tr("Debugger"), debuggerItem(k).userOutput()); return ItemList() << qMakePair(tr("Debugger"), displayString(k));
} }
DebuggerItem DebuggerKitInformation::debuggerItem(const ProjectExplorer::Kit *k) FileName DebuggerKitInformation::debuggerCommand(const ProjectExplorer::Kit *k)
{ {
if (!k) const DebuggerItem *item = DebuggerItemManager::debuggerFromKit(k);
return DebuggerItem(); QTC_ASSERT(item, return FileName());
return item->command;
// We used to have:
// <valuemap type="QVariantMap" key="Debugger.Information">
// <value type="QString" key="Binary">/data/dev/debugger/gdb-git/gdb/gdb</value>
// <value type="int" key="EngineType">1</value>
// </valuemap>
// Starting with 3.0 we have:
// <value type="QString" key="Debugger.Information">{75ecf347-f221-44c3-b613-ea1d29929cd4}</value>
QVariant id = k->value(DEBUGGER_INFORMATION);
if (!id.isValid())
return DebuggerItem();
QString pathOrUid;
if (id.type() == QVariant::Map) // 2.x
pathOrUid = id.toMap().value(QLatin1String("Binary")).toString();
else if (id.type() == QVariant::String) // 3.x
pathOrUid = id.toString();
if (pathOrUid.isEmpty())
return DebuggerItem();
DebuggerItem *item = 0;
if (pathOrUid.startsWith(QLatin1Char('{')))
item = DebuggerItemManager::debuggerFromId(id);
else
item = DebuggerItemManager::debuggerFromPath(pathOrUid);
QTC_ASSERT(item, return DebuggerItem());
return *item;
} }
void DebuggerKitInformation::setDebuggerItem(Kit *k, DebuggerEngineType DebuggerKitInformation::engineType(const ProjectExplorer::Kit *k)
DebuggerEngineType type, const Utils::FileName &command)
{ {
QTC_ASSERT(k, return); const DebuggerItem *item = DebuggerItemManager::debuggerFromKit(k);
DebuggerItem item; QTC_ASSERT(item, return NoEngineType);
item.engineType = type; return item->engineType;
item.command = command;
QVariant id = theDebuggerItemManager()->maybeAddDebugger(item);
k->setValue(DEBUGGER_INFORMATION, id);
} }
void DebuggerKitInformation::setDebuggerCommand(Kit *k, const FileName &command) QString DebuggerKitInformation::displayString(const Kit *k)
{ {
DebuggerItem item = debuggerItem(k); const DebuggerItem *item = DebuggerItemManager::debuggerFromKit(k);
item.command = command; if (!item)
QVariant id = theDebuggerItemManager()->maybeAddDebugger(item); return tr("No Debugger");
k->setValue(DEBUGGER_INFORMATION, id); QString binary = item->command.toUserOutput();
QString name = tr("%1 Engine").arg(item->engineTypeName());
return binary.isEmpty() ? tr("%1 <None>").arg(name) : tr("%1 using \"%2\"").arg(name, binary);
}
void DebuggerKitInformation::setDebugger(Kit *k,
DebuggerEngineType type, const FileName &command)
{
theDebuggerItemManager()->setDebugger(k, type, command);
} }
void DebuggerKitInformation::setSticky(Kit *k, bool b) void DebuggerKitInformation::setSticky(Kit *k, bool b)
@@ -376,13 +396,13 @@ static FileName userSettingsFileName()
return FileName::fromString(settingsLocation.absolutePath() + QLatin1String(DEBUGGER_FILENAME)); return FileName::fromString(settingsLocation.absolutePath() + QLatin1String(DEBUGGER_FILENAME));
} }
static QList<QStandardItem *> describeItem(DebuggerItem *item) static QList<QStandardItem *> describeItem(const DebuggerItem &item)
{ {
QList<QStandardItem *> row; QList<QStandardItem *> row;
row.append(new QStandardItem(item->displayName)); row.append(new QStandardItem(item.displayName));
row.append(new QStandardItem(item->command.toUserOutput())); row.append(new QStandardItem(item.command.toUserOutput()));
row.append(new QStandardItem(item->engineTypeName())); row.append(new QStandardItem(item.engineTypeName()));
row.at(0)->setData(item->id); row.at(0)->setData(item.id);
row.at(0)->setEditable(false); row.at(0)->setEditable(false);
row.at(1)->setEditable(false); row.at(1)->setEditable(false);
row.at(2)->setEditable(false); row.at(2)->setEditable(false);
@@ -416,7 +436,6 @@ class DebuggerItemConfigWidget;
DebuggerItemManager::DebuggerItemManager(QObject *parent) DebuggerItemManager::DebuggerItemManager(QObject *parent)
: QStandardItemModel(parent) : QStandardItemModel(parent)
{ {
m_currentDebugger = 0;
setColumnCount(3); setColumnCount(3);
QList<QStandardItem *> row = createRow(tr("Auto-detected")); QList<QStandardItem *> row = createRow(tr("Auto-detected"));
@@ -437,8 +456,6 @@ DebuggerItemManager::~DebuggerItemManager()
{ {
disconnect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()), disconnect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()),
this, SLOT(saveDebuggers())); this, SLOT(saveDebuggers()));
qDeleteAll(m_debuggers);
m_debuggers.clear();
delete m_writer; delete m_writer;
} }
@@ -457,6 +474,15 @@ QVariant DebuggerItemManager::headerData(int section, Qt::Orientation orientatio
return QVariant(); return QVariant();
} }
QString DebuggerItemManager::uniqueDisplayName(const QString &base) const
{
foreach (const DebuggerItem &item, m_debuggers)
if (item.displayName == base)
return uniqueDisplayName(base + QLatin1String(" (1)"));
return base;
}
void DebuggerItemManager::autoDetectCdbDebugger() void DebuggerItemManager::autoDetectCdbDebugger()
{ {
QList<FileName> cdbs; QList<FileName> cdbs;
@@ -503,13 +529,15 @@ void DebuggerItemManager::autoDetectCdbDebugger()
} }
foreach (const FileName &cdb, cdbs) { foreach (const FileName &cdb, cdbs) {
if (findByCommand(cdb))
continue;
DebuggerItem item; DebuggerItem item;
item.isAutoDetected = true; item.isAutoDetected = true;
item.abis = Abi::abisOfBinary(cdb); item.abis = Abi::abisOfBinary(cdb);
item.command = cdb; item.command = cdb;
item.engineType = CdbEngineType; item.engineType = CdbEngineType;
item.displayName = tr("Auto-detected CDB at %1").arg(cdb.toUserOutput()); item.displayName = uniqueDisplayName(tr("Auto-detected CDB at %1").arg(cdb.toUserOutput()));
maybeAddDebugger(item, false); doAddDebugger(item);
} }
} }
@@ -534,61 +562,107 @@ void DebuggerItemManager::autoDetectDebuggers()
foreach (const QFileInfo &fi, suspects) { foreach (const QFileInfo &fi, suspects) {
if (fi.exists()) { if (fi.exists()) {
FileName command = FileName::fromString(fi.absoluteFilePath());
if (findByCommand(command))
continue;
DebuggerItem item; DebuggerItem item;
item.command = FileName::fromString(fi.absoluteFilePath()); item.command = command;
item.id = QUuid::createUuid().toString();
item.reinitializeFromFile(); item.reinitializeFromFile();
item.displayName = tr("System %1 at %2") item.displayName = tr("System %1 at %2")
.arg(item.engineTypeName()).arg(fi.absoluteFilePath()); .arg(item.engineTypeName()).arg(fi.absoluteFilePath());
item.isAutoDetected = true; item.isAutoDetected = true;
maybeAddDebugger(item); doAddDebugger(item);
} }
} }
} }
QVariant DebuggerItemManager::maybeAddDebugger(const DebuggerItem &testItem, bool makeCurrent) void DebuggerItemManager::readLegacyDebuggers()
{ {
foreach (DebuggerItem *it, m_debuggers) { QFileInfo settingsLocation(Core::ICore::settings()->fileName());
if (it->looksLike(testItem)) { FileName legacyKits = FileName::fromString(settingsLocation.absolutePath() + QLatin1String(DEBUGGER_LEGACY_FILENAME));
m_currentDebugger = it;
return it->id;
}
}
DebuggerItem *item = new DebuggerItem(testItem); PersistentSettingsReader reader;
if (item->id.isNull()) if (!reader.load(legacyKits))
item->id = QUuid::createUuid().toString(); return;
foreach (const QVariant &v, reader.restoreValues()) {
QVariantMap data1 = v.toMap();
QString kitName = data1.value(QLatin1String("PE.Profile.Name")).toString();
QVariantMap data2 = data1.value(QLatin1String("PE.Profile.Data")).toMap();
QVariant v3 = data2.value(QLatin1String(DEBUGGER_INFORMATION));
QString fn;
if (v3.type() == QVariant::String)
fn = v3.toString();
else
fn = v3.toMap().value(QLatin1String(DEBUGGER_INFORMATION_COMMAND)).toString();
if (fn.isEmpty())
continue;
if (fn.startsWith(QLatin1Char('{')))
continue;
FileName command = FileName::fromUserInput(fn);
if (findByCommand(command))
continue;
DebuggerItem item;
item.command = command;
item.isAutoDetected = true;
item.reinitializeFromFile();
item.displayName = tr("Extracted from Kit %1").arg(kitName);
item.id = QUuid::createUuid().toString();
doAddDebugger(item);
}
}
QVariant DebuggerItemManager::doAddDebugger(const DebuggerItem &item0)
{
DebuggerItem item = item0;
if (item.id.isNull()) {
QTC_CHECK(false);
item.id = QUuid::createUuid().toString();
}
QList<QStandardItem *> row = describeItem(item); QList<QStandardItem *> row = describeItem(item);
(item->isAutoDetected ? m_autoRoot : m_manualRoot)->appendRow(row); (item.isAutoDetected ? m_autoRoot : m_manualRoot)->appendRow(row);
m_debuggers.append(item); m_debuggers.append(item);
m_itemFromDebugger[item] = row.at(0); emit debuggerAdded(item.id, item.displayName);
m_debuggerFromItem[row.at(0)] = item; return item.id;
if (makeCurrent)
m_currentDebugger = item;
emit debuggerAdded(item);
return item->id;
} }
void DebuggerItemManager::updateCurrentItem() const DebuggerItem *DebuggerItemManager::findByCommand(const FileName &command)
{ {
QTC_ASSERT(m_currentDebugger, return); foreach (const DebuggerItem &item, m_debuggers)
QStandardItem *item = m_itemFromDebugger.value(m_currentDebugger); if (item.command == command)
QTC_ASSERT(item, return); return &item;
m_currentDebugger->reinitializeFromFile();
QStandardItem *parent = item->parent(); return 0;
QTC_ASSERT(parent, return);
int row = item->row();
parent->child(row, 0)->setData(m_currentDebugger->displayName, Qt::DisplayRole);
parent->child(row, 1)->setData(m_currentDebugger->command.toUserOutput(), Qt::DisplayRole);
parent->child(row, 2)->setData(m_currentDebugger->engineTypeName(), Qt::DisplayRole);
emit debuggerUpdated(m_currentDebugger);
} }
static QList<DebuggerItem *> readDebuggers(const FileName &fileName) const DebuggerItem *DebuggerItemManager::findById(const QVariant &id)
{ {
QList<DebuggerItem *> result; foreach (const DebuggerItem &item, m_debuggers)
if (item.id == id)
return &item;
return 0;
}
QStandardItem *DebuggerItemManager::currentStandardItem() const
{
for (int i = 0, n = m_autoRoot->rowCount(); i != n; ++i) {
QStandardItem *sitem = m_autoRoot->child(i);
if (sitem->data() == m_currentDebugger)
return sitem;
}
for (int i = 0, n = m_manualRoot->rowCount(); i != n; ++i) {
QStandardItem *sitem = m_manualRoot->child(i);
if (sitem->data() == m_currentDebugger)
return sitem;
}
return 0;
}
static QList<DebuggerItem> readDebuggers(const FileName &fileName)
{
QList<DebuggerItem> result;
PersistentSettingsReader reader; PersistentSettingsReader reader;
if (!reader.load(fileName)) if (!reader.load(fileName))
@@ -621,9 +695,9 @@ static QList<DebuggerItem *> readDebuggers(const FileName &fileName)
if (!data.contains(key)) if (!data.contains(key))
break; break;
const QVariantMap dbMap = data.value(key).toMap(); const QVariantMap dbMap = data.value(key).toMap();
DebuggerItem *debugger = new DebuggerItem; DebuggerItem item;
debugger->fromMap(dbMap); item.fromMap(dbMap);
result.append(debugger); result.append(item);
} }
return result; return result;
@@ -631,36 +705,34 @@ static QList<DebuggerItem *> readDebuggers(const FileName &fileName)
void DebuggerItemManager::restoreDebuggers() void DebuggerItemManager::restoreDebuggers()
{ {
QList<DebuggerItem *> dbsToCheck; QList<DebuggerItem> dbsToCheck;
// Read debuggers from SDK // Read debuggers from SDK
QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName()); QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName());
QList<DebuggerItem *> dbsToRegister = QList<DebuggerItem> dbsToRegister =
readDebuggers(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(DEBUGGER_FILENAME))); readDebuggers(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(DEBUGGER_FILENAME)));
// These are autodetected. // These are autodetected.
foreach (DebuggerItem *item, dbsToRegister) for (int i = 0, n = dbsToRegister.size(); i != n; ++i)
item->isAutoDetected = true; dbsToRegister[i].isAutoDetected = true;
// SDK debuggers are always considered to be up-to-date, so no need to recheck them. // SDK debuggers are always considered to be up-to-date, so no need to recheck them.
// Read all debuggers from user file. // Read all debuggers from user file.
foreach (DebuggerItem *item, readDebuggers(userSettingsFileName())) { foreach (const DebuggerItem &item, readDebuggers(userSettingsFileName())) {
if (item->isAutoDetected) if (item.isAutoDetected)
dbsToCheck.append(item); dbsToCheck.append(item);
else else
dbsToRegister.append(item); dbsToRegister.append(item);
} }
// Remove debuggers configured by the SDK. // Remove debuggers configured by the SDK.
foreach (DebuggerItem *item, dbsToRegister) { // foreach (const DebuggerItem &item, dbsToRegister) {
for (int i = dbsToCheck.count(); --i >= 0; ) { // for (int i = dbsToCheck.count(); --i >= 0; ) {
if (dbsToCheck.at(i)->id == item->id) { // if (dbsToCheck.at(i).id == item.id)
delete dbsToCheck.at(i); // dbsToCheck.removeAt(i);
dbsToCheck.removeAt(i); // }
} // }
}
}
// QList<DebuggerItem *> detectedDbs; // QList<DebuggerItem *> detectedDbs;
// QList<DebuggerFactory *> factories = ExtensionSystem::PluginManager::getObjects<DebuggerFactory>(); // QList<DebuggerFactory *> factories = ExtensionSystem::PluginManager::getObjects<DebuggerFactory>();
@@ -685,23 +757,31 @@ void DebuggerItemManager::restoreDebuggers()
// } // }
// Keep debuggers that were not rediscovered but are still executable and delete the rest // Keep debuggers that were not rediscovered but are still executable and delete the rest
foreach (DebuggerItem *item, dbsToCheck) { foreach (const DebuggerItem &item, dbsToCheck) {
if (!item->isValid()) { if (!item.isValid()) {
qWarning() << QString::fromLatin1("DebuggerItem \"%1\" (%2) dropped since it is not valid") qWarning() << QString::fromLatin1("DebuggerItem \"%1\" (%2) dropped since it is not valid")
.arg(item->command.toString()).arg(item->id.toString()); .arg(item.command.toString()).arg(item.id.toString());
delete item;
} else { } else {
dbsToRegister += item; dbsToRegister.append(item);
} }
} }
// Store manual debuggers // Store manual debuggers
DebuggerItemManager *manager = theDebuggerItemManager(); DebuggerItemManager *manager = theDebuggerItemManager();
foreach (DebuggerItem *item, dbsToRegister) for (int i = 0, n = dbsToRegister.size(); i != n; ++i) {
manager->maybeAddDebugger(*item); DebuggerItem item = dbsToRegister.at(i);
if (manager->findByCommand(item.command))
continue;
if (item.id.isNull())
item.id = QUuid::createUuid().toString();
manager->doAddDebugger(item);
}
// Then auto detect // Auto detect current.
manager->autoDetectDebuggers(); manager->autoDetectDebuggers();
// Add debuggers from pre-3.x profiles.xml
manager->readLegacyDebuggers();
} }
void DebuggerItemManager::saveDebuggers() void DebuggerItemManager::saveDebuggers()
@@ -711,9 +791,9 @@ void DebuggerItemManager::saveDebuggers()
data.insert(QLatin1String(DEBUGGER_FILE_VERSION_KEY), 1); data.insert(QLatin1String(DEBUGGER_FILE_VERSION_KEY), 1);
int count = 0; int count = 0;
foreach (DebuggerItem *item, m_debuggers) { foreach (const DebuggerItem &item, m_debuggers) {
if (item->isValid()) { if (item.isValid()) {
QVariantMap tmp = item->toMap(); QVariantMap tmp = item.toMap();
if (tmp.isEmpty()) if (tmp.isEmpty())
continue; continue;
data.insert(QString::fromLatin1(DEBUGGER_DATA_KEY) + QString::number(count), tmp); data.insert(QString::fromLatin1(DEBUGGER_DATA_KEY) + QString::number(count), tmp);
@@ -726,87 +806,132 @@ void DebuggerItemManager::saveDebuggers()
// Do not save default debuggers as they are set by the SDK. // Do not save default debuggers as they are set by the SDK.
} }
QList<DebuggerItem *> DebuggerItemManager::findDebuggers(const Abi &abi) const const DebuggerItem *DebuggerItemManager::debuggerFromKit(const Kit *kit)
{ {
QList<DebuggerItem *> result; if (!kit)
foreach (DebuggerItem *item, m_debuggers) return 0;
foreach (const Abi targetAbi, item->abis) QVariant pathOrId = debuggerPathOrId(kit);
if (targetAbi.isCompatibleWith(abi)) foreach (const DebuggerItem &item, theDebuggerItemManager()->m_debuggers) {
result.append(item); if (item.id == pathOrId)
return result; return &item;
} if (item.command == FileName::fromUserInput(pathOrId.toString()))
return &item;
DebuggerItem *DebuggerItemManager::debuggerFromId(const QVariant &id) }
{
foreach (DebuggerItem *item, theDebuggerItemManager()->m_debuggers)
if (item->id == id)
return item;
return 0; return 0;
} }
DebuggerItem *DebuggerItemManager::debuggerFromPath(const QString &path) void DebuggerItemManager::setDebugger(Kit *kit, Debugger::DebuggerEngineType type, const FileName &command)
{ {
foreach (DebuggerItem *item, theDebuggerItemManager()->m_debuggers) QTC_ASSERT(kit, return);
if (item->command.toString() == path) // This should only operate on fresh kits.
return item; //QVariant id = k->value(DEBUGGER_INFORMATION);
return 0; //QTC_CHECK(id.isNull());
if (!findByCommand(command)) {
DebuggerItem item;
item.engineType = type;
item.command = command;
item.id = QUuid::createUuid().toString();
item.displayName = uniqueDisplayName(tr("Created by tool chain."));
doAddDebugger(item);
}
const DebuggerItem *it = findByCommand(command);
QTC_ASSERT(it, return);
QTC_ASSERT(it->id.isValid(), return);
kit->setValue(DEBUGGER_INFORMATION, it->id);
} }
QModelIndex DebuggerItemManager::currentIndex() const QModelIndex DebuggerItemManager::currentIndex() const
{ {
QStandardItem *current = m_itemFromDebugger.value(m_currentDebugger); QStandardItem *current = currentStandardItem();
return current ? current->index() : QModelIndex(); return current ? current->index() : QModelIndex();
} }
bool DebuggerItemManager::isLoaded() const
{
return m_writer;
}
void DebuggerItemManager::addDebugger() void DebuggerItemManager::addDebugger()
{ {
DebuggerItem item; DebuggerItem item;
item.displayName = tr("New Debugger");
item.engineType = NoEngineType; item.engineType = NoEngineType;
item.id = QUuid::createUuid().toString();
item.displayName = uniqueDisplayName(tr("New Debugger"));
item.isAutoDetected = false; item.isAutoDetected = false;
maybeAddDebugger(item); doAddDebugger(item);
} }
void DebuggerItemManager::cloneDebugger() void DebuggerItemManager::cloneDebugger()
{ {
DebuggerItem item; const DebuggerItem *item = findById(m_currentDebugger);
if (m_currentDebugger) QTC_ASSERT(item, return);
item = *m_currentDebugger; DebuggerItem newItem = *item;
item.displayName = tr("Clone of %1").arg(item.displayName); newItem.id = QUuid::createUuid().toString();
item.isAutoDetected = false; newItem.displayName = uniqueDisplayName(tr("Clone of %1").arg(item->displayName));
maybeAddDebugger(item); newItem.isAutoDetected = false;
doAddDebugger(newItem);
} }
void DebuggerItemManager::removeDebugger() void DebuggerItemManager::removeDebugger()
{ {
if (!m_currentDebugger) QTC_ASSERT(m_currentDebugger.isValid(), return);
return; QVariant id = m_currentDebugger;
bool ok = false;
emit debuggerRemoved(m_currentDebugger); for (int i = 0, n = m_debuggers.size(); i != n; ++i) {
bool ok = m_debuggers.removeOne(m_currentDebugger); if (m_debuggers.at(i).id == id) {
m_debuggers.removeAt(i);
ok = true;
break;
}
}
QTC_ASSERT(ok, return); QTC_ASSERT(ok, return);
QStandardItem *item = m_itemFromDebugger.take(m_currentDebugger); QStandardItem *sitem = currentStandardItem();
DebuggerItem *debugger = m_debuggerFromItem.take(item); QTC_ASSERT(sitem, return);
QTC_ASSERT(debugger == m_currentDebugger, return); QStandardItem *parent = sitem->parent();
QTC_ASSERT(item, return);
QTC_ASSERT(debugger, return);
QStandardItem *parent = item->parent();
QTC_ASSERT(parent, return); QTC_ASSERT(parent, return);
// This will trigger a change of m_currentDebugger via changing the // This will trigger a change of m_currentDebugger via changing the
// view selection. So don't delete m_currentDebugger but debugger. // view selection.
parent->removeRow(item->row()); parent->removeRow(sitem->row());
QTC_ASSERT(debugger != m_currentDebugger, return); emit debuggerRemoved(id);
delete debugger; }
void DebuggerItemManager::markCurrentDirty()
{
QStandardItem *sitem = currentStandardItem();
QTC_ASSERT(sitem, return);
QFont font = sitem->font();
font.setBold(true);
sitem->setFont(font);
} }
void DebuggerItemManager::setCurrentIndex(const QModelIndex &index) void DebuggerItemManager::setCurrentIndex(const QModelIndex &index)
{ {
m_currentDebugger = m_debuggerFromItem.value(itemFromIndex(index)); QStandardItem *sit = itemFromIndex(index);
m_currentDebugger = sit ? sit->data() : QVariant();
}
void DebuggerItemManager::setCurrentData(const QString &displayName, const FileName &fileName)
{
for (int i = 0, n = m_debuggers.size(); i != n; ++i) {
DebuggerItem &item = m_debuggers[i];
if (item.id == m_currentDebugger) {
item.displayName = displayName;
item.command = fileName;
item.reinitializeFromFile();
QStandardItem *sitem = currentStandardItem();
QTC_ASSERT(sitem, return);
QStandardItem *parent = sitem->parent();
QTC_ASSERT(parent, return);
int row = sitem->row();
QFont font = sitem->font();
font.setBold(false);
parent->child(row, 0)->setData(item.displayName, Qt::DisplayRole);
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)->setFont(font);
emit debuggerUpdated(m_currentDebugger, displayName);
return;
}
}
} }
QVariant DebuggerItemManager::defaultDebugger(ToolChain *tc) QVariant DebuggerItemManager::defaultDebugger(ToolChain *tc)
@@ -830,9 +955,10 @@ QVariant DebuggerItemManager::defaultDebugger(ToolChain *tc)
// result.first = result.second; // result.first = result.second;
QList<DebuggerItem *> compatible = findDebuggers(abi); foreach (const DebuggerItem &item, m_debuggers)
if (!compatible.isEmpty()) foreach (const Abi targetAbi, item.abis)
return compatible.front()->id; if (targetAbi.isCompatibleWith(abi))
return item.id;
return QVariant(); return QVariant();
@@ -888,8 +1014,8 @@ DebuggerKitConfigWidget::DebuggerKitConfigWidget(Kit *workingCopy, bool sticky)
m_comboBox->setEnabled(true); m_comboBox->setEnabled(true);
m_comboBox->setToolTip(toolTip()); m_comboBox->setToolTip(toolTip());
m_comboBox->addItem(tr("None"), QString()); m_comboBox->addItem(tr("None"), QString());
foreach (DebuggerItem *item, manager->debuggers()) foreach (const DebuggerItem &item, manager->m_debuggers)
m_comboBox->addItem(item->displayName, item->id); m_comboBox->addItem(item.displayName, item.id);
refresh(); refresh();
connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(currentDebuggerChanged(int))); connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(currentDebuggerChanged(int)));
@@ -898,12 +1024,12 @@ DebuggerKitConfigWidget::DebuggerKitConfigWidget(Kit *workingCopy, bool sticky)
m_manageButton->setContentsMargins(0, 0, 0, 0); m_manageButton->setContentsMargins(0, 0, 0, 0);
connect(m_manageButton, SIGNAL(clicked()), this, SLOT(manageDebuggers())); connect(m_manageButton, SIGNAL(clicked()), this, SLOT(manageDebuggers()));
connect(manager, SIGNAL(debuggerAdded(DebuggerItem*)), connect(manager, SIGNAL(debuggerAdded(QVariant,QString)),
this, SLOT(onDebuggerAdded(DebuggerItem*))); this, SLOT(onDebuggerAdded(QVariant,QString)));
connect(manager, SIGNAL(debuggerUpdated(DebuggerItem*)), connect(manager, SIGNAL(debuggerUpdated(QVariant,QString)),
this, SLOT(onDebuggerUpdated(DebuggerItem*))); this, SLOT(onDebuggerUpdated(QVariant,QString)));
connect(manager, SIGNAL(debuggerRemoved(DebuggerItem*)), connect(manager, SIGNAL(debuggerRemoved(QVariant)),
this, SLOT(onDebuggerRemoved(DebuggerItem*))); this, SLOT(onDebuggerRemoved(QVariant)));
} }
QString DebuggerKitConfigWidget::toolTip() const QString DebuggerKitConfigWidget::toolTip() const
@@ -924,8 +1050,8 @@ void DebuggerKitConfigWidget::makeReadOnly()
void DebuggerKitConfigWidget::refresh() void DebuggerKitConfigWidget::refresh()
{ {
DebuggerItem item = DebuggerKitInformation::debuggerItem(m_kit); const DebuggerItem *item = DebuggerItemManager::debuggerFromKit(m_kit);
updateComboBox(item.id); updateComboBox(item ? item->id : QVariant());
} }
QWidget *DebuggerKitConfigWidget::buttonWidget() const QWidget *DebuggerKitConfigWidget::buttonWidget() const
@@ -949,37 +1075,33 @@ void DebuggerKitConfigWidget::currentDebuggerChanged(int)
m_kit->setValue(DEBUGGER_INFORMATION, m_comboBox->itemData(m_comboBox->currentIndex())); m_kit->setValue(DEBUGGER_INFORMATION, m_comboBox->itemData(m_comboBox->currentIndex()));
} }
void DebuggerKitConfigWidget::onDebuggerAdded(DebuggerItem *item) void DebuggerKitConfigWidget::onDebuggerAdded(const QVariant &id, const QString &displayName)
{ {
m_comboBox->setEnabled(true); m_comboBox->setEnabled(true);
QVariant id = currentId(); m_comboBox->addItem(displayName, id);
m_comboBox->addItem(item->displayName, item->id);
updateComboBox(id); updateComboBox(id);
} }
void DebuggerKitConfigWidget::onDebuggerUpdated(DebuggerItem *item) void DebuggerKitConfigWidget::onDebuggerUpdated(const QVariant &id, const QString &displayName)
{ {
m_comboBox->setEnabled(true); m_comboBox->setEnabled(true);
const int pos = indexOf(item); const int pos = indexOf(id);
if (pos < 0) if (pos < 0)
return; return;
m_comboBox->setItemText(pos, item->displayName); m_comboBox->setItemText(pos, displayName);
} }
void DebuggerKitConfigWidget::onDebuggerRemoved(DebuggerItem *item) void DebuggerKitConfigWidget::onDebuggerRemoved(const QVariant &id)
{ {
const int pos = indexOf(item); if (const int pos = indexOf(id)) {
if (pos <= 0)
return;
QVariant id = currentId();
m_comboBox->removeItem(pos); m_comboBox->removeItem(pos);
updateComboBox(id); updateComboBox(id);
}
} }
int DebuggerKitConfigWidget::indexOf(const DebuggerItem *debugger) int DebuggerKitConfigWidget::indexOf(const QVariant &id)
{ {
QTC_ASSERT(debugger, return -1); QTC_ASSERT(id.isValid(), return -1);
const QVariant id = debugger->id;
for (int i = 0; i < m_comboBox->count(); ++i) { for (int i = 0; i < m_comboBox->count(); ++i) {
if (id == m_comboBox->itemData(i)) if (id == m_comboBox->itemData(i))
return i; return i;
@@ -1012,8 +1134,11 @@ class DebuggerItemConfigWidget : public QWidget
Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::DebuggerItemConfigWidget) Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::DebuggerItemConfigWidget)
public: public:
explicit DebuggerItemConfigWidget(); explicit DebuggerItemConfigWidget();
void loadItem(DebuggerItem *item); void loadItem();
void saveItem(DebuggerItem *item); void saveItem();
void connectDirty();
void disconnectDirty();
private: private:
QLineEdit *m_displayNameLineEdit; QLineEdit *m_displayNameLineEdit;
QLabel *m_cdbLabel; QLabel *m_cdbLabel;
@@ -1036,7 +1161,7 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget()
m_abis = new QLineEdit(this); m_abis = new QLineEdit(this);
m_abis->setEnabled(false); m_abis->setEnabled(false);
QFormLayout *formLayout = new QFormLayout; QFormLayout *formLayout = new QFormLayout(this);
formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
formLayout->addRow(new QLabel(tr("Name:")), m_displayNameLineEdit); formLayout->addRow(new QLabel(tr("Name:")), m_displayNameLineEdit);
// formLayout->addRow(new QLabel(tr("Type:")), m_engineTypeComboBox); // formLayout->addRow(new QLabel(tr("Type:")), m_engineTypeComboBox);
@@ -1044,19 +1169,41 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget()
formLayout->addRow(new QLabel(tr("Path:")), m_binaryChooser); formLayout->addRow(new QLabel(tr("Path:")), m_binaryChooser);
formLayout->addRow(new QLabel(tr("Abis:")), m_abis); formLayout->addRow(new QLabel(tr("Abis:")), m_abis);
setLayout(formLayout); connectDirty();
} }
void DebuggerItemConfigWidget::loadItem(DebuggerItem *item) void DebuggerItemConfigWidget::connectDirty()
{ {
DebuggerItemManager *manager = theDebuggerItemManager();
connect(m_displayNameLineEdit, SIGNAL(textChanged(QString)),
manager, SLOT(markCurrentDirty()));
connect(m_binaryChooser, SIGNAL(changed(QString)),
manager, SLOT(markCurrentDirty()));
}
void DebuggerItemConfigWidget::disconnectDirty()
{
DebuggerItemManager *manager = theDebuggerItemManager();
disconnect(m_displayNameLineEdit, SIGNAL(textChanged(QString)),
manager, SLOT(markCurrentDirty()));
disconnect(m_binaryChooser, SIGNAL(changed(QString)),
manager, SLOT(markCurrentDirty()));
}
void DebuggerItemConfigWidget::loadItem()
{
DebuggerItemManager *manager = theDebuggerItemManager();
const DebuggerItem *item = manager->findById(manager->m_currentDebugger);
if (!item) if (!item)
return; return;
disconnectDirty();
m_displayNameLineEdit->setEnabled(!item->isAutoDetected); m_displayNameLineEdit->setEnabled(!item->isAutoDetected);
m_displayNameLineEdit->setText(item->displayName); m_displayNameLineEdit->setText(item->displayName);
m_binaryChooser->setEnabled(!item->isAutoDetected); m_binaryChooser->setEnabled(!item->isAutoDetected);
m_binaryChooser->setFileName(item->command); m_binaryChooser->setFileName(item->command);
connectDirty();
QString text; QString text;
QString versionCommand; QString versionCommand;
@@ -1084,12 +1231,9 @@ void DebuggerItemConfigWidget::loadItem(DebuggerItem *item)
m_abis->setText(toList(item->abis).join(QLatin1String(", "))); m_abis->setText(toList(item->abis).join(QLatin1String(", ")));
} }
void DebuggerItemConfigWidget::saveItem(DebuggerItem *item) void DebuggerItemConfigWidget::saveItem()
{ {
QTC_ASSERT(item, return); theDebuggerItemManager()->setCurrentData(m_displayNameLineEdit->text(), m_binaryChooser->fileName());
item->displayName = m_displayNameLineEdit->text();
item->command = m_binaryChooser->fileName();
// item->engineType is immutable
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -1175,8 +1319,7 @@ QWidget *DebuggerOptionsPage::createPage(QWidget *parent)
void DebuggerOptionsPage::apply() void DebuggerOptionsPage::apply()
{ {
m_itemConfigWidget->saveItem(m_manager->currentDebugger()); m_itemConfigWidget->saveItem();
m_manager->updateCurrentItem();
debuggerModelChanged(); debuggerModelChanged();
} }
@@ -1224,9 +1367,8 @@ void DebuggerOptionsPage::debuggerSelectionChanged()
mi = mi.sibling(mi.row(), 0); mi = mi.sibling(mi.row(), 0);
m_manager->setCurrentIndex(mi); m_manager->setCurrentIndex(mi);
DebuggerItem *item = m_manager->currentDebugger(); m_itemConfigWidget->loadItem();
m_itemConfigWidget->loadItem(item); m_container->setVisible(m_manager->m_currentDebugger.isValid());
m_container->setVisible(item != 0);
updateState(); updateState();
} }
@@ -1234,9 +1376,8 @@ void DebuggerOptionsPage::debuggerModelChanged()
{ {
QTC_ASSERT(m_container, return); QTC_ASSERT(m_container, return);
DebuggerItem *item = m_manager->currentDebugger(); m_itemConfigWidget->loadItem();
m_itemConfigWidget->loadItem(item); m_container->setVisible(m_manager->m_currentDebugger.isValid());
m_container->setVisible(item != 0);
m_debuggerView->setCurrentIndex(m_manager->currentIndex()); m_debuggerView->setCurrentIndex(m_manager->currentIndex());
updateState(); updateState();
} }
@@ -1249,7 +1390,7 @@ void DebuggerOptionsPage::updateState()
bool canCopy = false; bool canCopy = false;
bool canDelete = false; bool canDelete = false;
if (DebuggerItem *item = m_manager->currentDebugger()) { if (const DebuggerItem *item = m_manager->findById(m_manager->m_currentDebugger)) {
canCopy = item->isValid() && item->canClone(); canCopy = item->isValid() && item->canClone();
canDelete = !item->isAutoDetected; canDelete = !item->isAutoDetected;
canDelete = true; // Do we want to remove auto-detected items? canDelete = true; // Do we want to remove auto-detected items?

View File

@@ -53,7 +53,9 @@ QT_END_NAMESPACE
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
class DebuggerItem;
class DebuggerItemConfigWidget; class DebuggerItemConfigWidget;
class DebuggerKitConfigWidget;
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// DebuggerItemManager // DebuggerItemManager
@@ -67,51 +69,53 @@ public:
DebuggerItemManager(QObject *parent); DebuggerItemManager(QObject *parent);
~DebuggerItemManager(); ~DebuggerItemManager();
QList<DebuggerItem *> debuggers() const { return m_debuggers; } static const DebuggerItem *debuggerFromKit(const ProjectExplorer::Kit *kit);
QList<DebuggerItem *> findDebuggers(const ProjectExplorer::Abi &abi) const; void setDebugger(ProjectExplorer::Kit *kit,
DebuggerItem *currentDebugger() const { return m_currentDebugger; } DebuggerEngineType type, const Utils::FileName &command);
static DebuggerItem *debuggerFromId(const QVariant &id);
static DebuggerItem *debuggerFromPath(const QString &path);
QModelIndex currentIndex() const; QModelIndex currentIndex() const;
void setCurrentIndex(const QModelIndex &index); void setCurrentIndex(const QModelIndex &index);
void setCurrentData(const QString &displayName, const Utils::FileName &fileName);
bool isLoaded() const;
void updateCurrentItem();
// Returns id. // Returns id.
QVariant defaultDebugger(ProjectExplorer::ToolChain *tc); QVariant defaultDebugger(ProjectExplorer::ToolChain *tc);
// Adds item unless present. Return id of a matching item.
QVariant maybeAddDebugger(const DebuggerItem &item, bool makeCurrent = true);
static void restoreDebuggers(); static void restoreDebuggers();
public slots: public slots:
void saveDebuggers(); void saveDebuggers();
void autoDetectDebuggers(); void autoDetectDebuggers();
void readLegacyDebuggers();
void addDebugger(); void addDebugger();
void cloneDebugger(); void cloneDebugger();
void removeDebugger(); void removeDebugger();
void markCurrentDirty();
signals: signals:
void debuggerAdded(DebuggerItem *item); void debuggerAdded(const QVariant &id, const QString &display);
void debuggerRemoved(DebuggerItem *item); void debuggerUpdated(const QVariant &id, const QString &display);
void debuggerUpdated(DebuggerItem *item); void debuggerRemoved(const QVariant &id);
private: private:
friend class Debugger::DebuggerKitInformation;
friend class DebuggerKitConfigWidget;
friend class DebuggerItemConfigWidget;
friend class DebuggerOptionsPage; friend class DebuggerOptionsPage;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QVariant doAddDebugger(const DebuggerItem &item);
const DebuggerItem *findByCommand(const Utils::FileName &command);
const DebuggerItem *findById(const QVariant &id);
QStandardItem *currentStandardItem() const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QString uniqueDisplayName(const QString &base) const;
void autoDetectCdbDebugger(); void autoDetectCdbDebugger();
QMap<QString, Utils::FileName> m_abiToDebugger;
Utils::PersistentSettingsWriter *m_writer; Utils::PersistentSettingsWriter *m_writer;
QList<DebuggerItem *> m_debuggers; QList<DebuggerItem> m_debuggers;
DebuggerItem *m_currentDebugger; QVariant m_currentDebugger;
QStandardItem *m_autoRoot; QStandardItem *m_autoRoot;
QStandardItem *m_manualRoot; QStandardItem *m_manualRoot;
QStringList added;
QStringList removed; QStringList removed;
QHash<DebuggerItem *, QStandardItem *> m_itemFromDebugger;
QHash<QStandardItem *, DebuggerItem *> m_debuggerFromItem;
}; };
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -135,12 +139,12 @@ public:
private slots: private slots:
void manageDebuggers(); void manageDebuggers();
void currentDebuggerChanged(int idx); void currentDebuggerChanged(int idx);
void onDebuggerAdded(DebuggerItem *); void onDebuggerAdded(const QVariant &id, const QString &displayName);
void onDebuggerUpdated(DebuggerItem *); void onDebuggerUpdated(const QVariant &id, const QString &displayName);
void onDebuggerRemoved(DebuggerItem *); void onDebuggerRemoved(const QVariant &id);
private: private:
int indexOf(const DebuggerItem *debugger); int indexOf(const QVariant &id);
QVariant currentId() const; QVariant currentId() const;
void updateComboBox(const QVariant &id); void updateComboBox(const QVariant &id);

View File

@@ -38,30 +38,6 @@
namespace Debugger { namespace Debugger {
class DEBUGGER_EXPORT DebuggerItem
{
public:
DebuggerItem();
bool looksLike(const DebuggerItem &rhs) const;
bool canClone() const { return true; }
bool isValid() const { return true; }
QString engineTypeName() const;
QString userOutput() const;
QVariantMap toMap() const;
void fromMap(const QVariantMap &data);
void reinitializeFromFile();
public:
QVariant id;
QString displayName;
DebuggerEngineType engineType;
Utils::FileName command;
bool isAutoDetected;
QList<ProjectExplorer::Abi> abis;
};
class DEBUGGER_EXPORT DebuggerKitInformation : public ProjectExplorer::KitInformation class DEBUGGER_EXPORT DebuggerKitInformation : public ProjectExplorer::KitInformation
{ {
Q_OBJECT Q_OBJECT
@@ -83,26 +59,16 @@ public:
ItemList toUserOutput(const ProjectExplorer::Kit *k) const; ItemList toUserOutput(const ProjectExplorer::Kit *k) const;
static DebuggerItem debuggerItem(const ProjectExplorer::Kit *k); static void setDebugger(ProjectExplorer::Kit *k,
static void setDebuggerItem(ProjectExplorer::Kit *k,
DebuggerEngineType type, const Utils::FileName &command); DebuggerEngineType type, const Utils::FileName &command);
static Utils::FileName debuggerCommand(const ProjectExplorer::Kit *k) static Utils::FileName debuggerCommand(const ProjectExplorer::Kit *k);
{ return debuggerItem(k).command; } static DebuggerEngineType engineType(const ProjectExplorer::Kit *k);
static QString displayString(const ProjectExplorer::Kit *k);
static void setDebuggerCommand(ProjectExplorer::Kit *k, const Utils::FileName &command);
static DebuggerEngineType engineType(const ProjectExplorer::Kit *k)
{ return debuggerItem(k).engineType; }
static void setSticky(ProjectExplorer::Kit *k, bool b); static void setSticky(ProjectExplorer::Kit *k, bool b);
}; };
inline bool operator==(const DebuggerItem &i1, const DebuggerItem &i2)
{ return i1.looksLike(i2); }
inline bool operator!=(const DebuggerItem &i1, const DebuggerItem &i2)
{ return !i1.looksLike(i2); }
} // namespace Debugger } // namespace Debugger
#endif // DEBUGGER_DEBUGGERKITINFORMATION_H #endif // DEBUGGER_DEBUGGERKITINFORMATION_H

View File

@@ -1627,8 +1627,7 @@ void DebuggerPluginPrivate::attachCore()
DebuggerStartParameters sp; DebuggerStartParameters sp;
QString display = dlg.useLocalCoreFile() ? dlg.localCoreFile() : dlg.remoteCoreFile(); QString display = dlg.useLocalCoreFile() ? dlg.localCoreFile() : dlg.remoteCoreFile();
QTC_ASSERT(fillParameters(&sp, dlg.kit()), return); QTC_ASSERT(fillParameters(&sp, dlg.kit()), return);
DebuggerItem info = DebuggerKitInformation::debuggerItem(dlg.kit()); sp.masterEngineType = DebuggerKitInformation::engineType(dlg.kit());
sp.masterEngineType = info.engineType;
sp.executable = dlg.localExecutableFile(); sp.executable = dlg.localExecutableFile();
sp.coreFile = dlg.localCoreFile(); sp.coreFile = dlg.localCoreFile();
sp.displayName = tr("Core file \"%1\"").arg(display); sp.displayName = tr("Core file \"%1\"").arg(display);

View File

@@ -264,12 +264,12 @@ Kit *BlackBerryConfiguration::createKit(QnxArchitecture arch, BaseQtVersion *qtV
QtKitInformation::setQtVersion(kit, qtVersion); QtKitInformation::setQtVersion(kit, qtVersion);
ToolChainKitInformation::setToolChain(kit, tc); ToolChainKitInformation::setToolChain(kit, tc);
if (arch == X86) { if (arch == X86) {
Debugger::DebuggerKitInformation::setDebuggerCommand(kit, m_simulatorDebuger); Debugger::DebuggerKitInformation::setDebugger(kit, Debugger::GdbEngineType, m_simulatorDebuger);
Qt4ProjectManager::QmakeKitInformation::setMkspec(kit, FileName::fromString(QString::fromLatin1("blackberry-x86-qcc"))); Qt4ProjectManager::QmakeKitInformation::setMkspec(kit, FileName::fromString(QString::fromLatin1("blackberry-x86-qcc")));
// TODO: Check if the name already exists(?) // TODO: Check if the name already exists(?)
kit->setDisplayName(tr("BlackBerry 10 (%1 - %2) - Simulator").arg(qtVersion->qtVersionString(), m_targetName)); kit->setDisplayName(tr("BlackBerry 10 (%1 - %2) - Simulator").arg(qtVersion->qtVersionString(), m_targetName));
} else { } else {
Debugger::DebuggerKitInformation::setDebuggerCommand(kit, m_deviceDebuger); Debugger::DebuggerKitInformation::setDebugger(kit, Debugger::GdbEngineType, m_deviceDebuger);
kit->setDisplayName(tr("BlackBerry 10 (%1 - %2)").arg(qtVersion->qtVersionString(), m_targetName)); kit->setDisplayName(tr("BlackBerry 10 (%1 - %2)").arg(qtVersion->qtVersionString(), m_targetName));
} }