File indexing completed on 2023-10-03 04:07:45

0001 /**
0002  * Copyright (C) 2004 Scott Wheeler <wheeler@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 PLAYLIST_COLLECTION_H
0018 #define PLAYLIST_COLLECTION_H
0019 
0020 #include "stringhash.h"
0021 #include "playlistinterface.h"
0022 
0023 #include <KDirLister>
0024 #include <KLocalizedString>
0025 
0026 #include <QPointer>
0027 #include <QKeySequence>
0028 #include <QVector>
0029 class QPixmap;
0030 class QStackedWidget;
0031 
0032 class QAction;
0033 
0034 class HistoryPlaylist;
0035 class UpcomingPlaylist;
0036 class SearchPlaylist;
0037 class DynamicPlaylist;
0038 class PlaylistItem;
0039 class Playlist;
0040 class PlayerManager;
0041 class FileHandle;
0042 
0043 
0044 typedef QVector<PlaylistItem *> PlaylistItemList;
0045 typedef QVector<Playlist *> PlaylistList;
0046 
0047 class PlaylistCollection : public PlaylistInterface
0048 {
0049     friend class Playlist;
0050     friend class CollectionList;
0051     friend class DynamicPlaylist;
0052 
0053 public:
0054     class ActionHandler;
0055     friend PlaylistCollection::ActionHandler;
0056 
0057     PlaylistCollection(PlayerManager *player, QStackedWidget *playlistStack);
0058     virtual ~PlaylistCollection();
0059 
0060     static PlaylistCollection *instance() { return m_instance; }
0061 
0062     virtual QString name() const override;
0063     virtual FileHandle currentFile() const override;
0064     virtual int count() const override;
0065     virtual int time() const override;
0066     virtual void playNext() override;
0067     virtual void playPrevious() override;
0068     virtual void stop() override;
0069     virtual bool playing() const override;
0070 
0071     void playFirst();
0072     void playNextAlbum();
0073 
0074     virtual QStringList playlists() const;
0075     virtual void createPlaylist(const QString &name);
0076     virtual void createDynamicPlaylist(const PlaylistList &playlists);
0077     virtual void showMore(const QString &artist, const QString &album = QString());
0078     virtual void removeTrack(const QString &playlist, const QStringList &files);
0079 
0080     virtual QString playlist() const;
0081     virtual QString playingPlaylist() const;
0082     virtual void setPlaylist(const QString &playlist);
0083 
0084     virtual QStringList playlistTracks(const QString &playlist) const;
0085     virtual QString trackProperty(const QString &file, const QString &property) const;
0086     virtual QPixmap trackCover(const QString &file, const QString &size = "Small") const;
0087 
0088     virtual void open(const QStringList &files = QStringList());
0089     virtual void open(const QString &playlist, const QStringList &files);
0090     virtual void addFolder();
0091     virtual void rename();
0092     virtual void duplicate();
0093     virtual void save();
0094     virtual void saveAs();
0095     virtual void remove() = 0;
0096     virtual void reload();
0097     virtual void editSearch();
0098     virtual void setDynamicListsFrozen(bool) = 0;
0099 
0100     bool showMoreActive() const;
0101     void clearShowMore(bool raise = true);
0102     void enableDirWatch(bool enable);
0103 
0104     void removeItems();
0105     void refreshItems();
0106     void openItemDir();
0107     void renameItems();
0108     void addCovers(bool fromFile);
0109     void addLocalCover();
0110     void addInternetCover();
0111     void removeCovers();
0112     void viewCovers();
0113     void showCoverManager();
0114 
0115     virtual PlaylistItemList selectedItems();
0116 
0117     // virtual to allow our QWidget subclass to emit a signal after we're done
0118     virtual void scanFolders();
0119 
0120     // Must be implemented by subclasses and is used to request a file
0121     // start playback
0122     virtual bool requestPlaybackFor(const FileHandle &file) = 0;
0123 
0124     void createPlaylist();
0125     void createSearchPlaylist();
0126     void createFolderPlaylist();
0127 
0128     void guessTagFromFile();
0129     void guessTagFromInternet();
0130 
0131     void setSearchEnabled(bool enable);
0132 
0133     HistoryPlaylist *historyPlaylist() const;
0134     void setHistoryPlaylistEnabled(bool enable);
0135 
0136     UpcomingPlaylist *upcomingPlaylist() const;
0137     void setUpcomingPlaylistEnabled(bool enable);
0138 
0139     void dirChanged(const QString &path);
0140 
0141     /**
0142      * Returns a pointer to the action handler.
0143      */
0144     ActionHandler *collectionActions() const;
0145 
0146     void newItems(const KFileItemList &list) const;
0147 
0148     /**
0149      * This is the current playlist in all things relating to the player.  It
0150      * represents the playlist that either should be played from or is currently
0151      * playing.
0152      */
0153     virtual Playlist *currentPlaylist() const;
0154 
0155     /**
0156      * This is the currently visible playlist and should be used for all user
0157      * interaction elements.
0158      */
0159     virtual Playlist *visiblePlaylist() const;
0160 
0161     /**
0162      * Makes \a playlist the currently visible playlist.
0163      */
0164     virtual void raise(Playlist *playlist);
0165 
0166     /**
0167      * @return true, if a playlist with the file name given in @p file is
0168      * already loaded into this collection, or false otherwise.
0169      *
0170      * @note @p file should be the "canonical" full path to the file to avoid
0171      * problems with duplicates and symlinks.
0172      */
0173     bool containsPlaylistFile(const QString &file) const;
0174 
0175     /**
0176      * @return list of folders to exclude from automatic searching (whether
0177      * by directory-change watchers or the startup folder scan). The user should
0178      * still be able to manually add files even under an excluded folder.
0179      */
0180     QStringList excludedFolders() const { return m_excludedFolderList; }
0181 
0182 protected:
0183     virtual QStackedWidget *playlistStack() const;
0184     virtual void setupPlaylist(Playlist *playlist, const QString &iconName);
0185     virtual void removePlaylist(Playlist *playlist) = 0;
0186 
0187     bool importPlaylists() const;
0188 
0189     QString playlistNameDialog(const QString &caption = i18n("Create New Playlist"),
0190                                const QString &suggest = QString(),
0191                                bool forceUnique = true) const;
0192     QString uniquePlaylistName(const QString &suggest = i18n("Playlist")) const;
0193 
0194     void addNameToDict(const QString &name);
0195     void addFileToDict(const QString &file);
0196     void removeNameFromDict(const QString &name);
0197     void removeFileFromDict(const QString &file);
0198 
0199     Playlist *playlistByName(const QString &name) const;
0200 
0201 private:
0202     void readConfig();
0203     void saveConfig();
0204 
0205     QStackedWidget   *m_playlistStack;
0206     HistoryPlaylist  *m_historyPlaylist;
0207     UpcomingPlaylist *m_upcomingPlaylist;
0208     ActionHandler    *m_actionHandler;
0209     PlayerManager    *m_playerManager;
0210 
0211     KDirLister  m_dirLister;
0212     StringHash  m_playlistNames;
0213     StringHash  m_playlistFiles;
0214     QStringList m_folderList;
0215     QStringList m_excludedFolderList;
0216     bool        m_importPlaylists;
0217     bool        m_searchEnabled;
0218     bool        m_playing;
0219 
0220     QPointer<SearchPlaylist> m_showMorePlaylist;
0221     QPointer<Playlist> m_belowShowMorePlaylist;
0222     QPointer<DynamicPlaylist> m_dynamicPlaylist;
0223     QPointer<Playlist> m_belowDistraction;
0224 
0225     QWidget *m_distraction;
0226 
0227     static PlaylistCollection *m_instance;
0228 };
0229 
0230 /**
0231  * This class is just used as a proxy to handle the signals coming from action
0232  * activations without requiring PlaylistCollection to be a QObject.
0233  */
0234 
0235 class PlaylistCollection::ActionHandler : public QObject
0236 {
0237     Q_OBJECT
0238 public:
0239     ActionHandler(PlaylistCollection *collection);
0240 
0241 private:
0242     // This is variadic but it's only used to help dispatch at compile time to
0243     // slots that accept 0 params or 1 param (a bool) from QAction::triggered
0244     template<typename ... PMFArg>
0245     QAction *createAction(const QString &text,
0246                           void (PlaylistCollection::*slot)(PMFArg...),
0247                           const char *name,
0248                           const QString &icon = QString(),
0249                           const QKeySequence &shortcut = QKeySequence());
0250 private slots:
0251     void slotPlayFirst()     { m_collection->playFirst(); }
0252 
0253     void slotOpen()         { m_collection->open(); }
0254     void slotSave()         { m_collection->save(); }
0255     void slotSaveAs()       { m_collection->saveAs(); }
0256 
0257     void slotSetSearchEnabled(bool enable)           { m_collection->setSearchEnabled(enable); }
0258 
0259 signals:
0260     void signalSelectedItemsChanged();
0261     void signalCountChanged();
0262 
0263 private:
0264     PlaylistCollection *m_collection;
0265 };
0266 
0267 #endif
0268 
0269 // vim: set et sw=4 tw=0 sta: