forked from qt-creator/qt-creator
Debugger: Use DebuggerTreeItem in DebuggerKitAspect
For sorting and icons. Task-number: QTCREATORBUG-31574 Change-Id: Ieefe3f2dfc0078439ca70db61b512394d9c35fdf Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -308,7 +308,7 @@ QDateTime DebuggerItem::lastModified() const
|
|||||||
|
|
||||||
DebuggerItem::Problem DebuggerItem::problem() const
|
DebuggerItem::Problem DebuggerItem::problem() const
|
||||||
{
|
{
|
||||||
if (isGeneric())
|
if (isGeneric() || !m_id.isValid()) // Id can only be invalid for the "none" item.
|
||||||
return Problem::None;
|
return Problem::None;
|
||||||
if (m_engineType == NoEngineType)
|
if (m_engineType == NoEngineType)
|
||||||
return Problem::NoEngine;
|
return Problem::NoEngine;
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include "debuggeritemmanager.h"
|
#include "debuggeritemmanager.h"
|
||||||
|
|
||||||
#include "debuggeritem.h"
|
|
||||||
#include "debuggertr.h"
|
#include "debuggertr.h"
|
||||||
|
|
||||||
#include <coreplugin/dialogs/ioptionspage.h>
|
#include <coreplugin/dialogs/ioptionspage.h>
|
||||||
@@ -26,7 +25,6 @@
|
|||||||
#include <utils/persistentsettings.h>
|
#include <utils/persistentsettings.h>
|
||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/treemodel.h>
|
|
||||||
#include <utils/winutils.h>
|
#include <utils/winutils.h>
|
||||||
|
|
||||||
#include <nanotrace/nanotrace.h>
|
#include <nanotrace/nanotrace.h>
|
||||||
@@ -102,21 +100,17 @@ private:
|
|||||||
// DebuggerTreeItem
|
// DebuggerTreeItem
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
class DebuggerTreeItem : public TreeItem
|
QVariant DebuggerTreeItem::data(int column, int role) const
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
DebuggerTreeItem(const DebuggerItem &item, bool changed)
|
|
||||||
: m_item(item), m_orig(item), m_added(changed), m_changed(changed)
|
|
||||||
{}
|
|
||||||
|
|
||||||
QVariant data(int column, int role) const override
|
|
||||||
{
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
switch (column) {
|
switch (column) {
|
||||||
case 0: return m_item.displayName();
|
case 0:
|
||||||
case 1: return m_item.command().toUserOutput();
|
return m_item.displayName();
|
||||||
case 2: return m_item.engineTypeName();
|
case 1:
|
||||||
|
return m_item.command().toUserOutput();
|
||||||
|
case 2:
|
||||||
|
return m_item.engineTypeName();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -136,16 +130,15 @@ public:
|
|||||||
|
|
||||||
case Qt::ToolTipRole:
|
case Qt::ToolTipRole:
|
||||||
return m_item.validityMessage();
|
return m_item.validityMessage();
|
||||||
|
|
||||||
|
case IdRole:
|
||||||
|
return m_item.id();
|
||||||
|
|
||||||
|
case ProblemRole:
|
||||||
|
return int(m_item.problem());
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerItem m_item; // Displayed, possibly unapplied data.
|
|
||||||
DebuggerItem m_orig; // Stored original data.
|
|
||||||
bool m_added;
|
|
||||||
bool m_changed;
|
|
||||||
bool m_removed = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// DebuggerItemModel
|
// DebuggerItemModel
|
||||||
|
@@ -5,15 +5,15 @@
|
|||||||
|
|
||||||
#include "debugger_global.h"
|
#include "debugger_global.h"
|
||||||
#include "debuggerconstants.h"
|
#include "debuggerconstants.h"
|
||||||
|
#include "debuggeritem.h"
|
||||||
|
|
||||||
#include <utils/filepath.h>
|
#include <utils/filepath.h>
|
||||||
|
#include <utils/treemodel.h>
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
|
|
||||||
class DebuggerItem;
|
|
||||||
|
|
||||||
namespace DebuggerItemManager {
|
namespace DebuggerItemManager {
|
||||||
|
|
||||||
DEBUGGER_EXPORT void restoreDebuggers();
|
DEBUGGER_EXPORT void restoreDebuggers();
|
||||||
@@ -34,4 +34,25 @@ DEBUGGER_EXPORT const DebuggerItem *findById(const QVariant &id);
|
|||||||
DEBUGGER_EXPORT const DebuggerItem *findByEngineType(DebuggerEngineType engineType);
|
DEBUGGER_EXPORT const DebuggerItem *findByEngineType(DebuggerEngineType engineType);
|
||||||
|
|
||||||
} // DebuggerItemManager
|
} // DebuggerItemManager
|
||||||
|
|
||||||
|
namespace Internal {
|
||||||
|
class DebuggerTreeItem : public Utils::TreeItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DebuggerTreeItem(const DebuggerItem &item, bool changed)
|
||||||
|
: m_item(item), m_orig(item), m_added(changed), m_changed(changed)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static const inline int IdRole = Qt::UserRole;
|
||||||
|
static const inline int ProblemRole = Qt::UserRole + 1;
|
||||||
|
QVariant data(int column, int role) const override;
|
||||||
|
|
||||||
|
DebuggerItem m_item; // Displayed, possibly unapplied data.
|
||||||
|
DebuggerItem m_orig; // Stored original data.
|
||||||
|
bool m_added;
|
||||||
|
bool m_changed;
|
||||||
|
bool m_removed = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // Internal
|
||||||
} // Debugger
|
} // Debugger
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
|
||||||
#include <utility>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
@@ -35,6 +35,98 @@ namespace Debugger {
|
|||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
class DebuggerItemListModel : public TreeModel<TreeItem, DebuggerTreeItem>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DebuggerItemListModel(const Kit &kit, QObject *parent)
|
||||||
|
: TreeModel(parent)
|
||||||
|
, m_kit(kit)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QModelIndex indexForId(const QVariant &id) const
|
||||||
|
{
|
||||||
|
// The "None" item always comes last
|
||||||
|
const auto noneIndex = [this] { return index(rowCount() - 1, 0); };
|
||||||
|
|
||||||
|
if (id.isNull())
|
||||||
|
return noneIndex();
|
||||||
|
const TreeItem *const item = findItemAtLevel<1>(
|
||||||
|
[id](TreeItem *item) { return item->data(0, DebuggerTreeItem::IdRole) == id; });
|
||||||
|
return item ? indexForItem(item) : noneIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
|
||||||
|
const IDeviceConstPtr device = BuildDeviceKitAspect::device(&m_kit);
|
||||||
|
const Utils::FilePath rootPath = device->rootPath();
|
||||||
|
const QList<DebuggerItem> debuggersForBuildDevice
|
||||||
|
= Utils::filtered(DebuggerItemManager::debuggers(), [&](const DebuggerItem &item) {
|
||||||
|
if (item.isGeneric())
|
||||||
|
return device->id() != ProjectExplorer::Constants::DESKTOP_DEVICE_ID;
|
||||||
|
return item.command().isSameDevice(rootPath);
|
||||||
|
});
|
||||||
|
for (const DebuggerItem &item : debuggersForBuildDevice)
|
||||||
|
rootItem()->appendChild(new DebuggerTreeItem(item, false));
|
||||||
|
DebuggerItem noneItem;
|
||||||
|
noneItem.setUnexpandedDisplayName(Tr::tr("None"));
|
||||||
|
rootItem()->appendChild(new DebuggerTreeItem(noneItem, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Kit &m_kit;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DebuggerItemSortModel : public SortModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DebuggerItemSortModel(QObject *parent) : SortModel(parent) {}
|
||||||
|
|
||||||
|
QModelIndex indexForId(const QVariant &id) const
|
||||||
|
{
|
||||||
|
return mapFromSource(
|
||||||
|
static_cast<DebuggerItemListModel *>(sourceModel())->indexForId(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() { static_cast<DebuggerItemListModel *>(sourceModel())->reset(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override
|
||||||
|
{
|
||||||
|
const auto source = static_cast<DebuggerItemListModel *>(sourceModel());
|
||||||
|
const auto item1 = static_cast<DebuggerTreeItem *>(source->itemForIndex(source_left));
|
||||||
|
const auto item2 = static_cast<DebuggerTreeItem *>(source->itemForIndex(source_right));
|
||||||
|
QTC_ASSERT(item1 && item2, return false);
|
||||||
|
|
||||||
|
// Criterion 1: "None" comes last
|
||||||
|
if (!item1->data(0, DebuggerTreeItem::IdRole).isValid())
|
||||||
|
return false;
|
||||||
|
if (!item2->data(0, DebuggerTreeItem::IdRole).isValid())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Criterion 2: Invalid items come after valid ones with warnings, which come
|
||||||
|
// after valid ones without warnings.
|
||||||
|
if (const QVariant &p1 = item1->data(0, DebuggerTreeItem::ProblemRole),
|
||||||
|
&p2 = item2->data(0, DebuggerTreeItem::ProblemRole);
|
||||||
|
p1 != p2) {
|
||||||
|
const auto problem1 = static_cast<DebuggerItem::Problem>(p1.toInt());
|
||||||
|
const auto problem2 = static_cast<DebuggerItem::Problem>(p2.toInt());
|
||||||
|
if (problem1 == DebuggerItem::Problem::None
|
||||||
|
|| problem2 == DebuggerItem::Problem::NoEngine) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (problem2 == DebuggerItem::Problem::None
|
||||||
|
|| problem1 == DebuggerItem::Problem::NoEngine) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Criterion 3: Name.
|
||||||
|
return SortModel::lessThan(source_left, source_right);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class DebuggerKitAspectImpl final : public KitAspect
|
class DebuggerKitAspectImpl final : public KitAspect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -46,16 +138,16 @@ public:
|
|||||||
m_comboBox = createSubWidget<QComboBox>();
|
m_comboBox = createSubWidget<QComboBox>();
|
||||||
m_comboBox->setSizePolicy(QSizePolicy::Ignored, m_comboBox->sizePolicy().verticalPolicy());
|
m_comboBox->setSizePolicy(QSizePolicy::Ignored, m_comboBox->sizePolicy().verticalPolicy());
|
||||||
m_comboBox->setEnabled(true);
|
m_comboBox->setEnabled(true);
|
||||||
|
const auto sortModel = new DebuggerItemSortModel(this);
|
||||||
|
sortModel->setSourceModel(new DebuggerItemListModel(*workingCopy, this));
|
||||||
|
m_comboBox->setModel(sortModel);
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
m_comboBox->setToolTip(factory->description());
|
m_comboBox->setToolTip(factory->description());
|
||||||
connect(m_comboBox, &QComboBox::currentIndexChanged, this, [this] {
|
connect(m_comboBox, &QComboBox::currentIndexChanged, this, [this] {
|
||||||
if (m_ignoreChanges.isLocked())
|
if (m_ignoreChanges.isLocked())
|
||||||
return;
|
return;
|
||||||
|
m_kit->setValue(DebuggerKitAspect::id(), currentId());
|
||||||
int currentIndex = m_comboBox->currentIndex();
|
|
||||||
QVariant id = m_comboBox->itemData(currentIndex);
|
|
||||||
m_kit->setValue(DebuggerKitAspect::id(), id);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -81,34 +173,16 @@ private:
|
|||||||
void refresh() override
|
void refresh() override
|
||||||
{
|
{
|
||||||
const GuardLocker locker(m_ignoreChanges);
|
const GuardLocker locker(m_ignoreChanges);
|
||||||
m_comboBox->clear();
|
const auto sortModel = static_cast<DebuggerItemSortModel *>(m_comboBox->model());
|
||||||
m_comboBox->addItem(Tr::tr("None"), QString());
|
sortModel->reset();
|
||||||
|
sortModel->sort(0);
|
||||||
IDeviceConstPtr device = BuildDeviceKitAspect::device(kit());
|
const DebuggerItem * const item = DebuggerKitAspect::debugger(m_kit);
|
||||||
const Utils::FilePath path = device->rootPath();
|
m_comboBox->setCurrentIndex(sortModel->indexForId(item ? item->id() : QVariant()).row());
|
||||||
|
|
||||||
const QList<DebuggerItem> debuggersForBuildDevice
|
|
||||||
= Utils::filtered(DebuggerItemManager::debuggers(), [path](const DebuggerItem &item) {
|
|
||||||
return item.command().isSameDevice(path);
|
|
||||||
});
|
|
||||||
for (const DebuggerItem &item : debuggersForBuildDevice)
|
|
||||||
m_comboBox->addItem(item.displayName(), item.id());
|
|
||||||
|
|
||||||
const DebuggerItem *item = DebuggerKitAspect::debugger(m_kit);
|
|
||||||
updateComboBox(item ? item->id() : QVariant());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant currentId() const { return m_comboBox->itemData(m_comboBox->currentIndex()); }
|
QVariant currentId() const
|
||||||
|
|
||||||
void updateComboBox(const QVariant &id)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < m_comboBox->count(); ++i) {
|
return m_comboBox->itemData(m_comboBox->currentIndex(), DebuggerTreeItem::IdRole);
|
||||||
if (id == m_comboBox->itemData(i)) {
|
|
||||||
m_comboBox->setCurrentIndex(i);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_comboBox->setCurrentIndex(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Guard m_ignoreChanges;
|
Guard m_ignoreChanges;
|
||||||
|
Reference in New Issue
Block a user