EditableTreeModel: Polish TreeModel::setupModelData()

- Use QStringView.
- Use a list of a pair-like struct to represent the state instead of
  2 lists.
- Use qsizetype.
- Use constLast() to avoid detaching.

Change-Id: I5ff8a17a4d583a7d2a0a11a52c29b9117280382c
Reviewed-by: Kai Köhne <kai.koehne@qt.io>
(cherry picked from commit 5134b3ad54743e3a997ff27af112df79821e5ce1)
This commit is contained in:
Friedemann Kleint 2023-11-28 13:52:44 +01:00
parent b1039a405a
commit a51ee84a61
2 changed files with 25 additions and 34 deletions

View File

@ -15,7 +15,7 @@ TreeModel::TreeModel(const QStringList &headers, const QString &data, QObject *p
rootData << header; rootData << header;
rootItem = std::make_unique<TreeItem>(rootData); rootItem = std::make_unique<TreeItem>(rootData);
setupModelData(data.split('\n'_L1)); setupModelData(QStringView{data}.split(u'\n'));
} }
//! [0] //! [0]
@ -193,55 +193,46 @@ bool TreeModel::setHeaderData(int section, Qt::Orientation orientation,
return result; return result;
} }
void TreeModel::setupModelData(const QStringList &lines) void TreeModel::setupModelData(const QList<QStringView> &lines)
{ {
QList<TreeItem *> parents; struct ParentIndentation
QList<int> indentations; {
parents << rootItem.get(); TreeItem *parent;
indentations << 0; qsizetype indentation;
};
int number = 0; QList<ParentIndentation> state{{rootItem.get(), 0}};
while (number < lines.count()) { for (const auto &line : lines) {
int position = 0; qsizetype position = 0;
while (position < lines[number].length()) { for ( ; position < line.length() && line.at(position).isSpace(); ++position) {
if (lines[number].at(position) != ' '_L1)
break;
++position;
} }
const QString lineData = lines[number].mid(position).trimmed(); const QStringView lineData = line.sliced(position).trimmed();
if (!lineData.isEmpty()) { if (!lineData.isEmpty()) {
// Read the column data from the rest of the line. // Read the column data from the rest of the line.
const QStringList columnStrings = const auto columnStrings = lineData.split(u'\t', Qt::SkipEmptyParts);
lineData.split('\t'_L1, Qt::SkipEmptyParts);
QVariantList columnData; QVariantList columnData;
columnData.reserve(columnStrings.size()); columnData.reserve(columnStrings.count());
for (const QString &columnString : columnStrings) for (const auto &columnString : columnStrings)
columnData << columnString; columnData << columnString.toString();
if (position > indentations.last()) { if (position > state.constLast().indentation) {
// The last child of the current parent is now the new parent // The last child of the current parent is now the new parent
// unless the current parent has no children. // unless the current parent has no children.
auto *lastParent = state.constLast().parent;
if (parents.last()->childCount() > 0) { if (lastParent->childCount() > 0)
parents << parents.last()->child(parents.last()->childCount()-1); state.append({lastParent->child(lastParent->childCount() - 1), position});
indentations << position;
}
} else { } else {
while (position < indentations.last() && parents.count() > 0) { while (position < state.constLast().indentation && !state.isEmpty())
parents.pop_back(); state.removeLast();
indentations.pop_back();
}
} }
// Append a new item to the current parent's list of children. // Append a new item to the current parent's list of children.
TreeItem *parent = parents.last(); auto *parent = state.constLast().parent;
parent->insertChildren(parent->childCount(), 1, rootItem->columnCount()); parent->insertChildren(parent->childCount(), 1, rootItem->columnCount());
for (int column = 0; column < columnData.size(); ++column) for (int column = 0; column < columnData.size(); ++column)
parent->child(parent->childCount() - 1)->setData(column, columnData[column]); parent->child(parent->childCount() - 1)->setData(column, columnData.at(column));
} }
++number;
} }
} }

View File

@ -52,7 +52,7 @@ public:
const QModelIndex &parent = {}) override; const QModelIndex &parent = {}) override;
private: private:
void setupModelData(const QStringList &lines); void setupModelData(const QList<QStringView> &lines);
TreeItem *getItem(const QModelIndex &index) const; TreeItem *getItem(const QModelIndex &index) const;
std::unique_ptr<TreeItem> rootItem; std::unique_ptr<TreeItem> rootItem;