1 /****************************************************************************************
2  * Copyright (c) 2007 Alexandre Pereira de Oliveira <aleprj@gmail.com>                  *
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 COLLECTIONTREEVIEW_H
18 #define COLLECTIONTREEVIEW_H
19 
20 #include "amarok_export.h"
21 #include "BrowserDefines.h"
22 #include "widgets/PrettyTreeView.h"
23 #include "browsers/CollectionTreeItem.h"
24 #include "core/meta/forward_declarations.h"
25 #include "playlist/PlaylistController.h"
26 
27 #include <QModelIndex>
28 #include <QMutex>
29 #include <QSet>
30 #include <QApplication>
31 
32 class AmarokMimeData;
33 class CollectionSortFilterProxyModel;
34 class CollectionTreeItemModelBase;
35 class PopupDropper;
36 namespace Collections {
37     class Collection;
38     class QueryMaker;
39 }
40 class QAction;
41 class QSortFilterProxyModel;
42 
43 typedef QList<QAction *> QActionList;
44 
45 class AMAROK_EXPORT CollectionTreeView : public Amarok::PrettyTreeView
46 {
47         Q_OBJECT
48 
49     public:
50         explicit CollectionTreeView( QWidget *parent = nullptr );
51         ~CollectionTreeView() override;
52 
53         QSortFilterProxyModel* filterModel() const;
54 
55         void setLevels( const QList<CategoryId::CatMenuId> &levels );
56         QList<CategoryId::CatMenuId> levels() const;
57 
58         void setLevel( int level, CategoryId::CatMenuId type );
59 
60         void setModel( QAbstractItemModel *model ) override;
61 
62         //Helper function to remove children if their parent is already present
63         static QSet<CollectionTreeItem*> cleanItemSet( const QSet<CollectionTreeItem*> &items );
64         static bool onlyOneCollection( const QModelIndexList &indices );
65         static Collections::Collection *getCollection( const QModelIndex &index );
66         Collections::QueryMaker* createMetaQueryFromItems( const QSet<CollectionTreeItem*> &items, bool cleanItems=true ) const;
67 
68         /**
69          * Copies all selected tracks to the local collection. The user can also
70          * choose to do on-the-fly transcoding.
71          */
72         void copySelectedToLocalCollection();
73 
74     public Q_SLOTS:
75         void slotSetFilter( const QString &filter );
76 
77         /**
78          * This should append all currently visible tracks to the playlist. Takes
79          * care to ensure that the tracks are added only after any pending searches
80          * are finished.
81          */
82         void slotAddFilteredTracksToPlaylist();
83 
84         void playChildTracksSlot( Meta::TrackList list );
85 
86     Q_SIGNALS:
87         /**
88          * This signal is emitted when slotAddFilteredTracksToPlaylist() has done its
89          * work.
90          */
91         void addingFilteredTracksDone();
92 
93     protected:
94         void contextMenuEvent( QContextMenuEvent *event ) override;
95         void mouseDoubleClickEvent( QMouseEvent *event ) override;
96         void mouseReleaseEvent( QMouseEvent *event ) override;
97         void keyPressEvent( QKeyEvent *event ) override;
98         void dragEnterEvent( QDragEnterEvent *event ) override;
99         void dragMoveEvent( QDragMoveEvent *event ) override;
100         void startDrag( Qt::DropActions supportedActions ) override;
101 
102     protected Q_SLOTS:
103         void selectionChanged ( const QItemSelection & selected, const QItemSelection & deselected ) override;
104         void slotCollapsed( const QModelIndex &index );
105         void slotExpanded( const QModelIndex &index );
106         void slotExpandIndex( const QModelIndex &index );
107 
108         void slotCheckAutoExpand( bool reallyExpand = true );
slotCheckAutoExpandReally()109         void slotCheckAutoExpandReally() { slotCheckAutoExpand( true ); }
110 
111         void slotReplacePlaylistWithChildTracks();
112         void slotAppendChildTracks();
113         void slotQueueChildTracks();
114         void slotEditTracks();
115         void slotCopyTracks();
116         void slotMoveTracks();
117         void slotTrashTracks();
118         void slotDeleteTracks();
119         void slotOrganize();
120 
121     private:
122         // Utility function to play all items
123         // that have this as a parent..
124         void playChildTracks( CollectionTreeItem *item, Playlist::AddOptions insertMode );
125         void playChildTracks( const QSet<CollectionTreeItem*> &items, Playlist::AddOptions insertMode );
126         void editTracks( const QSet<CollectionTreeItem*> &items ) const;
127         void organizeTracks( const QSet<CollectionTreeItem*> &items ) const;
128         void copyTracks( const QSet<CollectionTreeItem*> &items, Collections::Collection *destination,
129                          bool removeSources) const;
130         void removeTracks( const QSet<CollectionTreeItem*> &items, bool useTrash ) const;
131 
132         // creates different actions from the different objects.
133         // note: you should not delete the created actions.
134         QActionList createBasicActions( const QModelIndexList &indices );
135         QActionList createExtendedActions( const QModelIndexList &indices );
136         QActionList createCollectionActions( const QModelIndexList &indices );
137         QActionList createCustomActions( const QModelIndexList &indices );
138 
139         QHash<QAction*, Collections::Collection*> getCopyActions( const QModelIndexList &indices );
140         QHash<QAction*, Collections::Collection*> getMoveActions( const QModelIndexList &indices );
141 
142         CollectionTreeItem* getItemFromIndex( QModelIndex &index );
143 
144         CollectionSortFilterProxyModel *m_filterModel;
145         CollectionTreeItemModelBase *m_treeModel;
146         PopupDropper* m_pd;
147         QAction* m_appendAction;
148         QAction* m_loadAction;
149         QAction* m_editAction;
150         QAction* m_organizeAction;
151 
152         QHash<QAction*, Collections::Collection*> m_currentCopyDestination;
153         QHash<QAction*, Collections::Collection*> m_currentMoveDestination;
154 
155         QMap<AmarokMimeData*, Playlist::AddOptions> m_playChildTracksMode;
156 
157         QSet<CollectionTreeItem*> m_currentItems;
158 
159         bool m_ongoingDrag;
160 
161     Q_SIGNALS:
162         void itemSelected( CollectionTreeItem * item );
163         void leavingTree();
164 };
165 
166 #endif
167