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:
@@ -29,15 +29,14 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "debuggeroptionspage.h"
|
||||
|
||||
#include "debuggeritemmanager.h"
|
||||
#include "debuggeritemmodel.h"
|
||||
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
|
||||
#include <utils/detailswidget.h>
|
||||
#include <utils/pathchooser.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/treemodel.h>
|
||||
#include <utils/winutils.h>
|
||||
|
||||
#include <QFileInfo>
|
||||
@@ -55,17 +54,193 @@ using namespace Utils;
|
||||
namespace Debugger {
|
||||
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(DebuggerItemModel *model) :
|
||||
m_model(model)
|
||||
class DebuggerItemConfigWidget : public QWidget
|
||||
{
|
||||
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_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("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 item(m_id);
|
||||
if (m_id.isNull())
|
||||
return item;
|
||||
|
||||
item.setDisplayName(m_displayNameLineEdit->text());
|
||||
item.setCommand(m_binaryChooser->fileName());
|
||||
item.setAutoDetected(m_autodetected);
|
||||
@@ -117,12 +292,10 @@ DebuggerItem DebuggerItemConfigWidget::item() const
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
void DebuggerItemConfigWidget::store() const
|
||||
{
|
||||
DebuggerItem i = item();
|
||||
if (i.isValid())
|
||||
m_model->updateDebugger(i);
|
||||
if (!m_id.isNull())
|
||||
m_model->updateDebugger(item());
|
||||
}
|
||||
|
||||
void DebuggerItemConfigWidget::setAbis(const QStringList &abiNames)
|
||||
@@ -130,8 +303,51 @@ void DebuggerItemConfigWidget::setAbis(const QStringList &abiNames)
|
||||
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:
|
||||
const DebuggerItem *existing
|
||||
= DebuggerItemManager::findByCommand(m_binaryChooser->fileName());
|
||||
@@ -153,65 +369,135 @@ void DebuggerItemConfigWidget::handleCommandChange()
|
||||
m_engineType = NoEngineType;
|
||||
}
|
||||
}
|
||||
m_model->updateDebugger(item());
|
||||
store();
|
||||
}
|
||||
|
||||
void DebuggerItemConfigWidget::setItem(const DebuggerItem &item)
|
||||
// --------------------------------------------------------------------------
|
||||
// DebuggerConfigWidget
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
class DebuggerConfigWidget : public QWidget
|
||||
{
|
||||
store(); // store away the (changed) settings for future use
|
||||
public:
|
||||
DebuggerConfigWidget()
|
||||
{
|
||||
m_addButton = new QPushButton(tr("Add"), this);
|
||||
|
||||
m_id = QVariant(); // reset Id to avoid intermediate signal handling
|
||||
m_cloneButton = new QPushButton(tr("Clone"), this);
|
||||
m_cloneButton->setEnabled(false);
|
||||
|
||||
// Set values:
|
||||
m_autodetected = item.isAutoDetected();
|
||||
m_delButton = new QPushButton(tr("Remove"), this);
|
||||
m_delButton->setEnabled(false);
|
||||
|
||||
m_displayNameLineEdit->setEnabled(!item.isAutoDetected());
|
||||
m_displayNameLineEdit->setText(item.displayName());
|
||||
m_container = new DetailsWidget(this);
|
||||
m_container->setState(DetailsWidget::NoSummary);
|
||||
m_container->setVisible(false);
|
||||
|
||||
m_binaryChooser->setReadOnly(item.isAutoDetected());
|
||||
m_binaryChooser->setFileName(item.command());
|
||||
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();
|
||||
|
||||
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");
|
||||
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);
|
||||
}
|
||||
|
||||
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 cloneDebugger();
|
||||
void addDebugger();
|
||||
void removeDebugger();
|
||||
void currentDebuggerChanged(const QModelIndex &newCurrent);
|
||||
void updateState();
|
||||
|
||||
void DebuggerItemConfigWidget::apply()
|
||||
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 current = m_model->currentDebugger();
|
||||
if (!current.isValid())
|
||||
return; // Nothing was selected here.
|
||||
|
||||
store();
|
||||
setItem(item());
|
||||
}
|
||||
|
||||
void DebuggerItemConfigWidget::binaryPathHasChanged()
|
||||
{
|
||||
// Ignore change if this is no valid DebuggerItem
|
||||
if (!m_id.isValid())
|
||||
DebuggerItem *item = m_model.currentDebugger();
|
||||
if (!item)
|
||||
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()
|
||||
{
|
||||
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);
|
||||
setDisplayName(tr("Debuggers"));
|
||||
setCategory(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY);
|
||||
@@ -237,160 +516,22 @@ DebuggerOptionsPage::DebuggerOptionsPage()
|
||||
|
||||
QWidget *DebuggerOptionsPage::widget()
|
||||
{
|
||||
if (!m_configWidget) {
|
||||
m_configWidget = new QWidget;
|
||||
|
||||
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();
|
||||
}
|
||||
if (!m_configWidget)
|
||||
m_configWidget = new DebuggerConfigWidget;
|
||||
return m_configWidget;
|
||||
}
|
||||
|
||||
void DebuggerOptionsPage::apply()
|
||||
{
|
||||
m_itemConfigWidget->apply();
|
||||
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());
|
||||
QTC_ASSERT(m_configWidget, return);
|
||||
m_configWidget->m_itemConfigWidget->store();
|
||||
m_configWidget->m_model.apply();
|
||||
}
|
||||
|
||||
void DebuggerOptionsPage::finish()
|
||||
{
|
||||
delete m_configWidget;
|
||||
|
||||
// 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);
|
||||
m_configWidget = 0;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
Reference in New Issue
Block a user