File indexing completed on 2025-01-05 03:58:34

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2010-06-21
0007  * Description : A simple model to hold a tree structure.
0008  *
0009  * SPDX-FileCopyrightText: 2010-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2010-2014 by Michael G. Hansen <mike at mghansen dot de>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "simpletreemodel.h"
0017 
0018 namespace Digikam
0019 {
0020 
0021 class Q_DECL_HIDDEN SimpleTreeModel::Private
0022 {
0023 public:
0024 
0025     explicit Private()
0026         : rootItem   (nullptr),
0027           columnCount(1)
0028     {
0029     }
0030 
0031     SimpleTreeModel::Item* rootItem;
0032     int                    columnCount;
0033 };
0034 
0035 
0036 SimpleTreeModel::SimpleTreeModel(const int columnCount, QObject* const parent)
0037     : QAbstractItemModel(parent),
0038       d                 (new Private())
0039 {
0040     d->columnCount = columnCount;
0041     d->rootItem    = new Item();
0042 }
0043 
0044 SimpleTreeModel::~SimpleTreeModel()
0045 {
0046     delete d->rootItem;
0047     delete d;
0048 }
0049 
0050 int SimpleTreeModel::columnCount(const QModelIndex& parent) const
0051 {
0052     const Item* const item = indexToItem(parent);
0053 
0054     if (!item)
0055     {
0056         return 0;
0057     }
0058 
0059     return d->columnCount;
0060 }
0061 
0062 bool SimpleTreeModel::setData(const QModelIndex& index, const QVariant& value, int role)
0063 {
0064     Item* const item = indexToItem(index);
0065 
0066     if (!item)
0067     {
0068         return false;
0069     }
0070 
0071     const int column = index.column();
0072 
0073     if (column < 0)
0074     {
0075         return false;
0076     }
0077 
0078     while (item->dataColumns.count()<column)
0079     {
0080         item->dataColumns.append(QMap<int, QVariant>());
0081     }
0082 
0083     item->dataColumns[column].insert(role, value);
0084 
0085     Q_EMIT dataChanged(index, index);
0086 
0087     return true;
0088 }
0089 
0090 QVariant SimpleTreeModel::data(const QModelIndex& index, int role) const
0091 {
0092     const Item* const item = indexToItem(index);
0093 
0094     if (!item)
0095     {
0096         return QVariant();
0097     }
0098 
0099     if (index.row() > 0)
0100     {
0101         return QVariant();
0102     }
0103 
0104     const int column = index.column();
0105 
0106     if ((column < 0) || (column >= item->dataColumns.count()))
0107     {
0108         return QVariant();
0109     }
0110 
0111     return item->dataColumns.at(column).value(role);
0112 }
0113 
0114 QModelIndex SimpleTreeModel::index(int row, int column, const QModelIndex& parent) const
0115 {
0116     Item* const item = indexToItem(parent);
0117 
0118     if (!item)
0119     {
0120         return QModelIndex();
0121     }
0122 
0123     if (parent.isValid() && (parent.column() != 0))
0124     {
0125         return QModelIndex();
0126     }
0127 
0128     if ((row < 0) || (column != 0))
0129     {
0130         return QModelIndex();
0131     }
0132 
0133     if (row >= item->children.count())
0134     {
0135         return QModelIndex();
0136     }
0137 
0138     return createIndex(row, column, item);
0139 }
0140 
0141 QModelIndex SimpleTreeModel::parent(const QModelIndex& index) const
0142 {
0143     if (!index.isValid())
0144     {
0145         return QModelIndex();
0146     }
0147 
0148     Item* const item = indexToItem(index);
0149 
0150     if (!item)
0151     {
0152         return QModelIndex();
0153     }
0154 
0155     if ((item->parent == nullptr) || (item->parent == d->rootItem))
0156     {
0157         return QModelIndex();
0158     }
0159 
0160     return itemToIndex(item->parent);
0161 }
0162 
0163 int SimpleTreeModel::rowCount(const QModelIndex& parent) const
0164 {
0165     const Item* const item = indexToItem(parent);
0166 
0167     if (!item)
0168     {
0169         return 0;
0170     }
0171 
0172     return item->children.count();
0173 }
0174 
0175 bool SimpleTreeModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant& value, int role)
0176 {
0177     Q_UNUSED(section);
0178     Q_UNUSED(orientation);
0179     Q_UNUSED(value);
0180     Q_UNUSED(role);
0181 
0182     return false;
0183 }
0184 
0185 QVariant SimpleTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
0186 {
0187     Q_UNUSED(section);
0188     Q_UNUSED(orientation);
0189     Q_UNUSED(role);
0190 
0191     return QVariant();
0192 }
0193 
0194 Qt::ItemFlags SimpleTreeModel::flags(const QModelIndex& index) const
0195 {
0196     return QAbstractItemModel::flags(index);
0197 }
0198 
0199 SimpleTreeModel::Item* SimpleTreeModel::addItem(SimpleTreeModel::Item* const parentItem, const int rowNumber)
0200 {
0201     Item* const myParent = parentItem ? parentItem : d->rootItem;
0202     Item* const newItem  = new Item();
0203     newItem->parent      = myParent;
0204 
0205     const int childrenCount = myParent->children.count();
0206     int targetRow           = rowNumber;
0207 
0208     if ((rowNumber < 0) || (rowNumber > childrenCount))
0209     {
0210         targetRow = childrenCount;
0211     }
0212 
0213     beginInsertRows(itemToIndex(myParent), targetRow, targetRow);
0214     myParent->children.insert(targetRow, newItem);
0215     endInsertRows();
0216 
0217     return newItem;
0218 }
0219 
0220 SimpleTreeModel::Item* SimpleTreeModel::indexToItem(const QModelIndex& itemIndex) const
0221 {
0222     if (!itemIndex.isValid())
0223     {
0224         return d->rootItem;
0225     }
0226 
0227     Item* const item = static_cast<Item*>(itemIndex.internalPointer());
0228     const int row    = itemIndex.row();
0229 
0230     if ((row < 0) || (row >= item->children.count()))
0231     {
0232         return nullptr;
0233     }
0234 
0235     return item->children.at(row);
0236 }
0237 
0238 SimpleTreeModel::Item* SimpleTreeModel::rootItem() const
0239 {
0240     return d->rootItem;
0241 }
0242 
0243 QModelIndex SimpleTreeModel::itemToIndex(const Item* const item) const
0244 {
0245     if ((!item) || (item == d->rootItem))
0246     {
0247         return QModelIndex();
0248     }
0249 
0250     Item* const parentItem = item->parent;
0251     const int rowNumber    = parentItem->children.indexOf(const_cast<Item*>(item));
0252 
0253     if (rowNumber < 0)
0254     {
0255         return QModelIndex();
0256     }
0257 
0258     return createIndex(rowNumber, 0, parentItem);
0259 }
0260 
0261 } // namespace Digikam
0262 
0263 #include "moc_simpletreemodel.cpp"