covermanager.h 9.1 KB
Newer Older
1
/***************************************************************************
2
    begin                : Sun May 15 2005
Michael Pyne's avatar
Michael Pyne committed
3
    copyright            : (C) 2005, 2008 by Michael Pyne
4 5 6 7 8 9 10 11 12 13 14 15
    email                : michael.pyne@kdemail.net
***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

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

19 20
#include <ksharedptr.h>

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

class CoverManagerPrivate;
26
class CoverProxy;
27
class QPixmap;
28
class QTimer;
29
class KJob;
30 31 32 33 34 35

template<class Key, class Value>
class QMap;

template<class T>
class QList;
36

37 38
class KUrl;

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
/**
 * 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:
    CoverSaveHelper(QObject *parent);
    void saveCovers();

private slots:
    void commitChanges();

private:
    QTimer *m_timer;
};

60 61 62 63 64 65
/**
 * This class holds the data on a cover.  This includes the path to the cover
 * representation on-disk, and the artist and album associated with the cover.
 * 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.
66
 *
67 68 69 70 71 72 73 74 75 76 77 78
 * @author Michael Pyne <michael.pyne@kdemail.net>
 * @see CoverManager
 */
class CoverData : public KShared
{
public:
    QPixmap pixmap() const;
    QPixmap thumbnail() const;

    QString artist;
    QString album;
    QString path;
79 80

    unsigned refCount; // Refers to number of tracks using this.
81 82 83 84
};

typedef KSharedPtr<CoverData> CoverDataPtr;
typedef unsigned long coverKey; ///< Type of the id for a cover.
85

86 87
typedef QMap<coverKey, CoverDataPtr> CoverDataMap;

88 89 90 91 92
// I can't believe this actually works...
typedef CoverDataMap::const_iterator CoverDataMapIterator;

typedef QList<coverKey> CoverList;

Michael Pyne's avatar
Michael Pyne committed
93 94 95 96 97 98 99 100 101
/**
 * 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.
 *
 * As of this writing the mimetype is application/x-juk-coverid
 *
 * @author Michael Pyne <michael.pyne@kdemail.net>
 */
Michael Pyne's avatar
Michael Pyne committed
102
class CoverDrag : public QMimeData
Michael Pyne's avatar
Michael Pyne committed
103
{
Michael Pyne's avatar
Michael Pyne committed
104
    Q_OBJECT
Michael Pyne's avatar
Michael Pyne committed
105

Michael Pyne's avatar
Michael Pyne committed
106 107
public:
    CoverDrag(coverKey id);
Michael Pyne's avatar
Michael Pyne committed
108

109
    static const char* mimetype();
Michael Pyne's avatar
Michael Pyne committed
110

Michael Pyne's avatar
Michael Pyne committed
111 112 113 114 115
    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
116 117
};

118 119 120 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 150 151 152 153 154 155 156 157 158 159
/**
 * 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
 *
 * @author Michael Pyne <michael.pyne@kdemail.net>
 */
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);

160 161 162 163 164 165 166 167 168 169 170
    /**
     * Returns the cover art for @p ptr.  This function is intended for use
     * by CoverData.
     *
     * @param ptr The CoverData to get the cover of.  Note that it is a
     *            CoverData, not CoverDataPtr.
     * @param size The size to return it as.
     * @see CoverData
     */
    static QPixmap coverFromData(const CoverData &coverData, Size size = Thumbnail);

171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
    /**
     * 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.
     */
    static CoverDataPtr coverInfo(coverKey id);

    /**
     * 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.
     */
199
    static coverKey addCover(const KUrl &path, const QString &artist = "", const QString &album = "");
200 201 202

    /**
     * Function to determine if @p id matches any covers in the database.
203
     *
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
     * @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);

228 229 230 231 232 233 234 235
    /**
     * 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();

236 237 238 239 240 241 242 243 244 245
    /**
     * This is a hack, as we should be shut down automatically by
     * KStaticDeleter, but JuK is crashing for me on shutdown before
     * KStaticDeleter gets a chance to run, which is cramping my testing.
     */
    static void shutdown();

    /**
     * @return Iterator pointing to the first element in the cover database.
     */
246
    static CoverDataMapIterator begin();
247 248 249 250

    /**
     * @return Iterator pointing after the last element in the cover database.
     */
251
    static CoverDataMapIterator end();
252 253 254 255

    /**
     * @return A list of all of the id's listed in the database.
     */
256
    static CoverList keys();
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279

    /**
     * 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.
     */
280
    static const coverKey NoMatch;
281 282

    private:
283 284 285 286
    friend class CoverProxy; // Our QObject-wielding friend.

    /// Called by CoverProxy to notify of a completed job.
    static void jobComplete(KJob *job, bool completedSatisfactory);
287 288 289 290
    static CoverManagerPrivate *data();
    static QPixmap createThumbnail(const QPixmap &base);
};

Michael Pyne's avatar
Michael Pyne committed
291
#endif /* JUK_COVERMANAGER_H */
Michael Pyne's avatar
Michael Pyne committed
292

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