File indexing completed on 2024-05-19 15:52:39

0001 /****************************************************************************************
0002  * Copyright (c) 2007 Maximilian Kossick <maximilian.kossick@googlemail.com>            *
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 AMAROK_COLLECTION_QUERYMAKER_H
0018 #define AMAROK_COLLECTION_QUERYMAKER_H
0019 
0020 #include "core/amarokcore_export.h"
0021 #include "core/meta/forward_declarations.h"
0022 #include "core/meta/support/MetaConstants.h"
0023 
0024 #include <QObject>
0025 #include <QStringList>
0026 #include <QtGlobal>
0027 
0028 namespace Collections {
0029 
0030 class AMAROKCORE_EXPORT QueryMaker : public QObject
0031 {
0032     Q_OBJECT
0033 
0034     public:
0035         enum AlbumQueryMode {
0036             AllAlbums,
0037             OnlyCompilations ,
0038             OnlyNormalAlbums
0039         };
0040 
0041         enum LabelQueryMode {
0042             NoConstraint,
0043             OnlyWithLabels,
0044             OnlyWithoutLabels
0045         };
0046 
0047         enum ArtistMatchBehaviour {
0048             TrackArtists,
0049             AlbumArtists,
0050             AlbumOrTrackArtists
0051         };
0052 
0053         /**
0054          * Filters that the QueryMaker accepts for searching.
0055          * not all implementations will accept all filter levels, so make it possible to
0056          * specify which ones make sense for a given qm. Add to this as needed
0057          */
0058         enum ValidFilters {
0059             TitleFilter = 1,
0060             AlbumFilter = 2,
0061             ArtistFilter = 4,
0062             AlbumArtistFilter = 8,
0063             GenreFilter = 16,
0064             ComposerFilter = 32,
0065             YearFilter = 64,
0066             UrlFilter = 128,
0067             AllFilters = 65535
0068         };
0069 
0070         enum ReturnFunction {
0071             Count,
0072             Sum,
0073             Max,
0074             Min
0075         };
0076 
0077         enum NumberComparison {
0078             Equals,
0079             GreaterThan,
0080             LessThan
0081         };
0082 
0083         enum QueryType {
0084             None, // Set to facilitate using this in subclasses
0085             Track,
0086             Artist,
0087             Album,
0088             AlbumArtist,
0089             Genre,
0090             Composer,
0091             Year,
0092             Custom,
0093             Label
0094         };
0095         QueryMaker();
0096         ~QueryMaker() override;
0097 
0098         /**
0099          *  starts the query. This method returns immediately. All processing is done in one or more
0100          *  separate worker thread(s). One of the newResultReady signals will be emitted at least once,
0101          *  followed by the queryDone() signal exactly once.
0102          */
0103         virtual void run() = 0;
0104         /**
0105          *  aborts a running query. Calling this method aborts a running query as soon as possible.
0106          *  This method returns immediately. No signals will be emitted after calling this method.
0107          *  This method has no effect if no query is running.
0108          */
0109         virtual void abortQuery() = 0;
0110 
0111         /**
0112          * Sets the type of objects the querymaker will query for.  These are mutually
0113          * exclusive.  The results of the query will be returned as objects of the
0114          * appropriate type, therefore it is necessary to connect the client to the
0115          * newResultReady( Meta::Type ) signal
0116          *
0117          * if you set QueryType custom, this starts a custom query. Unlike other query types, you have to set up the return
0118          * values yourself using addReturnValue( qint64 ) and addReturnFunction(). The results will
0119          * be returned as a QStringList. Therefore you have to connect to the
0120          * newResultReady( QStringList ) signal to receive the results.
0121          * @return this
0122          */
0123         virtual QueryMaker* setQueryType( QueryType type ) = 0;
0124 
0125         /**
0126           * only works after starting a custom query with setQueryType( Custom )
0127           * Use this to inform the query maker you are looking for results of type @p value.
0128           * @param value the type of the results
0129           * @return this
0130           */
0131         virtual QueryMaker* addReturnValue( qint64 value ) = 0;
0132         /**
0133          * Returns the output of the function specified by function.
0134          * Only works after starting a custom query
0135          * @return this
0136          */
0137         virtual QueryMaker* addReturnFunction( ReturnFunction function, qint64 value ) = 0;
0138         /**
0139          * Return results sorted by @p value.
0140          * @return this
0141          */
0142         virtual QueryMaker* orderBy( qint64 value, bool descending = false ) = 0;
0143 
0144         virtual QueryMaker* addMatch( const Meta::TrackPtr &track ) = 0;
0145         /**
0146          * Match given artist. Depending on @param behaviour matches:
0147          *   @p track artist if TrackArtists is given,
0148          *   @p album artist if AlbumArtists is given,
0149          *   any of track or album artist if AlbumOrTrackArtists is given.
0150          *
0151          * By default matches only track artist.
0152          * @param artist the track artist.
0153          */
0154         virtual QueryMaker* addMatch( const Meta::ArtistPtr &artist, ArtistMatchBehaviour behaviour = TrackArtists ) = 0;
0155         virtual QueryMaker* addMatch( const Meta::AlbumPtr &album ) = 0;
0156         virtual QueryMaker* addMatch( const Meta::ComposerPtr &composer ) = 0;
0157         virtual QueryMaker* addMatch( const Meta::GenrePtr &genre ) = 0;
0158         virtual QueryMaker* addMatch( const Meta::YearPtr &year ) = 0;
0159         virtual QueryMaker* addMatch( const Meta::LabelPtr &label );
0160 
0161         /**
0162          * Add a filter of type @p value and value @p filter. The querymaker applies this to all queries.
0163          * @param value the type of the filter
0164          * @param filter the text to match
0165          * @param matchBegin If set then wildcard match the beginning of @p text (*text)
0166          * @param matchEnd If set then wildcard match the end of @p text (text*)
0167          * @return this
0168          */
0169         virtual QueryMaker* addFilter( qint64 value, const QString &filter, bool matchBegin = false, bool matchEnd = false ) = 0;
0170         /**
0171          * Exclude filter of type @p value and value @p filter. The querymaker applies this to all queries.
0172          * @param value the type of the filter
0173          * @param filter the text to match
0174          * @param matchBegin If set then wildcard match the beginning of @p text (*text)
0175          * @param matchEnd If set then wildcard match the end of @p text (text*)
0176          * @return this
0177          */
0178         virtual QueryMaker* excludeFilter( qint64 value, const QString &filter, bool matchBegin = false, bool matchEnd = false ) = 0;
0179 
0180         virtual QueryMaker* addNumberFilter( qint64 value, qint64 filter, NumberComparison compare ) = 0;
0181         virtual QueryMaker* excludeNumberFilter( qint64 value, qint64 filter, NumberComparison compare ) = 0;
0182 
0183         /**
0184          *  limit the maximum number of items in a result. the result will have [0..@p size ] items. When this function
0185          *  is not used, the result size is unbounded. Note: the maximum size applies to each result individually, so if
0186          *  the newResultReady signal is emitted multiple times, each result may have up to @p size items.
0187          */
0188         virtual QueryMaker* limitMaxResultSize( int size ) = 0;
0189 
0190         /**
0191          * select the mode for querying albums. If this method is not called,
0192          * QueryMaker defaults to AlbumQueryMode::AllAlbums.
0193          */
0194         virtual QueryMaker* setAlbumQueryMode( AlbumQueryMode mode );
0195 
0196         /**
0197           * Sets the label query mode. This method restricts a query to tracks
0198           * that have labels assigned to them, no labels assigned to them, or no constraint.
0199           * The default is no constraint.
0200           * @param mode The LabelQueryMode that will be used by the query.
0201           * @see LabelQueryMode
0202           */
0203         virtual QueryMaker* setLabelQueryMode( LabelQueryMode mode );
0204 
0205         virtual QueryMaker* beginAnd() = 0;
0206         virtual QueryMaker* beginOr() = 0;
0207         virtual QueryMaker* endAndOr() = 0;
0208 
0209         /**
0210          * Choose whether the query maker instance should delete itself after the query.
0211          * By passing true the query maker instance will delete itself after emitting queryDone().
0212          * Otherwise it is the responsibility of the owner (the code which called \::queryMaker() usually) to delete the instance
0213          * when it is not needed anymore.
0214          *
0215          * Defaults to false, i.e. the querymaker instance will not delete itself.
0216          */
0217         QueryMaker* setAutoDelete( bool autoDelete );
0218 
0219         virtual int validFilterMask();
0220 
0221     Q_SIGNALS:
0222         /**
0223          * newResultReady will be emitted every time new results from the query maker are received.
0224          * This signal can be emitted zero times (in case of no results) one (the usual case) or multiple times
0225          * (e.g. in case when the result is received in several batches).
0226          * The results will be terminated by a queryDone signal.
0227          */
0228         void newResultReady( const QStringList &);
0229         void newTracksReady( const Meta::TrackList &);
0230         void newArtistsReady( const Meta::ArtistList &);
0231         void newAlbumsReady( const Meta::AlbumList &);
0232         void newGenresReady( const Meta::GenreList &);
0233         void newComposersReady( const Meta::ComposerList &);
0234         void newYearsReady( const Meta::YearList &);
0235         void newLabelsReady( const Meta::LabelList &);
0236         void newDataReady( const Meta::DataList &);
0237 
0238         /**
0239          * This signal is emitted after all the results have been submitted via zero or more newResultReady signals.
0240          */
0241         void queryDone();
0242 };
0243 
0244 } //namespace Collections
0245 
0246 Q_DECLARE_METATYPE( Collections::QueryMaker* )
0247 
0248 #endif /* AMAROK_COLLECTION_QUERYMAKER_H */
0249