1 /**
2  * Copyright (C) 2002-2004 Scott Wheeler <wheeler@kde.org>
3  *
4  * This program is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU General Public License as published by the Free Software
6  * Foundation; either version 2 of the License, or (at your option) any later
7  * version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
11  * PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along with
14  * this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #ifndef PLAYLISTBOX_H
18 #define PLAYLISTBOX_H
19 
20 #include "playlistcollection.h"
21 
22 #include <QHash>
23 #include <QVector>
24 #include <QTreeWidget>
25 
26 class Playlist;
27 class PlaylistItem;
28 class ViewMode;
29 
30 class QMenu;
31 
32 typedef QVector<Playlist *> PlaylistList;
33 
34 /**
35  * This is the play list selection box that is by default on the left side of
36  * JuK's main widget (PlaylistSplitter).
37  */
38 
39 class PlaylistBox final : public QTreeWidget, public PlaylistCollection
40 {
41     Q_OBJECT
42 
43 public:
44     class Item;
45     typedef QVector<Item *> ItemList;
46 
47     friend class Item;
48 
49     PlaylistBox(PlayerManager *player, QWidget *parent, QStackedWidget *playlistStack);
50     virtual ~PlaylistBox();
51 
52     virtual void raise(Playlist *playlist) override;
53     virtual void duplicate() override;
54     virtual void remove() override;
55 
56     // Called after files loaded to pickup any new files that might be present
57     // in managed directories.
58     virtual void scanFolders() override;
59 
60     virtual bool requestPlaybackFor(const FileHandle &file) override;
61 
62     /**
63      * For view modes that have dynamic playlists, this freezes them from
64      * removing playlists.
65      */
66     virtual void setDynamicListsFrozen(bool frozen) override;
67 
dropItem()68     Item *dropItem() const { return m_dropItem; }
69 
70     void setupPlaylist(Playlist *playlist, const QString &iconName, Item *parentItem = nullptr);
71 
72 public slots:
73     void paste();
clear()74     void clear() {}
75 
76     void slotFreezePlaylists();
77     void slotUnfreezePlaylists();
78     void slotPlaylistDataChanged();
79     void slotSetHistoryPlaylistEnabled(bool enable);
80 
81 protected:
82     virtual void setupPlaylist(Playlist *playlist, const QString &iconName) override;
83     virtual void removePlaylist(Playlist *playlist) override;
84     virtual Qt::DropActions supportedDropActions() const override;
85     virtual bool dropMimeData(QTreeWidgetItem *, int, const QMimeData *, Qt::DropAction) override;
86     virtual QStringList mimeTypes() const override;
87 
88 signals:
89     void signalPlaylistDestroyed(Playlist *);
90     void signalMoveFocusAway(); // Handles keyboard scrolling up out of playlist
91     void startupComplete(); ///< Emitted after playlists are loaded.
92     void signalPlayFile(const FileHandle &file);
93 
94 private:
95     void readConfig();
96     void saveConfig();
97 
98     virtual void mousePressEvent(QMouseEvent *e) override;
99     virtual void mouseReleaseEvent(QMouseEvent *e) override;
100     virtual void keyPressEvent(QKeyEvent *e) override;
101     virtual void keyReleaseEvent(QKeyEvent *e) override;
102 
103     // selectedItems already used for something different
104 
105     ItemList selectedBoxItems();
106     void setSingleItem(QTreeWidgetItem *item);
107 
108     void setupItem(Item *item);
109     void setupUpcomingPlaylist();
viewModeIndex()110     int viewModeIndex() const { return m_viewModeIndex; }
viewMode()111     ViewMode *viewMode() const { return m_viewModes[m_viewModeIndex]; }
112     void dragMoveEvent(QDragMoveEvent *event) override;
113     void dragLeaveEvent(QDragLeaveEvent *event) override;
114 
115 private slots:
116     /**
117      * Catches QListBox::currentChanged(QListBoxItem *), does a cast and then re-emits
118      * the signal as currentChanged(Item *).
119      */
120     void slotPlaylistChanged();
121     void slotDoubleClicked(QTreeWidgetItem *);
122     void slotShowContextMenu(const QPoint &point);
123     void slotSetViewMode(int index);
124     void slotSavePlaylists();
125     void slotShowDropTarget();
126 
127     void slotPlaylistItemsDropped(Playlist *p);
128 
129     void slotAddItem(const QString &tag, unsigned column);
130     void slotRemoveItem(const QString &tag, unsigned column);
131 
132     // Used to load the playlists after GUI setup.
133     void slotLoadCachedPlaylists();
134 
135 private:
136     QHash<Playlist *, Item *> m_playlistDict;
137     QTimer *m_showTimer            = nullptr;
138     QTimer *m_savePlaylistTimer    = nullptr;
139     Item *m_dropItem               = nullptr;
140     QMenu *m_contextMenu           = nullptr;
141     QVector<ViewMode *> m_viewModes;
142     int m_viewModeIndex            = 0;
143     bool m_hasSelection            = false;
144     bool m_doingMultiSelect        = false;
145 };
146 
147 class PlaylistBox::Item final : public QObject, public QTreeWidgetItem
148 {
149     friend class PlaylistBox;
150     friend class PlaylistSplitter;
151     friend class ViewMode;
152     friend class CompactViewMode;
153     friend class TreeViewMode;
154 
155     Q_OBJECT
156 
157     // moc won't let me create private QObject subclasses and Qt won't let me
158     // make the destructor protected, so here's the closest hack that will
159     // compile.
160 
161 public:
162     virtual ~Item();
163 
164 protected:
165     using QTreeWidgetItem::text;
166 
167     Item(PlaylistBox *listBox, const QString &icon, const QString &text, Playlist *l = nullptr);
168     Item(Item *parent, const QString &icon, const QString &text, Playlist *l = nullptr);
169 
playlist()170     Playlist *playlist() const { return m_playlist; }
listView()171     PlaylistBox *listView() const { return static_cast<PlaylistBox *>(QTreeWidgetItem::treeWidget()); }
iconName()172     QString iconName() const { return m_iconName; }
text()173     QString text() const { return QTreeWidgetItem::text(0); }
174     void setSortedFirst(bool first = true) { m_sortedFirst = first; }
175 
176     virtual void setup();
177 
collectionItem()178     static Item *collectionItem() { return m_collectionItem; }
179 
180     // Used to post a timer in PlaylistBox to save playlists.
181     void playlistItemDataChanged();
182 
183 
184 protected slots:
185     void slotSetName(const QString &name);
186 
187 private:
188     // setup() was already taken.
189     void init();
190     QString sortTextFor(const QString &name) const;
191 
192     Playlist *m_playlist;
193     QString m_iconName;
194     bool m_sortedFirst;
195 
196     static Item *m_collectionItem;
197 };
198 
199 #endif
200 
201 // vim: set et sw=4 tw=0 sta:
202