1 /*
2  * Cantata
3  *
4  * Copyright (c) 2011-2020 Craig Drummond <craig.p.drummond@gmail.com>
5  *
6  * ----
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; see the file COPYING.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23 #ifndef DEVICES_MODEL_H
24 #define DEVICES_MODEL_H
25 
26 #include <QSet>
27 #include "mpd-interface/song.h"
28 #include "config.h"
29 #include "devices/remotefsdevice.h"
30 #include "musiclibrarymodel.h"
31 #include "devices/cdalbum.h"
32 #include "musiclibraryproxymodel.h"
33 
34 class QMimeData;
35 class Device;
36 class MirrorMenu;
37 
38 class DevicesModel : public MusicLibraryModel
39 {
40     Q_OBJECT
41 
42 public:
43     static DevicesModel * self();
44 
45     static void enableDebug();
46     static bool debugEnabled();
47     static QString fixDevicePath(const QString &path);
48 
49     DevicesModel(QObject *parent = nullptr);
50     ~DevicesModel() override;
51     QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override;
52     QModelIndex parent(const QModelIndex &index) const override;
53     QVariant headerData(int, Qt::Orientation, int = Qt::DisplayRole) const override { return QVariant(); }
54     int columnCount(const QModelIndex & = QModelIndex()) const override { return 1; }
55     int rowCount(const QModelIndex &parent=QModelIndex()) const override;
56     void getDetails(QSet<QString> &artists, QSet<QString> &albumArtists, QSet<QString> &composers, QSet<QString> &albums, QSet<QString> &genres);
57     QList<Song> songs(const QModelIndexList &indexes, bool playableOnly=false, bool fullPath=false) const;
58     QStringList filenames(const QModelIndexList &indexes, bool playableOnly=false, bool fullPath=false) const;
row(void * i)59     int row(void *i) const override { return collections.indexOf(static_cast<MusicLibraryItemRoot *>(i)); }
60     bool setData(const QModelIndex &index, const QVariant &value, int role) override;
61     QVariant data(const QModelIndex &, int) const override;
62     Qt::ItemFlags flags(const QModelIndex &index) const override;
63     QStringList playableUrls(const QModelIndexList &indexes) const;
64     void clear(bool clearConfig=true);
menu()65     MirrorMenu * menu() { return itemMenu; }
66     Device * device(const QString &udi);
isEnabled()67     bool isEnabled() const { return enabled; }
68     void setEnabled(bool e);
69     void stop();
70     QMimeData * mimeData(const QModelIndexList &indexes) const override;
71     #ifdef ENABLE_REMOTE_DEVICES
72     void unmountRemote();
73     #endif
74 
configureAct()75     Action * configureAct() const { return configureAction; }
refreshAct()76     Action * refreshAct() const { return refreshAction; }
connectAct()77     Action * connectAct() const { return connectAction; }
disconnectAct()78     Action * disconnectAct() const { return disconnectAction; }
79     #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND
editAct()80     Action * editAct() const { return editAction; }
81     void playCd(const QString &dev);
82     #endif
83 
84 private:
85     int indexOf(const QString &id);
86 
87 public Q_SLOTS:
88     void setCover(const Song &song, const QImage &img, const QString &file);
89     void setCover(const Song &song, const QImage &img);
90     void deviceAdded(const QString &udi);
91     void deviceRemoved(const QString &udi);
92     void accessibilityChanged(bool accessible, const QString &udi);
93     void deviceUpdating(const QString &udi, bool state);
94     void emitAddToDevice();
95     void addRemoteDevice(const DeviceOptions &opts, RemoteFsDevice::Details details);
96     void removeRemoteDevice(const QString &udi, bool removeFromConfig=true);
97     void remoteDeviceUdiChanged();
98     void mountsChanged();
99 
100 private:
101     void addLocalDevice(const QString &udi);
102     #ifdef ENABLE_REMOTE_DEVICES
103     void loadRemote();
104     #endif
105 
106 Q_SIGNALS:
107     void addToDevice(const QString &udi);
108     void error(const QString &text);
109     void updated(const QModelIndex &idx);
110     void matches(const QString &udi, const QList<CdAlbum> &albums);
111     void invalid(const QList<Song> &songs);
112     void updatedDetails(const QList<Song> &songs);
113     void add(const QStringList &files, int action, quint8 priority, bool decreasePriority); // add songs to MPD playqueue
114 
115 private Q_SLOTS:
116     void play(const QList<Song> &songs);
117     void loadLocal();
118     void updateItemMenu();
119 
120 private:
121     QList<MusicLibraryItemRoot *> collections;
122     QSet<QString> volumes;
123     MirrorMenu *itemMenu;
124     bool enabled;
125     bool inhibitMenuUpdate;
126     Action *configureAction;
127     Action *refreshAction;
128     Action *connectAction;
129     Action *disconnectAction;
130     #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND
131     QString autoplayCd;
132     Action *editAction;
133     #endif
134     friend class Device;
135 };
136 
137 #endif
138