1 /**************************************************************************************** 2 * Copyright (c) 2009 Alejandro Wainzinger <aikawarazuni@gmail.com> * 3 * * 4 * This program is free software; you can redistribute it and/or modify it under * 5 * the terms of the GNU General Public License as published by the Free Software * 6 * Foundation; either version 2 of the License, or (at your option) any later * 7 * version. * 8 * * 9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 11 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 12 * * 13 * You should have received a copy of the GNU General Public License along with * 14 * this program. If not, see <http://www.gnu.org/licenses/>. * 15 ****************************************************************************************/ 16 17 #ifndef UMSCOLLECTION_H 18 #define UMSCOLLECTION_H 19 20 #include "collectionscanner/Directory.h" 21 #include "core/collections/Collection.h" 22 #include "core/meta/Observer.h" 23 #include "core-impl/collections/support/MemoryCollection.h" 24 25 #include <KDirWatch> 26 #include <QIcon> 27 #include <QDir> 28 #include <solid/device.h> 29 30 #include <QtGlobal> 31 #include <QTimer> 32 33 class GenericScanManager; 34 class UmsPodcastProvider; 35 class UmsCollection; 36 class QAction; 37 38 using namespace Collections; 39 40 class UmsCollectionFactory : public CollectionFactory 41 { 42 Q_PLUGIN_METADATA(IID AmarokPluginFactory_iid FILE "amarok_collection-umscollection.json") 43 Q_INTERFACES(Plugins::PluginFactory) 44 Q_OBJECT 45 46 public: 47 UmsCollectionFactory(); 48 ~UmsCollectionFactory() override; 49 50 void init() override; 51 52 private Q_SLOTS: 53 /** 54 * Called when solid notifier detects a new device has been added 55 */ 56 void slotAddSolidDevice( const QString &udi ); 57 58 /** 59 * Called when solid StorageAccess device we are interested in is mounted or 60 * unmounted 61 */ 62 void slotAccessibilityChanged( bool accessible, const QString &udi ); 63 64 /** 65 * Called when solid notifier detects a device has been removed 66 */ 67 void slotRemoveSolidDevice( const QString &udi ); 68 69 /** 70 * Like @see slotRemoveSolidDevice(), but instructs Collection to eject the 71 * device after it has performed necessary teardown operations. 72 * 73 * Called when user wants to unmount the device from for example Device Notifier 74 */ 75 void slotRemoveAndTeardownSolidDevice( const QString &udi ); 76 77 /** 78 * Called when "tracked" collection is destroyed 79 */ 80 void slotCollectionDestroyed( QObject *collection ); 81 82 private: 83 /** 84 * Checks whether a solid device is a USB mass-storage one 85 */ 86 bool identifySolidDevice( const QString &udi ) const; 87 88 /** 89 * Attempts to create appropriate collection for already identified solid device 90 * @param udi. Should Q_EMIT newCollection() if the collection was successfully 91 * created and should become visible to the user. 92 */ 93 void createCollectionForSolidDevice( const QString &udi ); 94 95 // maps device udi to active UMS collections 96 QMap<QString, UmsCollection *> m_collectionMap; 97 }; 98 99 class UmsCollection : public Collection, public Meta::Observer 100 { 101 Q_OBJECT 102 103 public: 104 // inherited methods 105 106 explicit UmsCollection( const Solid::Device &device ); 107 ~UmsCollection() override; 108 109 /* TrackProvider methods */ 110 bool possiblyContainsTrack( const QUrl &url ) const override; 111 Meta::TrackPtr trackForUrl( const QUrl &url ) override; 112 113 /* Collection methods */ 114 QueryMaker *queryMaker() override; 115 QString uidUrlProtocol() const override; 116 117 QString collectionId() const override; 118 QString prettyName() const override; 119 QIcon icon() const override; 120 121 bool hasCapacity() const override; 122 float usedCapacity() const override; 123 float totalCapacity() const override; 124 125 CollectionLocation *location() override; 126 127 bool isOrganizable() const override; 128 129 /* Capability-related methods */ 130 bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override; 131 Capabilities::Capability *createCapabilityInterface( 132 Capabilities::Capability::Type type ) override; 133 134 /* Meta::Observer methods */ 135 void metadataChanged( const Meta::TrackPtr &track ) override; 136 using Meta::Observer::metadataChanged; // silence compiler warning about hidder overloads 137 138 /* own methods */ musicUrl()139 const QUrl &musicUrl() const { return m_musicUrl; } podcastUrl()140 const QUrl &podcastUrl() const { return m_podcastUrl; } 141 142 /** 143 * Get location where track @param track should be transferred to. 144 * 145 * @param fileExtension new extension to use. Leave empty if you don't wish to 146 * change file extension 147 */ 148 QUrl organizedUrl( const Meta::TrackPtr &track, const QString &fileExtension = QString() ) const; 149 memoryCollection()150 QSharedPointer<MemoryCollection> memoryCollection() const { return m_mc; } 151 152 Q_SIGNALS: 153 /** 154 * Start a count-down that emits updated() signal after it expires. 155 * Resets the timer to original timeout if already running. This is to ensure 156 * that we Q_EMIT update() max. once per \<timeout\> for batch updates. 157 * 158 * Timers can only be started from "their" thread so use signals & slots for that. 159 */ 160 void startUpdateTimer(); 161 162 public Q_SLOTS: 163 /** 164 * Destroy the collection (by emitting remove) 165 */ 166 void slotDestroy(); 167 168 /** 169 * Destroy the collection and try to eject the device from system 170 */ 171 void slotEject(); 172 173 void slotTrackAdded( const QUrl &trackLocation ); 174 void slotTrackRemoved( const Meta::TrackPtr &track ); 175 176 private Q_SLOTS: 177 /** 178 * Update m_lastUpdated timestamp and Q_EMIT updated() 179 */ 180 void collectionUpdated(); 181 182 void slotParseTracks(); 183 void slotParseActionTriggered(); 184 void slotConfigure(); 185 186 void slotDirectoryScanned( QSharedPointer<CollectionScanner::Directory> dir ); 187 188 /** 189 * Starts a timer that ensures we Q_EMIT updated() signal sometime in future. 190 */ 191 void slotStartUpdateTimer(); 192 193 private: 194 /** extended constructor */ 195 void init(); 196 197 //static variables relating to the on-disk configuration file 198 static QString s_settingsFileName; 199 static QString s_musicFolderKey; 200 static QString s_musicFilenameSchemeKey; 201 static QString s_vfatSafeKey; 202 static QString s_asciiOnlyKey; 203 static QString s_postfixTheKey; 204 static QString s_replaceSpacesKey; 205 static QString s_regexTextKey; 206 static QString s_replaceTextKey; 207 static QString s_podcastFolderKey; 208 static QString s_autoConnectKey; 209 static QString s_collectionName; 210 static QString s_transcodingGroup; 211 212 Solid::Device m_device; 213 QSharedPointer<MemoryCollection> m_mc; 214 bool m_tracksParsed; 215 216 bool m_autoConnect; 217 QString m_mountPoint; 218 QUrl m_musicUrl; 219 QUrl m_podcastUrl; 220 QString m_musicFilenameScheme; 221 bool m_vfatSafe; 222 bool m_asciiOnly; 223 bool m_postfixThe; 224 bool m_replaceSpaces; 225 QString m_regexText; 226 QString m_replaceText; 227 QString m_collectionName; 228 QString m_collectionId; 229 230 GenericScanManager *m_scanManager; 231 KDirWatch m_watcher; 232 233 QStringList m_supportedMimeTypes; 234 235 UmsPodcastProvider *m_podcastProvider; 236 237 QAction *m_parseAction; 238 QAction *m_configureAction; 239 QAction *m_ejectAction; 240 QTimer m_updateTimer; 241 qint64 m_lastUpdated; /* msecs since epoch */ 242 }; 243 244 #endif 245