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 24 #ifndef MTPDEVICE_H 25 #define MTPDEVICE_H 26 27 #include "fsdevice.h" 28 #include "mpd-interface/song.h" 29 #include "config.h" 30 #include "solid-lite/portablemediaplayer.h" 31 #include <libmtp.h> 32 33 class MusicLibraryItemRoot; 34 class Thread; 35 class QTemporaryFile; 36 37 class MtpConnection : public QObject 38 { 39 Q_OBJECT 40 public: 41 struct File { nameFile42 File(const QString &n=QString(), uint64_t s=0, uint32_t i=0) : name(n), size(s), id(i) { } 43 QString name; 44 uint64_t size; 45 uint32_t id; 46 }; 47 48 struct Folder { 49 Folder(const QString &pth=QString(), uint32_t i=0, uint32_t p=0, uint32_t s=0) pathFolder50 : path(pth) 51 , id(i) 52 , parentId(p) 53 , storageId(s) { 54 } 55 QString path; 56 uint32_t id; 57 uint32_t parentId; 58 uint32_t storageId; 59 QSet<uint32_t> folders; 60 QMap<uint32_t, File> files; 61 QMap<uint32_t, File> covers; 62 }; 63 64 struct Storage : public DeviceStorage { StorageStorage65 Storage() : id(0), musicFolderId(0) { } 66 uint32_t id; 67 uint32_t musicFolderId; 68 QString musicPath; 69 }; 70 71 MtpConnection(const QString &id, unsigned int bus, unsigned int dev, bool aaSupport); 72 virtual ~MtpConnection(); 73 isConnected()74 bool isConnected() const { return 0!=device; } 75 MusicLibraryItemRoot * takeLibrary(); capacity()76 uint64_t capacity() const { return size; } usedSpace()77 uint64_t usedSpace() const { return used; } 78 QList<DeviceStorage> getStorageList() const; 79 void emitProgress(int percent); 80 void trackListProgress(int percent); requestAbort(bool r)81 void requestAbort(bool r) { abortRequested=r; } abortWasRequested()82 bool abortWasRequested() const { return abortRequested; } 83 84 public Q_SLOTS: 85 void connectToDevice(); 86 void disconnectFromDevice(bool showStatus=true); 87 void updateLibrary(const DeviceOptions &opts); 88 void putSong(const Song &song, bool fixVa, const DeviceOptions &opts, bool overwrite, bool copyCover); 89 void getSong(const Song &song, const QString &dest, bool fixVa, bool copyCover); 90 void delSong(const Song &song); 91 void cleanDirs(const QSet<QString> &dirs); 92 void getCover(const Song &song); 93 void stop(); 94 95 Q_SIGNALS: 96 void statusMessage(const QString &message); 97 void putSongStatus(int, const QString &, bool, bool); 98 void getSongStatus(bool ok, bool copiedCover); 99 void delSongStatus(bool); 100 void cleanDirsStatus(bool ok); 101 void libraryUpdated(); 102 void progress(int); 103 void deviceDetails(const QString &serialNumber); 104 void updatePercentage(int); 105 void cover(const Song &s, const QImage &img); 106 107 private: 108 File getCoverDetils(const Song &s); 109 bool removeFolder(uint32_t folderId); 110 void updateFilesAndFolders(); 111 void listFolder(uint32_t storage, uint32_t parentDir, Folder *f=0); 112 void updateStorage(); 113 Storage & getStorage(const QString &volumeIdentifier); 114 Storage & getStorage(uint32_t id); 115 uint32_t createFolder(const QString &name, const QString &fullPath, uint32_t parentId, uint32_t storageId); 116 uint32_t getFolder(const QString &path, uint32_t storageId); 117 QString getPath(uint32_t folderId); 118 uint32_t checkFolderStructure(const QStringList &dirs, Storage &store); 119 void setMusicFolder(Storage &store); 120 #ifdef MTP_CLEAN_ALBUMS 121 void updateAlbums(); 122 LIBMTP_album_t * getAlbum(const Song &song); 123 #endif 124 void destroyData(); 125 126 private: 127 Thread *thread; 128 LIBMTP_mtpdevice_t *device; 129 #ifdef MTP_CLEAN_ALBUMS 130 LIBMTP_album_t *albums; 131 #endif 132 QMap<uint32_t, Folder> folderMap; 133 MusicLibraryItemRoot *library; 134 uint32_t defaultMusicFolder; 135 QList<Storage> storage; 136 uint64_t size; 137 uint64_t used; 138 int lastListPercent; 139 bool abortRequested; 140 unsigned int busNum; 141 unsigned int devNum; 142 bool supprtAlbumArtistTag; 143 }; 144 145 class MtpDevice : public Device 146 { 147 Q_OBJECT 148 149 public: 150 MtpDevice(MusicLibraryModel *m, Solid::Device &dev, unsigned int busNum, unsigned int devNum); 151 virtual ~MtpDevice(); 152 153 bool isConnected() const; isRefreshing()154 bool isRefreshing() const { return mtpUpdating; } 155 void stop(); 156 void configure(QWidget *parent); path()157 QString path() const { return QString(); } // audioFolder; } 158 void addSong(const Song &s, bool overwrite, bool copyCover); 159 void copySongTo(const Song &s, const QString &musicPath, bool overwrite, bool copyCover); 160 void removeSong(const Song &s); 161 void cleanDirs(const QSet<QString> &dirs); 162 Covers::Image requestCover(const Song &song); 163 double usedCapacity(); 164 QString capacityString(); 165 qint64 freeSpace(); devType()166 DevType devType() const { return Mtp; } 167 void saveOptions(); abortJob()168 void abortJob() { requestAbort(true); } 169 170 Q_SIGNALS: 171 // These are for talking to connection thread... 172 void updateLibrary(const DeviceOptions &opts); 173 void putSong(const Song &song, bool fixVa, const DeviceOptions &opts, bool overwrite, bool copyCover); 174 void getSong(const Song &song, const QString &dest, bool fixVa, bool copyCover); 175 void delSong(const Song &song); 176 void cleanMusicDirs(const QSet<QString> &dirs); 177 void getCover(const Song &s); 178 void cover(const Song &s, const QImage &img); 179 180 private Q_SLOTS: 181 void deviceDetails(const QString &s); 182 void libraryUpdated(); 183 void rescan(bool full=true); 184 void putSongStatus(int status, const QString &file, bool fixedVa, bool copiedCover); 185 void transcodeSongResult(int status); 186 void transcodePercent(int percent); 187 void emitProgress(int); 188 void getSongStatus(bool ok, bool copiedCover); 189 void delSongStatus(bool ok); 190 void cleanDirsStatus(bool ok); 191 void saveProperties(const QString &newPath, const DeviceOptions &opts); 192 void saveProperties(); 193 194 private: 195 void deleteTemp(); requestAbort(bool r)196 void requestAbort(bool r) { if (connection) connection->requestAbort(r); jobAbortRequested=r; } 197 198 private: 199 Solid::PortableMediaPlayer *pmp; 200 MtpConnection *connection; 201 QTemporaryFile *tempFile; 202 Song currentSong; 203 bool mtpUpdating; 204 QString serial; 205 QString defaultName; 206 friend class MtpConnection; 207 }; 208 209 #endif 210