File indexing completed on 2023-05-30 11:30:45

0001 /**
0002  * Copyright (C) 2005, 2008 Michael Pyne <mpyne@kde.org>
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 JUK_COVERMANAGER_H
0018 #define JUK_COVERMANAGER_H
0019 
0020 #include <QObject>
0021 #include <QMimeData>
0022 #include <QString>
0023 
0024 #include <map>
0025 
0026 class CoverManagerPrivate;
0027 class CoverProxy;
0028 class QPixmap;
0029 class QTimer;
0030 class QUrl;
0031 class KJob;
0032 
0033 template<class T>
0034 class QList;
0035 
0036 /**
0037  * This class saves the covers when its saveCovers() slot is called to avoid
0038  * making CoverManager a QObject and avoid moving the actual implementation
0039  * class (CoverManagerPrivate) to this .h file.  Used with a QTimer to save
0040  * the covers after changes are made.
0041  */
0042 class CoverSaveHelper : public QObject
0043 {
0044     Q_OBJECT
0045 
0046 public:
0047     explicit CoverSaveHelper(QObject *parent);
0048     void saveCovers();
0049 
0050 private slots:
0051     void commitChanges();
0052 
0053 private:
0054     QTimer *m_timer;
0055 };
0056 
0057 /**
0058  * This class holds the data on a cover.
0059  * Don't assume that the artist or album information is filled out, it is
0060  * there to allow the CoverManager to try to automatically assign covers to
0061  * new tracks.
0062  */
0063 class CoverData
0064 {
0065 public:
0066     QPixmap pixmap() const;
0067     QPixmap thumbnail() const;
0068 
0069     QString artist;
0070     QString album;
0071     QString path;
0072 
0073     unsigned refCount; // Refers to number of tracks using this.
0074 };
0075 
0076 typedef unsigned long coverKey; ///< Type of the id for a cover.
0077 
0078 using CoverDataMap = std::map<coverKey, CoverData>;
0079 using CoverDataMapIterator = typename CoverDataMap::const_iterator;
0080 
0081 typedef QList<coverKey> CoverList;
0082 
0083 /**
0084  * This class is used to drag covers in JuK.  It adds a special mimetype that
0085  * contains the cover ID used for this cover, and also supports an image/png
0086  * mimetype for dragging to other applications.
0087  *
0088  * The mimetype is "application/x-juk-coverid"
0089  *
0090  * @author Michael Pyne <mpyne@kde.org>
0091  */
0092 class CoverDrag : public QMimeData
0093 {
0094     Q_OBJECT
0095 
0096 public:
0097     explicit CoverDrag(coverKey id);
0098 
0099     static const char* mimetype();
0100 
0101     static bool isCover(const QMimeData *data);
0102 
0103     // CoverDrag stores QByteArray data for the cover id, this can convert it
0104     // back.
0105     static coverKey idFromData(const QMimeData *data);
0106 };
0107 
0108 /**
0109  * This class holds all of the cover art, and manages looking it up by artist
0110  * and/or album.  This class is similar to a singleton class, but instead all
0111  * of the methods are static.  This way you can invoke methods like this:
0112  * \code
0113  *   CoverManager::method()
0114  * \endcode
0115  * instead of using:
0116  * \code
0117  *   CoverManager::instance()->method()
0118  * \endcode
0119  *
0120  * @author Michael Pyne <mpyne@kde.org>
0121  */
0122 class CoverManager
0123 {
0124 public:
0125     /// The set of different sizes you can request a pixmap as.
0126     typedef enum { Thumbnail, FullSize } Size;
0127 
0128     /**
0129      * Tries to match @p artist and @p album to a cover in the database.
0130      *
0131      * @param artist The artist to look for matching covers on.
0132      * @param album The album to look for matching covers on.
0133      * @return NoMatch if no match could be found, otherwise the id of the
0134      *         cover art that matches the given metadata.
0135      */
0136     static coverKey idFromMetadata(const QString &artist, const QString &album);
0137 
0138     /**
0139      * Returns the cover art for @p id.
0140      *
0141      * @param id The id of the cover.
0142      * @param size The size to return it as.  Note that FullSize doesn't
0143      *             necessarily mean the pixmap is large, so you may need to
0144      *             scale it up.
0145      * @return QPixmap::null if there is no cover art for @p id, otherwise the
0146      *         cover art.
0147      */
0148     static QPixmap coverFromId(coverKey id, Size size = Thumbnail);
0149 
0150     /**
0151      * Returns the cover art for @p ptr.  This function is intended for use
0152      * by CoverData.
0153      *
0154      * @param ptr The CoverData to get the cover of.
0155      * @param size The size to return it as.
0156      * @see CoverData
0157      */
0158     static QPixmap coverFromData(const CoverData &coverData, Size size = Thumbnail);
0159 
0160     /**
0161      * Returns the full suite of information known about the cover given by
0162      * @p id.
0163      *
0164      * @param id the id of the cover to retrieve info on.
0165      * @return 0 if there is no info on @p id, otherwise its information.
0166      */
0167     static CoverData coverInfo(coverKey id);
0168 
0169     /**
0170      * Adds @p large to the cover database, associating with it @p artist and
0171      * @p album.
0172      *
0173      * @param large The full size cover (the thumbnail is automatically
0174      *              generated).
0175      * @param artist The artist of the new cover.
0176      * @param album  The album of the new cover.
0177      */
0178     static coverKey addCover(const QPixmap &large, const QString &artist = "", const QString &album = "");
0179 
0180     /**
0181      * Adds the file pointed to by the local path @p path to the database,
0182      * associating it with @p artist and @p album.
0183      *
0184      * @param path The absolute path to the fullsize cover art.
0185      * @param artist The artist of the new cover.
0186      * @param album  The album of the new cover.
0187      */
0188     static coverKey addCover(const QUrl &path, const QString &artist = "", const QString &album = "");
0189 
0190     /**
0191      * Function to determine if @p id matches any covers in the database.
0192      *
0193      * @param id The id of the cover to search for.
0194      * @return true if the database has a cover identified by @p id, false
0195      *         otherwise.
0196      */
0197     static bool hasCover(coverKey id);
0198 
0199     /**
0200      * Removes the cover identified by @p id.
0201      *
0202      * @param id the id of the cover to remove.
0203      * @return true if the removal was successful, false if unsuccessful or if
0204      *         the cover didn't exist.
0205      */
0206     static bool removeCover(coverKey id);
0207 
0208     /**
0209      * Replaces the cover art for the cover identified by @p id with @p large.
0210      * Any other metadata such as artist and album is unchanged.
0211      *
0212      * @param id The id of the cover to replace.
0213      * @param large The full size cover art for the new cover.
0214      */
0215     static bool replaceCover(coverKey id, const QPixmap &large);
0216 
0217     /**
0218      * Saves the current CoverManager information to disk.  Changes are not
0219      * automatically written to disk due to speed issues, so you can
0220      * periodically call this function while running to reduce the chance of
0221      * lost data in the event of a crash.
0222      */
0223     static void saveCovers();
0224 
0225     /**
0226      * @return Iterator pointing to the first element in the cover database.
0227      */
0228     static CoverDataMapIterator begin();
0229 
0230     /**
0231      * @return Iterator pointing after the last element in the cover database.
0232      */
0233     static CoverDataMapIterator end();
0234 
0235     /**
0236      * Associates @p path with the cover identified by @id.  No comparison of
0237      * metadata is performed to enforce this matching.
0238      *
0239      * @param path The absolute file path to the track.
0240      * @param id The identifier of the cover to use with @p path.
0241      */
0242     static void setIdForTrack(const QString &path, coverKey id);
0243 
0244     /**
0245      * Returns the identifier of the cover for the track at @p path.
0246      *
0247      * @param path The absolute file path to the track.
0248      * @return NoMatch if @p path doesn't have a cover, otherwise the id of
0249      *         its cover.
0250      */
0251     static coverKey idForTrack(const QString &path);
0252 
0253     /**
0254      * This identifier is used to indicate that no cover was found in the
0255      * database.
0256      */
0257     static const coverKey NoMatch;
0258 
0259     private:
0260     friend class CoverProxy; // Our QObject-wielding friend.
0261 
0262     /// Called by CoverProxy to notify of a completed job.
0263     static void jobComplete(KJob *job, bool completedSatisfactory);
0264     static CoverManagerPrivate *data();
0265     static QPixmap createThumbnail(const QPixmap &base);
0266 };
0267 
0268 #endif /* JUK_COVERMANAGER_H */
0269 
0270 // vim: set et sw=4 tw=0 sta: