swift
selcal.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #include "misc/aviation/selcal.h"
5 
6 #include <QStringList>
7 #include <Qt>
8 #include <QtGlobal>
9 
10 #include "misc/pq/frequency.h"
11 #include "misc/pq/units.h"
12 
13 using namespace swift::misc::physical_quantities;
14 
15 SWIFT_DEFINE_VALUEOBJECT_MIXINS(swift::misc::aviation, CSelcal)
16 
17 namespace swift::misc::aviation
18 {
19  QString CSelcal::convertToQString(bool ) const { return m_code; }
20 
21  QString CSelcal::unifyCode(const QString &selcalCandidate)
22  {
23  QString s;
24  for (QChar c : selcalCandidate)
25  {
26  if (CSelcal::isValidCharacter(c)) { s += c; }
27  }
28  return CSelcal::isValidCode(s) ? s : QString();
29  }
30 
31  bool CSelcal::equalsString(const QString &code) const
32  {
33  if (code.isEmpty()) return false;
34  return (m_code.compare(code, Qt::CaseInsensitive) == 0);
35  }
36 
37  QList<CFrequency> CSelcal::getFrequencies() const
38  {
40  if (!CSelcal::isValidCode(m_code)) return f;
41  f.reserve(m_code.length());
42  for (const QChar c : m_code) { f.append(CSelcal::audioFrequencyEquivalent(c)); }
43  return f;
44  }
45 
46  const QString &CSelcal::validCharacters()
47  {
48  static const QString valid = "ABCDEFGHJKLMPQRS";
49  return valid;
50  }
51 
52  bool CSelcal::isValidCharacter(QChar c) { return CSelcal::validCharacters().contains(c.toUpper()); }
53 
54  bool CSelcal::isValidCode(const QString &code)
55  {
56  if (code.length() != 4) return false;
57  int p1 {};
58  int p2 {};
59  int p3 {};
60  int p4 {};
61  QString codeUpper = code.toUpper();
62  if ((p1 = CSelcal::validCharacters().indexOf(codeUpper.at(0))) < 0) return false;
63  if ((p2 = CSelcal::validCharacters().indexOf(codeUpper.at(1))) < 0) return false;
64  if ((p3 = CSelcal::validCharacters().indexOf(codeUpper.at(2))) < 0) return false;
65  if ((p4 = CSelcal::validCharacters().indexOf(codeUpper.at(3))) < 0) return false;
66  if (p1 >= p2 || p3 >= p4) return false; // pair in alphabetical order
67  if (p1 == p3 || p2 == p3 || p2 == p4 || p3 == p4) // cppcheck-suppress knownConditionTrueFalse
68  return false; // given letter can be used only once in a SELCAL code
69  return true;
70  }
71 
72  const physical_quantities::CFrequency &CSelcal::audioFrequencyEquivalent(QChar c)
73  {
74  int pos = CSelcal::validCharacters().indexOf(c);
75  Q_ASSERT(pos >= 0);
76  Q_ASSERT(CSelcal::audioFrequencyEquivalents().size() > pos);
77  return CSelcal::audioFrequencyEquivalents()[pos];
78  }
79 
80  const QList<CFrequency> &CSelcal::audioFrequencyEquivalents()
81  {
82  static const QList<CFrequency> frequencies(
91  return frequencies;
92  }
93 
94  namespace private_ns
95  {
96  QStringList selcalCodePairs()
97  {
98  QStringList pairs;
99  for (int p1 = 0; p1 < (CSelcal::validCharacters().length() - 1); p1++)
100  {
101  for (int p2 = p1 + 1; p2 < CSelcal::validCharacters().length(); p2++)
102  {
103  QString pair;
104  pair.append(CSelcal::validCharacters().at(p1)).append(CSelcal::validCharacters().at(p2));
105  pairs.append(pair);
106  }
107  }
108  return pairs;
109  }
110  } // namespace private_ns
111 
112  const QStringList &CSelcal::codePairs()
113  {
114  static const QStringList allCodePairs = private_ns::selcalCodePairs();
115  return allCodePairs;
116  }
117 } // namespace swift::misc::aviation
static CFrequencyUnit Hz()
Hertz.
Definition: units.h:371
char32_t toUpper(char32_t ucs4)
void append(QList< T > &&value)
void reserve(qsizetype size)
QString & append(QChar ch)
const QChar at(qsizetype position) const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
qsizetype length() const const
QString toUpper() const const
CaseInsensitive
#define SWIFT_DEFINE_VALUEOBJECT_MIXINS(Namespace, Class)
Explicit template definition of mixins for a CValueObject subclass.
Definition: valueobject.h:67