maxLibQt
TreeComboBox.h
Go to the documentation of this file.
1 /*
2  TreeComboBox
3  https://github.com/mpaperno/maxLibQt
4 
5  COPYRIGHT: (c)2017 Maxim Paperno; All Right Reserved.
6  Contact: http://www.WorldDesign.com/contact
7 
8  LICENSE:
9 
10  Commercial License Usage
11  Licensees holding valid commercial licenses may use this file in
12  accordance with the terms contained in a written agreement between
13  you and the copyright holder.
14 
15  GNU General Public License Usage
16  Alternatively, this file may be used under the terms of the GNU
17  General Public License as published by the Free Software Foundation,
18  either version 3 of the License, or (at your option) any later version.
19 
20  This program is distributed in the hope that it will be useful,
21  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  GNU General Public License for more details.
24 
25  A copy of the GNU General Public License is available at <http://www.gnu.org/licenses/>.
26 */
27 
28 #ifndef TREECOMBOBOX_H
29 #define TREECOMBOBOX_H
30 
31 #include <QComboBox>
32 #include <QStyledItemDelegate>
33 #include <QTreeView>
34 #include <QModelIndex>
35 #include <QScrollBar>
36 
37 class QPainter;
38 
51 {
52  Q_OBJECT
53 
54  public:
56 
57  static bool isSeparator(const QModelIndex &index);
58  static bool isParent(const QModelIndex &index);
59  static void setSeparator(QAbstractItemModel *model, const QModelIndex &index);
60  static void setParent(QAbstractItemModel *model, const QModelIndex &index, const bool selectable = false);
61 
62  protected:
63  virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
64  virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
65 };
66 
67 
92 class TreeComboBox : public QComboBox
93 {
94  Q_OBJECT
95  Q_PROPERTY(bool autoData READ autoData WRITE setAutoData)
96 
97  public:
98  explicit TreeComboBox(QWidget * parent = Q_NULLPTR);
99 
103  void setView(QAbstractItemView *itemView = Q_NULLPTR); // only QTreeView and derived
104  inline QTreeView * view() const { return m_view; }
105  inline bool autoData() const { return m_autoData; }
106 
108  int currentIndex() const;
110  QVariant currentData(int role = Qt::UserRole) const;
112  QVariant itemData(int index, int role = Qt::UserRole) const;
114  QIcon itemIcon(int index) const;
115  inline QString itemText(int index) const { return itemData(index, Qt::DisplayRole).toString(); }
116 
118  void setItemData(const QModelIndex &index, const QVariant &value, int role = Qt::UserRole);
119  void setItemData(int index, const QVariant &value, int role = Qt::UserRole) { setItemData(m_indexMap.value(index, QModelIndex()), value, role); }
120  void setItemText(int index, const QString &text) { setItemData(index, QVariant::fromValue(text), Qt::EditRole); }
121  void setItemIcon(int index, const QIcon &icon) { setItemData(index, QVariant::fromValue(icon), Qt::DecorationRole); }
122 
125  inline int findText(const QString &text,
127 
136  QModelIndex insertItem(int index, const QMap<int, QVariant> &values = QMap<int, QVariant>(), const QModelIndex &parentIndex = QModelIndex(), const bool reload = true);
137 
146  QModelIndex insertItem(int index, const QIcon & icon, const QString &text, const QModelIndex &parentIndex, const QVariant &userData = QVariant(), const bool reload = true);
147 
149  void insertItems(int index, const QStringList &texts, const QModelIndex &parentIndex);
150 
151  // in addition to regular QComboBox add/insert, these allow specifying a parent item instead of the default root
152  inline QModelIndex addItem(const QString &text, const QModelIndex &parentIndex,
153  const QVariant &userData = QVariant()) { return addItem(QIcon(), text, parentIndex, userData); }
154  inline QModelIndex addItem(const QIcon &icon, const QString &text, const QModelIndex &parentIndex,
155  const QVariant &userData = QVariant()) { return insertItem(model()->rowCount(parentIndex), icon, text, parentIndex, userData); }
156  inline void addItems(const QStringList &texts, const QModelIndex &parentIndex) { insertItems(model()->rowCount(parentIndex), texts, parentIndex); }
157 
158  // re-implement QComboBox add/insert interface
159  inline void insertItem(int index, const QIcon &icon, const QString &text,
160  const QVariant &userData = QVariant()) { insertItem(index, icon, text, QModelIndex(), userData); }
161  inline void addItem(const QString &text, const QVariant &userData = QVariant()) { insertItem(count(), QIcon(), text, userData); }
162  inline void addItem(const QIcon &icon, const QString &text, const QVariant &userData = QVariant()) { insertItem(count(), icon, text, userData); }
163  inline void insertItem(int index, const QString &text, const QVariant &userData = QVariant()) { insertItem(index, QIcon(), text, userData); }
164  inline void addItems(const QStringList &texts) { insertItems(count(), texts); }
165  inline void insertItems(int index, const QStringList &texts) { insertItems(index, texts, QModelIndex()); }
166 
167  // parent items (convenience functions insted of creating own data model)
175  QModelIndex insertParentItem(int index, const QIcon &icon, const QString &text, const bool selectable = false,
176  const QModelIndex &parentIndex = QModelIndex(), const QVariant &userData = QVariant());
177  inline QModelIndex addParentItem(const QString &text, const bool selectable = false, const QModelIndex &parentIndex = QModelIndex(),
178  const QVariant &userData = QVariant()) { return addParentItem(QIcon(), text, selectable, parentIndex, userData); }
179  inline QModelIndex addParentItem(const QIcon &icon, const QString &text, const bool selectable = false, const QModelIndex &parentIndex = QModelIndex(),
180  const QVariant &userData = QVariant()) { return insertParentItem(model()->rowCount(parentIndex), icon, text, selectable, parentIndex, userData); }
181 
183  virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
185  virtual void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
187  virtual bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE;
189  virtual void showPopup() Q_DECL_OVERRIDE;
191  virtual void hidePopup() Q_DECL_OVERRIDE;
192 
193  public slots:
195  void clear();
197  void setCurrentIndex(int index);
199  void setCurrentIndex(const QModelIndex &index);
200  void setCurrentText(const QString &text) { setCurrentIndex(findText(text)); }
201 
206  int setCurrentData(const QVariant &data, const int defaultIdx = -1, int role = Qt::UserRole, Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchExactly | Qt::MatchCaseSensitive));
208  void keyboardSearchString(const QString &text);
209  void setAutoData(bool enable) { m_autoData = enable; }
210 
211  signals:
212  void currentModelIndexChanged(const QModelIndex &index);
213  void currentDataChanged(const QVariant &data);
214 
215  protected slots:
220  int buildMap(QModelIndex parent = QModelIndex(), int row = 0);
221  void reloadModel();
223  void ensureCurrentExpanded();
225  void adjustPopupWidth();
227  void adjustPopupHeight();
228 
229  protected:
235  QModelIndex lastIndex(const QModelIndex &index);
237  bool usePopup(QStyleOptionComboBox *option = NULL);
238 
246 };
247 
248 
256 {
257  Q_OBJECT
258  public:
259  inline void adjustWidth(int maxWidth) {
261  setMaximumWidth(maxWidth);
263  }
264 };
265 
266 #endif // TREECOMBOBOX_H
void adjustPopupHeight()
Resize visible popup height when items are expanded/collapsed in the tree view.
An item rendering delegate to highlight parent items and draw better item separators.
Definition: TreeComboBox.h:50
QModelIndex indexBelow(QModelIndex index)
Find first valid item index which if after given index.
QAbstractItemModel * model() const const
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
QModelIndex lastIndex(const QModelIndex &index)
Find last (greatest) valid item index in a set (eg.
QTreeView subclass used to display the combo box popup items.
Definition: TreeComboBox.h:255
QModelIndex addParentItem(const QString &text, const bool selectable=false, const QModelIndex &parentIndex=QModelIndex(), const QVariant &userData=QVariant())
Definition: TreeComboBox.h:177
typedef MatchFlags
int findText(const QString &text, Qt::MatchFlags flags=Qt::MatchFlags(Qt::MatchExactly|Qt::MatchCaseSensitive)) const
Definition: TreeComboBox.h:125
QTreeView * m_view
Definition: TreeComboBox.h:239
void setView(QAbstractItemView *itemView=Q_NULLPTR)
Like QComboBox::setView but only accepts QTreeView (and derived) view classes.
void insertItems(int index, const QStringList &texts)
Definition: TreeComboBox.h:165
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
void setMinimumWidth(int minw)
QIcon itemIcon(int index) const
Reimplemented from superclass.
virtual void keyPressEvent(QKeyEvent *event) override
Reimplemented from superclass.
QModelIndex indexAbove(QModelIndex index)
Find first valid item index which if before given index.
static void setParent(QAbstractItemModel *model, const QModelIndex &index, const bool selectable=false)
void addItem(const QIcon &icon, const QString &text, const QVariant &userData=QVariant())
Definition: TreeComboBox.h:162
QVariant itemData(int index, int role=Qt::UserRole) const
Reimplemented from superclass.
void insertItem(int index, const QIcon &icon, const QString &text, const QVariant &userData=QVariant())
Definition: TreeComboBox.h:159
QModelIndex addItem(const QString &text, const QModelIndex &parentIndex, const QVariant &userData=QVariant())
Definition: TreeComboBox.h:152
bool m_skipNextHide
Definition: TreeComboBox.h:245
A QComboBox control which works with a tree-based data model & view, allowing drill-down selection of...
Definition: TreeComboBox.h:92
QModelIndex insertItem(int index, const QMap< int, QVariant > &values=QMap< int, QVariant >(), const QModelIndex &parentIndex=QModelIndex(), const bool reload=true)
Insert an item at given index (row), with optional data values, under parent item indicated by parent...
QMap< int, QPersistentModelIndex > m_indexMap
Definition: TreeComboBox.h:241
static bool isParent(const QModelIndex &index)
virtual QSize sizeHint() const const override
virtual void hidePopup() override
Reimplemented from superclass.
int width() const const
void clear()
Like QComboBox::clear() but does NOT remove any items from the current data model.
virtual int sizeHintForColumn(int column) const const override
virtual bool event(QEvent *event) override
int currentIndex() const
Reimplemented from superclass.
void setItemData(const QModelIndex &index, const QVariant &value, int role=Qt::UserRole)
Sets the data role for the item at index to the specified value.
int count() const const
void keyboardSearchString(const QString &text)
Reimplemented from superclass.
void resizeColumnToContents(int column)
UserRole
QModelIndex insertParentItem(int index, const QIcon &icon, const QString &text, const bool selectable=false, const QModelIndex &parentIndex=QModelIndex(), const QVariant &userData=QVariant())
Inserts an item and marks is as a "parent" type item.
void insertItems(int index, const QStringList &texts, const QModelIndex &parentIndex)
Inserts multiple items from a list as children of parentIndex.
void addItems(const QStringList &texts, const QModelIndex &parentIndex)
Definition: TreeComboBox.h:156
void adjustWidth(int maxWidth)
Definition: TreeComboBox.h:259
QModelIndex addParentItem(const QIcon &icon, const QString &text, const bool selectable=false, const QModelIndex &parentIndex=QModelIndex(), const QVariant &userData=QVariant())
Definition: TreeComboBox.h:179
static void setSeparator(QAbstractItemModel *model, const QModelIndex &index)
QScrollBar * verticalScrollBar() const const
int indentation() const const
void setCurrentText(const QString &text)
Definition: TreeComboBox.h:200
QTreeView * view() const
Definition: TreeComboBox.h:104
TreeComboBox(QWidget *parent=Q_NULLPTR)
QVariant fromValue(const T &value)
void reloadModel()
QVariant currentData(int role=Qt::UserRole) const
Reimplemented from superclass.
bool autoData() const
Definition: TreeComboBox.h:105
void ensureCurrentExpanded()
Called before showing popup to make sure the initial view size is correct.
bool usePopup(QStyleOptionComboBox *option=NULL)
Return true if style options are set to use a "popup" presentation style (typ.
static bool isSeparator(const QModelIndex &index)
void setMaximumWidth(int maxw)
int findData(const QVariant &data, int role=Qt::UserRole, Qt::MatchFlags flags=Qt::MatchFlags(Qt::MatchExactly|Qt::MatchCaseSensitive)) const
Reimplemented from superclass.
virtual void wheelEvent(QWheelEvent *event) override
Reimplemented from superclass.
void setItemIcon(int index, const QIcon &icon)
Definition: TreeComboBox.h:121
void addItems(const QStringList &texts)
Definition: TreeComboBox.h:164
void adjustPopupWidth()
Make sure tree view has a reasonable width.
void setModel(QAbstractItemModel *model)
Reimplemented from superclass.
QModelIndex addItem(const QIcon &icon, const QString &text, const QModelIndex &parentIndex, const QVariant &userData=QVariant())
Definition: TreeComboBox.h:154
void addItem(const QString &text, const QVariant &userData=QVariant())
Definition: TreeComboBox.h:161
int buildMap(QModelIndex parent=QModelIndex(), int row=0)
Emitted along with currentIndexChanged() signals and if item has valid Qt::UserRole data.
void currentModelIndexChanged(const QModelIndex &index)
void setItemText(int index, const QString &text)
Definition: TreeComboBox.h:120
QMap< QPersistentModelIndex, int > m_rowMap
Definition: TreeComboBox.h:240
void setItemData(int index, const QVariant &value, int role=Qt::UserRole)
Definition: TreeComboBox.h:119
QString itemText(int index) const
Definition: TreeComboBox.h:115
virtual QSize minimumSizeHint() const const override
virtual void showPopup() override
Reimplemented from superclass.
int setCurrentData(const QVariant &data, const int defaultIdx=-1, int role=Qt::UserRole, Qt::MatchFlags flags=Qt::MatchFlags(Qt::MatchExactly|Qt::MatchCaseSensitive))
This is a shortcut to using setCurrentIndex(findData()), and also returns the new index (like findDat...
QPersistentModelIndex m_currentIndex
Definition: TreeComboBox.h:242
void setCurrentIndex(int index)
Reimplemented from superclass.
void insertItem(int index, const QString &text, const QVariant &userData=QVariant())
Definition: TreeComboBox.h:163
QObject * parent() const const
void setAutoData(bool enable)
Definition: TreeComboBox.h:209
QString toString() const const
TreeComboItemDelegate(QObject *parent=Q_NULLPTR)
Definition: TreeComboBox.h:55
const T value(const Key &key, const T &defaultValue) const const
void currentDataChanged(const QVariant &data)
virtual bool eventFilter(QObject *object, QEvent *event) override
Reimplemented from superclass.