2014-10-14 17:45:32 +02:00
|
|
|
/****************************************************************************
|
|
|
|
|
**
|
2016-01-15 14:58:39 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2014-10-14 17:45:32 +02:00
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator.
|
|
|
|
|
**
|
|
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2016-01-15 14:58:39 +01:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2014-10-14 17:45:32 +02:00
|
|
|
**
|
2016-01-15 14:58:39 +01:00
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2014-10-14 17:45:32 +02:00
|
|
|
**
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
2016-03-18 07:55:01 +01:00
|
|
|
#pragma once
|
2014-10-14 17:45:32 +02:00
|
|
|
|
|
|
|
|
#include "utils_global.h"
|
2015-01-08 13:27:30 +01:00
|
|
|
|
2014-10-14 17:45:32 +02:00
|
|
|
#include <QAbstractItemModel>
|
|
|
|
|
|
2015-01-09 10:32:17 +01:00
|
|
|
#include <functional>
|
|
|
|
|
|
2014-10-14 17:45:32 +02:00
|
|
|
namespace Utils {
|
|
|
|
|
|
2015-01-29 09:58:23 +01:00
|
|
|
class TreeItem;
|
2015-01-14 09:09:15 +01:00
|
|
|
class TreeModel;
|
|
|
|
|
|
2015-01-29 09:58:23 +01:00
|
|
|
class QTCREATOR_UTILS_EXPORT TreeItemVisitor
|
|
|
|
|
{
|
|
|
|
|
public:
|
2015-02-06 21:00:56 +01:00
|
|
|
TreeItemVisitor() : m_level(0) {}
|
2015-01-29 09:58:23 +01:00
|
|
|
virtual ~TreeItemVisitor() {}
|
|
|
|
|
|
2015-02-06 21:00:56 +01:00
|
|
|
virtual bool preVisit(TreeItem *) { return true; }
|
|
|
|
|
virtual void visit(TreeItem *) {}
|
|
|
|
|
virtual void postVisit(TreeItem *) {}
|
|
|
|
|
|
|
|
|
|
int level() const { return m_level; }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
friend class TreeItem;
|
|
|
|
|
int m_level;
|
2015-01-29 09:58:23 +01:00
|
|
|
};
|
|
|
|
|
|
2014-10-14 17:45:32 +02:00
|
|
|
class QTCREATOR_UTILS_EXPORT TreeItem
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
TreeItem();
|
2015-01-21 15:44:04 +01:00
|
|
|
explicit TreeItem(const QStringList &displays, int flags = Qt::ItemIsEnabled);
|
2014-10-14 17:45:32 +02:00
|
|
|
virtual ~TreeItem();
|
|
|
|
|
|
|
|
|
|
virtual TreeItem *parent() const { return m_parent; }
|
|
|
|
|
virtual TreeItem *child(int pos) const;
|
|
|
|
|
virtual int rowCount() const;
|
|
|
|
|
|
|
|
|
|
virtual QVariant data(int column, int role) const;
|
2015-01-13 13:46:15 +01:00
|
|
|
virtual bool setData(int column, const QVariant &data, int role);
|
2014-10-14 17:45:32 +02:00
|
|
|
virtual Qt::ItemFlags flags(int column) const;
|
|
|
|
|
|
2015-01-29 09:58:23 +01:00
|
|
|
virtual bool hasChildren() const;
|
2015-01-21 15:50:54 +01:00
|
|
|
virtual bool canFetchMore() const;
|
|
|
|
|
virtual void fetchMore() {}
|
|
|
|
|
|
2014-10-14 17:45:32 +02:00
|
|
|
void prependChild(TreeItem *item);
|
|
|
|
|
void appendChild(TreeItem *item);
|
2015-01-21 15:50:54 +01:00
|
|
|
void insertChild(int pos, TreeItem *item);
|
2015-01-14 09:09:15 +01:00
|
|
|
void removeChildren();
|
2015-03-19 12:42:53 +01:00
|
|
|
void sortChildren(const std::function<bool(const TreeItem *, const TreeItem *)> &cmp);
|
2015-01-14 09:09:15 +01:00
|
|
|
void update();
|
2015-03-11 16:24:01 +01:00
|
|
|
void updateColumn(int column);
|
2015-01-14 09:09:15 +01:00
|
|
|
void expand();
|
|
|
|
|
TreeItem *firstChild() const;
|
2014-12-19 08:44:20 +01:00
|
|
|
TreeItem *lastChild() const;
|
|
|
|
|
int level() const;
|
2014-10-14 17:45:32 +02:00
|
|
|
|
|
|
|
|
void setFlags(Qt::ItemFlags flags);
|
2015-04-22 14:49:14 +02:00
|
|
|
int childCount() const { return m_children.size(); }
|
|
|
|
|
TreeItem *childAt(int index) const { return m_children.at(index); }
|
2015-01-06 17:48:39 +01:00
|
|
|
QVector<TreeItem *> children() const { return m_children; }
|
2015-01-14 09:09:15 +01:00
|
|
|
QModelIndex index() const;
|
|
|
|
|
|
|
|
|
|
TreeModel *model() const { return m_model; }
|
2014-10-14 17:45:32 +02:00
|
|
|
|
2015-01-29 09:58:23 +01:00
|
|
|
void walkTree(TreeItemVisitor *visitor);
|
|
|
|
|
void walkTree(std::function<void(TreeItem *)> f);
|
|
|
|
|
|
2016-05-04 16:41:15 +02:00
|
|
|
// Levels are 1-based: Child at Level 1 is an immediate child.
|
|
|
|
|
template <class T, typename Function>
|
|
|
|
|
void forEachChildAtLevel(int n, Function func) {
|
|
|
|
|
foreach (auto item, m_children) {
|
|
|
|
|
if (n == 1)
|
|
|
|
|
func(static_cast<T>(item));
|
|
|
|
|
else
|
|
|
|
|
item->forEachChildAtLevel<T>(n - 1, func);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class T, typename Function>
|
|
|
|
|
void forEachChild(Function func) const {
|
|
|
|
|
forEachChildAtLevel<T>(1, func);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class T, typename Predicate>
|
|
|
|
|
T findChildAtLevel(int n, Predicate func) const {
|
|
|
|
|
if (n == 1) {
|
|
|
|
|
foreach (auto item, m_children)
|
|
|
|
|
if (func(static_cast<T>(item)))
|
|
|
|
|
return static_cast<T>(item);
|
|
|
|
|
} else {
|
|
|
|
|
foreach (auto item, m_children)
|
|
|
|
|
if (T found = item->findChildAtLevel<T>(n - 1, func))
|
|
|
|
|
return found;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-14 17:45:32 +02:00
|
|
|
private:
|
|
|
|
|
TreeItem(const TreeItem &) Q_DECL_EQ_DELETE;
|
|
|
|
|
void operator=(const TreeItem &) Q_DECL_EQ_DELETE;
|
|
|
|
|
|
|
|
|
|
void clear();
|
2015-01-16 15:24:53 +01:00
|
|
|
void propagateModel(TreeModel *m);
|
2014-10-14 17:45:32 +02:00
|
|
|
|
|
|
|
|
TreeItem *m_parent; // Not owned.
|
2015-01-14 09:09:15 +01:00
|
|
|
TreeModel *m_model; // Not owned.
|
2014-10-14 17:45:32 +02:00
|
|
|
QVector<TreeItem *> m_children; // Owned.
|
2014-12-19 08:44:20 +01:00
|
|
|
QStringList *m_displays;
|
2014-10-14 17:45:32 +02:00
|
|
|
Qt::ItemFlags m_flags;
|
2014-12-19 08:44:20 +01:00
|
|
|
|
|
|
|
|
friend class TreeModel;
|
2014-10-14 17:45:32 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class QTCREATOR_UTILS_EXPORT TreeModel : public QAbstractItemModel
|
|
|
|
|
{
|
2015-01-14 09:09:15 +01:00
|
|
|
Q_OBJECT
|
|
|
|
|
|
2014-10-14 17:45:32 +02:00
|
|
|
public:
|
|
|
|
|
explicit TreeModel(QObject *parent = 0);
|
2015-01-16 15:24:53 +01:00
|
|
|
explicit TreeModel(TreeItem *root, QObject *parent = 0);
|
2016-05-02 08:28:42 +02:00
|
|
|
~TreeModel() override;
|
2014-10-14 17:45:32 +02:00
|
|
|
|
2015-04-22 14:49:14 +02:00
|
|
|
void setHeader(const QStringList &displays);
|
2015-06-11 15:40:30 +02:00
|
|
|
void setHeaderToolTip(const QStringList &tips);
|
2015-04-22 14:49:14 +02:00
|
|
|
void clear();
|
|
|
|
|
|
|
|
|
|
TreeItem *rootItem() const;
|
|
|
|
|
void setRootItem(TreeItem *item);
|
|
|
|
|
TreeItem *itemForIndex(const QModelIndex &) const;
|
|
|
|
|
QModelIndex indexForItem(const TreeItem *needle) const;
|
|
|
|
|
|
|
|
|
|
int topLevelItemCount() const;
|
2016-05-02 08:28:42 +02:00
|
|
|
int rowCount(const QModelIndex &idx = QModelIndex()) const override;
|
|
|
|
|
int columnCount(const QModelIndex &idx) const override;
|
|
|
|
|
|
|
|
|
|
bool setData(const QModelIndex &idx, const QVariant &data, int role) override;
|
|
|
|
|
QVariant data(const QModelIndex &idx, int role) const override;
|
|
|
|
|
QModelIndex index(int, int, const QModelIndex &idx = QModelIndex()) const override;
|
|
|
|
|
QModelIndex parent(const QModelIndex &idx) const override;
|
|
|
|
|
Qt::ItemFlags flags(const QModelIndex &idx) const override;
|
|
|
|
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
|
|
|
|
bool hasChildren(const QModelIndex &idx) const override;
|
|
|
|
|
|
|
|
|
|
bool canFetchMore(const QModelIndex &idx) const override;
|
|
|
|
|
void fetchMore(const QModelIndex &idx) override;
|
2015-01-21 15:50:54 +01:00
|
|
|
|
2016-05-04 16:41:15 +02:00
|
|
|
template <class T, typename Function>
|
|
|
|
|
void forEachItemAtLevel(int n, Function func) const {
|
|
|
|
|
m_root->forEachChildAtLevel<T>(n, func);
|
2015-01-09 10:32:17 +01:00
|
|
|
}
|
|
|
|
|
|
2016-05-04 16:41:15 +02:00
|
|
|
template <class T, typename Predicate>
|
|
|
|
|
T findItemAtLevel(int n, Predicate func) const {
|
|
|
|
|
return m_root->findChildAtLevel<T>(n, func);
|
2015-01-09 10:32:17 +01:00
|
|
|
}
|
|
|
|
|
|
2015-06-09 09:33:14 +02:00
|
|
|
TreeItem *takeItem(TreeItem *item); // item is not destroyed.
|
2015-01-14 09:09:15 +01:00
|
|
|
|
|
|
|
|
signals:
|
|
|
|
|
void requestExpansion(QModelIndex);
|
|
|
|
|
|
2014-10-14 17:45:32 +02:00
|
|
|
private:
|
2015-01-14 09:09:15 +01:00
|
|
|
friend class TreeItem;
|
|
|
|
|
|
2014-10-14 17:45:32 +02:00
|
|
|
TreeItem *m_root; // Owned.
|
2015-01-16 15:24:53 +01:00
|
|
|
QStringList m_header;
|
2015-06-11 15:40:30 +02:00
|
|
|
QStringList m_headerToolTip;
|
2015-01-16 15:24:53 +01:00
|
|
|
int m_columnCount;
|
2014-10-14 17:45:32 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace Utils
|