1 /**************************************************************************************** 2 * Copyright (c) 2007 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_COLLECTION_QUERYMAKER_H 18 #define AMAROK_COLLECTION_QUERYMAKER_H 19 20 #include "core/amarokcore_export.h" 21 #include "core/meta/forward_declarations.h" 22 #include "core/meta/support/MetaConstants.h" 23 24 #include <QObject> 25 #include <QStringList> 26 #include <QtGlobal> 27 28 namespace Collections { 29 30 class AMAROKCORE_EXPORT QueryMaker : public QObject 31 { 32 Q_OBJECT 33 34 public: 35 enum AlbumQueryMode { 36 AllAlbums, 37 OnlyCompilations , 38 OnlyNormalAlbums 39 }; 40 41 enum LabelQueryMode { 42 NoConstraint, 43 OnlyWithLabels, 44 OnlyWithoutLabels 45 }; 46 47 enum ArtistMatchBehaviour { 48 TrackArtists, 49 AlbumArtists, 50 AlbumOrTrackArtists 51 }; 52 53 /** 54 * Filters that the QueryMaker accepts for searching. 55 * not all implementations will accept all filter levels, so make it possible to 56 * specify which ones make sense for a given qm. Add to this as needed 57 */ 58 enum ValidFilters { 59 TitleFilter = 1, 60 AlbumFilter = 2, 61 ArtistFilter = 4, 62 AlbumArtistFilter = 8, 63 GenreFilter = 16, 64 ComposerFilter = 32, 65 YearFilter = 64, 66 UrlFilter = 128, 67 AllFilters = 65535 68 }; 69 70 enum ReturnFunction { 71 Count, 72 Sum, 73 Max, 74 Min 75 }; 76 77 enum NumberComparison { 78 Equals, 79 GreaterThan, 80 LessThan 81 }; 82 83 enum QueryType { 84 None, // Set to facilitate using this in subclasses 85 Track, 86 Artist, 87 Album, 88 AlbumArtist, 89 Genre, 90 Composer, 91 Year, 92 Custom, 93 Label 94 }; 95 QueryMaker(); 96 ~QueryMaker() override; 97 98 /** 99 * starts the query. This method returns immediately. All processing is done in one or more 100 * separate worker thread(s). One of the newResultReady signals will be emitted at least once, 101 * followed by the queryDone() signal exactly once. 102 */ 103 virtual void run() = 0; 104 /** 105 * aborts a running query. Calling this method aborts a running query as soon as possible. 106 * This method returns immediately. No signals will be emitted after calling this method. 107 * This method has no effect if no query is running. 108 */ 109 virtual void abortQuery() = 0; 110 111 /** 112 * Sets the type of objects the querymaker will query for. These are mutually 113 * exclusive. The results of the query will be returned as objects of the 114 * appropriate type, therefore it is necessary to connect the client to the 115 * newResultReady( Meta::Type ) signal 116 * 117 * if you set QueryType custom, this starts a custom query. Unlike other query types, you have to set up the return 118 * values yourself using addReturnValue( qint64 ) and addReturnFunction(). The results will 119 * be returned as a QStringList. Therefore you have to connect to the 120 * newResultReady( QStringList ) signal to receive the results. 121 * @return this 122 */ 123 virtual QueryMaker* setQueryType( QueryType type ) = 0; 124 125 /** 126 * only works after starting a custom query with setQueryType( Custom ) 127 * Use this to inform the query maker you are looking for results of type @p value. 128 * @param value the type of the results 129 * @return this 130 */ 131 virtual QueryMaker* addReturnValue( qint64 value ) = 0; 132 /** 133 * Returns the output of the function specified by function. 134 * Only works after starting a custom query 135 * @return this 136 */ 137 virtual QueryMaker* addReturnFunction( ReturnFunction function, qint64 value ) = 0; 138 /** 139 * Return results sorted by @p value. 140 * @return this 141 */ 142 virtual QueryMaker* orderBy( qint64 value, bool descending = false ) = 0; 143 144 virtual QueryMaker* addMatch( const Meta::TrackPtr &track ) = 0; 145 /** 146 * Match given artist. Depending on @param behaviour matches: 147 * @p track artist if TrackArtists is given, 148 * @p album artist if AlbumArtists is given, 149 * any of track or album artist if AlbumOrTrackArtists is given. 150 * 151 * By default matches only track artist. 152 * @param artist the track artist. 153 */ 154 virtual QueryMaker* addMatch( const Meta::ArtistPtr &artist, ArtistMatchBehaviour behaviour = TrackArtists ) = 0; 155 virtual QueryMaker* addMatch( const Meta::AlbumPtr &album ) = 0; 156 virtual QueryMaker* addMatch( const Meta::ComposerPtr &composer ) = 0; 157 virtual QueryMaker* addMatch( const Meta::GenrePtr &genre ) = 0; 158 virtual QueryMaker* addMatch( const Meta::YearPtr &year ) = 0; 159 virtual QueryMaker* addMatch( const Meta::LabelPtr &label ); 160 161 /** 162 * Add a filter of type @p value and value @p filter. The querymaker applies this to all queries. 163 * @param value the type of the filter 164 * @param filter the text to match 165 * @param matchBegin If set then wildcard match the beginning of @p text (*text) 166 * @param matchEnd If set then wildcard match the end of @p text (text*) 167 * @return this 168 */ 169 virtual QueryMaker* addFilter( qint64 value, const QString &filter, bool matchBegin = false, bool matchEnd = false ) = 0; 170 /** 171 * Exclude filter of type @p value and value @p filter. The querymaker applies this to all queries. 172 * @param value the type of the filter 173 * @param filter the text to match 174 * @param matchBegin If set then wildcard match the beginning of @p text (*text) 175 * @param matchEnd If set then wildcard match the end of @p text (text*) 176 * @return this 177 */ 178 virtual QueryMaker* excludeFilter( qint64 value, const QString &filter, bool matchBegin = false, bool matchEnd = false ) = 0; 179 180 virtual QueryMaker* addNumberFilter( qint64 value, qint64 filter, NumberComparison compare ) = 0; 181 virtual QueryMaker* excludeNumberFilter( qint64 value, qint64 filter, NumberComparison compare ) = 0; 182 183 /** 184 * limit the maximum number of items in a result. the result will have [0..@p size ] items. When this function 185 * is not used, the result size is unbounded. Note: the maximum size applies to each result individually, so if 186 * the newResultReady signal is emitted multiple times, each result may have up to @p size items. 187 */ 188 virtual QueryMaker* limitMaxResultSize( int size ) = 0; 189 190 /** 191 * select the mode for querying albums. If this method is not called, 192 * QueryMaker defaults to AlbumQueryMode::AllAlbums. 193 */ 194 virtual QueryMaker* setAlbumQueryMode( AlbumQueryMode mode ); 195 196 /** 197 * Sets the label query mode. This method restricts a query to tracks 198 * that have labels assigned to them, no labels assigned to them, or no constraint. 199 * The default is no constraint. 200 * @param mode The LabelQueryMode that will be used by the query. 201 * @see LabelQueryMode 202 */ 203 virtual QueryMaker* setLabelQueryMode( LabelQueryMode mode ); 204 205 virtual QueryMaker* beginAnd() = 0; 206 virtual QueryMaker* beginOr() = 0; 207 virtual QueryMaker* endAndOr() = 0; 208 209 /** 210 * Choose whether the query maker instance should delete itself after the query. 211 * By passing true the query maker instance will delete itself after emitting queryDone(). 212 * Otherwise it is the responsibility of the owner (the code which called \::queryMaker() usually) to delete the instance 213 * when it is not needed anymore. 214 * 215 * Defaults to false, i.e. the querymaker instance will not delete itself. 216 */ 217 QueryMaker* setAutoDelete( bool autoDelete ); 218 219 virtual int validFilterMask(); 220 221 Q_SIGNALS: 222 /** 223 * newResultReady will be emitted every time new results from the query maker are received. 224 * This signal can be emitted zero times (in case of no results) one (the usual case) or multiple times 225 * (e.g. in case when the result is received in several batches). 226 * The results will be terminated by a queryDone signal. 227 */ 228 void newResultReady( const QStringList &); 229 void newTracksReady( const Meta::TrackList &); 230 void newArtistsReady( const Meta::ArtistList &); 231 void newAlbumsReady( const Meta::AlbumList &); 232 void newGenresReady( const Meta::GenreList &); 233 void newComposersReady( const Meta::ComposerList &); 234 void newYearsReady( const Meta::YearList &); 235 void newLabelsReady( const Meta::LabelList &); 236 void newDataReady( const Meta::DataList &); 237 238 /** 239 * This signal is emitted after all the results have been submitted via zero or more newResultReady signals. 240 */ 241 void queryDone(); 242 }; 243 244 } //namespace Collections 245 246 Q_DECLARE_METATYPE( Collections::QueryMaker* ) 247 248 #endif /* AMAROK_COLLECTION_QUERYMAKER_H */ 249 250