swift
aircraftcategory.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 <QRegularExpression>
7 #include <QStringBuilder>
8 #include <Qt>
9 #include <QtGlobal>
10 
11 #include "misc/comparefunctions.h"
13 #include "misc/logcategories.h"
14 #include "misc/propertyindexref.h"
15 #include "misc/statusmessage.h"
16 #include "misc/stringutils.h"
17 
18 using namespace swift::misc;
19 using namespace swift::misc::db;
20 
21 SWIFT_DEFINE_VALUEOBJECT_MIXINS(swift::misc::aviation, CAircraftCategory)
22 
23 namespace swift::misc::aviation
24 {
25  CAircraftCategory::CAircraftCategory(const QString &name, const QString &description, const QString &path,
26  bool assignable)
27  : m_name(name), m_description(description), m_path(path), m_assignable(assignable)
28  {}
29 
31  {
32  return (this->isLoadedFromDb()) ? this->getName() % u' ' % this->getDbKeyAsStringInParentheses() :
33  this->getName();
34  }
35 
36  QString CAircraftCategory::convertToQString(bool i18n) const
37  {
38  Q_UNUSED(i18n);
39  return QStringLiteral("%1 %2").arg(this->getNameDbKey(), this->getDescription());
40  }
41 
43 
44  bool CAircraftCategory::isNull() const { return m_name.isEmpty() && m_description.isEmpty(); }
45 
47  {
48  static const CAircraftCategory null;
49  return null;
50  }
51 
52  bool CAircraftCategory::hasName() const { return !m_name.isEmpty(); }
53 
54  bool CAircraftCategory::matchesName(const QString &name, Qt::CaseSensitivity cs) const
55  {
56  return stringCompare(name, this->getName(), cs);
57  }
58 
59  void CAircraftCategory::setLevel(int l1, int l2, int l3)
60  {
61  m_l1 = l1;
62  m_l2 = l2;
63  m_l3 = l3;
64  }
65 
66  bool CAircraftCategory::isLevel(int l1, int l2, int l3) const { return l1 == m_l1 && l2 == m_l2 && l3 == m_l3; }
67 
68  bool CAircraftCategory::isLevel(const QList<int> &level) const
69  {
70  if (level.size() != 3) { return false; }
71  return m_l1 == level[0] && m_l2 == level[1] && m_l3 == level[2];
72  }
73 
74  bool CAircraftCategory::isLevel(const CAircraftCategory &category) const
75  {
76  if (category.isNull()) { return false; }
77  return category.m_l1 == m_l1 && category.m_l2 == m_l2 && category.m_l3 == m_l3;
78  }
79 
80  QList<int> CAircraftCategory::getLevel() const
81  {
82  QList<int> l;
83  if (m_l1 > 0) l << m_l1;
84  if (m_l2 > 0) l << m_l2;
85  if (m_l3 > 0) l << m_l3;
86  return l;
87  }
88 
89  bool CAircraftCategory::isFirstLevel() const { return (m_l3 == 0 && m_l2 == 0 && m_l1 > 0); }
90 
92  {
93  if (this->isFirstLevel()) { return 1; }
94  if (m_l3 == 0 && m_l2 > 0 && m_l1 > 0) { return 2; }
95  return 3;
96  }
97 
99  {
100  if (this->isNull()) { return {}; }
101  return QStringLiteral("%1.%2.%3").arg(m_l1).arg(m_l2).arg(m_l3);
102  }
103 
105  {
106  if (this->isNull()) { return {}; }
107  return QStringLiteral("%1 %2").arg(this->getLevelString(), this->getName());
108  }
109 
111  {
112  if (this->isNull()) { return {}; }
113  return QStringLiteral("%1 %2").arg(this->getLevelString(), this->getPath());
114  }
115 
116  bool CAircraftCategory::matchesPath(const QString &path, Qt::CaseSensitivity cs)
117  {
118  return stringCompare(path, this->getPath(), cs);
119  }
120 
121  bool CAircraftCategory::matchesLevel(int l1, int l2, int l3) const
122  {
123  if (l1 != m_l1) { return false; }
124  if (l2 > 0 && l2 != m_l2) { return false; }
125  if (l3 > 0 && l3 != m_l3) { return false; }
126  return true;
127  }
128 
129  bool CAircraftCategory::matchesLevel(const QList<int> &level) const
130  {
131  if (level.isEmpty()) { return false; }
132  const int l1 = level.first();
133  const int l2 = level.size() > 1 ? level.at(1) : 0;
134  const int l3 = level.size() > 2 ? level.at(2) : 0;
135  return this->matchesLevel(l1, l2, l3);
136  }
137 
139  {
140  if (index.isMyself()) { return QVariant::fromValue(*this); }
141  if (IDatastoreObjectWithIntegerKey::canHandleIndex(index))
142  {
143  return IDatastoreObjectWithIntegerKey::propertyByIndex(index);
144  }
145  const ColumnIndex i = index.frontCasted<ColumnIndex>();
146  switch (i)
147  {
148  case IndexName: return QVariant::fromValue(m_name);
149  case IndexDescription: return QVariant::fromValue(m_description);
150  case IndexAssignable: return QVariant::fromValue(m_assignable);
151  case IndexPath: return QVariant::fromValue(m_path);
152  case IndexLevelString: return QVariant::fromValue(this->getLevelString());
153  case IndexLevelStringAndName: return QVariant::fromValue(this->getLevelAndName());
154  case IndexLevelStringAndPath: return QVariant::fromValue(this->getLevelAndPath());
155  default: return CValueObject::propertyByIndex(index);
156  }
157  }
158 
159  void CAircraftCategory::setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
160  {
161  if (index.isMyself())
162  {
163  (*this) = variant.value<CAircraftCategory>();
164  return;
165  }
166  if (IDatastoreObjectWithIntegerKey::canHandleIndex(index))
167  {
168  IDatastoreObjectWithIntegerKey::setPropertyByIndex(index, variant);
169  return;
170  }
171  const ColumnIndex i = index.frontCasted<ColumnIndex>();
172  switch (i)
173  {
174  case IndexName: this->setName(variant.value<QString>()); break;
175  case IndexDescription: this->setDescription(variant.value<QString>()); break;
176  case IndexAssignable: this->setAssignable(variant.value<bool>()); break;
177  default: CValueObject::setPropertyByIndex(index, variant); break;
178  }
179  }
180 
182  {
183  if (index.isMyself()) { return m_path.compare(compareValue.getPath(), Qt::CaseInsensitive); }
184  if (IDatastoreObjectWithIntegerKey::canHandleIndex(index))
185  {
186  return IDatastoreObjectWithIntegerKey::comparePropertyByIndex(index, compareValue);
187  }
188  const ColumnIndex i = index.frontCasted<ColumnIndex>();
189  switch (i)
190  {
191  case IndexName: return m_name.compare(compareValue.getName(), Qt::CaseInsensitive);
192  case IndexPath: return m_path.compare(compareValue.getPath(), Qt::CaseInsensitive);
193  case IndexDescription: return m_description.compare(compareValue.getDescription(), Qt::CaseInsensitive);
194  case IndexAssignable: return Compare::compare(this->isAssignable(), compareValue.isAssignable());
195  case IndexLevelStringAndName:
196  case IndexLevelStringAndPath:
197  case IndexLevelString: return this->compareByLevel(compareValue);
198  default: return CValueObject::comparePropertyByIndex(index, *this);
199  }
200  Q_ASSERT_X(false, Q_FUNC_INFO, "No comparison");
201  return 0;
202  }
203 
204  CAircraftCategory CAircraftCategory::fromDatabaseJson(const QJsonObject &json, const QString &prefix)
205  {
206  const QString name(json.value(prefix % u"name").toString());
207  const QString description(json.value(prefix % u"description").toString());
208  const QString path(json.value(prefix % u"path").toString());
209  const bool assignable = CDatastoreUtility::dbBoolStringToBool(json.value(prefix % u"assignable").toString());
210  const int l1 = json.value(prefix % u"l1").toInt();
211  const int l2 = json.value(prefix % u"l2").toInt();
212  const int l3 = json.value(prefix % u"l3").toInt();
213 
214  CAircraftCategory cat(name, description, path, assignable);
215  cat.setLevel(l1, l2, l3);
216  cat.setKeyVersionTimestampFromDatabaseJson(json, prefix);
217  return cat;
218  }
219 
221  {
222  // any faster or better way to compare can be used here
223  int c = Compare::compare(m_l1, other.m_l1);
224  if (c != 0) { return c; }
225  c = Compare::compare(m_l2, other.m_l2);
226  if (c != 0) { return c; }
227  c = Compare::compare(m_l3, other.m_l3);
228  return c;
229  }
230 
232  {
233  const int c = this->compareByLevel(other);
234  return c < 0;
235  }
236 } // namespace swift::misc::aviation
Non-owning reference to a CPropertyIndex with a subset of its features.
CastType frontCasted() const
First element casted to given type, usually the PropertIndex enum.
bool isMyself() const
Myself index, used with nesting.
Status messages, e.g. from Core -> GUI.
Value object for aircraft categories.
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
void setAssignable(bool assignable)
Mark/set assignable.
bool isHigherLevel(const CAircraftCategory &other) const
Higher level?
int comparePropertyByIndex(CPropertyIndexRef index, const CAircraftCategory &compareValue) const
Compare for index.
void setDescription(const QString &description)
Set description.
const QString & getPath() const
Path.
const QString & getDescription() const
Description.
int compareByLevel(const CAircraftCategory &other) const
Level compare.
QString getLevelAndName() const
Level and name.
swift::misc::CStatusMessageList validate() const
Validate data.
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?
QString getNameDbKey() const
Designator and DB key.
QList< int > getLevel() const
Levels depending on depth, 3.2 -> 3,2 / 1.0 -> 1 / 4.3.1 -> 4,3,1.
QString convertToQString(bool i18n=false) const
Cast as QString.
static CAircraftCategory fromDatabaseJson(const QJsonObject &json, const QString &prefix=QString())
From our database JSON format.
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
QString getLevelAndPath() const
Level and path.
bool matchesPath(const QString &path, Qt::CaseSensitivity cs)
Matching path?
void setLevel(int l1, int l2, int l3)
Level.
static const CAircraftCategory & null()
NULL object.
bool hasName() const
Aircraft designator?
const QString & getName() const
Get name.
bool matchesLevel(int l1, int l2=0, int l3=0) const
Is matching the level, 0 ignored.
void setName(const QString &name)
Set name.
bool isLoadedFromDb() const
Loaded from DB.
Definition: datastore.cpp:49
QString getDbKeyAsStringInParentheses(const QString &prefix={}) const
Db key in parentheses, e.g. "(3)".
Definition: datastore.cpp:36
void setKeyVersionTimestampFromDatabaseJson(const QJsonObject &json, const QString &prefix=QString())
Set key and timestamp values.
Definition: datastore.cpp:79
int comparePropertyByIndex(CPropertyIndexRef index, const Derived &compareValue) const
Compare for index.
Definition: mixinindex.h:187
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: mixinindex.h:160
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
Definition: mixinindex.h:167
Free functions in swift::misc.
SWIFT_MISC_EXPORT bool stringCompare(const QString &c1, const QString &c2, Qt::CaseSensitivity cs)
String compare.
#define SWIFT_DEFINE_VALUEOBJECT_MIXINS(Namespace, Class)
Explicit template definition of mixins for a CValueObject subclass.
Definition: valueobject.h:67