CalendarSupport

categoryhierarchyreader.cpp
1/*
2 SPDX-FileCopyrightText: 2005 Rafal Rzepecki <divide@users.sourceforge.net>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "categoryhierarchyreader.h"
8
9#include <QComboBox>
10
11using namespace CalendarSupport;
12
13namespace CategoryConfig
14{
15static const QLatin1StringView categorySeparator(":");
16}
17
18inline QString &quote(QString &string)
19{
20 Q_ASSERT(CategoryConfig::categorySeparator != QLatin1StringView("@"));
21 return string.replace(QLatin1Char('@'), QStringLiteral("@0")).replace(QLatin1Char('\\') + CategoryConfig::categorySeparator, QStringLiteral("@1"));
22}
23
24inline QStringList &unquote(QStringList &strings)
25{
26 return strings.replaceInStrings(QStringLiteral("@1"), CategoryConfig::categorySeparator).replaceInStrings(QStringLiteral("@0"), QStringLiteral("@"));
27}
28
29QStringList CategoryHierarchyReader::path(QString string)
30{
31 QStringList _path = quote(string).split(CategoryConfig::categorySeparator, Qt::SkipEmptyParts);
32 return unquote(_path);
33}
34
35void CategoryHierarchyReader::read(const QStringList &categories)
36{
37 clear();
38
39 // case insensitive sort
40 QMap<QString, QString> sortedCategories;
41 for (const QString &str : categories) {
42 sortedCategories.insert(str.toLower(), str);
43 }
44
45 QStringList last_path;
46 for (const QString &category : std::as_const(sortedCategories)) {
47 QStringList _path = path(category);
48
49 // we need to figure out where last item and the new one differ
52 int split_level = 0;
53 QStringList new_path = _path; // save it for later
54 for (jt = _path.begin(), kt = last_path.begin(); jt != _path.end() && kt != last_path.end(); ++jt, ++kt) {
55 if (*jt == *kt) {
56 split_level++;
57 } else {
58 break; // now we have first non_equal component in the iterators
59 }
60 }
61
62 // make a path relative to the shared ancestor
63 if (jt != _path.begin()) {
64 _path.erase(_path.begin(), jt);
65 }
66 last_path = new_path;
67
68 if (_path.isEmpty()) {
69 // something is wrong, we already have this node
70 continue;
71 }
72
73 // find that ancestor
74 while (split_level < depth()) {
75 goUp();
76 }
77 Q_ASSERT(split_level == depth());
78
79 // make the node and any non-existent ancestors
80 while (!_path.isEmpty()) {
81 addChild(_path.first(), QVariant(category));
82 _path.pop_front();
83 }
84 }
85}
86
87void CategoryHierarchyReaderQComboBox::clear()
88{
89 mBox->clear();
90}
91
92void CategoryHierarchyReaderQComboBox::goUp()
93{
94 mCurrentDepth--;
95}
96
97void CategoryHierarchyReaderQComboBox::addChild(const QString &label, const QVariant &userData)
98{
99 QString spaces;
100 spaces.fill(QLatin1Char(' '), 2 * mCurrentDepth);
101 mBox->addItem(spaces + label, userData);
102 mCurrentDepth++;
103}
104
105int CategoryHierarchyReaderQComboBox::depth() const
106{
107 return mCurrentDepth;
108}
void addItem(const QIcon &icon, const QString &text, const QVariant &userData)
void clear()
typedef Iterator
iterator begin()
iterator end()
iterator erase(const_iterator begin, const_iterator end)
T & first()
bool isEmpty() const const
void pop_front()
iterator insert(const Key &key, const T &value)
QString & fill(QChar ch, qsizetype size)
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QStringList & replaceInStrings(QStringView before, QStringView after, Qt::CaseSensitivity cs)
SkipEmptyParts
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:16:31 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.