Commit 7e522c8a authored by hjk's avatar hjk

TreeModel: Add model pointer to TreeItem

... and use the items themselves as main entry point for
item related operations.

With non-uniform tree items it's easier to have item specific
functionality directly in the item implementation instead of
the model.

Change-Id: I4e9b7db98d16b91ddef81917417691129bb83621
Reviewed-by: default avatarChristian Stenger <christian.stenger@theqtcompany.com>
parent 6bc0b9e5
......@@ -611,13 +611,13 @@ namespace Utils {
// TreeItem
//
TreeItem::TreeItem()
: m_parent(0), m_displays(0), m_lazy(false), m_populated(false),
: m_parent(0), m_model(0), m_displays(0), m_lazy(false), m_populated(false),
m_flags(Qt::ItemIsEnabled|Qt::ItemIsSelectable)
{
}
TreeItem::TreeItem(const QStringList &displays)
: m_parent(0), m_displays(new QStringList(displays)), m_lazy(false), m_populated(false),
: m_parent(0), m_model(0), m_displays(new QStringList(displays)), m_lazy(false), m_populated(false),
m_flags(Qt::ItemIsEnabled|Qt::ItemIsSelectable)
{
}
......@@ -679,15 +679,62 @@ Qt::ItemFlags TreeItem::flags(int column) const
void TreeItem::prependChild(TreeItem *item)
{
QTC_CHECK(!item->parent());
item->m_parent = this;
m_children.prepend(item);
if (m_model) {
QModelIndex idx = index();
m_model->beginInsertRows(idx, 0, 0);
item->m_parent = this;
item->m_model = m_model;
m_children.prepend(item);
m_model->endInsertRows();
} else {
m_children.prepend(item);
}
}
void TreeItem::appendChild(TreeItem *item)
{
QTC_CHECK(!item->parent());
item->m_parent = this;
m_children.append(item);
if (m_model) {
const int n = rowCount();
QModelIndex idx = index();
m_model->beginInsertRows(idx, n, n);
item->m_parent = this;
item->m_model = m_model;
m_children.append(item);
m_model->endInsertRows();
} else {
item->m_parent = this;
m_children.append(item);
}
}
void TreeItem::removeChildren()
{
if (rowCount() == 0)
return;
if (m_model) {
QModelIndex idx = index();
m_model->beginRemoveRows(idx, 0, rowCount() - 1);
clear();
m_model->endRemoveRows();
} else {
clear();
}
}
void TreeItem::update()
{
if (m_model) {
QModelIndex idx = index();
m_model->dataChanged(idx.sibling(idx.row(), 0), idx.sibling(idx.row(), columnCount() - 1));
}
}
TreeItem *TreeItem::firstChild() const
{
return m_children.isEmpty() ? 0 : m_children.first();
}
TreeItem *TreeItem::lastChild() const
......@@ -713,6 +760,21 @@ void TreeItem::setFlags(Qt::ItemFlags flags)
m_flags = flags;
}
QModelIndex TreeItem::index() const
{
QTC_ASSERT(m_model, return QModelIndex());
return m_model->indexFromItem(this);
}
void TreeItem::setModel(TreeModel *model)
{
if (m_model == model)
return;
m_model = model;
foreach (TreeItem *item, m_children)
item->setModel(model);
}
void TreeItem::clear()
{
while (m_children.size()) {
......@@ -722,6 +784,12 @@ void TreeItem::clear()
}
}
void TreeItem::expand()
{
QTC_ASSERT(m_model, return);
m_model->requestExpansion(index());
}
void TreeItem::ensurePopulated() const
{
if (!m_populated) {
......@@ -834,6 +902,7 @@ void TreeModel::setRootItem(TreeItem *item)
{
delete m_root;
m_root = item;
m_root->setModel(this);
}
QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
......@@ -866,22 +935,10 @@ QModelIndex TreeModel::indexFromItem(const TreeItem *item) const
return createIndex(row, 0, mitem);
}
void TreeModel::appendItem(TreeItem *parent, TreeItem *item)
void TreeModel::removeItems()
{
QTC_ASSERT(item, return);
QTC_ASSERT(parent, return);
QModelIndex idx = indexFromItem(parent);
const int n = parent->rowCount();
beginInsertRows(idx, n, n);
parent->appendChild(item);
endInsertRows();
}
void TreeModel::updateItem(TreeItem *item)
{
QModelIndex idx = indexFromItem(item);
dataChanged(idx.sibling(idx.row(), 0), idx.sibling(idx.row(), item->columnCount() - 1));
if (m_root)
m_root->removeChildren();
}
UntypedTreeLevelItems TreeModel::untypedLevelItems(int level, TreeItem *start) const
......@@ -915,17 +972,6 @@ void TreeModel::removeItem(TreeItem *item)
endRemoveRows();
}
void TreeModel::removeAllSubItems(TreeItem *item)
{
QTC_ASSERT(item, return);
if (item->rowCount() == 0)
return;
QModelIndex idx = indexFromItem(item);
beginRemoveRows(idx, 0, item->rowCount() - 1);
item->clear();
endRemoveRows();
}
//
// TreeLevelItems
//
......
......@@ -43,6 +43,8 @@
namespace Utils {
class TreeModel;
class QTCREATOR_UTILS_EXPORT TreeItem
{
public:
......@@ -63,6 +65,10 @@ public:
void prependChild(TreeItem *item);
void appendChild(TreeItem *item);
void removeChildren();
void update();
void expand();
TreeItem *firstChild() const;
TreeItem *lastChild() const;
int level() const;
......@@ -70,6 +76,10 @@ public:
void setPopulated(bool on);
void setFlags(Qt::ItemFlags flags);
QVector<TreeItem *> children() const { return m_children; }
QModelIndex index() const;
TreeModel *model() const { return m_model; }
void setModel(TreeModel *model);
private:
TreeItem(const TreeItem &) Q_DECL_EQ_DELETE;
......@@ -79,6 +89,7 @@ private:
void ensurePopulated() const;
TreeItem *m_parent; // Not owned.
TreeModel *m_model; // Not owned.
QVector<TreeItem *> m_children; // Owned.
QStringList *m_displays;
bool m_lazy;
......@@ -214,6 +225,8 @@ private:
class QTCREATOR_UTILS_EXPORT TreeModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit TreeModel(QObject *parent = 0);
virtual ~TreeModel();
......@@ -232,11 +245,7 @@ public:
void setRootItem(TreeItem *item);
TreeItem *itemFromIndex(const QModelIndex &) const;
QModelIndex indexFromItem(const TreeItem *needle) const;
void appendItem(TreeItem *parent, TreeItem *item);
void removeItem(TreeItem *item); // item is not destroyed.
void removeAllSubItems(TreeItem *item); // item is not destroyed.
void updateItem(TreeItem *item); // call to trigger dataChanged
void removeItems();
UntypedTreeLevelItems untypedLevelItems(int level = 0, TreeItem *start = 0) const;
UntypedTreeLevelItems untypedLevelItems(TreeItem *start) const;
......@@ -259,7 +268,14 @@ public:
return Utils::findOrDefault(treeLevelItems<T>(level, start), f);
}
void removeItem(TreeItem *item); // item is not destroyed.
signals:
void requestExpansion(QModelIndex);
private:
friend class TreeItem;
TreeItem *m_root; // Owned.
};
......
......@@ -98,7 +98,6 @@ public:
bool isLocatedAt(const QString &fileName, int lineNumber, bool useMarkerPosition) const;
bool needsChildren() const;
void update();
void setMarkerFileAndLine(const QString &fileName, int lineNumber);
......@@ -912,11 +911,6 @@ void BreakpointItem::deleteThis()
QTC_CHECK(invoker.wasSuccessful());
}
void BreakpointItem::update()
{
m_handler->updateItem(this);
}
void Breakpoint::gotoState(BreakpointState target, BreakpointState assumedCurrent)
{
QTC_ASSERT(b, return);
......@@ -981,7 +975,7 @@ void Breakpoint::notifyBreakpointChangeFailed()
void Breakpoint::notifyBreakpointReleased()
{
QTC_ASSERT(b, return);
b->m_handler->removeAllSubItems(b);
b->removeChildren();
//QTC_ASSERT(b->m_state == BreakpointChangeProceeding, qDebug() << b->m_state);
b->m_state = BreakpointNew;
b->m_engine = 0;
......@@ -1052,7 +1046,7 @@ void BreakHandler::appendBreakpointInternal(const BreakpointParameters &params)
BreakpointItem *b = new BreakpointItem(this);
b->m_params = params;
b->updateMarker();
appendItem(rootItem(), b);
rootItem()->appendChild(b);
}
void BreakHandler::handleAlienBreakpoint(const BreakpointResponse &response, DebuggerEngine *engine)
......@@ -1070,7 +1064,7 @@ void BreakHandler::handleAlienBreakpoint(const BreakpointResponse &response, Deb
b->m_state = BreakpointInserted;
b->m_engine = engine;
b->updateMarker();
appendItem(rootItem(), b);
rootItem()->appendChild(b);
}
}
......@@ -1092,7 +1086,7 @@ void BreakpointItem::insertSubBreakpoint(const BreakpointResponse &params)
if (l->params.id.minorPart() == minorPart) {
// This modifies an existing sub-breakpoint.
l->params = params;
m_handler->updateItem(l);
l->update();
return;
}
}
......@@ -1100,9 +1094,8 @@ void BreakpointItem::insertSubBreakpoint(const BreakpointResponse &params)
// This is a new sub-breakpoint.
LocationItem *l = new LocationItem;
l->params = params;
m_handler->appendItem(this, l);
m_handler->requestExpansion(m_handler->indexFromItem(this));
appendChild(l);
expand();
}
void BreakHandler::saveSessionData()
......@@ -1112,7 +1105,7 @@ void BreakHandler::saveSessionData()
void BreakHandler::loadSessionData()
{
removeAllSubItems(rootItem());
removeItems();
loadBreakpoints();
}
......
......@@ -214,9 +214,6 @@ public:
Breakpoint breakpointById(BreakpointModelId id) const;
signals:
void requestExpansion(QModelIndex);
private:
friend class BreakpointItem;
friend class Breakpoint;
......
......@@ -131,7 +131,7 @@ DebuggerItemModel::DebuggerItemModel()
void DebuggerItemModel::addDebugger(const DebuggerItem &item, bool changed)
{
int group = item.isAutoDetected() ? 0 : 1;
appendItem(rootItem()->child(group), new DebuggerTreeItem(item, changed));
rootItem()->child(group)->appendChild(new DebuggerTreeItem(item, changed));
}
void DebuggerItemModel::updateDebugger(const DebuggerItem &item)
......@@ -146,8 +146,7 @@ void DebuggerItemModel::updateDebugger(const DebuggerItem &item)
const DebuggerItem *orig = DebuggerItemManager::findById(item.id());
treeItem->m_changed = !orig || *orig != item;
treeItem->m_item = item;
updateItem(treeItem); // Notify views.
treeItem->update(); // Notify views.
}
QModelIndex DebuggerItemModel::lastIndex() const
......
......@@ -198,7 +198,7 @@ QAbstractItemModel *ModulesHandler::model() const
void ModulesHandler::removeAll()
{
m_model->removeAllSubItems(m_model->rootItem());
m_model->removeItems();
}
Modules ModulesHandler::modules() const
......@@ -228,13 +228,13 @@ void ModulesHandler::updateModule(const Module &module)
} else {
item = new ModuleItem;
item->module = module;
m_model->appendItem(m_model->rootItem(), item);
m_model->rootItem()->appendChild(item);
}
try { // MinGW occasionallly throws std::bad_alloc.
ElfReader reader(path);
item->module.elfData = reader.readHeaders();
m_model->updateItem(item);
item->update();
} catch(...) {
qWarning("%s: An exception occurred while reading module '%s'",
Q_FUNC_INFO, qPrintable(module.modulePath));
......
......@@ -198,7 +198,7 @@ void KitModel::apply()
foreach (KitNode *n, treeLevelItems<KitNode *>(2)) {
if (n->widget->isDirty()) {
n->widget->apply();
updateItem(n);
n->update();
}
}
......@@ -212,11 +212,9 @@ void KitModel::markForRemoval(Kit *k)
return;
if (node == m_defaultNode) {
TreeItem *newDefault = 0;
if (!m_autoRoot->children().isEmpty())
newDefault = m_autoRoot->children().at(0);
else if (!m_manualRoot->children().isEmpty())
newDefault = m_manualRoot->children().at(0);
TreeItem *newDefault = m_autoRoot->firstChild();
if (!newDefault)
newDefault = m_manualRoot->firstChild();
setDefaultNode(static_cast<KitNode *>(newDefault));
}
......@@ -230,7 +228,7 @@ void KitModel::markForRemoval(Kit *k)
Kit *KitModel::markForAddition(Kit *baseKit)
{
KitNode *node = createNode(0);
appendItem(m_manualRoot, node);
m_manualRoot->appendChild(node);
Kit *k = node->widget->workingCopy();
KitGuard g(k);
if (baseKit) {
......@@ -261,7 +259,9 @@ KitNode *KitModel::createNode(Kit *k)
{
KitNode *node = new KitNode(k);
m_parentLayout->addWidget(node->widget);
connect(node->widget, &KitManagerConfigWidget::dirty, [this, node] { updateItem(node); });
connect(node->widget, &KitManagerConfigWidget::dirty, [node] {
node->update();
});
return node;
}
......@@ -269,12 +269,12 @@ void KitModel::setDefaultNode(KitNode *node)
{
if (m_defaultNode) {
m_defaultNode->widget->setIsDefaultKit(false);
updateItem(m_defaultNode);
m_defaultNode->update();
}
m_defaultNode = node;
if (m_defaultNode) {
m_defaultNode->widget->setIsDefaultKit(true);
updateItem(m_defaultNode);
m_defaultNode->update();
}
}
......@@ -287,7 +287,7 @@ void KitModel::addKit(Kit *k)
}
TreeItem *parent = k->isAutoDetected() ? m_autoRoot : m_manualRoot;
appendItem(parent, createNode(k));
parent->appendChild(createNode(k));
validateKitNames();
emit kitStateChanged();
......
......@@ -64,16 +64,16 @@ namespace Internal {
class ToolChainTreeItem : public TreeItem
{
public:
ToolChainTreeItem(TreeModel *model, ToolChain *tc, bool c) :
ToolChainTreeItem(ToolChain *tc, bool c) :
toolChain(tc), changed(c)
{
widget = tc->configurationWidget();
if (widget) {
if (tc->isAutoDetected())
widget->makeReadOnly();
QObject::connect(widget, &ToolChainConfigWidget::dirty, [this, model] {
QObject::connect(widget, &ToolChainConfigWidget::dirty, [this] {
changed = true;
model->updateItem(this);
update();
});
}
}
......@@ -126,7 +126,7 @@ public:
root->appendChild(m_manualRoot);
foreach (ToolChain *tc, ToolChainManager::toolChains()) {
TreeItem *parent = tc->isAutoDetected() ? m_autoRoot : m_manualRoot;
parent->appendChild(new ToolChainTreeItem(&m_model, tc, false));
parent->appendChild(new ToolChainTreeItem(tc, false));
}
m_model.setRootItem(root);
......@@ -244,7 +244,7 @@ void ToolChainOptionsWidget::addToolChain(ToolChain *tc)
}
TreeItem *parent = m_model.rootItem()->child(tc->isAutoDetected() ? 0 : 1);
m_model.appendItem(parent, new ToolChainTreeItem(&m_model, tc, false));
parent->appendChild(new ToolChainTreeItem(tc, false));
updateState();
}
......@@ -301,7 +301,7 @@ void ToolChainOptionsWidget::apply()
if (item->widget)
item->widget->apply();
item->changed = false;
m_model.updateItem(item);
item->update();
}
}
......@@ -355,10 +355,10 @@ void ToolChainOptionsWidget::createToolChain(ToolChainFactory *factory)
if (!tc)
return;
ToolChainTreeItem *item = new ToolChainTreeItem(&m_model, tc, true);
ToolChainTreeItem *item = new ToolChainTreeItem(tc, true);
m_toAddList.append(item);
m_model.appendItem(m_manualRoot, item);
m_manualRoot->appendChild(item);
m_toolChainView->setCurrentIndex(m_model.indexFromItem(item));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment