From ed3d462674d8fdc01a066dfa76bd87d5a64845e0 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Mon, 21 Jan 2019 22:38:46 +0100 Subject: [PATCH] Fix memory leak and use ItemToIndex / IndexToItem (#6262) --- src/devices/connecteddevice.cpp | 28 ++-- src/devices/devicemanager.cpp | 239 +++++++++++++++++-------------- src/devices/devicemanager.h | 32 +++-- src/devices/deviceproperties.cpp | 14 +- src/devices/deviceproperties.h | 2 +- src/devices/deviceview.cpp | 40 +++--- src/devices/deviceview.h | 4 +- src/devices/filesystemdevice.cpp | 2 +- 8 files changed, 195 insertions(+), 166 deletions(-) diff --git a/src/devices/connecteddevice.cpp b/src/devices/connecteddevice.cpp index ddd2cdf88..c99803c06 100644 --- a/src/devices/connecteddevice.cpp +++ b/src/devices/connecteddevice.cpp @@ -91,7 +91,11 @@ void ConnectedDevice::InitBackendDirectory(const QString& mount_point, void ConnectedDevice::ConnectAsync() { emit ConnectFinished(unique_id_, true); } void ConnectedDevice::Eject() { - manager_->UnmountAsync(manager_->FindDeviceById(unique_id_)); + DeviceInfo* info = manager_->FindDeviceById(unique_id_); + if (!info) return; + QModelIndex idx = manager_->ItemToIndex(info); + if (!idx.isValid()) return; + manager_->UnmountAsync(idx); } void ConnectedDevice::FinishCopy(bool) { @@ -103,18 +107,24 @@ void ConnectedDevice::FinishDelete(bool) { } MusicStorage::TranscodeMode ConnectedDevice::GetTranscodeMode() const { - int index = manager_->FindDeviceById(unique_id_); + DeviceInfo* info = manager_->FindDeviceById(unique_id_); + if (!info) return MusicStorage::TranscodeMode(); + + QModelIndex idx = manager_->ItemToIndex(info); + if (!idx.isValid()) return MusicStorage::TranscodeMode(); + return MusicStorage::TranscodeMode( - manager_->index(index, 0, QModelIndex()) - .data(DeviceManager::Role_TranscodeMode) - .toInt()); + idx.data(DeviceManager::Role_TranscodeMode).toInt()); } Song::FileType ConnectedDevice::GetTranscodeFormat() const { - int index = manager_->FindDeviceById(unique_id_); - return Song::FileType(manager_->index(index, 0, QModelIndex()) - .data(DeviceManager::Role_TranscodeFormat) - .toInt()); + DeviceInfo* info = manager_->FindDeviceById(unique_id_); + if (!info) return Song::Type_Unknown; + + QModelIndex idx = manager_->ItemToIndex(info); + if (!idx.isValid()) return Song::Type_Unknown; + + return Song::FileType(idx.data(DeviceManager::Role_TranscodeFormat).toInt()); } void ConnectedDevice::BackendTotalSongCountUpdated(int count) { diff --git a/src/devices/devicemanager.cpp b/src/devices/devicemanager.cpp index 7c8e01cee..6e911d23e 100644 --- a/src/devices/devicemanager.cpp +++ b/src/devices/devicemanager.cpp @@ -138,19 +138,19 @@ void DeviceManager::LoadAllDevices() { Q_ASSERT(QThread::currentThread() != qApp->thread()); DeviceDatabaseBackend::DeviceList devices = backend_->GetAllDevices(); for (const DeviceDatabaseBackend::Device& device : devices) { - DeviceInfo* info = new DeviceInfo(DeviceInfo::Type_Root, root_); + DeviceInfo* info = new DeviceInfo(DeviceInfo::Type_Device, root_); info->InitFromDb(device); - beginInsertRows(QModelIndex(), devices_.count(), devices_.count()); + beginInsertRows(ItemToIndex(root_), devices_.count(), devices_.count()); devices_ << info; endInsertRows(); } } -QVariant DeviceManager::data(const QModelIndex& index, int role) const { - if (!index.isValid() || index.column() != 0) return QVariant(); +QVariant DeviceManager::data(const QModelIndex& idx, int role) const { + if (!idx.isValid() || idx.column() != 0) return QVariant(); - const DeviceInfo* info = IndexToItem(index); + DeviceInfo* info = IndexToItem(idx); if (!info) return QVariant(); switch (role) { @@ -218,13 +218,14 @@ QVariant DeviceManager::data(const QModelIndex& index, int role) const { case MusicStorage::Role_Storage: if (!info->device_ && info->database_id_ != -1) - const_cast(this)->Connect(index.row()); + const_cast(this)->Connect(info); if (!info->device_) return QVariant(); return QVariant::fromValue>(info->device_); case MusicStorage::Role_StorageForceConnect: + if (!info->BestBackend()) return QVariant(); if (!info->device_) { - if (info->database_id_ == -1 && info->BestBackend() && + if (info->database_id_ == -1 && !info->BestBackend()->lister_->DeviceNeedsMount( info->BestBackend()->unique_id_)) { if (info->BestBackend()->lister_->AskForScan( @@ -243,7 +244,7 @@ QVariant DeviceManager::data(const QModelIndex& index, int role) const { } } - const_cast(this)->Connect(index.row()); + const_cast(this)->Connect(info); } if (!info->device_) return QVariant(); return QVariant::fromValue>(info->device_); @@ -285,17 +286,17 @@ void DeviceManager::AddLister(DeviceLister* lister) { lister->Start(); } -int DeviceManager::FindDeviceById(const QString& id) const { +DeviceInfo* DeviceManager::FindDeviceById(const QString& id) const { for (int i = 0; i < devices_.count(); ++i) { for (const DeviceInfo::Backend& backend : devices_[i]->backends_) { - if (backend.unique_id_ == id) return i; + if (backend.unique_id_ == id) return devices_[i]; } } - return -1; + return nullptr; } -int DeviceManager::FindDeviceByUrl(const QList& urls) const { - if (urls.isEmpty()) return -1; +DeviceInfo* DeviceManager::FindDeviceByUrl(const QList& urls) const { + if (urls.isEmpty()) return nullptr; for (int i = 0; i < devices_.count(); ++i) { for (const DeviceInfo::Backend& backend : devices_[i]->backends_) { @@ -304,11 +305,11 @@ int DeviceManager::FindDeviceByUrl(const QList& urls) const { QList device_urls = backend.lister_->MakeDeviceUrls(backend.unique_id_); for (const QUrl& url : device_urls) { - if (urls.contains(url)) return i; + if (urls.contains(url)) return devices_[i]; } } } - return -1; + return nullptr; } void DeviceManager::PhysicalDeviceAdded(const QString& id) { @@ -317,9 +318,8 @@ void DeviceManager::PhysicalDeviceAdded(const QString& id) { qLog(Info) << "Device added:" << id; // Do we have this device already? - int i = FindDeviceById(id); - if (i != -1) { - DeviceInfo* info = devices_[i]; + DeviceInfo* info = FindDeviceById(id); + if (info) { for (int backend_index = 0; backend_index < info->backends_.count(); ++backend_index) { if (info->backends_[backend_index].unique_id_ == id) { @@ -327,14 +327,13 @@ void DeviceManager::PhysicalDeviceAdded(const QString& id) { break; } } - - emit dataChanged(index(i, 0), index(i, 0)); + QModelIndex idx = ItemToIndex(info); + if (idx.isValid()) emit dataChanged(idx, idx); } else { // Check if we have another device with the same URL - i = FindDeviceByUrl(lister->MakeDeviceUrls(id)); - if (i != -1) { + info = FindDeviceByUrl(lister->MakeDeviceUrls(id)); + if (info) { // Add this device's lister to the existing device - DeviceInfo* info = devices_[i]; info->backends_ << DeviceInfo::Backend(lister, id); // If the user hasn't saved the device in the DB yet then overwrite the @@ -345,16 +344,17 @@ void DeviceManager::PhysicalDeviceAdded(const QString& id) { info->LoadIcon(lister->DeviceIcons(id), info->friendly_name_); } - emit dataChanged(index(i, 0), index(i, 0)); + QModelIndex idx = ItemToIndex(info); + if (idx.isValid()) emit dataChanged(idx, idx); } else { // It's a completely new device - DeviceInfo* info = new DeviceInfo(DeviceInfo::Type_Root, root_); + DeviceInfo* info = new DeviceInfo(DeviceInfo::Type_Device, root_); info->backends_ << DeviceInfo::Backend(lister, id); info->friendly_name_ = lister->MakeFriendlyName(id); info->size_ = lister->DeviceCapacity(id); info->LoadIcon(lister->DeviceIcons(id), info->friendly_name_); - beginInsertRows(QModelIndex(), devices_.count(), devices_.count()); + beginInsertRows(ItemToIndex(root_), devices_.count(), devices_.count()); devices_ << info; endInsertRows(); } @@ -366,13 +366,14 @@ void DeviceManager::PhysicalDeviceRemoved(const QString& id) { qLog(Info) << "Device removed:" << id; - int i = FindDeviceById(id); - if (i == -1) { + DeviceInfo* info = FindDeviceById(id); + if (!info) { // Shouldn't happen return; } - DeviceInfo* info = devices_[i]; + QModelIndex idx = ItemToIndex(info); + if (!idx.isValid()) return; if (info->database_id_ != -1) { // Keep the structure around, but just "disconnect" it @@ -387,9 +388,9 @@ void DeviceManager::PhysicalDeviceRemoved(const QString& id) { if (info->device_ && info->device_->lister() == lister) info->device_.reset(); - if (!info->device_) emit DeviceDisconnected(i); + if (!info->device_) emit DeviceDisconnected(idx); - emit dataChanged(index(i, 0), index(i, 0)); + emit dataChanged(idx, idx); } else { // If this was the last lister for the device then remove it from the model for (int backend_index = 0; backend_index < info->backends_.count(); @@ -401,16 +402,9 @@ void DeviceManager::PhysicalDeviceRemoved(const QString& id) { } if (info->backends_.isEmpty()) { - beginRemoveRows(QModelIndex(), i, i); - devices_.removeAt(i); - - for (const QModelIndex& idx : persistentIndexList()) { - if (idx.row() == i) - changePersistentIndex(idx, QModelIndex()); - else if (idx.row() > i) - changePersistentIndex(idx, index(idx.row() - 1, idx.column())); - } - + beginRemoveRows(ItemToIndex(root_), idx.row(), idx.row()); + devices_.removeAll(info); + root_->Delete(info->row); endRemoveRows(); } } @@ -420,8 +414,8 @@ void DeviceManager::PhysicalDeviceChanged(const QString& id) { DeviceLister* lister = qobject_cast(sender()); Q_UNUSED(lister); - int i = FindDeviceById(id); - if (i == -1) { + DeviceInfo* info = FindDeviceById(id); + if (!info) { // Shouldn't happen return; } @@ -429,14 +423,22 @@ void DeviceManager::PhysicalDeviceChanged(const QString& id) { // TODO } -std::shared_ptr DeviceManager::Connect(int row) { - DeviceInfo* info = devices_[row]; +std::shared_ptr DeviceManager::Connect(QModelIndex idx) { + DeviceInfo* info = IndexToItem(idx); + if (!info) return std::shared_ptr(); + + return Connect(info); +} + +std::shared_ptr DeviceManager::Connect(DeviceInfo* info) { + std::shared_ptr ret; + + if (!info) return ret; if (info->device_) // Already connected return info->device_; - std::shared_ptr ret; - - if (!info->BestBackend()->lister_) // Not physically connected + if (!info->BestBackend() || + !info->BestBackend()->lister_) // Not physically connected return ret; if (info->BestBackend()->lister_->DeviceNeedsMount( @@ -521,9 +523,9 @@ std::shared_ptr DeviceManager::Connect(int row) { ret->Init(); info->device_ = ret; - QModelIndex index = ItemToIndex(info); - if (!index.isValid()) return ret; - emit dataChanged(index, index); + QModelIndex idx = ItemToIndex(info); + if (!idx.isValid()) return ret; + emit dataChanged(idx, idx); connect(info->device_.get(), SIGNAL(TaskStarted(int)), SLOT(DeviceTaskStarted(int))); connect(info->device_.get(), SIGNAL(SongCountUpdated(int)), @@ -537,62 +539,75 @@ std::shared_ptr DeviceManager::Connect(int row) { } void DeviceManager::DeviceConnectFinished(const QString& id, bool success) { - int row = FindDeviceById(id); - if (row != -1) { - if (success) { - emit DeviceConnected(row); - } else { - devices_[row]->device_.reset(); - } + DeviceInfo* info = FindDeviceById(id); + if (!info) return; + + QModelIndex idx = ItemToIndex(info); + if (!idx.isValid()) return; + + if (success) { + emit DeviceConnected(idx); + } else { + info->device_.reset(); } } std::shared_ptr DeviceManager::GetConnectedDevice( - int row) const { - return devices_[row]->device_; + QModelIndex idx) const { + DeviceInfo* info = IndexToItem(idx); + if (!info) return std::shared_ptr(); + return info->device_; } -int DeviceManager::GetDatabaseId(int row) const { - return devices_[row]->database_id_; +std::shared_ptr DeviceManager::GetConnectedDevice( + DeviceInfo* info) const { + if (!info) return std::shared_ptr(); + return info->device_; } -DeviceLister* DeviceManager::GetLister(int row) const { - return devices_[row]->BestBackend()->lister_; +int DeviceManager::GetDatabaseId(const QModelIndex& idx) const { + if (!idx.isValid()) return -1; + DeviceInfo* info = IndexToItem(idx); + if (!info) return -1; + return info->database_id_; } -void DeviceManager::Disconnect(int row) { - DeviceInfo* info = devices_[row]; - if (!info->device_) // Already disconnected +DeviceLister* DeviceManager::GetLister(QModelIndex idx) const { + if (!idx.isValid()) return nullptr; + + DeviceInfo* info = IndexToItem(idx); + if (!info || !info->BestBackend()) return nullptr; + return info->BestBackend()->lister_; +} + +void DeviceManager::Disconnect(QModelIndex idx) { + if (!idx.isValid()) return; + DeviceInfo* info = IndexToItem(idx); + if (!info || !info->device_) // Already disconnected return; info->device_.reset(); - emit DeviceDisconnected(row); - QModelIndex index = ItemToIndex(info); - if (!index.isValid()) return; - emit dataChanged(index, index); + emit DeviceDisconnected(idx); + emit dataChanged(idx, idx); } -void DeviceManager::Forget(int row) { - DeviceInfo* info = devices_[row]; +void DeviceManager::Forget(QModelIndex idx) { + if (!idx.isValid()) return; + DeviceInfo* info = IndexToItem(idx); + if (!info) return; if (info->database_id_ == -1) return; - if (info->device_) Disconnect(row); + if (info->device_) Disconnect(idx); backend_->RemoveDevice(info->database_id_); info->database_id_ = -1; - if (!info->BestBackend()->lister_) { + if (!info->BestBackend() || + (info->BestBackend() && !info->BestBackend()->lister_)) { // It's not attached any more so remove it from the list - beginRemoveRows(QModelIndex(), row, row); - devices_.removeAt(row); - - for (const QModelIndex& idx : persistentIndexList()) { - if (idx.row() == row) - changePersistentIndex(idx, QModelIndex()); - else if (idx.row() > row) - changePersistentIndex(idx, index(idx.row() - 1, idx.column())); - } - + beginRemoveRows(ItemToIndex(root_), idx.row(), idx.row()); + devices_.removeAll(info); + root_->Delete(info->row); endRemoveRows(); } else { // It's still attached, set the name and icon back to what they were @@ -603,21 +618,24 @@ void DeviceManager::Forget(int row) { info->LoadIcon(info->BestBackend()->lister_->DeviceIcons(id), info->friendly_name_); - dataChanged(index(row, 0), index(row, 0)); + dataChanged(idx, idx); } } -void DeviceManager::SetDeviceOptions(int row, const QString& friendly_name, +void DeviceManager::SetDeviceOptions(QModelIndex idx, + const QString& friendly_name, const QString& icon_name, MusicStorage::TranscodeMode mode, Song::FileType format) { - DeviceInfo* info = devices_[row]; + if (!idx.isValid()) return; + DeviceInfo* info = IndexToItem(idx); + if (!info) return; info->friendly_name_ = friendly_name; info->LoadIcon(QVariantList() << icon_name, friendly_name); info->transcode_mode_ = mode; info->transcode_format_ = format; - emit dataChanged(index(row, 0), index(row, 0)); + emit dataChanged(idx, idx); if (info->database_id_ != -1) backend_->SetDeviceOptions(info->database_id_, friendly_name, icon_name, @@ -648,38 +666,41 @@ void DeviceManager::TasksChanged() { for (const TaskManager::Task& task : tasks) { if (!active_tasks_.contains(task.id)) continue; - QPersistentModelIndex index = active_tasks_[task.id]; - if (!index.isValid()) continue; + QPersistentModelIndex idx = active_tasks_[task.id]; + if (!idx.isValid()) continue; - DeviceInfo* info = IndexToItem(index); + DeviceInfo* info = IndexToItem(idx); if (task.progress_max) info->task_percentage_ = float(task.progress) / task.progress_max * 100; else info->task_percentage_ = 0; - emit dataChanged(index, index); - finished_tasks.removeAll(index); + emit dataChanged(idx, idx); + finished_tasks.removeAll(idx); } - for (const QPersistentModelIndex& index : finished_tasks) { - if (!index.isValid()) continue; + for (const QPersistentModelIndex& idx : finished_tasks) { + if (!idx.isValid()) continue; - DeviceInfo* info = devices_[index.row()]; + DeviceInfo* info = IndexToItem(idx); + if (!info) continue; info->task_percentage_ = -1; - emit dataChanged(index, index); + emit dataChanged(idx, idx); - active_tasks_.remove(active_tasks_.key(index)); + active_tasks_.remove(active_tasks_.key(idx)); } } -void DeviceManager::UnmountAsync(int row) { - Q_ASSERT(QMetaObject::invokeMethod(this, "Unmount", Q_ARG(int, row))); +void DeviceManager::UnmountAsync(QModelIndex idx) { + Q_ASSERT(QMetaObject::invokeMethod(this, "Unmount", Q_ARG(QModelIndex, idx))); } -void DeviceManager::Unmount(int row) { - DeviceInfo* info = devices_[row]; +void DeviceManager::Unmount(QModelIndex idx) { + if (!idx.isValid()) return; + DeviceInfo* info = IndexToItem(idx); + if (!info) return; if (info->database_id_ != -1 && !info->device_) return; - if (info->device_) Disconnect(row); + if (info->device_) Disconnect(idx); if (info->BestBackend()->lister_) info->BestBackend()->lister_->UnmountDevice( @@ -690,13 +711,13 @@ void DeviceManager::DeviceSongCountUpdated(int count) { ConnectedDevice* device = qobject_cast(sender()); if (!device) return; - int row = FindDeviceById(device->unique_id()); - if (row == -1) return; + DeviceInfo* info = FindDeviceById(device->unique_id()); + if (!info) return; - QModelIndex index = ItemToIndex(devices_[row]); - if (!index.isValid()) return; + QModelIndex idx = ItemToIndex(info); + if (!idx.isValid()) return; - emit dataChanged(index, index); + emit dataChanged(idx, idx); } void DeviceManager::LazyPopulate(DeviceInfo* parent, bool signal) { diff --git a/src/devices/devicemanager.h b/src/devices/devicemanager.h index 8a13aa9fc..595a5d5c7 100644 --- a/src/devices/devicemanager.h +++ b/src/devices/devicemanager.h @@ -72,33 +72,35 @@ class DeviceManager : public SimpleTreeModel { } // Get info about devices - int GetDatabaseId(int row) const; - DeviceLister* GetLister(int row) const; - std::shared_ptr GetConnectedDevice(int row) const; + int GetDatabaseId(const QModelIndex& idx) const; + DeviceLister* GetLister(QModelIndex idx) const; + std::shared_ptr GetConnectedDevice(QModelIndex idx) const; + std::shared_ptr GetConnectedDevice(DeviceInfo* info) const; - int FindDeviceById(const QString& id) const; - int FindDeviceByUrl(const QList& url) const; + DeviceInfo* FindDeviceById(const QString& id) const; + DeviceInfo* FindDeviceByUrl(const QList& url) const; // Actions on devices - std::shared_ptr Connect(int row); - void Disconnect(int row); - void Forget(int row); - void UnmountAsync(int row); + std::shared_ptr Connect(DeviceInfo* info); + std::shared_ptr Connect(QModelIndex idx); + void Disconnect(QModelIndex idx); + void Forget(QModelIndex idx); + void UnmountAsync(QModelIndex idx); - void SetDeviceOptions(int row, const QString& friendly_name, + void SetDeviceOptions(QModelIndex idx, const QString& friendly_name, const QString& icon_name, MusicStorage::TranscodeMode mode, Song::FileType format); // QAbstractItemModel - QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; + QVariant data(const QModelIndex& idx, int role = Qt::DisplayRole) const; public slots: - void Unmount(int row); + void Unmount(QModelIndex idx); -signals: - void DeviceConnected(int row); - void DeviceDisconnected(int row); + signals: + void DeviceConnected(QModelIndex idx); + void DeviceDisconnected(QModelIndex idx); private slots: void PhysicalDeviceAdded(const QString& id); diff --git a/src/devices/deviceproperties.cpp b/src/devices/deviceproperties.cpp index a469525fb..70fd872a6 100644 --- a/src/devices/deviceproperties.cpp +++ b/src/devices/deviceproperties.cpp @@ -59,7 +59,7 @@ void DeviceProperties::SetDeviceManager(DeviceManager* manager) { SLOT(ModelChanged())); } -void DeviceProperties::ShowDevice(int row) { +void DeviceProperties::ShowDevice(QModelIndex idx) { if (ui_->icon->count() == 0) { // Only load the icons the first time the dialog is shown QStringList icon_names = QStringList() @@ -97,7 +97,7 @@ void DeviceProperties::ShowDevice(int row) { ui_->transcode_format->model()->sort(0); } - index_ = manager_->index(row, 0, QModelIndex()); + index_ = idx; // Basic information ui_->name->setText(index_.data(DeviceManager::Role_FriendlyName).toString()); @@ -137,7 +137,7 @@ void DeviceProperties::ModelChanged() { void DeviceProperties::UpdateHardwareInfo() { // Hardware information QString id = index_.data(DeviceManager::Role_UniqueId).toString(); - if (DeviceLister* lister = manager_->GetLister(index_.row())) { + if (DeviceLister* lister = manager_->GetLister(index_)) { QVariantMap info = lister->DeviceHardwareInfo(id); // Remove empty items @@ -180,9 +180,9 @@ void DeviceProperties::UpdateHardwareInfo() { void DeviceProperties::UpdateFormats() { QString id = index_.data(DeviceManager::Role_UniqueId).toString(); - DeviceLister* lister = manager_->GetLister(index_.row()); + DeviceLister* lister = manager_->GetLister(index_); std::shared_ptr device = - manager_->GetConnectedDevice(index_.row()); + manager_->GetConnectedDevice(index_); // Transcode mode MusicStorage::TranscodeMode mode = MusicStorage::TranscodeMode( @@ -255,11 +255,11 @@ void DeviceProperties::accept() { icon_name = ui_->icon->currentItem()->data(Qt::UserRole).toString(); } - manager_->SetDeviceOptions(index_.row(), ui_->name->text(), icon_name, mode, + manager_->SetDeviceOptions(index_, ui_->name->text(), icon_name, mode, format); } -void DeviceProperties::OpenDevice() { manager_->Connect(index_.row()); } +void DeviceProperties::OpenDevice() { manager_->Connect(index_); } void DeviceProperties::UpdateFormatsFinished(QFuture future) { updating_formats_ = false; diff --git a/src/devices/deviceproperties.h b/src/devices/deviceproperties.h index 11f8419c8..cf470cda6 100644 --- a/src/devices/deviceproperties.h +++ b/src/devices/deviceproperties.h @@ -35,7 +35,7 @@ class DeviceProperties : public QDialog { ~DeviceProperties(); void SetDeviceManager(DeviceManager* manager); - void ShowDevice(int row); + void ShowDevice(QModelIndex idx); public slots: void accept(); diff --git a/src/devices/deviceview.cpp b/src/devices/deviceview.cpp index b12e1f7f8..c9e0beb2c 100644 --- a/src/devices/deviceview.cpp +++ b/src/devices/deviceview.cpp @@ -167,10 +167,10 @@ void DeviceView::SetApplication(Application* app) { Q_ASSERT(app_ == nullptr); app_ = app; - connect(app_->device_manager(), SIGNAL(DeviceConnected(int)), - SLOT(DeviceConnected(int))); - connect(app_->device_manager(), SIGNAL(DeviceDisconnected(int)), - SLOT(DeviceDisconnected(int))); + connect(app_->device_manager(), SIGNAL(DeviceConnected(QModelIndex)), + SLOT(DeviceConnected(QModelIndex))); + connect(app_->device_manager(), SIGNAL(DeviceDisconnected(QModelIndex)), + SLOT(DeviceDisconnected(QModelIndex))); sort_model_ = new QSortFilterProxyModel(this); sort_model_->setSourceModel(app_->device_manager()); @@ -239,10 +239,9 @@ void DeviceView::contextMenuEvent(QContextMenuEvent* e) { const QModelIndex library_index = MapToLibrary(menu_index_); if (device_index.isValid()) { - const bool is_plugged_in = - app_->device_manager()->GetLister(device_index.row()); + const bool is_plugged_in = app_->device_manager()->GetLister(device_index); const bool is_remembered = - app_->device_manager()->GetDatabaseId(device_index.row()) != -1; + app_->device_manager()->GetDatabaseId(device_index) != -1; forget_action_->setEnabled(is_remembered); eject_action_->setEnabled(is_plugged_in); @@ -254,7 +253,7 @@ void DeviceView::contextMenuEvent(QContextMenuEvent* e) { bool is_filesystem_device = false; if (parent_device_index.isValid()) { std::shared_ptr device = - app_->device_manager()->GetConnectedDevice(parent_device_index.row()); + app_->device_manager()->GetConnectedDevice(parent_device_index); if (device && !device->LocalPath().isEmpty()) is_filesystem_device = true; } @@ -298,13 +297,12 @@ void DeviceView::Connect() { MusicStorage::Role_StorageForceConnect); } -void DeviceView::DeviceConnected(int row) { +void DeviceView::DeviceConnected(QModelIndex idx) { std::shared_ptr device = - app_->device_manager()->GetConnectedDevice(row); + app_->device_manager()->GetConnectedDevice(idx); if (!device) return; - QModelIndex sort_idx = - sort_model_->mapFromSource(app_->device_manager()->index(row, 0)); + QModelIndex sort_idx = sort_model_->mapFromSource(idx); QSortFilterProxyModel* sort_model = new QSortFilterProxyModel(device->model()); @@ -317,9 +315,8 @@ void DeviceView::DeviceConnected(int row) { expand(menu_index_); } -void DeviceView::DeviceDisconnected(int row) { - merged_model_->RemoveSubModel( - sort_model_->mapFromSource(app_->device_manager()->index(row, 0))); +void DeviceView::DeviceDisconnected(QModelIndex idx) { + merged_model_->RemoveSubModel(sort_model_->mapFromSource(idx)); } void DeviceView::Forget() { @@ -327,9 +324,8 @@ void DeviceView::Forget() { QString unique_id = app_->device_manager() ->data(device_idx, DeviceManager::Role_UniqueId) .toString(); - if (app_->device_manager()->GetLister(device_idx.row()) && - app_->device_manager()->GetLister(device_idx.row())->AskForScan( - unique_id)) { + if (app_->device_manager()->GetLister(device_idx) && + app_->device_manager()->GetLister(device_idx)->AskForScan(unique_id)) { std::unique_ptr dialog(new QMessageBox( QMessageBox::Question, tr("Forget device"), tr("Forgetting a device will remove it from this list and Clementine " @@ -342,11 +338,11 @@ void DeviceView::Forget() { if (dialog->clickedButton() != forget) return; } - app_->device_manager()->Forget(device_idx.row()); + app_->device_manager()->Forget(device_idx); } void DeviceView::Properties() { - properties_dialog_->ShowDevice(MapToDevice(menu_index_).row()); + properties_dialog_->ShowDevice(MapToDevice(menu_index_)); } void DeviceView::mouseDoubleClickEvent(QMouseEvent* event) { @@ -355,7 +351,7 @@ void DeviceView::mouseDoubleClickEvent(QMouseEvent* event) { QModelIndex merged_index = indexAt(event->pos()); QModelIndex device_index = MapToDevice(merged_index); if (device_index.isValid()) { - if (!app_->device_manager()->GetConnectedDevice(device_index.row())) { + if (!app_->device_manager()->GetConnectedDevice(device_index)) { menu_index_ = merged_index; Connect(); } @@ -436,7 +432,7 @@ void DeviceView::Organise() { void DeviceView::Unmount() { QModelIndex device_idx = MapToDevice(menu_index_); - app_->device_manager()->Unmount(device_idx.row()); + app_->device_manager()->Unmount(device_idx); } void DeviceView::DeleteFinished(const SongList& songs_with_errors) { diff --git a/src/devices/deviceview.h b/src/devices/deviceview.h index 92858c787..1647e8284 100644 --- a/src/devices/deviceview.h +++ b/src/devices/deviceview.h @@ -71,8 +71,8 @@ class DeviceView : public AutoExpandingTreeView { void Organise(); void Delete(); - void DeviceConnected(int row); - void DeviceDisconnected(int row); + void DeviceConnected(QModelIndex idx); + void DeviceDisconnected(QModelIndex idx); void DeleteFinished(const SongList& songs_with_errors); diff --git a/src/devices/filesystemdevice.cpp b/src/devices/filesystemdevice.cpp index 17ced6e27..3b1bd3ec0 100644 --- a/src/devices/filesystemdevice.cpp +++ b/src/devices/filesystemdevice.cpp @@ -40,7 +40,7 @@ FilesystemDevice::FilesystemDevice(const QUrl& url, DeviceLister* lister, watcher_->set_device_name( manager - ->data(manager->index(manager->FindDeviceById(unique_id), 0), + ->data(manager->ItemToIndex(manager->FindDeviceById(unique_id)), DeviceManager::Role_FriendlyName) .toString()); watcher_->set_backend(backend_);