forked from qt-creator/qt-creator
DeviceManager: Remember auto-detected devices.
The current implementation "forgets" auto-detected devices when they've been disconnected or Creator has been closed. This has the drawback that potential changes by users to the connection parameters cannot become persistent. This is overcome by introducing a device fingerprint and keeping removed auto-connected devices in a special list from which they can later be retrieved, typically when the device gets connected again. Change-Id: I98cfd25c677e6a2a46891a0facf3a28f0a0c3465 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@nokia.com>
This commit is contained in:
@@ -52,6 +52,18 @@
|
||||
namespace ProjectExplorer {
|
||||
namespace Internal {
|
||||
|
||||
static IDevice::Ptr findAutoDetectedDevice(const QList<IDevice::Ptr> &deviceList,
|
||||
const QString &type, const QString &fingerprint)
|
||||
{
|
||||
foreach (const IDevice::Ptr &device, deviceList) {
|
||||
if (device->isAutoDetected() && device->type() == type
|
||||
&& device->fingerprint() == fingerprint) {
|
||||
return device;
|
||||
}
|
||||
}
|
||||
return IDevice::Ptr();
|
||||
}
|
||||
|
||||
const char DeviceManagerKey[] = "DeviceManager";
|
||||
const char DeviceListKey[] = "DeviceList";
|
||||
const char DefaultDevicesKey[] = "DefaultDevices";
|
||||
@@ -62,6 +74,7 @@ public:
|
||||
static DeviceManager *instance;
|
||||
static DeviceManager *clonedInstance;
|
||||
QList<IDevice::Ptr> devices;
|
||||
QList<IDevice::Ptr> inactiveAutoDetectedDevices;
|
||||
QHash<QString, IDevice::Id> defaultDevices;
|
||||
};
|
||||
DeviceManager *DeviceManagerPrivate::instance = 0;
|
||||
@@ -192,7 +205,10 @@ void DeviceManager::fromMap(const QVariantMap &map)
|
||||
QTC_ASSERT(device, continue);
|
||||
if (device->internalId() == IDevice::invalidId())
|
||||
device->setInternalId(unusedId());
|
||||
d->devices << device;
|
||||
if (device->isAutoDetected())
|
||||
d->inactiveAutoDetectedDevices << device;
|
||||
else
|
||||
d->devices << device;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,10 +223,10 @@ QVariantMap DeviceManager::toMap() const
|
||||
}
|
||||
map.insert(QLatin1String(DefaultDevicesKey), defaultDeviceMap);
|
||||
QVariantList deviceList;
|
||||
foreach (const IDevice::ConstPtr &device, d->devices) {
|
||||
if (!device->isAutoDetected())
|
||||
deviceList << device->toMap();
|
||||
}
|
||||
foreach (const IDevice::ConstPtr &device, d->devices)
|
||||
deviceList << device->toMap();
|
||||
foreach (const IDevice::ConstPtr &device, d->inactiveAutoDetectedDevices)
|
||||
deviceList << device->toMap();
|
||||
map.insert(QLatin1String(DeviceListKey), deviceList);
|
||||
return map;
|
||||
}
|
||||
@@ -224,6 +240,8 @@ QString DeviceManager::settingsFilePath()
|
||||
void DeviceManager::addDevice(const IDevice::Ptr &device)
|
||||
{
|
||||
QTC_ASSERT(this != DeviceManagerPrivate::instance || (device->isAutoDetected()), return);
|
||||
QTC_ASSERT(!device->isAutoDetected() || !findAutoDetectedDevice(d->devices, device->type(),
|
||||
device->fingerprint()), return);
|
||||
|
||||
// Ensure uniqueness of name.
|
||||
QString name = device->displayName();
|
||||
@@ -241,13 +259,25 @@ void DeviceManager::addDevice(const IDevice::Ptr &device)
|
||||
d->devices << device;
|
||||
if (this == d->instance && d->clonedInstance)
|
||||
d->clonedInstance->addDevice(device->clone());
|
||||
if (this == d->instance) {
|
||||
QList<IDevice::Ptr>::Iterator it = d->inactiveAutoDetectedDevices.begin();
|
||||
while (it != d->inactiveAutoDetectedDevices.end()) {
|
||||
if (it->data()->type() == device->type()
|
||||
&& it->data()->fingerprint() == device->fingerprint()) {
|
||||
d->inactiveAutoDetectedDevices.erase(it);
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
emit deviceAdded(device);
|
||||
emit updated();
|
||||
}
|
||||
|
||||
void DeviceManager::removeDevice(int idx)
|
||||
{
|
||||
const IDevice::ConstPtr device = deviceAt(idx);
|
||||
const IDevice::Ptr device = mutableDeviceAt(idx);
|
||||
QTC_ASSERT(device, return);
|
||||
QTC_ASSERT(this != DeviceManagerPrivate::instance || device->isAutoDetected(), return);
|
||||
|
||||
@@ -269,6 +299,8 @@ void DeviceManager::removeDevice(int idx)
|
||||
d->clonedInstance->removeDevice(d->clonedInstance->
|
||||
indexForInternalId(device->internalId()));
|
||||
}
|
||||
if (this == d->instance && device->isAutoDetected())
|
||||
d->inactiveAutoDetectedDevices << device;
|
||||
|
||||
emit updated();
|
||||
}
|
||||
@@ -357,6 +389,12 @@ IDevice::ConstPtr DeviceManager::find(IDevice::Id id) const
|
||||
return index == -1 ? IDevice::ConstPtr() : deviceAt(index);
|
||||
}
|
||||
|
||||
IDevice::ConstPtr DeviceManager::findInactiveAutoDetectedDevice(const QString &type,
|
||||
const QString &fingerprint)
|
||||
{
|
||||
return findAutoDetectedDevice(d->inactiveAutoDetectedDevices, type, fingerprint);
|
||||
}
|
||||
|
||||
IDevice::ConstPtr DeviceManager::defaultDevice(const QString &deviceType) const
|
||||
{
|
||||
const IDevice::Id id = d->defaultDevices.value(deviceType, IDevice::invalidId());
|
||||
|
@@ -40,6 +40,7 @@
|
||||
|
||||
namespace ProjectExplorer {
|
||||
class IDeviceFactory;
|
||||
|
||||
namespace Internal {
|
||||
class DeviceManagerPrivate;
|
||||
class DeviceSettingsWidget;
|
||||
@@ -58,6 +59,8 @@ public:
|
||||
int deviceCount() const;
|
||||
IDevice::ConstPtr deviceAt(int index) const;
|
||||
IDevice::ConstPtr find(IDevice::Id id) const;
|
||||
IDevice::ConstPtr findInactiveAutoDetectedDevice(const QString &type,
|
||||
const QString &fingerprint);
|
||||
IDevice::ConstPtr defaultDevice(const QString &deviceType) const;
|
||||
bool hasDevice(const QString &name) const;
|
||||
IDevice::Id internalId(const IDevice::ConstPtr &device) const;
|
||||
|
@@ -183,8 +183,8 @@ void DeviceSettingsWidget::displayCurrent()
|
||||
m_ui->defaultDeviceButton->setEnabled(
|
||||
m_deviceManager->defaultDevice(current->type()) != current);
|
||||
m_ui->osTypeValueLabel->setText(DeviceManager::displayNameForDeviceType(current->type()));
|
||||
m_ui->autoDetectionValueLabel->setText(current->isAutoDetected() ? tr("Yes") : tr("No"));
|
||||
|
||||
m_ui->autoDetectionValueLabel->setText(current->isAutoDetected()
|
||||
? tr("Yes (fingerprint is '%1')").arg(current->fingerprint()) : tr("No"));
|
||||
m_nameValidator->setDisplayName(current->displayName());
|
||||
m_ui->removeConfigButton->setEnabled(!current->isAutoDetected());
|
||||
fillInValues();
|
||||
|
@@ -31,6 +31,8 @@
|
||||
**************************************************************************/
|
||||
#include "idevice.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QString>
|
||||
|
||||
/*!
|
||||
@@ -74,6 +76,15 @@
|
||||
* \brief Identify the device internally.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn QString ProjectExplorer::IDevice::fingerprint() const
|
||||
* \brief Uniquely identifies an auto-detected device.
|
||||
* The fingerprint can later be used to retrieve changes the user has done to the settings
|
||||
* of an auto-detected device so they are not lost when the device goes away, e.g. because
|
||||
* it has been disconnected.
|
||||
* \sa ProjectExplorer::DeviceManager::findInactiveAutoDetectedDevice()
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn ProjectExplorer::IDevice::Id ProjectExplorer::IDevice::invalidId()
|
||||
* \brief A value that no device can ever have as its internal id.
|
||||
@@ -103,6 +114,8 @@ namespace ProjectExplorer {
|
||||
const char DisplayNameKey[] = "Name";
|
||||
const char TypeKey[] = "OsType";
|
||||
const char InternalIdKey[] = "InternalId";
|
||||
const char OriginKey[] = "Origin";
|
||||
const char FingerprintKey[] = "FingerPrint";
|
||||
|
||||
namespace Internal {
|
||||
class IDevicePrivate
|
||||
@@ -112,6 +125,7 @@ public:
|
||||
QString type;
|
||||
IDevice::Origin origin;
|
||||
IDevice::Id internalId;
|
||||
QString fingerprint;
|
||||
};
|
||||
} // namespace Internal
|
||||
|
||||
@@ -119,10 +133,13 @@ IDevice::IDevice() : d(new Internal::IDevicePrivate)
|
||||
{
|
||||
}
|
||||
|
||||
IDevice::IDevice(const QString &type, Origin origin) : d(new Internal::IDevicePrivate)
|
||||
IDevice::IDevice(const QString &type, Origin origin, const QString fingerprint)
|
||||
: d(new Internal::IDevicePrivate)
|
||||
{
|
||||
d->type = type;
|
||||
d->origin = origin;
|
||||
d->fingerprint = fingerprint;
|
||||
QTC_CHECK(d->origin == ManuallyAdded || !d->fingerprint.isEmpty());
|
||||
}
|
||||
|
||||
IDevice::IDevice(const IDevice &other) : d(new Internal::IDevicePrivate)
|
||||
@@ -155,6 +172,11 @@ bool IDevice::isAutoDetected() const
|
||||
return d->origin == AutoDetected;
|
||||
}
|
||||
|
||||
QString IDevice::fingerprint() const
|
||||
{
|
||||
return d->fingerprint;
|
||||
}
|
||||
|
||||
IDevice::Id IDevice::internalId() const
|
||||
{
|
||||
return d->internalId;
|
||||
@@ -178,9 +200,11 @@ QString IDevice::typeFromMap(const QVariantMap &map)
|
||||
void IDevice::fromMap(const QVariantMap &map)
|
||||
{
|
||||
d->type = typeFromMap(map);
|
||||
d->origin = ManuallyAdded;
|
||||
d->displayName = map.value(QLatin1String(DisplayNameKey)).toString();
|
||||
d->internalId = map.value(QLatin1String(InternalIdKey), invalidId()).toULongLong();
|
||||
d->origin = static_cast<Origin>(map.value(QLatin1String(OriginKey), ManuallyAdded).toInt());
|
||||
d->fingerprint = map.value(QLatin1String(FingerprintKey)).toString();
|
||||
QTC_CHECK(d->origin == ManuallyAdded || !d->fingerprint.isEmpty());
|
||||
}
|
||||
|
||||
QVariantMap IDevice::toMap() const
|
||||
@@ -189,6 +213,8 @@ QVariantMap IDevice::toMap() const
|
||||
map.insert(QLatin1String(DisplayNameKey), d->displayName);
|
||||
map.insert(QLatin1String(TypeKey), d->type);
|
||||
map.insert(QLatin1String(InternalIdKey), d->internalId);
|
||||
map.insert(QLatin1String(OriginKey), d->origin);
|
||||
map.insert(QLatin1String(FingerprintKey), d->fingerprint);
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@@ -59,6 +59,7 @@ public:
|
||||
|
||||
QString type() const;
|
||||
bool isAutoDetected() const;
|
||||
QString fingerprint() const;
|
||||
Id internalId() const;
|
||||
|
||||
virtual void fromMap(const QVariantMap &map);
|
||||
@@ -70,7 +71,7 @@ public:
|
||||
|
||||
protected:
|
||||
IDevice();
|
||||
IDevice(const QString &type, Origin origin);
|
||||
IDevice(const QString &type, Origin origin, const QString fingerprint = QString());
|
||||
IDevice(const IDevice &other);
|
||||
|
||||
virtual QVariantMap toMap() const;
|
||||
|
@@ -79,9 +79,9 @@ LinuxDeviceConfiguration::~LinuxDeviceConfiguration()
|
||||
}
|
||||
|
||||
LinuxDeviceConfiguration::Ptr LinuxDeviceConfiguration::create(const QString &name,
|
||||
const QString &type, MachineType machineType, Origin origin)
|
||||
const QString &type, MachineType machineType, Origin origin, const QString &fingerprint)
|
||||
{
|
||||
return Ptr(new LinuxDeviceConfiguration(name, type, machineType, origin));
|
||||
return Ptr(new LinuxDeviceConfiguration(name, type, machineType, origin, fingerprint));
|
||||
}
|
||||
|
||||
LinuxDeviceConfiguration::LinuxDeviceConfiguration() : d(new LinuxDeviceConfigurationPrivate)
|
||||
@@ -89,8 +89,8 @@ LinuxDeviceConfiguration::LinuxDeviceConfiguration() : d(new LinuxDeviceConfigur
|
||||
}
|
||||
|
||||
LinuxDeviceConfiguration::LinuxDeviceConfiguration(const QString &name, const QString &type,
|
||||
MachineType machineType, Origin origin)
|
||||
: IDevice(type, origin), d(new LinuxDeviceConfigurationPrivate)
|
||||
MachineType machineType, Origin origin, const QString &fingerprint)
|
||||
: IDevice(type, origin, fingerprint), d(new LinuxDeviceConfigurationPrivate)
|
||||
{
|
||||
setDisplayName(name);
|
||||
d->machineType = machineType;
|
||||
|
@@ -68,14 +68,14 @@ public:
|
||||
|
||||
static Ptr create();
|
||||
static Ptr create(const QString &name, const QString &type, MachineType machineType,
|
||||
Origin origin = ManuallyAdded);
|
||||
Origin origin = ManuallyAdded, const QString &fingerprint = QString());
|
||||
|
||||
void fromMap(const QVariantMap &map);
|
||||
ProjectExplorer::IDevice::Ptr clone() const;
|
||||
private:
|
||||
LinuxDeviceConfiguration();
|
||||
LinuxDeviceConfiguration(const QString &name, const QString &type, MachineType machineType,
|
||||
Origin origin);
|
||||
Origin origin, const QString &fingerprint);
|
||||
|
||||
LinuxDeviceConfiguration(const LinuxDeviceConfiguration &other);
|
||||
LinuxDeviceConfiguration &operator=(const LinuxDeviceConfiguration &);
|
||||
|
Reference in New Issue
Block a user