1 /* This file is part of Clementine.
2 Copyright 2010, David Sansome <me@davidsansome.com>
3
4 Clementine is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 Clementine is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with Clementine. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifndef DEVICEMANAGER_H
19 #define DEVICEMANAGER_H
20
21 #include "devicedatabasebackend.h"
22
23 #include <memory>
24
25 #include <QAbstractItemModel>
26 #include <QIcon>
27 #include <QThreadPool>
28
29 #include "core/simpletreemodel.h"
30 #include "deviceinfo.h"
31 #include "library/librarymodel.h"
32
33 class Application;
34 class ConnectedDevice;
35 class DeviceLister;
36 class DeviceStateFilterModel;
37
38 class DeviceManager : public SimpleTreeModel<DeviceInfo> {
39 Q_OBJECT
40
41 public:
42 DeviceManager(Application* app, QObject* parent = nullptr);
43 ~DeviceManager();
44
45 enum Role {
46 Role_State = LibraryModel::LastRole,
47 Role_UniqueId,
48 Role_FriendlyName,
49 Role_Capacity,
50 Role_FreeSpace,
51 Role_IconName,
52 Role_UpdatingPercentage,
53 Role_MountPath,
54 Role_TranscodeMode,
55 Role_TranscodeFormat,
56 Role_SongCount,
57 LastRole,
58 };
59
60 enum State {
61 State_Remembered,
62 State_NotMounted,
63 State_NotConnected,
64 State_Connected,
65 };
66
67 static const int kDeviceIconSize;
68 static const int kDeviceIconOverlaySize;
69
connected_devices_model()70 DeviceStateFilterModel* connected_devices_model() const {
71 return connected_devices_model_;
72 }
73
74 // Get info about devices
75 int GetDatabaseId(const QModelIndex& idx) const;
76 DeviceLister* GetLister(QModelIndex idx) const;
77 std::shared_ptr<ConnectedDevice> GetConnectedDevice(QModelIndex idx) const;
78 std::shared_ptr<ConnectedDevice> GetConnectedDevice(DeviceInfo* info) const;
79
80 DeviceInfo* FindDeviceById(const QString& id) const;
81 DeviceInfo* FindDeviceByUrl(const QList<QUrl>& url) const;
82 DeviceInfo* FindEquivalentDevice(DeviceInfo* info) const;
83
84 // Actions on devices
85 std::shared_ptr<ConnectedDevice> Connect(DeviceInfo* info);
86 std::shared_ptr<ConnectedDevice> Connect(QModelIndex idx);
87 void Disconnect(QModelIndex idx);
88 void Forget(QModelIndex idx);
89 void UnmountAsync(QModelIndex idx);
90
91 void SetDeviceOptions(QModelIndex idx, const QString& friendly_name,
92 const QString& icon_name,
93 MusicStorage::TranscodeMode mode,
94 Song::FileType format);
95
96 // QAbstractItemModel
97 QVariant data(const QModelIndex& idx, int role = Qt::DisplayRole) const;
98
99 public slots:
100 void Unmount(QModelIndex idx);
101
102 signals:
103 void DeviceConnected(QModelIndex idx);
104 void DeviceDisconnected(QModelIndex idx);
105 void DeviceCreatedFromDb(DeviceInfo* info);
106
107 private slots:
108 void PhysicalDeviceAdded(const QString& id);
109 void PhysicalDeviceRemoved(const QString& id);
110 void PhysicalDeviceChanged(const QString& id);
111 void DeviceTaskStarted(int id);
112 void TasksChanged();
113 void DeviceSongCountUpdated(int count);
114 void LoadAllDevices();
115 void DeviceConnectFinished(const QString& id, bool success);
116 void AddDeviceFromDb(DeviceInfo* info);
117
118 protected:
LazyPopulate(DeviceInfo * item)119 void LazyPopulate(DeviceInfo* item) { LazyPopulate(item, true); }
120 void LazyPopulate(DeviceInfo* item, bool signal);
121
122 private:
123
124 void AddLister(DeviceLister* lister);
125 template <typename T>
126 void AddDeviceClass();
127
128 DeviceDatabaseBackend::Device InfoToDatabaseDevice(const DeviceInfo& info)
129 const;
130
131 private:
132 Application* app_;
133 DeviceDatabaseBackend* backend_;
134
135 DeviceStateFilterModel* connected_devices_model_;
136
137 QIcon not_connected_overlay_;
138
139 QList<DeviceLister*> listers_;
140 QList<DeviceInfo*> devices_;
141
142 QMultiMap<QString, QMetaObject> device_classes_;
143
144 // Map of task ID to device index
145 QMap<int, QPersistentModelIndex> active_tasks_;
146
147 QThreadPool thread_pool_;
148 };
149
150 template <typename T>
AddDeviceClass()151 void DeviceManager::AddDeviceClass() {
152 QStringList schemes = T::url_schemes();
153 QMetaObject obj = T::staticMetaObject;
154
155 for (const QString& scheme : schemes) {
156 device_classes_.insert(scheme, obj);
157 }
158 }
159
160 #endif // DEVICEMANAGER_H
161