diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp index a7205d34a1c..0769d293dee 100644 --- a/src/plugins/debugger/debuggeritem.cpp +++ b/src/plugins/debugger/debuggeritem.cpp @@ -116,6 +116,9 @@ void DebuggerItem::createId() void DebuggerItem::reinitializeFromFile(QString *error, Utils::Environment *customEnv) { + if (isGeneric()) + return; + // CDB only understands the single-dash -version, whereas GDB and LLDB are // happy with both -version and --version. So use the "working" -version // except for the experimental LLDB-MI which insists on --version. @@ -282,6 +285,16 @@ QString DebuggerItem::engineTypeName() const } } +void DebuggerItem::setGeneric(bool on) +{ + m_detectionSource = on ? QLatin1String("Generic") : QLatin1String(); +} + +bool DebuggerItem::isGeneric() const +{ + return m_detectionSource == "Generic"; +} + QStringList DebuggerItem::abiNames() const { QStringList list; @@ -297,13 +310,15 @@ QDateTime DebuggerItem::lastModified() const QIcon DebuggerItem::decoration() const { + if (isGeneric()) + return {}; if (m_engineType == NoEngineType) return Icons::CRITICAL.icon(); if (!m_command.isExecutableFile()) return Icons::WARNING.icon(); if (!m_workingDirectory.isEmpty() && !m_workingDirectory.isDir()) return Icons::WARNING.icon(); - return QIcon(); + return {}; } QString DebuggerItem::validityMessage() const diff --git a/src/plugins/debugger/debuggeritem.h b/src/plugins/debugger/debuggeritem.h index 1edaf283ca4..95993665b67 100644 --- a/src/plugins/debugger/debuggeritem.h +++ b/src/plugins/debugger/debuggeritem.h @@ -8,7 +8,7 @@ #include -#include +#include #include #include @@ -84,6 +84,9 @@ public: QString detectionSource() const { return m_detectionSource; } void setDetectionSource(const QString &source) { m_detectionSource = source; } + bool isGeneric() const; + void setGeneric(bool on); + static bool addAndroidLldbPythonEnv(const Utils::FilePath &lldbCmd, Utils::Environment &env); private: diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp index 3e77bf73bf2..a74ac5071fc 100644 --- a/src/plugins/debugger/debuggeritemmanager.cpp +++ b/src/plugins/debugger/debuggeritemmanager.cpp @@ -92,7 +92,8 @@ static DebuggerItemManagerPrivate *d = nullptr; class DebuggerItemConfigWidget : public QWidget { public: - explicit DebuggerItemConfigWidget(); + DebuggerItemConfigWidget(); + void load(const DebuggerItem *item); void store() const; @@ -104,13 +105,18 @@ private: QLineEdit *m_displayNameLineEdit; QLineEdit *m_typeLineEdit; QLabel *m_cdbLabel; - QLineEdit *m_versionLabel; PathChooser *m_binaryChooser; - PathChooser *m_workingDirectoryChooser; - QLineEdit *m_abis; bool m_autodetected = false; + bool m_generic = false; DebuggerEngineType m_engineType = NoEngineType; QVariant m_id; + + QLabel *m_abisLabel; + QLineEdit *m_abis; + QLabel *m_versionLabel; + QLineEdit *m_version; + QLabel *m_workingDirectoryLabel; + PathChooser *m_workingDirectoryChooser; }; // -------------------------------------------------------------------------- @@ -174,7 +180,7 @@ public: QModelIndex lastIndex() const; void setCurrentIndex(const QModelIndex &index); - void addDebugger(const DebuggerItem &item, bool changed = false); + DebuggerTreeItem *addDebugger(const DebuggerItem &item, bool changed = false); void updateDebugger(const DebuggerItem &item); void apply(); void cancel(); @@ -213,6 +219,7 @@ DebuggerItemModel::DebuggerItemModel() DebuggerItem genericGdb(QVariant("gdb")); genericGdb.setAutoDetected(true); + genericGdb.setGeneric(true); genericGdb.setEngineType(GdbEngineType); genericGdb.setAbi(Abi()); genericGdb.setCommand("gdb"); @@ -222,17 +229,20 @@ DebuggerItemModel::DebuggerItemModel() DebuggerItem genericLldb(QVariant("lldb")); genericLldb.setAutoDetected(true); genericLldb.setEngineType(LldbEngineType); + genericLldb.setGeneric(true); genericLldb.setAbi(Abi()); genericLldb.setCommand("lldb"); genericLldb.setUnexpandedDisplayName(Tr::tr("%1 from PATH on Build Device").arg("LLDB")); generic->appendChild(new DebuggerTreeItem(genericLldb, false)); } -void DebuggerItemModel::addDebugger(const DebuggerItem &item, bool changed) +DebuggerTreeItem *DebuggerItemModel::addDebugger(const DebuggerItem &item, bool changed) { - QTC_ASSERT(item.id().isValid(), return); - int group = item.isAutoDetected() ? AutoDetected : Manual; - rootItem()->childAt(group)->appendChild(new DebuggerTreeItem(item, changed)); + QTC_ASSERT(item.id().isValid(), return {}); + int group = item.isGeneric() ? Generic : (item.isAutoDetected() ? AutoDetected : Manual); + auto treeItem = new DebuggerTreeItem(item, changed); + rootItem()->childAt(group)->appendChild(treeItem); + return treeItem; } void DebuggerItemModel::updateDebugger(const DebuggerItem &item) @@ -321,6 +331,7 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget() }); m_binaryChooser->setAllowPathFromDevice(true); + m_workingDirectoryLabel = new QLabel(Tr::tr("ABIs:")); m_workingDirectoryChooser = new PathChooser(this); m_workingDirectoryChooser->setExpectedKind(PathChooser::Directory); m_workingDirectoryChooser->setMinimumWidth(400); @@ -330,10 +341,12 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget() m_cdbLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); m_cdbLabel->setOpenExternalLinks(true); - m_versionLabel = new QLineEdit(this); - m_versionLabel->setPlaceholderText(Tr::tr("Unknown")); - m_versionLabel->setEnabled(false); + m_versionLabel = new QLabel(Tr::tr("Version:")); + m_version = new QLineEdit(this); + m_version->setPlaceholderText(Tr::tr("Unknown")); + m_version->setEnabled(false); + m_abisLabel = new QLabel(Tr::tr("Working directory:")); m_abis = new QLineEdit(this); m_abis->setEnabled(false); @@ -343,9 +356,9 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget() formLayout->addRow(m_cdbLabel); formLayout->addRow(new QLabel(Tr::tr("Path:")), m_binaryChooser); formLayout->addRow(new QLabel(Tr::tr("Type:")), m_typeLineEdit); - formLayout->addRow(new QLabel(Tr::tr("ABIs:")), m_abis); - formLayout->addRow(new QLabel(Tr::tr("Version:")), m_versionLabel); - formLayout->addRow(new QLabel(Tr::tr("Working directory:")), m_workingDirectoryChooser); + formLayout->addRow(m_abisLabel, m_abis); + formLayout->addRow(m_versionLabel, m_version); + formLayout->addRow(m_workingDirectoryLabel, m_workingDirectoryChooser); connect(m_binaryChooser, &PathChooser::textChanged, this, &DebuggerItemConfigWidget::binaryPathHasChanged); @@ -357,21 +370,24 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget() DebuggerItem DebuggerItemConfigWidget::item() const { + static const QRegularExpression noAbi("[^A-Za-z0-9-_]+"); + DebuggerItem item(m_id); item.setUnexpandedDisplayName(m_displayNameLineEdit->text()); item.setCommand(m_binaryChooser->filePath()); item.setWorkingDirectory(m_workingDirectoryChooser->filePath()); item.setAutoDetected(m_autodetected); Abis abiList; - const QStringList abis = m_abis->text().split(QRegularExpression("[^A-Za-z0-9-_]+")); + const QStringList abis = m_abis->text().split(noAbi); for (const QString &a : abis) { if (a.isNull()) continue; abiList << Abi::fromString(a); } item.setAbis(abiList); - item.setVersion(m_versionLabel->text()); + item.setVersion(m_version->text()); item.setEngineType(m_engineType); + item.setGeneric(m_generic); return item; } @@ -393,6 +409,7 @@ void DebuggerItemConfigWidget::load(const DebuggerItem *item) return; // Set values: + m_generic = item->isGeneric(); m_autodetected = item->isAutoDetected(); m_displayNameLineEdit->setEnabled(!item->isAutoDetected()); @@ -402,6 +419,15 @@ void DebuggerItemConfigWidget::load(const DebuggerItem *item) m_binaryChooser->setReadOnly(item->isAutoDetected()); m_binaryChooser->setFilePath(item->command()); + m_binaryChooser->setExpectedKind(m_generic ? PathChooser::Any : PathChooser::ExistingCommand); + + m_abisLabel->setVisible(!m_generic); + m_abis->setVisible(!m_generic); + m_versionLabel->setVisible(!m_generic); + m_version->setVisible(!m_generic); + m_workingDirectoryLabel->setVisible(!m_generic); + m_workingDirectoryChooser->setVisible(!m_generic); + m_workingDirectoryChooser->setReadOnly(item->isAutoDetected()); m_workingDirectoryChooser->setFilePath(item->workingDirectory()); @@ -425,7 +451,7 @@ void DebuggerItemConfigWidget::load(const DebuggerItem *item) m_cdbLabel->setText(text); m_cdbLabel->setVisible(!text.isEmpty()); m_binaryChooser->setCommandVersionArguments(QStringList(versionCommand)); - m_versionLabel->setText(item->version()); + m_version->setText(item->version()); setAbis(item->abiNames()); m_engineType = item->engineType(); m_id = item->id(); @@ -437,16 +463,18 @@ void DebuggerItemConfigWidget::binaryPathHasChanged() if (!m_id.isValid()) return; - DebuggerItem tmp; - if (m_binaryChooser->filePath().isExecutableFile()) { - tmp = item(); - tmp.reinitializeFromFile(); - } + if (!m_generic) { + DebuggerItem tmp; + if (m_binaryChooser->filePath().isExecutableFile()) { + tmp = item(); + tmp.reinitializeFromFile(); + } - setAbis(tmp.abiNames()); - m_versionLabel->setText(tmp.version()); - m_engineType = tmp.engineType(); - m_typeLineEdit->setText(tmp.engineTypeName()); + setAbis(tmp.abiNames()); + m_version->setText(tmp.version()); + m_engineType = tmp.engineType(); + m_typeLineEdit->setText(tmp.engineTypeName()); + } store(); } @@ -554,8 +582,10 @@ void DebuggerConfigWidget::cloneDebugger() newItem.setUnexpandedDisplayName(d->uniqueDisplayName(Tr::tr("Clone of %1").arg(item->displayName()))); newItem.reinitializeFromFile(); newItem.setAutoDetected(false); - d->m_model->addDebugger(newItem, true); - m_debuggerView->setCurrentIndex(d->m_model->lastIndex()); + newItem.setGeneric(item->isGeneric()); + newItem.setEngineType(item->engineType()); + auto addedItem = d->m_model->addDebugger(newItem, true); + m_debuggerView->setCurrentIndex(d->m_model->indexForItem(addedItem)); } void DebuggerConfigWidget::addDebugger() @@ -565,8 +595,8 @@ void DebuggerConfigWidget::addDebugger() item.setEngineType(NoEngineType); item.setUnexpandedDisplayName(d->uniqueDisplayName(Tr::tr("New Debugger"))); item.setAutoDetected(false); - d->m_model->addDebugger(item, true); - m_debuggerView->setCurrentIndex(d->m_model->lastIndex()); + auto addedItem = d->m_model->addDebugger(item, true); + m_debuggerView->setCurrentIndex(d->m_model->indexForItem(addedItem)); } void DebuggerConfigWidget::removeDebugger()