covermanager.h 8.11 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/**
 * Copyright (C) 2005, 2008 Michael Pyne <mpyne@kde.org>
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */
16

Michael Pyne's avatar
Michael Pyne committed
17 18
#ifndef JUK_COVERMANAGER_H
#define JUK_COVERMANAGER_H
Michael Pyne's avatar
Michael Pyne committed
19

20
#include <QObject>
Michael Pyne's avatar
Michael Pyne committed
21
#include <QMimeData>
22
#include <QString>
23

Michael Pyne's avatar
Michael Pyne committed
24 25
#include <map>

26
class CoverManagerPrivate;
27
class CoverProxy;
28
class QPixmap;
29
class QTimer;
Michael Pyne's avatar
Michael Pyne committed
30
class QUrl;
31
class KJob;
32 33 34

template<class T>
class QList;
35

36 37 38 39 40 41 42 43 44 45 46
/**
 * This class saves the covers when its saveCovers() slot is called to avoid
 * making CoverManager a QObject and avoid moving the actual implementation
 * class (CoverManagerPrivate) to this .h file.  Used with a QTimer to save
 * the covers after changes are made.
 */
class CoverSaveHelper : public QObject
{
    Q_OBJECT

public:
Yuri Chornoivan's avatar
Yuri Chornoivan committed
47
    explicit CoverSaveHelper(QObject *parent);
48 49 50 51 52 53 54 55 56
    void saveCovers();

private slots:
    void commitChanges();

private:
    QTimer *m_timer;
};

57
/**
Michael Pyne's avatar
Michael Pyne committed
58
 * This class holds the data on a cover.
59 60 61 62
 * Don't assume that the artist or album information is filled out, it is
 * there to allow the CoverManager to try to automatically assign covers to
 * new tracks.
 */
Michael Pyne's avatar
Michael Pyne committed
63
class CoverData
64 65 66 67 68 69 70 71
{
public:
    QPixmap pixmap() const;
    QPixmap thumbnail() const;

    QString artist;
    QString album;
    QString path;
72 73

    unsigned refCount; // Refers to number of tracks using this.
74 75 76
};

typedef unsigned long coverKey; ///< Type of the id for a cover.
77

Michael Pyne's avatar
Michael Pyne committed
78 79
using CoverDataMap = std::map<coverKey, CoverData>;
using CoverDataMapIterator = typename CoverDataMap::const_iterator;
80 81 82

typedef QList<coverKey> CoverList;

Michael Pyne's avatar
Michael Pyne committed
83 84 85 86 87
/**
 * This class is used to drag covers in JuK.  It adds a special mimetype that
 * contains the cover ID used for this cover, and also supports an image/png
 * mimetype for dragging to other applications.
 *
Michael Pyne's avatar
Michael Pyne committed
88
 * The mimetype is "application/x-juk-coverid"
Michael Pyne's avatar
Michael Pyne committed
89
 *
90
 * @author Michael Pyne <mpyne@kde.org>
Michael Pyne's avatar
Michael Pyne committed
91
 */
Michael Pyne's avatar
Michael Pyne committed
92
class CoverDrag : public QMimeData
Michael Pyne's avatar
Michael Pyne committed
93
{
Michael Pyne's avatar
Michael Pyne committed
94
    Q_OBJECT
Michael Pyne's avatar
Michael Pyne committed
95

Michael Pyne's avatar
Michael Pyne committed
96
public:
Yuri Chornoivan's avatar
Yuri Chornoivan committed
97
    explicit CoverDrag(coverKey id);
Michael Pyne's avatar
Michael Pyne committed
98

99
    static const char* mimetype();
Michael Pyne's avatar
Michael Pyne committed
100

Michael Pyne's avatar
Michael Pyne committed
101 102 103 104 105
    static bool isCover(const QMimeData *data);

    // CoverDrag stores QByteArray data for the cover id, this can convert it
    // back.
    static coverKey idFromData(const QMimeData *data);
Michael Pyne's avatar
Michael Pyne committed
106 107
};

108 109 110 111 112 113 114 115 116 117 118 119
/**
 * This class holds all of the cover art, and manages looking it up by artist
 * and/or album.  This class is similar to a singleton class, but instead all
 * of the methods are static.  This way you can invoke methods like this:
 * \code
 *   CoverManager::method()
 * \endcode
 * instead of using:
 * \code
 *   CoverManager::instance()->method()
 * \endcode
 *
120
 * @author Michael Pyne <mpyne@kde.org>
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
 */
class CoverManager
{
public:
    /// The set of different sizes you can request a pixmap as.
    typedef enum { Thumbnail, FullSize } Size;

    /**
     * Tries to match @p artist and @p album to a cover in the database.
     *
     * @param artist The artist to look for matching covers on.
     * @param album The album to look for matching covers on.
     * @return NoMatch if no match could be found, otherwise the id of the
     *         cover art that matches the given metadata.
     */
    static coverKey idFromMetadata(const QString &artist, const QString &album);

    /**
     * Returns the cover art for @p id.
     *
     * @param id The id of the cover.
     * @param size The size to return it as.  Note that FullSize doesn't
     *             necessarily mean the pixmap is large, so you may need to
     *             scale it up.
     * @return QPixmap::null if there is no cover art for @p id, otherwise the
     *         cover art.
     */
    static QPixmap coverFromId(coverKey id, Size size = Thumbnail);

150 151 152 153
    /**
     * Returns the cover art for @p ptr.  This function is intended for use
     * by CoverData.
     *
Michael Pyne's avatar
Michael Pyne committed
154
     * @param ptr The CoverData to get the cover of.
155 156 157 158 159
     * @param size The size to return it as.
     * @see CoverData
     */
    static QPixmap coverFromData(const CoverData &coverData, Size size = Thumbnail);

160 161 162 163 164 165 166
    /**
     * Returns the full suite of information known about the cover given by
     * @p id.
     *
     * @param id the id of the cover to retrieve info on.
     * @return 0 if there is no info on @p id, otherwise its information.
     */
Michael Pyne's avatar
Michael Pyne committed
167
    static CoverData coverInfo(coverKey id);
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

    /**
     * Adds @p large to the cover database, associating with it @p artist and
     * @p album.
     *
     * @param large The full size cover (the thumbnail is automatically
     *              generated).
     * @param artist The artist of the new cover.
     * @param album  The album of the new cover.
     */
    static coverKey addCover(const QPixmap &large, const QString &artist = "", const QString &album = "");

    /**
     * Adds the file pointed to by the local path @p path to the database,
     * associating it with @p artist and @p album.
     *
     * @param path The absolute path to the fullsize cover art.
     * @param artist The artist of the new cover.
     * @param album  The album of the new cover.
     */
Michael Pyne's avatar
Michael Pyne committed
188
    static coverKey addCover(const QUrl &path, const QString &artist = "", const QString &album = "");
189 190 191

    /**
     * Function to determine if @p id matches any covers in the database.
192
     *
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
     * @param id The id of the cover to search for.
     * @return true if the database has a cover identified by @p id, false
     *         otherwise.
     */
    static bool hasCover(coverKey id);

    /**
     * Removes the cover identified by @p id.
     *
     * @param id the id of the cover to remove.
     * @return true if the removal was successful, false if unsuccessful or if
     *         the cover didn't exist.
     */
    static bool removeCover(coverKey id);

    /**
     * Replaces the cover art for the cover identified by @p id with @p large.
     * Any other metadata such as artist and album is unchanged.
     *
     * @param id The id of the cover to replace.
     * @param large The full size cover art for the new cover.
     */
    static bool replaceCover(coverKey id, const QPixmap &large);

217 218 219 220 221 222 223 224
    /**
     * Saves the current CoverManager information to disk.  Changes are not
     * automatically written to disk due to speed issues, so you can
     * periodically call this function while running to reduce the chance of
     * lost data in the event of a crash.
     */
    static void saveCovers();

225 226 227
    /**
     * @return Iterator pointing to the first element in the cover database.
     */
228
    static CoverDataMapIterator begin();
229 230 231 232

    /**
     * @return Iterator pointing after the last element in the cover database.
     */
233
    static CoverDataMapIterator end();
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256

    /**
     * Associates @p path with the cover identified by @id.  No comparison of
     * metadata is performed to enforce this matching.
     *
     * @param path The absolute file path to the track.
     * @param id The identifier of the cover to use with @p path.
     */
    static void setIdForTrack(const QString &path, coverKey id);

    /**
     * Returns the identifier of the cover for the track at @p path.
     *
     * @param path The absolute file path to the track.
     * @return NoMatch if @p path doesn't have a cover, otherwise the id of
     *         its cover.
     */
    static coverKey idForTrack(const QString &path);

    /**
     * This identifier is used to indicate that no cover was found in the
     * database.
     */
257
    static const coverKey NoMatch;
258 259

    private:
260 261 262 263
    friend class CoverProxy; // Our QObject-wielding friend.

    /// Called by CoverProxy to notify of a completed job.
    static void jobComplete(KJob *job, bool completedSatisfactory);
264 265 266 267
    static CoverManagerPrivate *data();
    static QPixmap createThumbnail(const QPixmap &base);
};

Michael Pyne's avatar
Michael Pyne committed
268
#endif /* JUK_COVERMANAGER_H */
Michael Pyne's avatar
Michael Pyne committed
269

270
// vim: set et sw=4 tw=0 sta: