Commit f88636e6 authored by Tobias Hunger's avatar Tobias Hunger
Browse files

Kit: Improve the options page



* Update warning icon as changes happen
* Make clone clone the current settings, not what used to be there
  before changes were made
* Make sure the edited entry is visible in list view
* I find the KitModel much easier to understand now

Task-number: QTCREATORBUG-7862
Task-number: QTCREATORBUG-7803
Change-Id: I124c2e5a96cea7386896084e1027ba79a8be20b7
Reviewed-by: default avatarDaniel Teske <daniel.teske@digia.com>
Reviewed-by: default avatarEike Ziller <eike.ziller@digia.com>
parent 47e42e53
......@@ -64,13 +64,12 @@ static const char dgbToolsDownloadLink64C[] = "http://www.microsoft.com/whdc/dev
// DebuggerKitConfigWidget:
// -----------------------------------------------------------------------
DebuggerKitConfigWidget::DebuggerKitConfigWidget(ProjectExplorer::Kit *k,
DebuggerKitConfigWidget::DebuggerKitConfigWidget(ProjectExplorer::Kit *workingCopy,
const DebuggerKitInformation *ki,
QWidget *parent) :
ProjectExplorer::KitConfigWidget(parent),
m_kit(k),
m_kit(workingCopy),
m_info(ki),
m_dirty(false),
m_label(new QLabel(this)),
m_button(new QPushButton(tr("Manage..."), this))
{
......@@ -88,7 +87,7 @@ DebuggerKitConfigWidget::DebuggerKitConfigWidget(ProjectExplorer::Kit *k,
connect(changeAction, SIGNAL(triggered()), this, SLOT(showDialog()));
m_button->setMenu(buttonMenu);
discard();
refresh();
}
QWidget *DebuggerKitConfigWidget::buttonWidget() const
......@@ -106,45 +105,23 @@ void DebuggerKitConfigWidget::makeReadOnly()
m_button->setEnabled(false);
}
void DebuggerKitConfigWidget::apply()
void DebuggerKitConfigWidget::refresh()
{
DebuggerKitInformation::setDebuggerItem(m_kit, m_item);
m_dirty = false;
}
void DebuggerKitConfigWidget::discard()
{
doSetItem(DebuggerKitInformation::debuggerItem(m_kit));
m_dirty = false;
m_label->setText(DebuggerKitInformation::userOutput(DebuggerKitInformation::debuggerItem(m_kit)));
}
void DebuggerKitConfigWidget::autoDetectDebugger()
{
setItem(DebuggerKitInformation::autoDetectItem(m_kit));
}
void DebuggerKitConfigWidget::doSetItem(const DebuggerKitInformation::DebuggerItem &item)
{
m_item = item;
m_label->setText(DebuggerKitInformation::userOutput(m_item));
}
void DebuggerKitConfigWidget::setItem(const DebuggerKitInformation::DebuggerItem &item)
{
if (m_item != item) {
m_dirty = true;
doSetItem(item);
emit dirty();
}
DebuggerKitInformation::setDebuggerItem(m_kit, DebuggerKitInformation::autoDetectItem(m_kit));
}
void DebuggerKitConfigWidget::showDialog()
{
DebuggerKitConfigDialog dialog;
dialog.setWindowTitle(tr("Debugger for \"%1\"").arg(m_kit->displayName()));
dialog.setDebuggerItem(m_item);
dialog.setDebuggerItem(DebuggerKitInformation::debuggerItem(m_kit));
if (dialog.exec() == QDialog::Accepted)
setItem(dialog.item());
DebuggerKitInformation::setDebuggerItem(m_kit, dialog.item());
}
// -----------------------------------------------------------------------
......
......@@ -61,7 +61,7 @@ class DebuggerKitConfigWidget : public ProjectExplorer::KitConfigWidget
Q_OBJECT
public:
DebuggerKitConfigWidget(ProjectExplorer::Kit *k,
DebuggerKitConfigWidget(ProjectExplorer::Kit *workingCopy,
const DebuggerKitInformation *ki,
QWidget *parent = 0);
......@@ -69,9 +69,8 @@ public:
void makeReadOnly();
void apply();
void discard();
bool isDirty() const { return m_dirty; }
void refresh();
QWidget *buttonWidget() const;
private slots:
......@@ -79,13 +78,8 @@ private slots:
void showDialog();
private:
void setItem(const DebuggerKitInformation::DebuggerItem &item);
void doSetItem(const DebuggerKitInformation::DebuggerItem &item);
ProjectExplorer::Kit *m_kit;
const DebuggerKitInformation *m_info;
DebuggerKitInformation::DebuggerItem m_item;
bool m_dirty;
QLabel *m_label;
QPushButton *m_button;
};
......
......@@ -52,10 +52,7 @@ public:
virtual QString displayName() const = 0;
virtual void makeReadOnly() = 0;
virtual void apply() = 0;
virtual void discard() = 0;
virtual bool isDirty() const = 0;
virtual void refresh() = 0;
virtual QWidget *buttonWidget() const { return 0; }
......
......@@ -69,7 +69,7 @@ SysRootInformationConfigWidget::SysRootInformationConfigWidget(Kit *k, QWidget *
m_chooser->setFileName(SysRootKitInformation::sysRoot(k));
connect(m_chooser, SIGNAL(changed(QString)), this, SIGNAL(dirty()));
connect(m_chooser, SIGNAL(changed(QString)), this, SLOT(pathWasChanged()));
}
QString SysRootInformationConfigWidget::displayName() const
......@@ -77,21 +77,11 @@ QString SysRootInformationConfigWidget::displayName() const
return tr("Sysroot:");
}
void SysRootInformationConfigWidget::apply()
{
SysRootKitInformation::setSysRoot(m_kit, m_chooser->fileName());
}
void SysRootInformationConfigWidget::discard()
void SysRootInformationConfigWidget::refresh()
{
m_chooser->setFileName(SysRootKitInformation::sysRoot(m_kit));
}
bool SysRootInformationConfigWidget::isDirty() const
{
return SysRootKitInformation::sysRoot(m_kit) != m_chooser->fileName();
}
void SysRootInformationConfigWidget::makeReadOnly()
{
m_chooser->setEnabled(false);
......@@ -102,6 +92,11 @@ QWidget *SysRootInformationConfigWidget::buttonWidget() const
return m_chooser->buttonAtIndex(0);
}
void SysRootInformationConfigWidget::pathWasChanged()
{
SysRootKitInformation::setSysRoot(m_kit, m_chooser->fileName());
}
// --------------------------------------------------------------------------
// ToolChainInformationConfigWidget:
// --------------------------------------------------------------------------
......@@ -128,8 +123,8 @@ ToolChainInformationConfigWidget::ToolChainInformationConfigWidget(Kit *k, QWidg
updateComboBox();
discard();
connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(dirty()));
refresh();
connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(currentToolChainChanged(int)));
m_manageButton->setContentsMargins(0, 0, 0, 0);
m_manageButton->setText(tr("Manage..."));
......@@ -148,25 +143,11 @@ QString ToolChainInformationConfigWidget::displayName() const
return tr("Compiler:");
}
void ToolChainInformationConfigWidget::apply()
{
const QString id = m_comboBox->itemData(m_comboBox->currentIndex()).toString();
ToolChain *tc = ToolChainManager::instance()->findToolChain(id);
ToolChainKitInformation::setToolChain(m_kit, tc);
}
void ToolChainInformationConfigWidget::discard()
void ToolChainInformationConfigWidget::refresh()
{
m_comboBox->setCurrentIndex(indexOf(ToolChainKitInformation::toolChain(m_kit)));
}
bool ToolChainInformationConfigWidget::isDirty() const
{
ToolChain *tc = ToolChainKitInformation::toolChain(m_kit);
return (m_comboBox->itemData(m_comboBox->currentIndex()).toString())
!= (tc ? tc->id() : QString());
}
void ToolChainInformationConfigWidget::makeReadOnly()
{
m_comboBox->setEnabled(false);
......@@ -205,6 +186,13 @@ void ToolChainInformationConfigWidget::manageToolChains()
QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_PAGE_ID));
}
void ToolChainInformationConfigWidget::currentToolChainChanged(int idx)
{
const QString id = m_comboBox->itemData(idx).toString();
ToolChain *tc = ToolChainManager::instance()->findToolChain(id);
ToolChainKitInformation::setToolChain(m_kit, tc);
}
void ToolChainInformationConfigWidget::updateComboBox()
{
// remove unavailable tool chain:
......@@ -234,9 +222,9 @@ int ToolChainInformationConfigWidget::indexOf(const ToolChain *tc)
// DeviceTypeInformationConfigWidget:
// --------------------------------------------------------------------------
DeviceTypeInformationConfigWidget::DeviceTypeInformationConfigWidget(Kit *k, QWidget *parent) :
DeviceTypeInformationConfigWidget::DeviceTypeInformationConfigWidget(Kit *workingCopy, QWidget *parent) :
KitConfigWidget(parent),
m_isReadOnly(false), m_kit(k),
m_isReadOnly(false), m_kit(workingCopy),
m_comboBox(new QComboBox)
{
setToolTip(tr("The type of device to run applications on."));
......@@ -250,12 +238,12 @@ DeviceTypeInformationConfigWidget::DeviceTypeInformationConfigWidget(Kit *k, QWi
= ExtensionSystem::PluginManager::instance()->getObjects<IDeviceFactory>();
foreach (IDeviceFactory *factory, factories) {
foreach (Core::Id id, factory->availableCreationIds()) {
m_comboBox->addItem(factory->displayNameForId(id), QVariant::fromValue(id));
m_comboBox->addItem(factory->displayNameForId(id), id.uniqueIdentifier());
}
}
discard();
connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(dirty()));
refresh();
connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(currentTypeChanged(int)));
}
QString DeviceTypeInformationConfigWidget::displayName() const
......@@ -263,47 +251,37 @@ QString DeviceTypeInformationConfigWidget::displayName() const
return tr("Device type:");
}
void DeviceTypeInformationConfigWidget::apply()
{
Core::Id devType;
if (m_comboBox->currentIndex() >= 0)
devType = m_comboBox->itemData(m_comboBox->currentIndex()).value<Core::Id>();
DeviceTypeKitInformation::setDeviceTypeId(m_kit, devType);
}
void DeviceTypeInformationConfigWidget::discard()
void DeviceTypeInformationConfigWidget::refresh()
{
Core::Id devType = DeviceTypeKitInformation::deviceTypeId(m_kit);
if (!devType.isValid())
m_comboBox->setCurrentIndex(-1);
for (int i = 0; i < m_comboBox->count(); ++i) {
if (m_comboBox->itemData(i).value<Core::Id>() == devType) {
if (m_comboBox->itemData(i).toInt() == devType.uniqueIdentifier()) {
m_comboBox->setCurrentIndex(i);
break;
}
}
}
bool DeviceTypeInformationConfigWidget::isDirty() const
void DeviceTypeInformationConfigWidget::makeReadOnly()
{
Core::Id devType;
if (m_comboBox->currentIndex() >= 0)
devType = m_comboBox->itemData(m_comboBox->currentIndex()).value<Core::Id>();
return DeviceTypeKitInformation::deviceTypeId(m_kit) != devType;
m_comboBox->setEnabled(false);
}
void DeviceTypeInformationConfigWidget::makeReadOnly()
void DeviceTypeInformationConfigWidget::currentTypeChanged(int idx)
{
m_comboBox->setEnabled(false);
Core::Id type = idx < 0 ? Core::Id() : Core::Id::fromUniqueIdentifier(m_comboBox->itemData(idx).toInt());
DeviceTypeKitInformation::setDeviceTypeId(m_kit, type);
}
// --------------------------------------------------------------------------
// DeviceInformationConfigWidget:
// --------------------------------------------------------------------------
DeviceInformationConfigWidget::DeviceInformationConfigWidget(Kit *k, QWidget *parent) :
DeviceInformationConfigWidget::DeviceInformationConfigWidget(Kit *workingCopy, QWidget *parent) :
KitConfigWidget(parent),
m_isReadOnly(false), m_kit(k),
m_isReadOnly(false), m_kit(workingCopy),
m_comboBox(new QComboBox), m_manageButton(new QPushButton(this)),
m_model(new DeviceManagerModel(DeviceManager::instance()))
{
......@@ -323,8 +301,8 @@ DeviceInformationConfigWidget::DeviceInformationConfigWidget(Kit *k, QWidget *pa
m_manageButton->setContentsMargins(0, 0, 0, 0);
m_manageButton->setText(tr("Manage..."));
discard();
connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(dirty()));
refresh();
connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(currentDeviceChanged()));
connect(m_manageButton, SIGNAL(clicked()), this, SLOT(manageDevices()));
}
......@@ -334,26 +312,12 @@ QString DeviceInformationConfigWidget::displayName() const
return tr("Device:");
}
void DeviceInformationConfigWidget::apply()
{
int idx = m_comboBox->currentIndex();
if (idx >= 0)
DeviceKitInformation::setDeviceId(m_kit, m_model->deviceId(idx));
else
DeviceKitInformation::setDeviceId(m_kit, IDevice::invalidId());
}
void DeviceInformationConfigWidget::discard()
void DeviceInformationConfigWidget::refresh()
{
m_model->setTypeFilter(DeviceTypeKitInformation::deviceTypeId(m_kit));
m_comboBox->setCurrentIndex(m_model->indexOf(DeviceKitInformation::device(m_kit)));
}
bool DeviceInformationConfigWidget::isDirty() const
{
Core::Id devId = DeviceKitInformation::deviceId(m_kit);
return devId != m_model->deviceId(m_comboBox->currentIndex());
}
void DeviceInformationConfigWidget::makeReadOnly()
{
m_comboBox->setEnabled(false);
......@@ -380,5 +344,10 @@ void DeviceInformationConfigWidget::modelReset()
m_comboBox->setCurrentIndex(m_model->indexForId(m_selectedId));
}
void DeviceInformationConfigWidget::currentDeviceChanged()
{
DeviceKitInformation::setDeviceId(m_kit, m_model->deviceId(m_comboBox->currentIndex()));
}
} // namespace Internal
} // namespace ProjectExplorer
......@@ -61,12 +61,13 @@ public:
explicit SysRootInformationConfigWidget(Kit *k, QWidget *parent = 0);
QString displayName() const;
void apply();
void discard();
bool isDirty() const;
void refresh();
void makeReadOnly();
QWidget *buttonWidget() const;
private slots:
void pathWasChanged();
private:
Kit *m_kit;
Utils::PathChooser *m_chooser;
......@@ -84,9 +85,7 @@ public:
explicit ToolChainInformationConfigWidget(Kit *k, QWidget *parent = 0);
QString displayName() const;
void apply();
void discard();
bool isDirty() const;
void refresh();
void makeReadOnly();
QWidget *buttonWidget() const;
......@@ -95,6 +94,7 @@ private slots:
void toolChainRemoved(ProjectExplorer::ToolChain *tc);
void toolChainUpdated(ProjectExplorer::ToolChain *tc);
void manageToolChains();
void currentToolChainChanged(int idx);
private:
void updateComboBox();
......@@ -115,14 +115,15 @@ class DeviceTypeInformationConfigWidget : public KitConfigWidget
Q_OBJECT
public:
explicit DeviceTypeInformationConfigWidget(Kit *k, QWidget *parent = 0);
explicit DeviceTypeInformationConfigWidget(Kit *workingCopy, QWidget *parent = 0);
QString displayName() const;
void apply();
void discard();
bool isDirty() const;
void refresh();
void makeReadOnly();
private slots:
void currentTypeChanged(int idx);
private:
bool m_isReadOnly;
Kit *m_kit;
......@@ -138,12 +139,10 @@ class DeviceInformationConfigWidget : public KitConfigWidget
Q_OBJECT
public:
explicit DeviceInformationConfigWidget(Kit *k, QWidget *parent = 0);
explicit DeviceInformationConfigWidget(Kit *workingCopy, QWidget *parent = 0);
QString displayName() const;
void apply();
void discard();
bool isDirty() const;
void refresh();
void makeReadOnly();
QWidget *buttonWidget() const;
......@@ -151,6 +150,7 @@ private slots:
void manageDevices();
void modelAboutToReset();
void modelReset();
void currentDeviceChanged();
private:
bool m_isReadOnly;
......
......@@ -359,11 +359,9 @@ QList<KitInformation *> KitManager::kitInformation() const
Internal::KitManagerConfigWidget *KitManager::createConfigWidget(Kit *k) const
{
if (!k)
return 0;
Internal::KitManagerConfigWidget *result = new Internal::KitManagerConfigWidget(k);
foreach (KitInformation *ki, d->m_informationList)
result->addConfigWidget(ki->createConfigWidget(k));
result->addConfigWidget(ki->createConfigWidget(result->workingCopy()));
return result;
}
......
......@@ -30,6 +30,7 @@
#include "kitmanagerconfigwidget.h"
#include "kit.h"
#include "kitmanager.h"
#include <utils/detailswidget.h>
......@@ -43,16 +44,20 @@
#include <QSizePolicy>
#include <QStyle>
static const char WORKING_COPY_KIT_ID[] = "modified kit";
namespace ProjectExplorer {
namespace Internal {
KitManagerConfigWidget::KitManagerConfigWidget(Kit *k, QWidget *parent) :
KitConfigWidget(parent),
QWidget(parent),
m_layout(new QGridLayout),
m_iconButton(new QToolButton),
m_nameEdit(new QLineEdit),
m_kit(k)
m_kit(k),
m_modifiedKit(new Kit(Core::Id(WORKING_COPY_KIT_ID))),
m_fixingKit(false)
{
QVBoxLayout *top = new QVBoxLayout(this);
top->setMargin(0);
......@@ -81,7 +86,21 @@ KitManagerConfigWidget::KitManagerConfigWidget(Kit *k, QWidget *parent) :
discard();
connect(m_iconButton, SIGNAL(clicked()), this, SLOT(setIcon()));
connect(m_nameEdit, SIGNAL(textChanged(QString)), this, SIGNAL(dirty()));
connect(m_nameEdit, SIGNAL(textChanged(QString)), this, SLOT(setDisplayName()));
KitManager *km = KitManager::instance();
connect(km, SIGNAL(unmanagedKitUpdated(ProjectExplorer::Kit*)),
this, SLOT(workingCopyWasUpdated(ProjectExplorer::Kit*)));
connect(km, SIGNAL(kitUpdated(ProjectExplorer::Kit*)),
this, SLOT(kitWasUpdated(ProjectExplorer::Kit*)));
}
KitManagerConfigWidget::~KitManagerConfigWidget()
{
delete m_modifiedKit;
// Make sure our workingCopy did not get registered somehow:
foreach (const Kit *k, KitManager::instance()->kits())
Q_ASSERT(k->id() != Core::Id(WORKING_COPY_KIT_ID));
}
QString KitManagerConfigWidget::displayName() const
......@@ -91,27 +110,51 @@ QString KitManagerConfigWidget::displayName() const
void KitManagerConfigWidget::apply()
{
foreach (KitConfigWidget *w, m_widgets)
w->apply();
m_kit->setIconPath(m_iconPath);
m_kit->setDisplayName(m_nameEdit->text());
KitManager *km = KitManager::instance();
bool mustRegister = false;
if (!m_kit) {
mustRegister = true;
m_kit = new Kit;
}
m_kit->copyFrom(m_modifiedKit);
if (mustRegister)
km->registerKit(m_kit);
if (m_isDefaultKit)
km->setDefaultKit(m_kit);
emit dirty();
}
void KitManagerConfigWidget::discard()
{
foreach (KitConfigWidget *w, m_widgets)
w->discard();
m_iconButton->setIcon(m_kit->icon());
m_iconPath = m_kit->iconPath();
m_nameEdit->setText(m_kit->displayName());
if (m_kit) {
m_modifiedKit->copyFrom(m_kit);
m_isDefaultKit = (m_kit == KitManager::instance()->defaultKit());
} else {
// This branch will only ever get reached once during setup of widget for a not-yet-existing
// kit.
m_isDefaultKit = false;
}
m_iconButton->setIcon(m_modifiedKit->icon());
m_nameEdit->setText(m_modifiedKit->displayName());
emit dirty();
}
bool KitManagerConfigWidget::isDirty() const
{
foreach (KitConfigWidget *w, m_widgets)
if (w->isDirty())
return true;
return (m_kit->iconPath() != m_iconPath) || (m_kit->displayName() != m_nameEdit->text());
return !m_kit
|| !m_kit->isEqual(m_modifiedKit)
|| m_isDefaultKit != (KitManager::instance()->defaultKit() == m_kit);
}
bool KitManagerConfigWidget::isValid() const
{
return m_modifiedKit->isValid();
}
QString KitManagerConfigWidget::validityMessage() const
{
return m_modifiedKit->toHtml();
}
void KitManagerConfigWidget::addConfigWidget(ProjectExplorer::KitConfigWidget *widget)
......@@ -119,8 +162,6 @@ void KitManagerConfigWidget::addConfigWidget(ProjectExplorer::KitConfigWidget *w
Q_ASSERT(widget);
Q_ASSERT(!m_widgets.contains(widget));
connect(widget, SIGNAL(dirty()), this, SIGNAL(dirty()));
addToLayout(widget->displayName(), widget->toolTip(), widget, widget->buttonWidget());
m_widgets.append(widget);
}
......@@ -133,9 +174,39 @@ void KitManagerConfigWidget::makeReadOnly()
m_nameEdit->setEnabled(false);
}
Kit *KitManagerConfigWidget::workingCopy() const
{
return m_modifiedKit;
}
bool KitManagerConfigWidget::configures(Kit *k) const
{
return m_kit == k;
}
void KitManagerConfigWidget::setIsDefaultKit(bool d)
{
if (m_isDefaultKit != d)
return;
m_isDefaultKit = d;
emit dirty();
}
bool KitManagerConfigWidget::isDefaultKit() const
{
return m_isDefaultKit;
}