1 /****************************************************************************************
2  * Copyright (c) 2007-2008 Maximilian Kossick <maximilian.kossick@googlemail.com>       *
3  *                                                                                      *
4  * This program is free software; you can redistribute it and/or modify it under        *
5  * the terms of the GNU General Public License as published by the Free Software        *
6  * Foundation; either version 2 of the License, or (at your option) any later           *
7  * version.                                                                             *
8  *                                                                                      *
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
11  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
12  *                                                                                      *
13  * You should have received a copy of the GNU General Public License along with         *
14  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
15  ****************************************************************************************/
16 
17 #ifndef AMAROK_COLLECTIONMANAGER_H
18 #define AMAROK_COLLECTIONMANAGER_H
19 
20 #include "amarok_export.h"
21 #include "core/meta/forward_declarations.h"
22 
23 #include <QUrl>
24 
25 #include <QList>
26 #include <QObject>
27 
28 
29 namespace Plugins {
30     class PluginFactory;
31 }
32 
33 namespace Collections {
34     class Collection;
35     class CollectionFactory;
36     class TrackProvider;
37     class QueryMaker;
38 }
39 
40 /** Class managing the different collections.
41  *
42  *  This singleton class is the main repository for all current collections.
43  *  The most useful functions are probably queryMaker and
44  *  viewableCollections
45  */
46 class AMAROK_EXPORT CollectionManager : public QObject
47 {
48     Q_OBJECT
49 
50     public:
51 
52         /**
53          * defines the status of a collection in respect to global queries (i.e. queries that query all known collections)
54          * or the collection browser.
55          */
56         enum CollectionStatus { CollectionDisabled = 1, ///< Collection neither viewable nor queryable (but might produce tracks that can be played)
57                                 CollectionViewable = 2, ///< Collection will not be queried by CollectionManager::queryMaker
58                                 CollectionQueryable= 4, ///< Collection wil not show up in the browser, but is queryable by global queries
59                                 CollectionEnabled = CollectionViewable | CollectionQueryable ///< Collection viewable in the browser and queryable
60         };
61         Q_ENUM( CollectionStatus )
62 
63         static CollectionManager *instance();
64 
65         /** Destroys the instance of the CollectionManager.
66          */
67         static void destroy();
68 
69         /**
70          * Returns a query maker that queries all queryable the collections
71          */
72         Collections::QueryMaker *queryMaker() const;
73 
74         /**
75          * returns all viewable collections.
76          */
77         QList<Collections::Collection*> viewableCollections() const;
78 
79         //TODO: Remove
80         /**
81           * Allows access to one of Amarok's collection.
82           *
83           * @deprecated DO NOT USE this method. This is legacy code from the early days of Amarok
84           * when SqlCollection was the only working collection. If you are writing new code, make
85           * sure that it is able to handle multiple collections,
86           * e.g. multiple connected media devices. Using this method means you are lazy. An easy way
87           * is to use CollectionManager::queryMaker(). Alternatively, access the available collections
88           * using CollectionManager::queryableCollections() or CollectionManager::viewableCollections()
89           * and do whatever you want to.
90           *
91           */
92         Collections::Collection* primaryCollection() const;
93 
94         /**
95             This method will try to get a Track object for the given url. This method will return 0 if no Track object
96             could be created for the url.
97         */
98         Meta::TrackPtr trackForUrl( const QUrl &url );
99 
100         CollectionStatus collectionStatus( const QString &collectionId ) const;
101 
102         QHash<Collections::Collection*, CollectionStatus> collections() const;
103 
104         /**
105          * adds a TrackProvider to the list of TrackProviders,
106          * which allows CollectionManager to create tracks in trackForUrl.
107          * CollectionManager does not take ownership of the TrackProvider pointer
108          *
109          * Note: collections that CollectionManager knows about are automatically
110          * added to the list of TrackProviders.
111          *
112          * @param provider the new TrackProvider
113          */
114         void addTrackProvider( Collections::TrackProvider *provider );
115 
116         /**
117          * removes a TrackProvider. Does not do anything if
118          * CollectionManager does not know the given TrackProvider.
119          *
120          * Note: collections will be automatically removed from
121          * the list of available TrackProviders.
122          *
123          * @param provider the provider to be removed
124          */
125         void removeTrackProvider( Collections::TrackProvider *provider );
126 
127         /**
128          * Set the list of current factories
129          *
130          * For every factory that is a CollectionFactory uses it to create new
131          * collections and register with this manager.
132          */
133         void setFactories( const QList<QSharedPointer<Plugins::PluginFactory> > &factories );
134 
135     public Q_SLOTS:
136         /** Starts the full scan for each collection with CollectionScanCapability */
137         void startFullScan();
138         /** Starts the incremental scan for each collection with CollectionScanCapability */
139         void startIncrementalScan( const QString &directory = QString() );
140         void stopScan();
141         void checkCollectionChanges();
142 
143     Q_SIGNALS:
144         //deprecated, use collectionAdded( Collections::Collection*, CollectionStatus ) instead
145 //         void collectionAdded( Collections::Collection *newCollection );
146 
147         void collectionAdded( Collections::Collection *newCollection, CollectionManager::CollectionStatus status );
148         void collectionRemoved( const QString &collectionId );
149         void trackProviderAdded( Collections::TrackProvider *provider );
150         //this signal will be emitted after major changes to the collection
151         //e.g. new songs where added, or an album changed
152         //from compilation to non-compilation (and vice versa)
153         //it will not be emitted on minor changes (e.g. the tags of a song were changed)
154         void collectionDataChanged( Collections::Collection *changedCollection );
155 
156     private Q_SLOTS:
157         /** Will be called whenever a registered collection factory creates a new collection */
158         void slotNewCollection( Collections::Collection *newCollection );
159         /** Will remove the collection that emitted the signal */
160         void slotRemoveCollection();
161         void slotCollectionChanged();
162 
163     private:
164         static CollectionManager* s_instance;
165         CollectionManager();
166         ~CollectionManager() override;
167 
168         void init();
169 
170 
171         Q_DISABLE_COPY( CollectionManager )
172 
173         struct Private;
174         Private * const d;
175 };
176 
177 #endif /* AMAROK_COLLECTIONMANAGER_H */
178