diff --git a/src/plugins/projectexplorer/devicesupport/devicesettingspage.cpp b/src/plugins/projectexplorer/devicesupport/devicesettingspage.cpp index 03005ad1809..a432bff3f60 100644 --- a/src/plugins/projectexplorer/devicesupport/devicesettingspage.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicesettingspage.cpp @@ -11,6 +11,8 @@ #include "idevice.h" #include "idevicefactory.h" #include "idevicewidget.h" + +#include "../kitaspect.h" #include "../projectexplorerconstants.h" #include "../projectexplorertr.h" @@ -41,6 +43,72 @@ namespace ProjectExplorer::Internal { const char LastDeviceIndexKey[] = "LastDisplayedMaemoDeviceConfig"; +class DeviceProxyModel : public QIdentityProxyModel +{ +public: + QVariant data(const QModelIndex &index, int role) const override + { + if (role == Qt::FontRole) { + const Id id = Id::fromSetting(index.data(KitAspect::IdRole)); + + const bool isMarkedForDeletion = m_markedForDeletion.contains(id); + const bool isNewDevice = m_newDevices.contains(id); + + QFont font; + font.setItalic(isNewDevice); + font.setStrikeOut(isMarkedForDeletion); + return font; + } + + return QIdentityProxyModel::data(index, role); + } + + void toggleMarkForDeletion(const Id &id) + { + if (m_markedForDeletion.contains(id)) + m_markedForDeletion.remove(id); + else + m_markedForDeletion.insert(id); + + emitDataChanged(id); + } + + void markAsNew(const Id &id) + { + m_newDevices.insert(id); + emitDataChanged(id); + } + + void commitNewDevices() + { + m_newDevices.clear(); + emit dataChanged(index(0, 0), index(rowCount() - 1, 0), {Qt::FontRole}); + } + + bool isMarkedForDeletion(const Id &id) const { return m_markedForDeletion.contains(id); } + bool isNewDevice(const Id &id) const { return m_newDevices.contains(id); } + + QSet markedForDeletion() const { return m_markedForDeletion; } + QSet newDevices() const { return m_newDevices; } + +private: + void emitDataChanged(const Id &id) + { + for (int i = 0; i < rowCount(); ++i) { + const Id deviceId = Id::fromSetting(data(index(i, 0), KitAspect::IdRole)); + if (deviceId == id) { + QModelIndex modelIndex = index(i, 0); + emit dataChanged(modelIndex, modelIndex, {Qt::FontRole}); + break; + } + } + } + +private: + QSet m_markedForDeletion; + QSet m_newDevices; +}; + class DeviceSettingsWidget final : public Core::IOptionsPageWidget { public: @@ -48,12 +116,12 @@ public: ~DeviceSettingsWidget() final { delete m_configWidget; } private: - void apply() final { saveSettings(); } + void apply() final; void cancel() final; void saveSettings(); - void handleDeviceUpdated(Utils::Id id); + void handleDeviceUpdated(Id id); void currentDeviceChanged(int index); void addDevice(); void removeDevice(); @@ -70,7 +138,10 @@ private: QString parseTestOutput(); void updateDeviceFromUi(); + void updateButtons(); + DeviceManagerModel * const m_deviceManagerModel; + DeviceProxyModel m_deviceProxyModel; QList m_additionalActionButtons; IDeviceWidget *m_configWidget = nullptr; @@ -89,8 +160,22 @@ private: QLayout *m_generalFormLayout; }; +void DeviceSettingsWidget::apply() +{ + for (const Id &id : m_deviceProxyModel.markedForDeletion()) + DeviceManager::instance()->removeDevice(id); + + m_deviceProxyModel.commitNewDevices(); + updateButtons(); + + saveSettings(); +} + void DeviceSettingsWidget::cancel() { + for (const Id &id : m_deviceProxyModel.newDevices()) + DeviceManager::instance()->removeDevice(id); + for (int i = 0; i < m_deviceManagerModel->rowCount(); i++) m_deviceManagerModel->device(i)->cancel(); IOptionsPageWidget::cancel(); @@ -99,9 +184,11 @@ void DeviceSettingsWidget::cancel() DeviceSettingsWidget::DeviceSettingsWidget() : m_deviceManagerModel(new DeviceManagerModel(DeviceManager::instance(), this)) { + m_deviceProxyModel.setSourceModel(m_deviceManagerModel); + m_configurationLabel = new QLabel(Tr::tr("&Device:")); m_configurationComboBox = new QComboBox; - m_configurationComboBox->setModel(m_deviceManagerModel); + m_configurationComboBox->setModel(&m_deviceProxyModel); m_generalGroupBox = new QGroupBox(Tr::tr("General")); m_osTypeValueLabel = new QLabel; m_autoDetectionLabel = new QLabel; @@ -135,7 +222,8 @@ DeviceSettingsWidget::DeviceSettingsWidget() IDevice::Ptr device = factory->construct(); QTC_ASSERT(device, return); DeviceManager::instance()->addDevice(device); - m_removeConfigButton->setEnabled(true); + m_deviceProxyModel.markAsNew(device->id()); + updateButtons(); m_configurationComboBox->setCurrentIndex(m_deviceManagerModel->indexOf(device)); saveSettings(); }); @@ -231,7 +319,9 @@ void DeviceSettingsWidget::addDevice() Utils::asyncRun([device] { device->checkOsType(); }); DeviceManager::instance()->addDevice(device); - m_removeConfigButton->setEnabled(true); + m_deviceProxyModel.markAsNew(device->id()); + + updateButtons(); m_configurationComboBox->setCurrentIndex(m_deviceManagerModel->indexOf(device)); saveSettings(); if (device->hasDeviceTester()) @@ -240,9 +330,30 @@ void DeviceSettingsWidget::addDevice() void DeviceSettingsWidget::removeDevice() { - DeviceManager::instance()->removeDevice(currentDevice()->id()); - if (DeviceManager::instance()->deviceCount() == 0) - currentDeviceChanged(-1); + m_deviceProxyModel.toggleMarkForDeletion(currentDevice()->id()); + updateButtons(); +} + +void DeviceSettingsWidget::updateButtons() +{ + const IDevice::ConstPtr ¤t = currentDevice(); + + const bool isMarkedForDeletion = m_deviceProxyModel.isMarkedForDeletion(current->id()); + const bool isNewDevice = m_deviceProxyModel.isNewDevice(current->id()); + + m_removeConfigButton->setEnabled( + (!current->isAutoDetected() || current->deviceState() == IDevice::DeviceDisconnected) + && !isNewDevice); + + if (isMarkedForDeletion) + m_removeConfigButton->setText(Tr::tr("&Restore")); + else + m_removeConfigButton->setText(Tr::tr("&Remove")); + + QFont f = m_configurationComboBox->font(); + f.setStrikeOut(isMarkedForDeletion); + f.setItalic(isNewDevice); + m_configurationComboBox->setFont(f); } void DeviceSettingsWidget::displayCurrent() @@ -260,8 +371,7 @@ void DeviceSettingsWidget::displayCurrent() m_deviceStateIconLabel->hide(); m_deviceStateTextLabel->setText(current->deviceStateToString()); - m_removeConfigButton->setEnabled(!current->isAutoDetected() - || current->deviceState() == IDevice::DeviceDisconnected); + updateButtons(); } void DeviceSettingsWidget::setDeviceInfoWidgetsEnabled(bool enable) @@ -332,7 +442,7 @@ void DeviceSettingsWidget::currentDeviceChanged(int index) const IDevice::ConstPtr device = m_deviceManagerModel->device(index); if (!device) { setDeviceInfoWidgetsEnabled(false); - m_removeConfigButton->setEnabled(false); + updateButtons(); clearDetails(); m_defaultDeviceButton->setEnabled(false); return; @@ -348,7 +458,7 @@ void DeviceSettingsWidget::currentDeviceChanged(int index) m_deviceNameEditWidget = newEdit; setDeviceInfoWidgetsEnabled(true); - m_removeConfigButton->setEnabled(true); + updateButtons(); if (device->hasDeviceTester()) { QPushButton * const button = new QPushButton(Tr::tr("Test"));