1 /*
2  *      Copyright (C) 2019 Jean-Luc Barriere
3  *
4  *  This program is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18 #ifndef TRACKS_H
19 #define TRACKS_H
20 
21 #include "aggregate.h"
22 #include "listmodel.h"
23 #include "tools.h"
24 
25 namespace mediascanner
26 {
27 
28 class TrackModel : public Model
29 {
30 public:
31   TrackModel(const MediaFilePtr& file);
key()32   const QByteArray& key() const { return m_key; }
title()33   const QString& title() { return m_file->mediaInfo->title; }
author()34   const QString& author() { return m_file->mediaInfo->artist; }
album()35   const QString& album() { return m_file->mediaInfo->album; }
genre()36   const QString& genre() { return m_file->mediaInfo->genre; }
composer()37   const QString& composer() { return m_file->mediaInfo->composer; }
codec()38   const QString& codec() { return m_file->mediaInfo->codec; }
filePath()39   const QString& filePath() { return m_file->filePath; }
albumTrackNo()40   int albumTrackNo() { return m_file->mediaInfo->trackNo; }
year()41   int year() { return m_file->mediaInfo->year; }
duration()42   int duration() { return m_file->mediaInfo->duration; }
sampleRate()43   int sampleRate() { return m_file->mediaInfo->sampleRate; }
channels()44   int channels() { return m_file->mediaInfo->channels; }
bitRate()45   int bitRate() { return m_file->mediaInfo->bitRate; }
hasArt()46   bool hasArt() { return m_file->mediaInfo->hasArt; }
normalized()47   const QString& normalized() { return m_normalized; }
art()48   const QString& art() const { return m_art; }
setArt(const QString & art)49   void setArt(const QString& art) { m_art = art; }
50   QVariant payload() const;
51 private:
52   QByteArray m_key;
53   QString m_normalized;
54   QString m_art;
55 };
56 
57 class Tracks : public ListModel
58 {
59   Q_OBJECT
60   Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
61   Q_PROPERTY(QString artist READ artistFilter WRITE setArtistFilter NOTIFY artistChanged)
62   Q_PROPERTY(QString album READ albumFilter WRITE setAlbumFilter NOTIFY albumChanged)
63   Q_PROPERTY(QString genre READ genreFilter WRITE setGenreFilter NOTIFY genreChanged)
64   Q_PROPERTY(QString composer READ composerFilter WRITE setComposerFilter NOTIFY composerChanged)
65 
66   typedef Aggregate<TrackModel> AggregateType;
67   typedef AggregateType::TuplePtr ItemPtr;
68 
69 public:
70 
71   enum Roles
72   {
73     PayloadRole,
74     IdRole,
75     TitleRole,
76     AlbumRole,
77     AuthorRole,
78     GenreRole,
79     ComposerRole,
80     CodecRole,
81     FilePathRole,
82     AlbumTrackNoRole,
83     YearRole,
84     DurationRole,
85     SampleRateRole,
86     ChannelsRole,
87     BitRateRole,
88     HasArtRole,
89     ArtRole,
90     NormalizedRole,
91   };
92 
93   Tracks(QObject* parent = nullptr);
94   virtual ~Tracks() override;
95 
artistFilter()96   const QString& artistFilter() { return m_artistFilter; }
setArtistFilter(const QString & filter)97   void setArtistFilter(const QString& filter) { m_artistFilter = filter; emit artistChanged(); }
albumFilter()98   const QString& albumFilter() { return m_albumFilter; }
setAlbumFilter(const QString & filter)99   void setAlbumFilter(const QString& filter) { m_albumFilter = filter; emit albumChanged(); }
genreFilter()100   const QString& genreFilter() { return m_genreFilter; }
setGenreFilter(const QString & filter)101   void setGenreFilter(const QString& filter) { m_genreFilter = filter; emit genreChanged(); }
composerFilter()102   const QString& composerFilter() { return m_composerFilter; }
setComposerFilter(const QString & filter)103   void setComposerFilter(const QString& filter) { m_composerFilter = filter; emit composerChanged(); }
104 
105   void addItem(ItemPtr& item);
106 
107   void removeItem(const QByteArray& key);
108 
109   int rowCount(const QModelIndex& parent = QModelIndex()) const override;
110 
111   QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
112 
113   bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
114 
115   Q_INVOKABLE QVariantMap get(int row);
116 
isNew()117   Q_INVOKABLE bool isNew() { return m_dataState == ListModel::New; }
118 
119   Q_INVOKABLE bool init(bool fill = true) override { return ListModel::init(fill); }
120 
121   Q_INVOKABLE void clear() override;
122 
123   Q_INVOKABLE bool load() override;
124 
125   void onFileAdded(const MediaFilePtr& file) override;
126   void onFileRemoved(const MediaFilePtr& file) override;
127 
128 signals:
129   void countChanged();
130   void loaded(bool succeeded);
131   void dataUpdated();
132 
133   void artistChanged();
134   void albumChanged();
135   void genreChanged();
136   void composerChanged();
137 
138 protected:
139   QHash<int, QByteArray> roleNames() const override;
140 
141 private:
142   AggregateType m_data;
143   QList<ItemPtr> m_items;
144   QString m_artistFilter;
145   QString m_albumFilter;
146   QString m_genreFilter;
147   QString m_composerFilter;
148 };
149 
150 }
151 
152 Q_DECLARE_METATYPE(mediascanner::Aggregate<mediascanner::TrackModel>::TuplePtr);
153 
154 #endif /* TRACKS_H */
155 
156