1 /****************************************************************************************
2  * Copyright (c) 2008 Nikolaj Hald Nielsen <nhn@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 AMAROK_PRETTYTREEVIEW_H
18 #define AMAROK_PRETTYTREEVIEW_H
19 
20 #include "amarok_export.h"
21 
22 #include <QTreeView>
23 
24 namespace Amarok
25 {
26     /**
27      * A utility QTreeView subcass that handles:
28      * - drawing nice (svg themed) rows
29      * - palette changes
30      * - nicer expanding/collapsing interaction even when single click is used
31      * - decorator actions for root level items when isRootDecorated() is false
32      *
33      * If you use decorator actions, don't forget to set mouseTracking to true as
34      * PrettyTreeView doesn't do it automatically as it would be too costly for models
35      * that don't use the actions.
36      *
37      * @author: Nikolaj Hald Nielsen <nhn@kde.org>
38      */
39     class AMAROK_EXPORT PrettyTreeView : public QTreeView
40     {
41         Q_OBJECT
42 
43         public:
44             explicit PrettyTreeView( QWidget *parent = nullptr );
45             ~PrettyTreeView() override;
46         /**
47          * Return pointer to decorator action which was most recently mouse-pressed
48          * or null it mouse button was released since then. Used by PrettyTreeDelegate.
49          */
50         QAction *pressedDecoratorAction() const;
51 
52         public Q_SLOTS:
53             /* There is a need to overload even this edit() variant, otherwise it hides
54              * QAbstractItemView's implementation. Note that it is NOT safe to do anything
55              * special in this method, as it is not virtual.
56              * bool edit( const QModelIndex &index, EditTrigger trigger, QEvent *event )
57              * IS virtual. */
58             void edit( const QModelIndex &index );
59 
60 
61         protected:
62             bool edit( const QModelIndex &index, EditTrigger trigger, QEvent *event ) override;
63             void drawRow( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const override;
64 
65             /**
66              * Reimplemented to trigger item redraw in case mouse is over an item which
67              * has decorator actions.
68              */
69             void mouseMoveEvent( QMouseEvent *event ) override;
70 
71             /**
72              * Reimplemented to handle expanding with single-click mouse setting event
73              * when it is clicked outside the arrow and for consistency with
74              * mouseReleaseEvent() in case of decorator actions.
75              */
76             void mousePressEvent( QMouseEvent *event ) override;
77 
78             /**
79              * Reimplemented to handle expanding with single-click mouse setting event
80              * when it is clicked outside the arrow and to handle clicking on decorator
81              * actions */
82             void mouseReleaseEvent( QMouseEvent *event ) override;
83 
84             /**
85              * Reimplemented to show proper tooltips for decorator actions.
86              */
87             bool viewportEvent( QEvent *event ) override;
88 
89             /**
90              * Get dectorator action (little action icon as seen for example in collection
91              * items in collection browser) of index @p idx under mouse position @p pos.
92              */
93             QAction *decoratorActionAt( const QModelIndex &idx, const QPoint &pos );
94 
95         protected Q_SLOTS:
96             virtual void newPalette( const QPalette &palette );
97 
98         private:
99             /**
100              * Position (relative to this widget) where the mouse button was pressed to
101              * trigger expand/collapse, or null pointer where expand/collapse shouldn't
102              * be handled in mouseReleaseEvent()
103              */
104             QScopedPointer<QPoint> m_expandCollapsePressedAt;
105 
106             /**
107              * Pointer to decorator action which was pressed in mousePressEvent() or null
108              * pointer if no action was pressed in the most recent mouse press
109              */
110             QAction *m_decoratorActionPressed;
111     };
112 }
113 
114 #endif
115