swift
aircraftcategorylist.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2019 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include <QJsonValue>
7 #include <QMap>
8 #include <Qt>
9 
10 #include "misc/setbuilder.h"
11 
12 SWIFT_DEFINE_SEQUENCE_MIXINS(swift::misc::aviation, CAircraftCategory, CAircraftCategoryList)
13 
14 namespace swift::misc::aviation
15 {
18  {}
19 
21  {
22  return this->findBy([&](const CAircraftCategory &category) { return category.matchesName(name, cs); });
23  }
24 
26 
28  {
29  this->sort([](const CAircraftCategory &a, const CAircraftCategory &b) {
30  const int c = a.compareByLevel(b);
31  return c < 0;
32  });
33  }
34 
36  {
37  CSetBuilder<QString> levels;
38  for (const CAircraftCategory &category : *this) { levels.insert(category.getLevelString()); }
39  return levels;
40  }
41 
43  {
44  const QSet<QString> levels = this->getLevelStrings();
45  if (levels.isEmpty()) { return {}; }
46  return levels.values().join(separator);
47  }
48 
50  {
51  CSetBuilder<int> levels;
52  for (const CAircraftCategory &category : *this) { levels.insert(category.getFirstLevel()); }
53  QList<int> ll = levels;
54  ll.removeOne(0);
55  return ll;
56  }
57 
59  {
60  CSetBuilder<int> levels;
61  for (const CAircraftCategory &category : *this) { levels.insert(category.getSecondLevel()); }
62  QList<int> ll = levels;
63  ll.removeOne(0);
64  return ll;
65  }
66 
68  {
69  if (categories.isEmpty()) { return {}; }
70  QMap<int, CAircraftCategory> highestLevels;
71  for (const CAircraftCategory &category : *this)
72  {
73  const int fl = category.getFirstLevel();
74  if (highestLevels.contains(fl))
75  {
76  if (highestLevels[fl].isHigherLevel(category)) { highestLevels[fl] = category; }
77  }
78  else { highestLevels[fl] = category; }
79  }
80 
81  CAircraftCategoryList topLevels;
82  for (const CAircraftCategory &category : highestLevels.values()) { topLevels.push_back(category); }
83  return topLevels;
84  }
85 
87  {
88  CAircraftCategoryList categories;
89  for (const CAircraftCategory &category : *this)
90  {
91  if (category.getFirstLevel() == level) { categories.push_back(category); }
92  }
93  return categories;
94  }
95 
97  {
98  CAircraftCategoryList categories;
99  if (level.isEmpty()) { return categories; }
100  const int ls = level.size();
101  for (const CAircraftCategory &category : *this)
102  {
103  if (noRootNode && ls == category.getDepth()) { continue; } // ignore root nodes
104  if (category.matchesLevel(level)) { categories.push_back(category); }
105  }
106  return categories;
107  }
108 
110  {
111  if (level.size() != 3) { return {}; }
112  for (const CAircraftCategory &category : *this)
113  {
114  if (category.isLevel(level[0], level[1], level[2])) { return category; }
115  }
116  return {};
117  }
118 
120  {
121  return this->findBy(&CAircraftCategory::isFirstLevel, true);
122  }
123 
125  {
126  QList<int> levels = category.getLevel();
127  CAircraftCategoryList categories;
128  if (levels.size() < 2) { categories = this->findFirstLevels(); }
129  else
130  {
131  levels.removeLast();
132  categories = this->findByLevel(levels, true);
133  }
134  categories.remove(category);
135  return categories;
136  }
137 
139  {
140  if (category.isNull() || this->isEmpty()) { return {}; }
141  if (category.isFirstLevel()) { return {}; }
142  const bool isL2 = category.getDepth() == 2;
143  const QList<int> loopLevels = isL2 ? this->getFirstLevels() : this->getSecondLevels();
144  if (loopLevels.isEmpty()) { return {}; }
145 
146  QList<int> level = category.getLevel();
147  CAircraftCategoryList result;
148  for (int l = loopLevels.front(); loopLevels.back() >= l; ++l)
149  {
150  level[isL2 ? 0 : 1] = l;
151  if (category.isLevel(level)) { continue; } // ignore category itself
152  const CAircraftCategory cat = this->findByFullLevel(level);
153  if (!cat.isNull()) { result.push_back(cat); }
154  }
155  return result;
156  }
157 
159  {
160  if (level.isEmpty()) { return 0; }
161  const int c = this->size();
162  const CAircraftCategoryList removed = this->removedLevel(level);
163  const int delta = c - removed.size();
164  if (delta > 0) { *this = removed; }
165  return delta;
166  }
167 
169  {
170  if (level.isEmpty()) { return *this; } // nothing removed
171  CAircraftCategoryList removed;
172  for (const CAircraftCategory &category : *this)
173  {
174  if (category.matchesLevel(level)) { continue; }
175  removed.push_back(category);
176  }
177  return removed;
178  }
179 
181  {
182  CAircraftCategoryList categories;
183  for (const QJsonValue &value : array)
184  {
185  const CAircraftCategory category(CAircraftCategory::fromDatabaseJson(value.toObject()));
186  categories.push_back(category);
187  }
188  return categories;
189  }
190 
191 } // namespace swift::misc::aviation
size_type size() const
Returns number of elements in the sequence.
Definition: sequence.h:273
void sortBy(K1 key1, Keys... keys)
In-place sort by some particular key(s).
Definition: sequence.h:576
CSequence findBy(Predicate p) const
Return a copy containing only those elements for which a given predicate returns true.
Definition: sequence.h:398
void push_back(const T &value)
Appends an element at the end of the sequence.
Definition: sequence.h:305
int remove(const T &object)
Remove all elements equal to the given object, if it is contained.
Definition: sequence.h:435
bool isEmpty() const
Synonym for empty.
Definition: sequence.h:285
void sort(Predicate p)
In-place sort by a given comparator predicate.
Definition: sequence.h:560
Build a QSet more efficiently when calling insert() in a for loop.
Definition: setbuilder.h:25
void insert(const T &value)
Add an element to the set. Runs in amortized constant time.
Definition: setbuilder.h:29
Value object for aircraft categories.
const QString & getPath() const
Path.
int compareByLevel(const CAircraftCategory &other) const
Level compare.
bool isLevel(int l1, int l2, int l3) const
Is that given level?
QString getLevelString() const
Level string.
bool matchesName(const QString &name, Qt::CaseSensitivity cs) const
Matching name?
QList< int > getLevel() const
Levels depending on depth, 3.2 -> 3,2 / 1.0 -> 1 / 4.3.1 -> 4,3,1.
static CAircraftCategory fromDatabaseJson(const QJsonObject &json, const QString &prefix=QString())
From our database JSON format.
bool matchesLevel(int l1, int l2=0, int l3=0) const
Is matching the level, 0 ignored.
Value object encapsulating a list of ICAO codes.
CAircraftCategoryList findByLevel(const QList< int > &level, bool noRootNode=false) const
Find by levels.
QList< int > getFirstLevels() const
All levels sorted.
CAircraftCategoryList()=default
Default constructor.
QString getLevelsString(const QString &separator=", ") const
Get all level strings.
int removeIfLevel(const QList< int > &level)
Remove by level.
CAircraftCategoryList findInParallelBranch(const CAircraftCategory &category) const
Find siblings.
CAircraftCategoryList findByFirstLevel(int level) const
Find by first level.
CAircraftCategoryList findFirstLevels() const
Find first levels.
static CAircraftCategoryList fromDatabaseJson(const QJsonArray &array)
From our database JSON format.
CAircraftCategoryList findByName(const QString &name, Qt::CaseSensitivity cs=Qt::CaseInsensitive) const
Find by name.
CAircraftCategory findByFullLevel(const QList< int > &level) const
Find by exact levels.
QList< int > getSecondLevels() const
All levels sorted.
QSet< QString > getLevelStrings() const
Get all level strings.
CAircraftCategoryList removedLevel(const QList< int > &level) const
With removed categories.
CAircraftCategoryList findHighestLevels(const CAircraftCategoryList &categories)
Find highest (top) level of categories.
CAircraftCategoryList findSiblings(const CAircraftCategory &category) const
Find siblings.
QList< T >::reference back()
QList< T >::reference front()
bool isEmpty() const const
void removeLast()
bool removeOne(const AT &t)
qsizetype size() const const
bool contains(const Key &key) const const
QList< T > values() const const
bool isEmpty() const const
QList< T > values() const const
CaseSensitivity
#define SWIFT_DEFINE_SEQUENCE_MIXINS(Namespace, T, List)
Explicit template definition of mixins for a CSequence subclass.
Definition: sequence.h:63