File indexing completed on 2025-01-05 04:26:00
0001 /**************************************************************************************** 0002 * Copyright (c) 2012 Matěj Laitl <matej@laitl.cz * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #ifndef IPODCOLLECTION_H 0018 #define IPODCOLLECTION_H 0019 0020 #include "ui_IpodConfiguration.h" 0021 #include "core/collections/Collection.h" 0022 #include "core/meta/Observer.h" 0023 0024 #include <QMutex> 0025 #include <QSharedPointer> 0026 #include <QTimer> 0027 0028 namespace Collections { class MemoryCollection; } 0029 namespace IpodMeta { class Track; } 0030 class IphoneMountPoint; 0031 class IpodParseTracksJob; 0032 class IpodWriteDatabaseJob; 0033 class IpodPlaylistProvider; 0034 class QDir; 0035 class QTemporaryFile; 0036 struct _Itdb_iTunesDB; 0037 typedef _Itdb_iTunesDB Itdb_iTunesDB; 0038 0039 namespace Playlists 0040 { 0041 class UserPlaylistProvider; 0042 } 0043 0044 class IpodCollection : public Collections::Collection, public Meta::Observer 0045 { 0046 Q_OBJECT 0047 0048 public: 0049 /** 0050 * Creates an iPod collection on top of already-mounted filesystem. 0051 * 0052 * @param mountPoint actual iPod mount point to use, must be already mounted and 0053 * accessible. When eject is requested, solid StorageAccess with this mount point 0054 * is searched for to perform unmounting. 0055 * @param uuid filesystem volume UUID or another unique identifier for this iPod 0056 */ 0057 explicit IpodCollection( const QDir &mountPoint, const QString &uuid ); 0058 0059 /** 0060 * Creates an iPod collection on top of not-mounted iPhone/iPad by accessing it 0061 * using libimobiledevice by its 40-digit device UUID. UUID may be empty which 0062 * means "any connected iPhone/iPad". 0063 */ 0064 explicit IpodCollection( const QString &uuid ); 0065 0066 virtual ~IpodCollection(); 0067 0068 // TrackProvider methods: 0069 bool possiblyContainsTrack( const QUrl &url ) const override; 0070 Meta::TrackPtr trackForUrl( const QUrl &url ) override; 0071 0072 // CollectionBase methods: 0073 bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override; 0074 Capabilities::Capability* createCapabilityInterface( Capabilities::Capability::Type type ) override; 0075 0076 // Collection methods: 0077 Collections::QueryMaker *queryMaker() override; 0078 0079 QString uidUrlProtocol() const override; 0080 QString collectionId() const override; 0081 QString prettyName() const override; 0082 QIcon icon() const override; 0083 0084 bool hasCapacity() const override; 0085 float usedCapacity() const override; 0086 float totalCapacity() const override; 0087 0088 Collections::CollectionLocation *location() override; 0089 bool isWritable() const override; 0090 bool isOrganizable() const override; 0091 0092 // Observer methods: 0093 void metadataChanged( const Meta::TrackPtr &track ) override; 0094 // so that the compiler doesn't complain about hidden virtual functions: 0095 using Meta::Observer::metadataChanged; 0096 0097 // IpodCollection methods: 0098 /** 0099 * In-fact second phase of the constructor. Called by CollectionFactory right after 0100 * constructor. Should return true if the collection initialised itself successfully 0101 * and should be shown to the user; return value of false means it should be 0102 * destroyed and forgotten by the factory. 0103 */ 0104 bool init(); 0105 0106 /** 0107 * Get local mount point. Can return QString() in case no reasonable mountpoint 0108 * is available 0109 */ 0110 QString mountPoint(); 0111 0112 /** 0113 * Return number of bytes that should be kept free in iPod for database operations. 0114 * CollectionLocation should try hard not to occupy this safety margin. 0115 */ 0116 float capacityMargin() const; 0117 0118 /** 0119 * Return a list of file formats (compatible with Meta::Track::type()) current iPod 0120 * is able to play. 0121 */ 0122 QStringList supportedFormats() const; 0123 0124 /** 0125 * Return pointer to playlist provider associated with this iPod. May be null in 0126 * special cases (iPod not yet initialised etc.) 0127 */ 0128 Playlists::UserPlaylistProvider *playlistProvider() const; 0129 0130 Meta::TrackPtr trackForUidUrl( const QString &uidUrl ); 0131 0132 Q_SIGNALS: 0133 /** 0134 * Start a count-down that emits updated() signal after it expires. 0135 * Resets the timer to original timeout if already running. This is to ensure 0136 * that we Q_EMIT update() max. once per \<timeout\> for batch updates. 0137 * 0138 * Timers can only be started from "their" thread so use signals & slots for that. 0139 */ 0140 void startUpdateTimer(); 0141 0142 /** 0143 * Start a count-down that initiates iTunes database writing after it expires. 0144 * Resets the timer to original timeout if already running. This is to ensure 0145 * that we don't write the database all the time for batch updates. 0146 * 0147 * Timers can only be started from "their" thread so use signals & slots for that. 0148 */ 0149 void startWriteDatabaseTimer(); 0150 0151 public Q_SLOTS: 0152 /** 0153 * Destroy the collection, try to write back iTunes database (if dirty) 0154 */ 0155 void slotDestroy(); 0156 0157 /** 0158 * Destroy the collection, write back iTunes db (if dirty) and try to eject the 0159 * iPod from system 0160 */ 0161 void slotEject(); 0162 0163 /** 0164 * Shows the configuration dialog in a non-modal window. If m_itdb is null, shows 0165 * some info and a button to try to initialize iPod. 0166 */ 0167 void slotShowConfigureDialog(); 0168 0169 /** 0170 * Shows the configuration dialog in a non-modal window. If m_itdb is null, shows 0171 * some info and a button to try to initialize iPod. 0172 */ 0173 void slotShowConfigureDialogWithError( const QString &errorMessage ); 0174 0175 private Q_SLOTS: 0176 /** 0177 * Update m_lastUpdated timestamp and Q_EMIT updated() 0178 */ 0179 void collectionUpdated(); 0180 0181 /** 0182 * Tries to initialize iPod, read the database, add tracks. (Re)shows the 0183 * configuration dialog with info about initialization. 0184 */ 0185 void slotInitialize(); 0186 0187 /** 0188 * Sets iPod name to the name in configure dialog. 0189 */ 0190 void slotApplyConfiguration(); 0191 0192 /** 0193 * Starts a timer that ensures we Q_EMIT updated() signal sometime in future. 0194 */ 0195 void slotStartUpdateTimer(); 0196 0197 /** 0198 * Starts a timer that initiates iTunes database writing after 30 seconds. 0199 */ 0200 void slotStartWriteDatabaseTimer(); 0201 0202 /** 0203 * Enqueues a job in a thread that writes iTunes database back to iPod. Should 0204 * only be called from m_writeDatabaseTimer's timeout() signal. (with exception 0205 * when IpodCollection is about to destroy itself) 0206 */ 0207 void slotInitiateDatabaseWrite(); 0208 0209 /** 0210 * Tries to unmount underlying solid device. You must try to write database before 0211 * calling this. Emits remove() before returning. 0212 */ 0213 void slotPerformTeardownAndRemove(); 0214 0215 /** 0216 * Do sanity checks and Q_EMIT remove() so that this collection is destroyed by 0217 * CollectionManager. No other method is allowed to Q_EMIT remove()! 0218 */ 0219 void slotRemove(); 0220 0221 private: 0222 friend class IpodCopyTracksJob; 0223 friend class IpodDeleteTracksJob; 0224 friend class IpodParseTracksJob; 0225 friend class IpodWriteDatabaseJob; 0226 friend class IpodPlaylistProvider; 0227 0228 static const QString s_uidUrlProtocol; 0229 static const QStringList s_audioFileTypes; 0230 static const QStringList s_videoFileTypes; 0231 static const QStringList s_audioVideoFileTypes; 0232 0233 // method for IpodParseTracksJob and IpodCopyTracksJob: 0234 /** 0235 * Add an iPod track to the collection. 0236 * 0237 * This method adds it to the collection, master playlist (if not already there) 0238 * etc. The file must be already physically copied to iPod. (Re)Sets track's 0239 * collection to this collection. Takes ownership of the track (passes it to 0240 * AmarokSharedPointer) 0241 * 0242 * This method is thread-safe. 0243 * 0244 * @return pointer to newly added track if successful, null pointer otherwise 0245 */ 0246 Meta::TrackPtr addTrack( IpodMeta::Track *track ); 0247 0248 // method for IpodDeleteTracksJob: 0249 /** 0250 * Removes a track from iPod collection. Does not delete the file physically, 0251 * caller must do it after calling this method. 0252 * 0253 * @param track a track from associated MemoryCollection to delete. Accepts also 0254 * underlying IpodMeta::Track, this is treated as if MemoryMeta::Track track 0255 * proxy it was passed. 0256 * 0257 * This method is thread-safe. 0258 */ 0259 void removeTrack( const Meta::TrackPtr &track ); 0260 0261 // method for IpodWriteDatabaseJob and destructor: 0262 /** 0263 * Calls itdb_write() directly. Logs a message about success/failure in Amarok 0264 * interface. 0265 */ 0266 bool writeDatabase(); 0267 0268 QDialog *m_configureDialog; 0269 Ui::IpodConfiguration m_configureDialogUi; 0270 QSharedPointer<Collections::MemoryCollection> m_mc; 0271 /** 0272 * pointer to libgpod iTunes database. If null, this collection is invalid 0273 * (not yet initialised). Can only be changed with m_itdbMutex hold. 0274 */ 0275 Itdb_iTunesDB *m_itdb; 0276 QMutex m_itdbMutex; 0277 QTimer m_updateTimer; 0278 qint64 m_lastUpdated; /* msecs since epoch */ 0279 QTimer m_writeDatabaseTimer; 0280 QTemporaryFile *m_preventUnmountTempFile; 0281 QString m_mountPoint; 0282 QString m_uuid; 0283 IphoneMountPoint *m_iphoneAutoMountpoint; 0284 QString m_prettyName; 0285 IpodPlaylistProvider *m_playlistProvider; 0286 QAction *m_configureAction; 0287 QAction *m_ejectAction; 0288 QAction *m_consolidateAction; 0289 QPointer<IpodParseTracksJob> m_parseTracksJob; 0290 QPointer<IpodWriteDatabaseJob> m_writeDatabaseJob; 0291 }; 0292 0293 #endif // IPODCOLLECTION_H