1 /*
2  * Cantata
3  *
4  * Copyright (c) 2011-2020 Craig Drummond <craig.p.drummond@gmail.com>
5  *
6  * ----
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; see the file COPYING.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23 
24 #ifndef RULES_PLAYLISTS_H
25 #define RULES_PLAYLISTS_H
26 
27 #include <QIcon>
28 #include <QList>
29 #include <QMap>
30 #include <QString>
31 #include <QStringList>
32 #include "models/actionmodel.h"
33 
34 class RulesPlaylists : public ActionModel
35 {
36     Q_OBJECT
37 
38 public:
39     enum Order {
40         Order_AlbumArtist,
41         Order_Artist,
42         Order_Album,
43         Order_Composer,
44         Order_Date,
45         Order_Genre,
46         Order_Rating,
47         Order_Title,
48         Order_Age,
49         Order_Random,
50 
51         Order_Count
52     };
53 
54     static Order toOrder(const QString &str);
55     static QString orderStr(Order order);
56     static QString orderName(Order order);
57 
58     typedef QMap<QString, QString> Rule;
59     struct Entry {
nameEntry60         Entry(const QString &n=QString()) : name(n) { }
61         bool operator==(const Entry &o) const { return name==o.name; }
haveRatingEntry62         bool haveRating() const { return ratingFrom>=0 && ratingTo>0; }
63         QString name;
64         QList<Rule> rules;
65         bool includeUnrated = false;
66         int ratingFrom = 0;
67         int ratingTo = 0;
68         int minDuration = 0;
69         int maxDuration = 0;
70         int maxAge = 0;
71         int numTracks = 10;
72         Order order = Order_Random;
73         bool orderAscending = true;
74     };
75 
76     static const QString constExtension;
77     static const QString constRuleKey;
78     static const QString constArtistKey;
79     static const QString constSimilarArtistsKey;
80     static const QString constAlbumArtistKey;
81     static const QString constComposerKey;
82     static const QString constCommentKey;
83     static const QString constAlbumKey;
84     static const QString constTitleKey;
85     static const QString constGenreKey;
86     static const QString constDateKey;
87     static const QString constRatingKey;
88     static const QString constIncludeUnratedKey;
89     static const QString constDurationKey;
90     static const QString constNumTracksKey;
91     static const QString constMaxAgeKey;
92     static const QString constFileKey;
93     static const QString constExactKey;
94     static const QString constExcludeKey;
95     static const QString constOrderKey;
96     static const QString constOrderAscendingKey;
97     static const QChar constRangeSep;
98     static const QChar constKeyValSep;
99 
100     RulesPlaylists(int icon, const QString &dir);
~RulesPlaylists()101     ~RulesPlaylists() override { }
102 
103     virtual QString name() const =0;
104     virtual QString title() const =0;
105     virtual QString descr() const =0;
isDynamic()106     virtual bool isDynamic() const { return false; }
icon()107     const QIcon & icon() const { return icn; }
isRemote()108     virtual bool isRemote() const { return false; }
minTracks()109     virtual int minTracks() const { return 10; }
maxTracks()110     virtual int maxTracks() const { return 500; }
defaultNumTracks()111     virtual int defaultNumTracks() const { return 10; }
saveRemote(const QString & string,const Entry & e)112     virtual bool saveRemote(const QString &string, const Entry &e) { Q_UNUSED(string); Q_UNUSED(e); return false; }
113     virtual void stop(bool sendClear=false) { Q_UNUSED(sendClear) }
114     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
115     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
columnCount(const QModelIndex &)116     int columnCount(const QModelIndex&) const override { return 1; }
117     bool hasChildren(const QModelIndex &parent) const override;
118     QModelIndex parent(const QModelIndex &index) const override;
119     QModelIndex index(int row, int column, const QModelIndex &parent) const override;
120     QVariant data(const QModelIndex &, int) const override;
121     Qt::ItemFlags flags(const QModelIndex &index) const override;
122     Entry entry(const QString &e);
entry(int row)123     Entry entry(int row) const { return row>=0 && row<entryList.count() ? entryList.at(row) : Entry(); }
exists(const QString & e)124     bool exists(const QString &e) { return entryList.end()!=find(e); }
125     bool save(const Entry &e);
126     virtual void del(const QString &name);
current()127     QString current() const { return currentEntry; }
entries()128     const QList<Entry> & entries() const { return entryList; }
129 
130 protected:
131     QList<Entry>::Iterator find(const QString &e);
132     void loadLocal();
133     void updateEntry(const Entry &e);
134 
135 protected:
136     QIcon icn;
137     QString rulesDir;
138     QList<Entry> entryList;
139     QString currentEntry;
140 };
141 
142 #endif
143