1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #pragma once
27 
28 #include "utils_global.h"
29 
30 #include "itemviews.h"
31 
32 QT_BEGIN_NAMESPACE
33 class QSettings;
34 QT_END_NAMESPACE
35 
36 namespace Utils {
37 
38 namespace Internal { class BaseTreeViewPrivate; }
39 
40 class QTCREATOR_UTILS_EXPORT BaseTreeView : public TreeView
41 {
42     Q_OBJECT
43 
44 public:
45     enum {
46         ExtraIndicesForColumnWidth = 12734,
47 
48         ItemViewEventRole = Qt::UserRole + 12735,
49 
50         ItemActivatedRole,
51         ItemClickedRole,
52 
53         ItemDelegateRole,
54     };
55 
56     BaseTreeView(QWidget *parent = nullptr);
57     ~BaseTreeView() override;
58 
59     void setSettings(QSettings *settings, const QByteArray &key);
60 
61     void setModel(QAbstractItemModel *model) override;
62     void mousePressEvent(QMouseEvent *ev) override;
63     void mouseMoveEvent(QMouseEvent *ev) override;
64     void mouseReleaseEvent(QMouseEvent *ev) override;
65     void contextMenuEvent(QContextMenuEvent *ev) override;
66     void showEvent(QShowEvent *ev) override;
67     void keyPressEvent(QKeyEvent *ev) override;
68     void dragEnterEvent(QDragEnterEvent *ev) override;
69     void dropEvent(QDropEvent *ev) override;
70     void dragMoveEvent(QDragMoveEvent *ev) override;
71     void mouseDoubleClickEvent(QMouseEvent *ev) override;
72     void resizeEvent(QResizeEvent *event) override;
73 
74     void showProgressIndicator();
75     void hideProgressIndicator();
76     void resizeColumns();
77 
78     int spanColumn() const;
79     void setSpanColumn(int column);
80 
81     void enableColumnHiding();
82 
83     // In some situations this needs to be called when manually resizing columns when the span
84     // column is set.
85     void refreshSpanColumn();
86 
87 signals:
88     void aboutToShow();
89 
90 private:
91     void rowActivated(const QModelIndex &index);
92     void rowClicked(const QModelIndex &index);
93 
94     Internal::BaseTreeViewPrivate *d;
95 };
96 
97 template <typename Event> struct EventCode;
98 template <> struct EventCode<QDragEnterEvent> { enum { code = QEvent::DragEnter }; };
99 template <> struct EventCode<QDragLeaveEvent> { enum { code = QEvent::DragLeave }; };
100 template <> struct EventCode<QDragMoveEvent> { enum { code = QEvent::DragMove }; };
101 template <> struct EventCode<QDropEvent> { enum { code = QEvent::Drop }; };
102 template <> struct EventCode<QContextMenuEvent> { enum { code = QEvent::ContextMenu }; };
103 template <> struct EventCode<QMouseEvent> { enum { code = QEvent::MouseButtonPress }; };
104 template <> struct EventCode<QKeyEvent> { enum { code = QEvent::KeyPress }; };
105 
106 template <class T> T *checkEventType(QEvent *ev)
107 {
108     const int cc = EventCode<T>::code;
109     const int tt = ev->type();
110     if (cc == tt)
111         return static_cast<T *>(ev);
112     if (cc == QEvent::MouseButtonPress) {
113         if (tt == QEvent::MouseButtonDblClick || tt == QEvent::MouseButtonRelease || tt == QEvent::MouseMove)
114             return static_cast<T *>(ev);
115     }
116     if (cc == QEvent::KeyPress && tt == QEvent::KeyRelease)
117         return static_cast<T *>(ev);
118     return nullptr;
119 }
120 
121 class QTCREATOR_UTILS_EXPORT ItemViewEvent
122 {
123 public:
124     ItemViewEvent() = default;
125     ItemViewEvent(QEvent *ev, QAbstractItemView *view);
126 
127     template <class T> T *as() const {
128         return checkEventType<T>(m_event);
129     }
130 
131     template <class T> T *as(QEvent::Type t) const {
132         return m_event->type() == t ? as<T>() : nullptr;
133     }
134 
135     QEvent::Type type() const { return m_event->type(); }
136     QWidget *view() const { return m_view; }
137     QPoint pos() const { return m_pos; }
138     QPoint globalPos() const { return m_view->mapToGlobal(m_pos); }
139     QModelIndex index() const { return m_index; }
140     QModelIndex sourceModelIndex() const { return m_sourceModelIndex; }
141     QModelIndexList selectedRows() const { return m_selectedRows; }
142     QModelIndexList currentOrSelectedRows() const;
143 
144 private:
145     QEvent *m_event = nullptr;
146     QWidget *m_view = nullptr;
147     QPoint m_pos;
148     QModelIndex m_index;
149     QModelIndex m_sourceModelIndex;
150     QModelIndexList m_selectedRows;
151 };
152 
153 } // namespace Utils
154 
155 Q_DECLARE_METATYPE(Utils::ItemViewEvent);
156