1 #pragma once
2 
3 #include <QAbstractItemModel>
4 #include <QDesktopServices>
5 #include <QFileDialog>
6 #include <QIcon>
7 #include <QList>
8 #include <QModelIndex>
9 #include <QObject>
10 #include <QString>
11 #include <QUrl>
12 #include <QVariant>
13 #include <QtDebug>
14 
15 #include "library/coverartcache.h"
16 #include "library/dao/trackdao.h"
17 #include "library/treeitemmodel.h"
18 #include "track/track_decl.h"
19 
20 class KeyboardEventFilter;
21 class Library;
22 class TrackModel;
23 class WLibrary;
24 class WLibrarySidebar;
25 
26 // pure virtual (abstract) class to provide an interface for libraryfeatures
27 class LibraryFeature : public QObject {
28   Q_OBJECT
29   public:
30     LibraryFeature(
31             Library* pLibrary,
32             UserSettingsPointer pConfig);
33     ~LibraryFeature() override = default;
34 
35     virtual QVariant title() = 0;
36     virtual QIcon getIcon() = 0;
37 
dropAccept(const QList<QUrl> & urls,QObject * pSource)38     virtual bool dropAccept(const QList<QUrl>& urls, QObject* pSource) {
39         Q_UNUSED(urls);
40         Q_UNUSED(pSource);
41         return false;
42     }
dropAcceptChild(const QModelIndex & index,const QList<QUrl> & urls,QObject * pSource)43     virtual bool dropAcceptChild(const QModelIndex& index,
44             const QList<QUrl>& urls,
45             QObject* pSource) {
46         Q_UNUSED(index);
47         Q_UNUSED(urls);
48         Q_UNUSED(pSource);
49         return false;
50     }
dragMoveAccept(const QUrl & url)51     virtual bool dragMoveAccept(const QUrl& url) {
52         Q_UNUSED(url);
53         return false;
54     }
dragMoveAcceptChild(const QModelIndex & index,const QUrl & url)55     virtual bool dragMoveAcceptChild(const QModelIndex& index, const QUrl& url) {
56         Q_UNUSED(index);
57         Q_UNUSED(url);
58         return false;
59     }
60 
61     // Reimplement this to register custom views with the library widget.
bindLibraryWidget(WLibrary *,KeyboardEventFilter *)62     virtual void bindLibraryWidget(WLibrary* /* libraryWidget */,
63                             KeyboardEventFilter* /* keyboard */) {}
bindSidebarWidget(WLibrarySidebar *)64     virtual void bindSidebarWidget(WLibrarySidebar* /* sidebar widget */) {}
65     virtual TreeItemModel* getChildModel() = 0;
66 
hasTrackTable()67     virtual bool hasTrackTable() {
68         return false;
69     }
70 
71   protected:
getPlaylistFiles()72     QStringList getPlaylistFiles() const {
73         return getPlaylistFiles(QFileDialog::ExistingFiles);
74     }
getPlaylistFile()75     QString getPlaylistFile() const {
76         const QStringList playListFiles = getPlaylistFiles();
77         if (playListFiles.isEmpty()) {
78             return QString(); // no file chosen
79         } else {
80             return playListFiles.first();
81         }
82     }
83 
84     Library* const m_pLibrary;
85 
86     const UserSettingsPointer m_pConfig;
87 
88   public slots:
89     // called when you single click on the root item
90     virtual void activate() = 0;
91     // called when you single click on a child item, e.g., a concrete playlist or crate
activateChild(const QModelIndex & index)92     virtual void activateChild(const QModelIndex& index) {
93         Q_UNUSED(index);
94     }
95     // called when you right click on the root item
onRightClick(const QPoint & globalPos)96     virtual void onRightClick(const QPoint& globalPos) {
97         Q_UNUSED(globalPos);
98     }
99     // called when you right click on a child item, e.g., a concrete playlist or crate
onRightClickChild(const QPoint & globalPos,const QModelIndex & index)100     virtual void onRightClickChild(const QPoint& globalPos, const QModelIndex& index) {
101         Q_UNUSED(globalPos);
102         Q_UNUSED(index);
103     }
104     // Only implement this, if using incremental or lazy childmodels, see BrowseFeature.
105     // This method is executed whenever you **double** click child items
onLazyChildExpandation(const QModelIndex & index)106     virtual void onLazyChildExpandation(const QModelIndex& index) {
107         Q_UNUSED(index);
108     }
109   signals:
110     void showTrackModel(QAbstractItemModel* model);
111     void switchToView(const QString& view);
112     void loadTrack(TrackPointer pTrack);
113     void loadTrackToPlayer(TrackPointer pTrack, const QString& group, bool play = false);
114     void restoreSearch(const QString&);
115     void disableSearch();
116     // emit this signal before you parse a large music collection, e.g., iTunes, Traktor.
117     // The second arg indicates if the feature should be "selected" when loading starts
118     void featureIsLoading(LibraryFeature*, bool selectFeature);
119     // emit this signal if the foreign music collection has been imported/parsed.
120     void featureLoadingFinished(LibraryFeature*s);
121     // emit this signal to select pFeature
122     void featureSelect(LibraryFeature* pFeature, const QModelIndex& index);
123     // emit this signal to enable/disable the cover art widget
124     void enableCoverArtDisplay(bool);
125     void trackSelected(TrackPointer pTrack);
126 
127   protected:
128     // TODO: Move common crate/playlist functions into
129     // a separate base class
130     static bool exportPlaylistItemsIntoFile(
131             QString playlistFilePath,
132             const QList<QString>& playlistItemLocations,
133             bool useRelativePath);
134 
135   private:
136     QStringList getPlaylistFiles(QFileDialog::FileMode mode) const;
137 };
138