KitChooser: Introduce virtual methods for Debugger.

Introduce virtual methods such that it is possible to
write derived classes for specific KitInformation classes,
allowing for filtering and setting text and tooltip.

Remove debugging-specific code of KitChooser from
the ProjectExplorer.

Move populate() away from the constructor as not to call
virtuals from it.

Implement DebuggerKitChooser. It should no longer be
possible to to choose an invalid kit for debugging
from the debugger starter dialogs.

Add a protected constructor to DeviceProcessesDialog
allowing to pass a KitChooser.

Change-Id: I8c683a2da7d69bfbccdc08213cb47d69a0df8b3e
Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com>
This commit is contained in:
Friedemann Kleint
2012-09-05 10:55:05 +02:00
parent af6bbc442e
commit c3f50e3192
9 changed files with 121 additions and 46 deletions

View File

@@ -69,7 +69,7 @@ StartRemoteDialog::StartRemoteDialog(QWidget *parent)
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setWindowTitle(tr("Start Remote Analysis"));
d->kitChooser = new KitChooser(this, KitChooser::RemoteDebugging);
d->kitChooser = new KitChooser(this);
d->executable = new QLineEdit(this);
d->arguments = new QLineEdit(this);
d->workingDirectory = new QLineEdit(this);

View File

@@ -39,7 +39,6 @@
#include <coreplugin/icore.h>
#include <projectexplorer/abi.h>
#include <projectexplorer/kitchooser.h>
#include <projectexplorer/kitinformation.h>
#include <utils/historycompleter.h>
#include <utils/pathchooser.h>
@@ -109,6 +108,36 @@ Q_DECLARE_METATYPE(Debugger::Internal::StartApplicationParameters)
namespace Debugger {
namespace Internal {
///////////////////////////////////////////////////////////////////////
//
// DebuggerKitChooser
//
///////////////////////////////////////////////////////////////////////
DebuggerKitChooser::DebuggerKitChooser(Mode mode, QWidget *parent)
: ProjectExplorer::KitChooser(parent)
, m_hostAbi(ProjectExplorer::Abi::hostAbi())
, m_mode(mode)
{
}
// Match valid debuggers and restrict local debugging to compatible toolchains.
bool DebuggerKitChooser::kitMatches(const ProjectExplorer::Kit *k) const
{
if (!DebuggerKitInformation::isValidDebugger(k))
return false;
if (m_mode == LocalDebugging) {
const ProjectExplorer::ToolChain *tc = ToolChainKitInformation::toolChain(k);
return tc && tc->targetAbi().os() == m_hostAbi.os();
}
return true;
}
QString DebuggerKitChooser::kitToolTip(Kit *k) const
{
return DebuggerKitInformation::userOutput(k);
}
///////////////////////////////////////////////////////////////////////
//
// StartApplicationParameters
@@ -225,7 +254,8 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent)
d->runInTerminalCheckBox = new QCheckBox(this);
d->kitChooser = new KitChooser(this, KitChooser::LocalDebugging);
d->kitChooser = new DebuggerKitChooser(DebuggerKitChooser::LocalDebugging, this);
d->kitChooser->populate();
d->breakAtMainCheckBox = new QCheckBox(this);
d->breakAtMainCheckBox->setText(QString());
@@ -439,7 +469,8 @@ AttachToQmlPortDialog::AttachToQmlPortDialog(QWidget *parent)
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setWindowTitle(tr("Start Debugger"));
d->kitChooser = new KitChooser(this);
d->kitChooser = new DebuggerKitChooser(DebuggerKitChooser::RemoteDebugging, this);
d->kitChooser->populate();
d->portSpinBox = new QSpinBox(this);
d->portSpinBox->setMaximum(65535);

View File

@@ -31,6 +31,9 @@
#ifndef DEBUGGER_DIALOGS_H
#define DEBUGGER_DIALOGS_H
#include <projectexplorer/kitchooser.h>
#include <projectexplorer/abi.h>
#include <QDialog>
#include <QHash>
#include <QStringList>
@@ -58,6 +61,22 @@ class StartApplicationParameters;
class StartApplicationDialogPrivate;
class StartRemoteEngineDialogPrivate;
class DebuggerKitChooser : public ProjectExplorer::KitChooser {
Q_OBJECT
public:
enum Mode { RemoteDebugging, LocalDebugging };
explicit DebuggerKitChooser(Mode mode = RemoteDebugging, QWidget *parent = 0);
protected:
bool kitMatches(const ProjectExplorer::Kit *k) const;
QString kitToolTip(ProjectExplorer::Kit *k) const;
private:
const ProjectExplorer::Abi m_hostAbi;
const Mode m_mode;
};
class StartApplicationDialog : public QDialog
{
Q_OBJECT

View File

@@ -1670,9 +1670,21 @@ void DebuggerPluginPrivate::attachToRunningApplication()
attachToProcess(false);
}
class DebuggerProcessesDialog : public ProjectExplorer::DeviceProcessesDialog {
public:
DebuggerProcessesDialog(DebuggerKitChooser::Mode m, QWidget *parent) :
ProjectExplorer::DeviceProcessesDialog(new DebuggerKitChooser(m), parent)
{
addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
}
};
void DebuggerPluginPrivate::attachToProcess(bool startServerOnly)
{
DeviceProcessesDialog *dlg = new DeviceProcessesDialog(mainWindow());
const DebuggerKitChooser::Mode mode = startServerOnly ?
DebuggerKitChooser::RemoteDebugging : DebuggerKitChooser::LocalDebugging;
DeviceProcessesDialog *dlg = new DebuggerProcessesDialog(mode, mainWindow());
dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
dlg->showAllDevices();
if (dlg->exec() == QDialog::Rejected) {

View File

@@ -33,6 +33,7 @@
#include "debuggerconstants.h"
#include "debuggercore.h"
#include "debuggerstartparameters.h"
#include "debuggerdialogs.h"
#include <coreplugin/icore.h>
#include <projectexplorer/abi.h>
@@ -245,7 +246,8 @@ AttachCoreDialog::AttachCoreDialog(QWidget *parent)
d->settings = ICore::settings();
d->kitChooser = new KitChooser(this);
d->kitChooser = new DebuggerKitChooser(DebuggerKitChooser::RemoteDebugging, this);
d->kitChooser->populate();
d->selectRemoteCoreButton = new QPushButton(tr("Browse..."), this);
d->remoteCoreFileName = new QLineEdit(this);

View File

@@ -96,7 +96,7 @@ class DeviceProcessesDialogPrivate : public QObject
Q_OBJECT
public:
DeviceProcessesDialogPrivate(QWidget *parent);
DeviceProcessesDialogPrivate(KitChooser *chooser, QWidget *parent);
public slots:
void setDevice(const IDevice::ConstPtr &device);
@@ -124,16 +124,20 @@ public:
QDialogButtonBox *buttonBox;
};
DeviceProcessesDialogPrivate::DeviceProcessesDialogPrivate(QWidget *parent)
: q(parent), acceptButton(0), buttonBox(new QDialogButtonBox(parent))
DeviceProcessesDialogPrivate::DeviceProcessesDialogPrivate(KitChooser *chooser, QWidget *parent)
: q(parent), kitChooser(chooser), acceptButton(0), buttonBox(new QDialogButtonBox(parent))
{
q->setWindowTitle(DeviceProcessesDialog::tr("List of Processes"));
q->setWindowFlags(q->windowFlags() & ~Qt::WindowContextHelpButtonHint);
q->setMinimumHeight(500);
processList = 0;
processFilterLineEdit = new FilterLineEdit(q);
processFilterLineEdit->setPlaceholderText(DeviceProcessesDialog::tr("Filter"));
processFilterLineEdit->setFocus(Qt::TabFocusReason);
kitChooser = new KitChooser(q);
kitChooser->populate();
procView = new QTreeView(q);
procView->setModel(&proxyModel);
@@ -295,11 +299,13 @@ DeviceProcess DeviceProcessesDialogPrivate::selectedProcess() const
*/
DeviceProcessesDialog::DeviceProcessesDialog(QWidget *parent)
: QDialog(parent), d(new Internal::DeviceProcessesDialogPrivate(this))
: QDialog(parent), d(new Internal::DeviceProcessesDialogPrivate(new KitChooser(this), this))
{
}
DeviceProcessesDialog::DeviceProcessesDialog(KitChooser *chooser, QWidget *parent)
: QDialog(parent), d(new Internal::DeviceProcessesDialogPrivate(chooser, this))
{
setWindowTitle(tr("List of Processes"));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setMinimumHeight(500);
}
DeviceProcessesDialog::~DeviceProcessesDialog()

View File

@@ -60,6 +60,9 @@ public:
KitChooser *kitChooser() const;
void logMessage(const QString &line);
protected:
DeviceProcessesDialog(KitChooser *chooser, QWidget *parent);
private:
Internal::DeviceProcessesDialogPrivate * const d;
};

View File

@@ -38,42 +38,43 @@
namespace ProjectExplorer {
KitChooser::KitChooser(QWidget *parent, unsigned flags) :
KitChooser::KitChooser(QWidget *parent) :
QComboBox(parent)
{
populate(flags);
onCurrentIndexChanged(currentIndex());
connect(this, SIGNAL(currentIndexChanged(int)), SLOT(onCurrentIndexChanged(int)));
}
void KitChooser::onCurrentIndexChanged(int index)
{
if (Kit *kit = kitAt(index))
setToolTip(kit->toHtml());
setToolTip(kitToolTip(kit));
else
setToolTip(QString());
}
void KitChooser::populate(unsigned flags)
bool KitChooser::kitMatches(const Kit *k) const
{
return k->isValid();
}
QString KitChooser::kitText(const Kit *k) const
{
return k->displayName();
}
QString KitChooser::kitToolTip(Kit *k) const
{
return k->toHtml();
}
void KitChooser::populate()
{
clear();
const Abi hostAbi = Abi::hostAbi();
foreach (Kit *kit, KitManager::instance()->kits()) {
if (!kit->isValid() && !(flags & IncludeInvalidKits))
continue;
ToolChain *tc = ToolChainKitInformation::toolChain(kit);
if (!tc)
continue;
const Abi abi = tc->targetAbi();
if ((flags & HostAbiOnly) && hostAbi.os() != abi.os())
continue;
const QString debuggerCommand = kit->value(Core::Id("Debugger.Information")).toString();
if ((flags & HasDebugger) && debuggerCommand.isEmpty())
continue;
const QString completeBase = QFileInfo(debuggerCommand).completeBaseName();
const QString name = tr("%1 (%2)").arg(kit->displayName(), completeBase);
addItem(name, qVariantFromValue(kit->id()));
setItemData(count() - 1, kit->toHtml(), Qt::ToolTipRole);
if (kitMatches(kit)) {
addItem(kitText(kit), qVariantFromValue(kit->id()));
setItemData(count() - 1, kitToolTip(kit), Qt::ToolTipRole);
}
}
setEnabled(count() > 1);
}

View File

@@ -47,24 +47,25 @@ class PROJECTEXPLORER_EXPORT KitChooser : public QComboBox
Q_OBJECT
public:
enum Flags {
HostAbiOnly = 0x1,
IncludeInvalidKits = 0x2,
HasDebugger = 0x4,
RemoteDebugging = IncludeInvalidKits | HasDebugger,
LocalDebugging = RemoteDebugging | HostAbiOnly
};
explicit KitChooser(QWidget *parent, unsigned flags = 0);
explicit KitChooser(QWidget *parent = 0);
void setCurrentKitId(Core::Id id);
Core::Id currentKitId() const;
Kit *currentKit() const;
public slots:
void populate();
private slots:
void onCurrentIndexChanged(int index);
protected:
virtual bool kitMatches(const Kit *k) const;
virtual QString kitText(const Kit *k) const;
virtual QString kitToolTip(Kit *k) const;
private:
Q_SLOT void onCurrentIndexChanged(int index);
void populate(unsigned flags);
Kit *kitAt(int index) const;
};