forked from qt-creator/qt-creator
TreeModel: (Partially) separate header data from root item
Full separation does not seem possible as QTreeView assumes all items to have equal column count. Change-Id: Ia260924fe13ea62789923af8484f9838295355b6 Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
@@ -285,8 +285,7 @@ PluginView::PluginView(QWidget *parent)
|
||||
m_categoryView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
|
||||
m_model = new TreeModel(this);
|
||||
m_model->setRootItem(new TreeItem(QStringList()
|
||||
<< tr("Name") << tr("Load") << tr("Version") << tr("Vendor")));
|
||||
m_model->setHeader(QStringList() << tr("Name") << tr("Load") << tr("Version") << tr("Vendor"));
|
||||
m_categoryView->setModel(m_model);
|
||||
|
||||
QGridLayout *gridLayout = new QGridLayout(this);
|
||||
|
@@ -640,11 +640,6 @@ bool TreeItem::isLazy() const
|
||||
return m_lazy;
|
||||
}
|
||||
|
||||
int TreeItem::columnCount() const
|
||||
{
|
||||
return m_displays ? m_displays->size() : 1;
|
||||
}
|
||||
|
||||
int TreeItem::rowCount() const
|
||||
{
|
||||
ensurePopulated();
|
||||
@@ -680,8 +675,9 @@ void TreeItem::prependChild(TreeItem *item)
|
||||
{
|
||||
QTC_CHECK(!item->parent());
|
||||
|
||||
if (m_model) {
|
||||
if (m_model && !m_lazy) {
|
||||
QModelIndex idx = index();
|
||||
item->propagateModel(m_model);
|
||||
m_model->beginInsertRows(idx, 0, 0);
|
||||
item->m_parent = this;
|
||||
item->m_model = m_model;
|
||||
@@ -696,9 +692,10 @@ void TreeItem::appendChild(TreeItem *item)
|
||||
{
|
||||
QTC_CHECK(!item->parent());
|
||||
|
||||
if (m_model) {
|
||||
if (m_model && !m_lazy) {
|
||||
const int n = rowCount();
|
||||
QModelIndex idx = index();
|
||||
item->propagateModel(m_model);
|
||||
m_model->beginInsertRows(idx, n, n);
|
||||
item->m_parent = this;
|
||||
item->m_model = m_model;
|
||||
@@ -728,7 +725,7 @@ void TreeItem::update()
|
||||
{
|
||||
if (m_model) {
|
||||
QModelIndex idx = index();
|
||||
m_model->dataChanged(idx.sibling(idx.row(), 0), idx.sibling(idx.row(), columnCount() - 1));
|
||||
m_model->dataChanged(idx.sibling(idx.row(), 0), idx.sibling(idx.row(), m_model->m_columnCount - 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -799,6 +796,17 @@ void TreeItem::ensurePopulated() const
|
||||
}
|
||||
}
|
||||
|
||||
void TreeItem::propagateModel(TreeModel *m)
|
||||
{
|
||||
QTC_ASSERT(m, return);
|
||||
QTC_ASSERT(m_model == 0 || m_model == m, return);
|
||||
if (m && !m_model) {
|
||||
m_model = m;
|
||||
foreach (TreeItem *item, m_children)
|
||||
item->propagateModel(m);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\class Utils::TreeModel
|
||||
|
||||
@@ -807,13 +815,24 @@ void TreeItem::ensurePopulated() const
|
||||
*/
|
||||
|
||||
TreeModel::TreeModel(QObject *parent)
|
||||
: QAbstractItemModel(parent), m_root(new TreeItem)
|
||||
: QAbstractItemModel(parent),
|
||||
m_root(new TreeItem)
|
||||
{
|
||||
m_columnCount = 1;
|
||||
m_root->m_model = this;
|
||||
#if USE_MODEL_TEST
|
||||
new ModelTest(this, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
TreeModel::TreeModel(TreeItem *root, QObject *parent)
|
||||
: QAbstractItemModel(parent),
|
||||
m_root(root)
|
||||
{
|
||||
m_columnCount = 1;
|
||||
m_root->m_model = this;
|
||||
}
|
||||
|
||||
TreeModel::~TreeModel()
|
||||
{
|
||||
delete m_root;
|
||||
@@ -854,11 +873,9 @@ int TreeModel::rowCount(const QModelIndex &idx) const
|
||||
int TreeModel::columnCount(const QModelIndex &idx) const
|
||||
{
|
||||
CHECK_INDEX(idx);
|
||||
if (!idx.isValid())
|
||||
return m_root->columnCount();
|
||||
if (idx.column() > 0)
|
||||
return 0;
|
||||
return itemFromIndex(idx)->columnCount();
|
||||
return m_columnCount;
|
||||
}
|
||||
|
||||
bool TreeModel::setData(const QModelIndex &idx, const QVariant &data, int role)
|
||||
@@ -879,8 +896,8 @@ QVariant TreeModel::data(const QModelIndex &idx, int role) const
|
||||
QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal)
|
||||
return m_root->data(section, role);
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section < m_header.size())
|
||||
return m_header.at(section);
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
@@ -898,11 +915,15 @@ TreeItem *TreeModel::rootItem() const
|
||||
return m_root;
|
||||
}
|
||||
|
||||
void TreeModel::setRootItem(TreeItem *item)
|
||||
void TreeModel::setHeader(const QStringList &displays)
|
||||
{
|
||||
delete m_root;
|
||||
m_root = item;
|
||||
m_root->setModel(this);
|
||||
m_header = displays;
|
||||
m_columnCount = displays.size();
|
||||
}
|
||||
|
||||
void TreeModel::setColumnCount(int columnCount)
|
||||
{
|
||||
m_columnCount = columnCount;
|
||||
}
|
||||
|
||||
QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
|
||||
|
@@ -55,7 +55,6 @@ public:
|
||||
virtual TreeItem *parent() const { return m_parent; }
|
||||
virtual TreeItem *child(int pos) const;
|
||||
virtual bool isLazy() const;
|
||||
virtual int columnCount() const;
|
||||
virtual int rowCount() const;
|
||||
virtual void populate();
|
||||
|
||||
@@ -87,6 +86,7 @@ private:
|
||||
|
||||
void clear();
|
||||
void ensurePopulated() const;
|
||||
void propagateModel(TreeModel *m);
|
||||
|
||||
TreeItem *m_parent; // Not owned.
|
||||
TreeModel *m_model; // Not owned.
|
||||
@@ -229,6 +229,7 @@ class QTCREATOR_UTILS_EXPORT TreeModel : public QAbstractItemModel
|
||||
|
||||
public:
|
||||
explicit TreeModel(QObject *parent = 0);
|
||||
explicit TreeModel(TreeItem *root, QObject *parent = 0);
|
||||
virtual ~TreeModel();
|
||||
|
||||
int rowCount(const QModelIndex &idx = QModelIndex()) const;
|
||||
@@ -242,11 +243,13 @@ public:
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
|
||||
TreeItem *rootItem() const;
|
||||
void setRootItem(TreeItem *item);
|
||||
TreeItem *itemFromIndex(const QModelIndex &) const;
|
||||
QModelIndex indexFromItem(const TreeItem *needle) const;
|
||||
void removeItems();
|
||||
|
||||
void setHeader(const QStringList &displays);
|
||||
void setColumnCount(int columnCount);
|
||||
|
||||
UntypedTreeLevelItems untypedLevelItems(int level = 0, TreeItem *start = 0) const;
|
||||
UntypedTreeLevelItems untypedLevelItems(TreeItem *start) const;
|
||||
|
||||
@@ -277,6 +280,8 @@ private:
|
||||
friend class TreeItem;
|
||||
|
||||
TreeItem *m_root; // Owned.
|
||||
QStringList m_header;
|
||||
int m_columnCount;
|
||||
};
|
||||
|
||||
} // namespace Utils
|
||||
|
@@ -56,8 +56,6 @@ namespace Internal {
|
||||
|
||||
struct LocationItem : public TreeItem
|
||||
{
|
||||
int columnCount() const { return 8; }
|
||||
|
||||
QVariant data(int column, int role) const
|
||||
{
|
||||
if (role == Qt::DisplayRole) {
|
||||
@@ -86,7 +84,6 @@ class BreakpointItem : public QObject, public TreeItem
|
||||
public:
|
||||
~BreakpointItem();
|
||||
|
||||
int columnCount() const { return 8; }
|
||||
QVariant data(int column, int role) const;
|
||||
|
||||
QIcon icon() const;
|
||||
@@ -251,10 +248,9 @@ BreakHandler::BreakHandler()
|
||||
#if USE_BREAK_MODEL_TEST
|
||||
new ModelTest(this, 0);
|
||||
#endif
|
||||
auto root = new TreeItem(QStringList()
|
||||
setHeader(QStringList()
|
||||
<< tr("Number") << tr("Function") << tr("File") << tr("Line")
|
||||
<< tr("Address") << tr("Condition") << tr("Ignore") << tr("Threads"));
|
||||
setRootItem(root);
|
||||
}
|
||||
|
||||
QIcon BreakHandler::breakpointIcon()
|
||||
|
@@ -65,8 +65,6 @@ class DebuggerTreeItem : public TreeItem
|
||||
public:
|
||||
DebuggerTreeItem(const DebuggerItem &item, bool changed) : m_item(item), m_changed(changed) {}
|
||||
|
||||
int columnCount() const { return 3; }
|
||||
|
||||
QVariant data(int column, int role) const
|
||||
{
|
||||
switch (role) {
|
||||
@@ -119,10 +117,9 @@ private:
|
||||
DebuggerItemModel::DebuggerItemModel()
|
||||
: m_currentTreeItem(0)
|
||||
{
|
||||
auto root = new TreeItem(QStringList() << tr("Name") << tr("Location") << tr("Type"));
|
||||
root->appendChild(new TreeItem(QStringList() << tr("Auto-detected") << QString() << QString()));
|
||||
root->appendChild(new TreeItem(QStringList() << tr("Manual") << QString() << QString()));
|
||||
setRootItem(root);
|
||||
setHeader(QStringList() << tr("Name") << tr("Location") << tr("Type"));
|
||||
rootItem()->appendChild(new TreeItem(QStringList() << tr("Auto-detected") << QString() << QString()));
|
||||
rootItem()->appendChild(new TreeItem(QStringList() << tr("Manual") << QString() << QString()));
|
||||
|
||||
foreach (const DebuggerItem &item, DebuggerItemManager::debuggers())
|
||||
addDebugger(item, false);
|
||||
|
@@ -177,14 +177,13 @@ ModulesHandler::ModulesHandler(DebuggerEngine *engine)
|
||||
QString pad = QLatin1String(" ");
|
||||
m_model = new TreeModel(this);
|
||||
m_model->setObjectName(QLatin1String("ModulesModel"));
|
||||
auto root = new TreeItem(QStringList()
|
||||
m_model->setHeader(QStringList()
|
||||
<< ModulesHandler::tr("Module Name") + pad
|
||||
<< ModulesHandler::tr("Module Path") + pad
|
||||
<< ModulesHandler::tr("Symbols Read") + pad
|
||||
<< ModulesHandler::tr("Symbols Type") + pad
|
||||
<< ModulesHandler::tr("Start Address") + pad
|
||||
<< ModulesHandler::tr("End Address") + pad);
|
||||
m_model->setRootItem(root);
|
||||
|
||||
m_proxyModel = new QSortFilterProxyModel(this);
|
||||
m_proxyModel->setObjectName(QLatin1String("ModulesProxyModel"));
|
||||
|
@@ -371,7 +371,6 @@ public:
|
||||
: m_subKind(subKind), m_subSize(subSize), m_count(count), m_changed(false)
|
||||
{}
|
||||
|
||||
int columnCount() const { return 2; }
|
||||
QVariant data(int column, int role) const;
|
||||
|
||||
Qt::ItemFlags flags(int column) const
|
||||
@@ -393,7 +392,6 @@ class RegisterItem : public Utils::TreeItem
|
||||
public:
|
||||
explicit RegisterItem(const Register ®);
|
||||
|
||||
int columnCount() const { return 2; }
|
||||
QVariant data(int column, int role) const;
|
||||
Qt::ItemFlags flags(int column) const;
|
||||
|
||||
@@ -524,26 +522,11 @@ QVariant RegisterSubItem::data(int column, int role) const
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
class RegisterRootItem : public Utils::TreeItem
|
||||
{
|
||||
public:
|
||||
int columnCount() const { return 2; }
|
||||
QVariant data(int section, int role) const
|
||||
{
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch (section) {
|
||||
case 0: return RegisterHandler::tr("Name");
|
||||
case 1: return RegisterHandler::tr("Value");
|
||||
};
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
};
|
||||
|
||||
RegisterHandler::RegisterHandler()
|
||||
{
|
||||
setObjectName(QLatin1String("RegisterModel"));
|
||||
setRootItem(new RegisterRootItem); // Needed to get two columns.
|
||||
setHeader(QStringList() << tr("Name") << tr("Value"));
|
||||
|
||||
#if USE_REGISTER_MODEL_TEST
|
||||
new ModelTest(this, 0);
|
||||
#endif
|
||||
|
@@ -112,12 +112,11 @@ KitModel::KitModel(QBoxLayout *parentLayout, QObject *parent) :
|
||||
m_defaultNode(0),
|
||||
m_keepUnique(true)
|
||||
{
|
||||
auto root = new TreeItem(QStringList(tr("Name")));
|
||||
setHeader(QStringList(tr("Name")));
|
||||
m_autoRoot = new TreeItem(QStringList(tr("Auto-detected")));
|
||||
m_manualRoot = new TreeItem(QStringList(tr("Manual")));
|
||||
root->appendChild(m_autoRoot);
|
||||
root->appendChild(m_manualRoot);
|
||||
setRootItem(root);
|
||||
rootItem()->appendChild(m_autoRoot);
|
||||
rootItem()->appendChild(m_manualRoot);
|
||||
|
||||
foreach (Kit *k, KitManager::sortedKits())
|
||||
addKit(k);
|
||||
|
@@ -491,8 +491,7 @@ void ProjectWizardPage::initializeProjectTree(Node *context, const QStringList &
|
||||
|
||||
setAdditionalInfo(selector.deployingProjects());
|
||||
|
||||
TreeModel *model = new TreeModel;
|
||||
model->setRootItem(tree);
|
||||
TreeModel *model = new TreeModel(tree);
|
||||
setModel(model);
|
||||
setBestNode(selector.bestChoice());
|
||||
setAddingSubProject(action == AddSubProject);
|
||||
|
@@ -78,8 +78,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
int columnCount() const { return 2; }
|
||||
|
||||
QVariant data(int column, int role) const
|
||||
{
|
||||
switch (role) {
|
||||
@@ -119,23 +117,22 @@ public:
|
||||
m_factories = ExtensionSystem::PluginManager::getObjects<ToolChainFactory>(
|
||||
[](ToolChainFactory *factory) { return factory->canCreate();});
|
||||
|
||||
auto root = new TreeItem(QStringList() << tr("Name") << tr("Type"));
|
||||
m_model.setHeader(QStringList() << tr("Name") << tr("Type"));
|
||||
m_autoRoot = new TreeItem(QStringList() << tr("Auto-detected") << QString());
|
||||
m_manualRoot = new TreeItem(QStringList() << tr("Manual") << QString());
|
||||
root->appendChild(m_autoRoot);
|
||||
root->appendChild(m_manualRoot);
|
||||
m_model.rootItem()->appendChild(m_autoRoot);
|
||||
m_model.rootItem()->appendChild(m_manualRoot);
|
||||
foreach (ToolChain *tc, ToolChainManager::toolChains()) {
|
||||
TreeItem *parent = tc->isAutoDetected() ? m_autoRoot : m_manualRoot;
|
||||
parent->appendChild(new ToolChainTreeItem(tc, false));
|
||||
}
|
||||
m_model.setRootItem(root);
|
||||
|
||||
m_toolChainView = new QTreeView(this);
|
||||
m_toolChainView->setUniformRowHeights(true);
|
||||
m_toolChainView->header()->setStretchLastSection(false);
|
||||
m_toolChainView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_toolChainView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
m_toolChainView->setModel(&m_model);
|
||||
m_toolChainView->header()->setStretchLastSection(false);
|
||||
m_toolChainView->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||
m_toolChainView->header()->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
m_toolChainView->expandAll();
|
||||
|
Reference in New Issue
Block a user