1 /**
2  * \file configurabletreeview.h
3  * QTreeView with configurable visibility, order and sort column.
4  *
5  * \b Project: Kid3
6  * \author Urs Fleisch
7  * \date 3 Jan 2014
8  *
9  * Copyright (C) 2014-2018  Urs Fleisch
10  *
11  * This file is part of Kid3.
12  *
13  * Kid3 is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * Kid3 is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25  */
26 
27 #pragma once
28 
29 #include <QTreeView>
30 #include <QKeySequence>
31 
32 class QActionGroup;
33 
34 /**
35  * QTreeView with configurable visibility, order and sort column.
36  */
37 class ConfigurableTreeView : public QTreeView {
38   Q_OBJECT
39 public:
40   /**
41    * Constructor.
42    * @param parent parent widget
43    */
44   explicit ConfigurableTreeView(QWidget* parent = nullptr);
45 
46   /**
47    * Destructor.
48    */
49   virtual ~ConfigurableTreeView() override = default;
50 
51   /**
52    * Set visible columns.
53    * @param columns logical indexes of visible columns
54    */
55   void setVisibleColumns(const QList<int>& columns);
56 
57   /**
58    * Get visible columns.
59    * @return logical indexes of visible columns.
60    */
61   QList<int> getVisibleColumns() const;
62 
63   /**
64    * Set if custom column widths are enabled.
65    * @param enable true to enable custom column widths, false for automatic
66    * column widths
67    */
68   void setCustomColumnWidthsEnabled(bool enable);
69 
70   /**
71    * Check if custom column widths are enabled.
72    * @return true if custom column widths are enabled.
73    */
74   bool areCustomColumnWidthsEnabled() const;
75 
76   /**
77    * Initialize custom column widths from contents if not yet valid.
78    * @param minimumWidth minimum width for column, -1 if not used
79    * @return size of first section, -1 when initialization not necessary.
80    */
81   int initializeColumnWidthsFromContents(int minimumWidth);
82 
83   /**
84    * Set column widths.
85    * @param columnWidths column widths
86    */
87   void setColumnWidths(const QList<int>& columnWidths);
88 
89   /**
90    * Get column widths.
91    * @return column widths.
92    */
93   QList<int> getColumnWidths() const;
94 
95   /**
96    * Get sort column and order.
97    * This method returns the values which can be set with sortByColumn().
98    *
99    * @param column the logical index of the sort column is returned here
100    * @param order the sort order is returned here
101    */
102   void getSortByColumn(int& column, Qt::SortOrder& order) const;
103 
104   /**
105    * Temporarily disconnect the model to improve performance.
106    * The old model state is preserved and will be restored by reconnectModel().
107    */
108   void disconnectModel();
109 
110   /**
111    * Reconnect to the model.
112    * The state before the call to disconnectModel() is restored.
113    */
114   void reconnectModel();
115 
116   /**
117    * Set keyboard shortcuts for the open parent and open current actions.
118    * @param map map of action names to key sequences
119    */
120   void setShortcuts(const QMap<QString, QKeySequence>& map);
121 
122 signals:
123   /**
124    * Emitted when the parent shall be activated.
125    * This is emitted when Command + Up is pressed to mimic the shortcut of the
126    * macOS Finder.
127    * @param index root index of item view
128    */
129   void parentActivated(const QModelIndex& index);
130 
131 protected:
132   /**
133    * Reimplemented to go to parent item with Left key and
134    * make Return/Enter send activated() also on the Mac.
135    * @param event key event
136    */
137   virtual void keyPressEvent(QKeyEvent* event) override;
138 
139 private slots:
140   /**
141    * Show context menu for header.
142    * @param pos context menu position
143    */
144   void showHeaderContextMenu(const QPoint& pos);
145 
146   /**
147    * Toggle visibility of column.
148    * @param visible true to set column visible
149    */
150   void toggleColumnVisibility(bool visible);
151 
152 private:
153   /**
154    * Set column widths to custom column widths set with setColumnWidths().
155    * @return true if custom column widths settings could be applied.
156    */
157   bool resizeColumnWidths();
158 
159   quint32 m_columnVisibility;
160 
161   /** State stored by disconnectModel() and restored by reconnectModel() */
162   QAbstractItemModel* m_oldModel;
163   QItemSelectionModel* m_oldSelectionModel;
164   QPersistentModelIndex m_oldRootIndex;
165   QList<int> m_columnWidths;
166   QActionGroup* m_columnActionGroup;
167   QAction* m_autoColumnAction;
168   QAction* m_customColumnAction;
169   QKeySequence m_openParentKey;
170   QKeySequence m_openCurrentKey;
171 };
172