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