1 /****************************************************************************************
2  * Copyright (c) 2012 Matěj Laitl <matej@laitl.cz>                                      *
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 STATSYNCING_PROVIDER_H
18 #define STATSYNCING_PROVIDER_H
19 
20 #include "amarok_export.h"
21 #include "statsyncing/Track.h"
22 
23 #include <QIcon>
24 #include <QMap>
25 #include <QSet>
26 #include <QString>
27 #include <QVariantMap>
28 #include <QWidget>
29 
30 namespace StatSyncing
31 {
32     /**
33      * A widget class used for configuring providers.
34      */
35     class AMAROK_EXPORT ProviderConfigWidget : public QWidget
36     {
37         Q_OBJECT
38 
39         public:
40             explicit ProviderConfigWidget( QWidget *parent, Qt::WindowFlags f = {} );
41             ~ProviderConfigWidget() override;
42 
43             /**
44              * Return a QVariantMap holding configuration for the provider. Types stored
45              * in QVariantMap must be supported by @see KConfigGroup .
46              */
47             virtual QVariantMap config() const = 0;
48     };
49 
50     /**
51      * A class that can provide tracks for statistics synchronization. It can be backed
52      * by local Amarok collections or by online services such as Last.fm.
53      *
54      * Instances of subclasses are guaranteed to be created in the main thread.
55      * Providers are memory-managed as explicitly shared data, always use ProviderPtr
56      * to store a reference to Provider.
57      */
58     class AMAROK_EXPORT Provider : public QObject
59     {
60         Q_OBJECT
61 
62         public:
63             Provider();
64             ~Provider() override;
65 
66             /**
67              * Unique identifier for this collection; may be used as a key to store
68              * configuration; must be thread-safe
69              */
70             virtual QString id() const = 0;
71 
72             /**
73              * User-visible name of the provider; must be thread-safe
74              */
75             virtual QString prettyName() const = 0;
76 
77             /**
78              * User-visible short localized description. Default implementation returns
79              * an empty string.
80              */
81             virtual QString description() const;
82 
83             /**
84              * Icon of this provider; must be thread-safe
85              */
86             virtual QIcon icon() const = 0;
87 
88             /**
89              * Return true if this provider can be reconfigured after creation. Returns
90              * false by default.
91              */
92             virtual bool isConfigurable() const;
93 
94             /**
95              * Return a ProviderConfigWidget of configuration widget for this provider.
96              * Returns a null pointer by default. Please note that Provider does *not*
97              * retain ownership of this pointer, therefore should always return a new
98              * instance.
99              */
100             virtual ProviderConfigWidget *configWidget();
101 
102             /**
103              * Reconfigure the provider using configuration stored in @p config.
104              * Does nothing by default.
105              *
106              * @param config the configuration
107              */
108             virtual void reconfigure( const QVariantMap &config );
109 
110             /**
111              * Return binary OR of Meta::val* fields that this provider knows about its
112              * tracks. Must include at least: Meta::valTitle, Meta::valArtist and
113              * Meta::valAlbum. Optional fields: Meta::valComposer, Meta::valYear
114              * Meta::valTrackNr and Meta::valDiscNr
115              */
116             virtual qint64 reliableTrackMetaData() const = 0;
117 
118             /**
119              * Return binary OR of Meta::val* fields that this provider can write back
120              * to tracks. Choose a combination of: Meta::valRating, valFirstPlayed,
121              * valLastPlayed, valPlaycount, valLabel.
122              */
123             virtual qint64 writableTrackStatsData() const = 0;
124 
125             enum Preference {
126                 Never, /// never synchronize automatically
127                 NoByDefault, /// don't synchronize automatically by default
128                 Ask, /// ask on first appearance whether to synchronize by default
129                 YesByDefault /// enable auto syncing on first appearance without asking
130                              /// intended only for Local Collection
131             };
132 
133             /**
134              * Return if this provider should participate in synchronization by
135              * default even when the user does not actively add it. User can always
136              * disable providers even if they are checked by default.
137              */
138             virtual Preference defaultPreference() = 0;
139 
140             /**
141              * Return a set of track artist names that appear in this provider. Multiple
142              * artists differing just in letter case are allowed, or rather mandated,
143              * because @see artistTracks() method is case-sensitive.
144              *
145              * This method must be called in non-main thread and is allowed to block for
146              * a longer time; it must be implemented in a reentrant manner.
147              */
148             virtual QSet<QString> artists() = 0;
149 
150             /**
151              * Return a list of track delegates from (track) artist @param artistName that
152              * appear in this provider; the matching should be performed CASE-SENSITIVELY
153              * and should match the whole string, not just substring. If you have multiple
154              * variants of the artist name differing just in letter case, you should
155              * return all of the variants in @see artists().
156              *
157              * This method must be called in non-main thread and is allowed to block for
158              * a longer time; it must be implemented in a reentrant manner.
159              */
160             virtual TrackList artistTracks( const QString &artistName ) = 0;
161 
162             /**
163              * Write back statistics to the underlying storage for all updated tracks
164              * managed by this provider that weren't yet saved. Default implementation
165              * does nothing.
166              *
167              * Guaranteed to be (and must be) called from non-main thread. Can block for
168              * a longer time.
169              */
170             virtual void commitTracks();
171 
172         Q_SIGNALS:
173             /**
174              * Emitted when some data such as prettyName() were updated.
175              */
176             void updated();
177     };
178 
179     typedef QSharedPointer<Provider> ProviderPtr;
180     typedef QList<ProviderPtr> ProviderPtrList;
181     typedef QSet<ProviderPtr> ProviderPtrSet;
182 
183     /**
184      * Container for a set of track frovider lists, one for each provider
185      */
186     typedef QMap<ProviderPtr, TrackList> PerProviderTrackList;
187 
188 } // namespace StatSyncing
189 
190 #endif // STATSYNCING_PROVIDER_H
191