1 /* 2 * Cantata 3 * 4 * Copyright (c) 2017-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 BROWSE_MODEL_H 25 #define BROWSE_MODEL_H 26 27 #include "actionmodel.h" 28 #include "mpd-interface/song.h" 29 #include "support/utils.h" 30 #include "support/icon.h" 31 #include <QMap> 32 33 struct MPDStatsValues; 34 35 class BrowseModel : public ActionModel 36 { 37 Q_OBJECT 38 39 public: 40 41 class FolderItem; 42 class Item 43 { 44 public: 45 Item(FolderItem *p=nullptr) parent(p)46 : parent(p), row(0) { } ~Item()47 virtual ~Item() { } 48 getChildCount()49 virtual int getChildCount() const { return 0; } isFolder()50 virtual bool isFolder() const { return false; } 51 virtual QString getText() const =0; 52 virtual QString getSubText() const =0; getParent()53 FolderItem * getParent() const { return parent; } getRow()54 int getRow() const { return row; } setRow(int r)55 void setRow(int r) { row=r; } 56 57 private: 58 FolderItem *parent; 59 int row; 60 }; 61 62 class TrackItem : public Item 63 { 64 public: 65 TrackItem(const Song &s, FolderItem *p=nullptr) Item(p)66 : Item(p) 67 , song(s) { } ~TrackItem()68 ~TrackItem() override { } 69 getText()70 QString getText() const override { return song.trackAndTitleStr(); } getSubText()71 QString getSubText() const override { return Song::Playlist==song.type || 0==song.time ? QString() : Utils::formatTime(song.time, true); } getSong()72 const Song & getSong() const { return song; } 73 74 private: 75 Song song; 76 }; 77 78 class FolderItem : public Item 79 { 80 public: 81 enum State { 82 State_Initial, 83 State_Fetching, 84 State_Fetched 85 }; 86 87 FolderItem(const QString &n, const QString &pth, FolderItem *p=nullptr) Item(p)88 : Item(p), name(n), path(pth), state(State_Initial) { } ~FolderItem()89 ~FolderItem() override { } 90 clear()91 void clear() { qDeleteAll(children); children.clear(); state=State_Initial; } getChildren()92 const QList<Item *> getChildren() const { return children; } getChildCount()93 int getChildCount() const override { return children.count();} isFolder()94 bool isFolder() const override { return true; } 95 void add(Item *i); getText()96 QString getText() const override { return name; } getSubText()97 QString getSubText() const override { return QString(); } getPath()98 const QString & getPath() const { return path; } canFetchMore()99 bool canFetchMore() const { return State_Initial==state; } isFetching()100 bool isFetching() const { return State_Fetching==state; } setState(State s)101 void setState(State s) { state=s; } 102 QStringList allEntries(bool allowPlaylists) const; 103 104 private: 105 QString name; 106 QString path; 107 QList<Item *> children; 108 State state; 109 }; 110 111 BrowseModel(QObject *p); 112 113 QString name() const; 114 QString title() const; 115 QString descr() const; icon()116 const QIcon & icon() const { return icn; } 117 void clear(); 118 void load(); isEnabled()119 bool isEnabled() const { return enabled; } 120 void setEnabled(bool e); 121 Qt::ItemFlags flags(const QModelIndex &index) const override; 122 QModelIndex index(int row, int column, const QModelIndex &parent) const override; 123 QModelIndex parent(const QModelIndex &child) const override; 124 int rowCount(const QModelIndex &parent) const override; 125 int columnCount(const QModelIndex &parent) const override; 126 bool hasChildren(const QModelIndex &index) const override; 127 bool canFetchMore(const QModelIndex &index) const override; 128 void fetchMore(const QModelIndex &index) override; 129 QVariant data(const QModelIndex &index, int role) const override; 130 QMimeData * mimeData(const QModelIndexList &indexes) const override; 131 QList<Song> songs(const QModelIndexList &indexes, bool allowPlaylists) const; 132 133 Q_SIGNALS: 134 void listFolder(const QString &path); 135 136 private Q_SLOTS: 137 void connectionChanged(); 138 void statsUpdated(const MPDStatsValues &stats); 139 void folderContents(const QString &path, const QStringList &folders, const QList<Song> &songs); 140 141 private: toItem(const QModelIndex & index)142 Item * toItem(const QModelIndex &index) const { return index.isValid() ? static_cast<Item*>(index.internalPointer()) : root; } 143 144 private: 145 QIcon icn; 146 FolderItem *root; 147 QMap<QString, FolderItem *> folderIndex; 148 bool enabled; 149 time_t dbVersion; 150 }; 151 152 #endif 153