forked from rossy/mpc-qt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdrawnplaylist.h
157 lines (131 loc) · 4.71 KB
/
drawnplaylist.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#ifndef QDRAWNPLAYLIST_H
#define QDRAWNPLAYLIST_H
#include <QListWidget>
#include <QUuid>
#include <functional>
#include "playlist.h"
class DisplayParser;
class QThread;
class PlaylistSearcher;
class PlayPainter : public QAbstractItemDelegate {
Q_OBJECT
public:
PlayPainter(QObject *parent = nullptr);
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const;
};
class PlayItem : public QListWidgetItem {
public:
PlayItem(const QUuid &uuid = QUuid(), const QUuid &playlistUuid = QUuid(), QListWidget *parent = nullptr);
~PlayItem();
QUuid playlistUuid();
QUuid uuid();
private:
QUuid playlistUuid_;
QUuid uuid_;
};
// DrawnPlaylist abuses a ListWidget's items to store the uuid of playlist
// items, which is decoded and looked up during drawing. The alternative is a
// subclass of QAbstractItemModel with about 1.5x the code.
class DrawnPlaylist : public QListWidget {
Q_OBJECT
public:
DrawnPlaylist(QWidget *parent = nullptr);
~DrawnPlaylist();
virtual QSharedPointer<Playlist> playlist() const;
QUuid uuid() const;
void setUuid(const QUuid &uuid);
QUuid currentItemUuid() const;
QList<QUuid> currentItemUuids() const;
void traverseSelected(std::function<void(QUuid)> callback);
void setCurrentItem(QUuid itemUuid);
void scrollToItem(QUuid itemUuid);
virtual void addItem(QUuid uuid);
void addItems(const QList<QUuid> &items);
void addItemsAfter(QUuid item, const QList<QUuid> &items);
void removeItem(QUuid uuid);
void removeItems(const QList<int> &indicies);
void removeAll();
template<class T>
void sort(std::function<T(QSharedPointer<Item>)> converter,
std::function<bool(const T &a, const T &b)> lessThan);
QPair<QUuid,QUuid> importUrl(QUrl url);
void currentToQueue();
QUuid nowPlayingItem();
void setNowPlayingItem(QUuid uuid);
QVariantMap toVMap() const;
void fromVMap(const QVariantMap &qvm);
void setDisplayParser(DisplayParser *parser);
DisplayParser *displayParser();
void setFilter(QString needles);
protected:
bool event(QEvent *e);
private:
QUuid uuid_;
QHash <QUuid, PlayItem*> itemsByUuid;
QUuid lastSelectedItem;
QUuid nowPlayingItem_;
DisplayParser *displayParser_ = nullptr;
QThread *worker = nullptr;
PlaylistSearcher *searcher;
QString currentFilterText;
QStringList currentFilterList;
signals:
// for lack of a better term that doesn't conflict with what we already
// have, when an item is made hot by double clicking.
void itemDesired(QUuid playlistUuid, QUuid itemUuid);
void searcher_filterPlaylist(QSharedPointer<Playlist>, QString text);
void menuOpenItem(QUuid playlistUuid, QUuid itemUuid);
void contextMenuRequested(QPoint p, QUuid playlistUuid, QUuid itemUuid);
private slots:
void repopulateItems();
void model_rowsMoved(const QModelIndex & parent, int start, int end,
const QModelIndex & destination, int row);
void self_currentItemChanged(QListWidgetItem *current,
QListWidgetItem *previous);
void self_itemDoubleClicked(QListWidgetItem *item);
void self_customContextMenuRequested(const QPoint &p);
};
template<class T>
void DrawnPlaylist::sort(
std::function<T(QSharedPointer<Item>)> converter,
std::function<bool(const T &a, const T &b)> lessThan) {
QMap<QUuid,T> playlistMap;
QList<QSharedPointer<Item>> items;
auto pl = playlist();
int index = 0;
pl->iterateItems([&](QSharedPointer<Item> i) {
playlistMap.insertMulti(i->uuid(), converter(i));
items.append(i);
i->setOriginalPosition(index++);
});
qSort(items.begin(), items.end(), [&](const QSharedPointer<Item> &a, const QSharedPointer<Item> &b) {
return lessThan(playlistMap.value(a->uuid()), playlistMap.value(b->uuid()));
});
pl->takeItemsRaw(items);
pl->addItems(QUuid(), items);
repopulateItems();
}
class DrawnQueue : public DrawnPlaylist {
Q_OBJECT
public:
virtual QSharedPointer<Playlist> playlist() const;
void addItem(QUuid uuid);
};
class PlaylistSelectionPrivate;
class PlaylistSelection {
public:
PlaylistSelection();
PlaylistSelection(PlaylistSelection &other);
~PlaylistSelection();
void fromItem(QUuid playlistUuid, QUuid itemUuid);
void fromQueue(DrawnPlaylist *list);
void fromSelected(DrawnPlaylist *list);
void appendToPlaylist(DrawnPlaylist *list);
void appendAndQuickQueue(DrawnPlaylist *list);
private:
PlaylistSelectionPrivate *d = nullptr;
};
#endif // QDRAWNPLAYLIST_H