Skip to content

Commit

Permalink
Convert devices manager(model) to QAbstractItemModel (#6260)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaski authored and hatstand committed Jan 21, 2019
1 parent a82cc2f commit 7e25a7c
Show file tree
Hide file tree
Showing 9 changed files with 411 additions and 299 deletions.
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Expand Up @@ -137,6 +137,7 @@ set(SOURCES
devices/deviceview.cpp
devices/deviceviewcontainer.cpp
devices/filesystemdevice.cpp
devices/deviceinfo.cpp

engines/devicefinder.cpp
engines/enginebase.cpp
Expand Down Expand Up @@ -454,6 +455,7 @@ set(HEADERS
devices/deviceview.h
devices/deviceviewcontainer.h
devices/filesystemdevice.h
devices/deviceinfo.h

engines/enginebase.h
engines/gstengine.h
Expand Down
9 changes: 6 additions & 3 deletions src/devices/connecteddevice.cpp
Expand Up @@ -105,13 +105,16 @@ void ConnectedDevice::FinishDelete(bool) {
MusicStorage::TranscodeMode ConnectedDevice::GetTranscodeMode() const {
int index = manager_->FindDeviceById(unique_id_);
return MusicStorage::TranscodeMode(
manager_->index(index).data(DeviceManager::Role_TranscodeMode).toInt());
manager_->index(index, 0, QModelIndex())
.data(DeviceManager::Role_TranscodeMode)
.toInt());
}

Song::FileType ConnectedDevice::GetTranscodeFormat() const {
int index = manager_->FindDeviceById(unique_id_);
return Song::FileType(
manager_->index(index).data(DeviceManager::Role_TranscodeFormat).toInt());
return Song::FileType(manager_->index(index, 0, QModelIndex())
.data(DeviceManager::Role_TranscodeFormat)
.toInt());
}

void ConnectedDevice::BackendTotalSongCountUpdated(int count) {
Expand Down
124 changes: 124 additions & 0 deletions src/devices/deviceinfo.cpp
@@ -0,0 +1,124 @@
/* This file is part of Clementine.
Copyright 2010, David Sansome <me@davidsansome.com>
Clementine is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Clementine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/

#include "devicemanager.h"

#include <memory>

#include <QIcon>
#include <QPixmap>
#include <QString>
#include <QStringList>
#include <QVariant>

#include "config.h"
#include "core/logging.h"
#include "core/simpletreemodel.h"
#include "ui/iconloader.h"

#include "devicedatabasebackend.h"
#include "deviceinfo.h"
#include "devicelister.h"

DeviceDatabaseBackend::Device DeviceInfo::SaveToDb() const {
DeviceDatabaseBackend::Device ret;
ret.friendly_name_ = friendly_name_;
ret.size_ = size_;
ret.id_ = database_id_;
ret.icon_name_ = icon_name_;
ret.transcode_mode_ = transcode_mode_;
ret.transcode_format_ = transcode_format_;

QStringList unique_ids;
for (const Backend& backend : backends_) {
unique_ids << backend.unique_id_;
}
ret.unique_id_ = unique_ids.join(",");

return ret;
}

void DeviceInfo::InitFromDb(const DeviceDatabaseBackend::Device& dev) {
database_id_ = dev.id_;
friendly_name_ = dev.friendly_name_;
size_ = dev.size_;
transcode_mode_ = dev.transcode_mode_;
transcode_format_ = dev.transcode_format_;

QStringList icon_names = dev.icon_name_.split(',');
QVariantList icons;
for (const QString& icon_name : icon_names) {
icons << icon_name;
}

LoadIcon(icons, friendly_name_);

QStringList unique_ids = dev.unique_id_.split(',');
for (const QString& id : unique_ids) {
backends_ << Backend(nullptr, id);
}
}

const DeviceInfo::Backend* DeviceInfo::BestBackend() const {
int best_priority = -1;
const Backend* ret = nullptr;

for (int i = 0; i < backends_.count(); ++i) {
if (backends_[i].lister_ &&
backends_[i].lister_->priority() > best_priority) {
best_priority = backends_[i].lister_->priority();
ret = &(backends_[i]);
}
}

if (!ret && !backends_.isEmpty()) return &(backends_[0]);
return ret;
}

void DeviceInfo::LoadIcon(const QVariantList& icons, const QString& name_hint) {
if (icons.isEmpty()) {
icon_name_ = "drive-removable-media-usb-pendrive";
icon_ = IconLoader::Load(icon_name_, IconLoader::Base);
return;
}

// Try to load the icon with that exact name first
for (const QVariant& icon : icons) {
if (!icon.value<QPixmap>().isNull()) {
icon_ = QIcon(icon.value<QPixmap>());
return;
} else {
icon_ = IconLoader::Load(icon.toString(), IconLoader::Base);
if (!icon_.isNull()) {
icon_name_ = icon.toString();
return;
}
}
}

QString hint = QString(icons.first().toString() + name_hint).toLower();

// If that failed than try to guess if it's a phone or ipod. Fall back on
// a usb memory stick icon.
if (hint.contains("phone"))
icon_name_ = "phone";
else if (hint.contains("ipod") || hint.contains("apple"))
icon_name_ = "multimedia-player-ipod-standard-monochrome";
else
icon_name_ = "drive-removable-media-usb-pendrive";
icon_ = IconLoader::Load(icon_name_, IconLoader::Base);
}
108 changes: 108 additions & 0 deletions src/devices/deviceinfo.h
@@ -0,0 +1,108 @@
/* This file is part of Clementine.
Copyright 2010, David Sansome <me@davidsansome.com>
Clementine is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Clementine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef DEVICEINFO_H
#define DEVICEINFO_H

#include <memory>

#include <QIcon>
#include <QList>
#include <QString>
#include <QVariant>

#include "core/musicstorage.h"
#include "core/simpletreeitem.h"
#include "core/simpletreemodel.h"
#include "core/song.h"
#include "devicedatabasebackend.h"
#include "library/librarymodel.h"

class ConnectedDevice;
class DeviceLister;

// Devices can be in three different states:
// 1) Remembered in the database but not physically connected at the moment.
// database_id valid, lister null, device null
// 2) Physically connected but the user hasn't "connected" it to Clementine
// yet.
// database_id == -1, lister valid, device null
// 3) Physically connected and connected to Clementine
// database_id valid, lister valid, device valid
// Devices in all states will have a unique_id.
class DeviceInfo : public SimpleTreeItem<DeviceInfo> {
public:
enum Type {
Type_Root,
Type_Device,
};

DeviceInfo(SimpleTreeModel<DeviceInfo>* model)
: SimpleTreeItem<DeviceInfo>(Type_Root, model),
database_id_(-1),
size_(0),
transcode_mode_(MusicStorage::Transcode_Unsupported),
transcode_format_(Song::Type_Unknown),
task_percentage_(-1) {}

DeviceInfo(Type type, DeviceInfo* parent = nullptr)
: SimpleTreeItem<DeviceInfo>(type, parent),
database_id_(-1),
size_(0),
transcode_mode_(MusicStorage::Transcode_Unsupported),
transcode_format_(Song::Type_Unknown),
task_percentage_(-1) {}

// A device can be discovered in different ways (devicekit, gio, etc.)
// Sometimes the same device is discovered more than once. In this case
// the device will have multiple "backends".
struct Backend {
Backend(DeviceLister* lister = nullptr, const QString& id = QString())
: lister_(lister), unique_id_(id) {}

DeviceLister* lister_; // nullptr if not physically connected
QString unique_id_;
};

// Serialising to the database
void InitFromDb(const DeviceDatabaseBackend::Device& dev);
DeviceDatabaseBackend::Device SaveToDb() const;

// Tries to load a good icon for the device. Sets icon_name_ and icon_.
void LoadIcon(const QVariantList& icons, const QString& name_hint);

// Gets the best backend available (the one with the highest priority)
const Backend* BestBackend() const;

int database_id_; // -1 if not remembered in the database
std::shared_ptr<ConnectedDevice>
device_; // nullptr if not connected to clementine
QList<Backend> backends_;

QString friendly_name_;
quint64 size_;

QString icon_name_;
QIcon icon_;

MusicStorage::TranscodeMode transcode_mode_;
Song::FileType transcode_format_;

int task_percentage_;
};

#endif // DEVICEINFO_H

0 comments on commit 7e25a7c

Please sign in to comment.