swift
transponder.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 
5 
6 #include <QRegularExpression>
7 #include <Qt>
8 
10 
11 SWIFT_DEFINE_VALUEOBJECT_MIXINS(swift::misc::aviation, CTransponder)
12 
13 namespace swift::misc::aviation
14 {
16  {
18  qRegisterMetaType<TransponderMode>();
19  qDBusRegisterMetaType<CTransponder::TransponderMode>();
20  }
21 
22  CTransponder::CTransponder(int transponderCode, CTransponder::TransponderMode transponderMode)
23  : m_transponderCode(transponderCode), m_transponderMode(transponderMode)
24  {}
25 
26  CTransponder::CTransponder(int transponderCode, const QString &transponderMode)
27  : m_transponderCode(transponderCode), m_transponderMode(StateStandby)
28  {
29  this->setModeAsString(transponderMode);
30  }
31 
32  CTransponder::CTransponder(const QString &transponderCode, CTransponder::TransponderMode transponderMode)
33  : m_transponderCode(0), m_transponderMode(transponderMode)
34  {
35  bool ok = false;
36  m_transponderCode = transponderCode.toInt(&ok);
37  if (!ok) m_transponderCode = -1; // will cause assert / exception
38  }
39 
40  CTransponder::CTransponder(const QString &transponderCode, const QString &transponderMode)
41  : m_transponderCode(0), m_transponderMode(StateStandby)
42  {
43  bool ok = false;
44  m_transponderCode = transponderCode.toInt(&ok);
45  if (!ok) m_transponderCode = -1; // will cause assert / exception
46  this->setModeAsString(transponderMode);
47  }
48 
49  bool CTransponder::validValues() const { return CTransponder::isValidTransponderCode(m_transponderCode); }
50 
52  {
53  switch (this->getTransponderMode())
54  {
55  case ModeA:
56  case ModeC:
57  case ModeMil1:
58  case ModeMil2:
59  case ModeMil3:
60  case ModeMil4:
61  case ModeMil5: return true;
62  case StateIdent:
63  case StateStandby:
64  default: return false;
65  }
66  }
67 
69  {
70  if (this->getTransponderMode() == StateIdent || this->isInNormalSendingMode())
71  {
73  }
74  else { this->setTransponderMode(ModeC); }
75  }
76 
77  QString CTransponder::convertToQString(bool /* i18n */) const
78  {
79  return this->getTransponderCodeFormatted().append(" ").append(this->getModeAsString());
80  }
81 
83  {
84  if (modeString.startsWith("I", Qt::CaseInsensitive)) return StateIdent;
85  if (modeString.startsWith("S", Qt::CaseInsensitive)) return StateStandby;
86  if (modeString.startsWith("Mode C", Qt::CaseInsensitive)) return ModeC;
87  if (modeString.startsWith("C", Qt::CaseInsensitive)) return ModeC;
88  if (modeString.startsWith("Mode S", Qt::CaseInsensitive)) return ModeS;
89  if (modeString.contains("1", Qt::CaseInsensitive)) return ModeMil1;
90  if (modeString.contains("2", Qt::CaseInsensitive)) return ModeMil2;
91  if (modeString.contains("3", Qt::CaseInsensitive)) return ModeMil3;
92  if (modeString.contains("4", Qt::CaseInsensitive)) return ModeMil4;
93  if (modeString.contains("5", Qt::CaseInsensitive)) return ModeMil5;
94  return StateStandby;
95  }
96 
98  {
99  const int m = static_cast<int>(mode);
100  if (m == m_transponderMode) { return false; }
101  m_transponderMode = m;
102  return true;
103  }
104 
106  {
107  QString f("0000");
108  f = f.append(QString::number(m_transponderCode));
109  return f.right(4);
110  }
111 
113  {
114  QString s = this->getTransponderCodeFormatted();
115  s.append(' ').append(this->getModeAsString());
116  return s;
117  }
118 
119  void CTransponder::setTransponderCode(const QString &transponderCode)
120  {
121  if (CTransponder::isValidTransponderCode(transponderCode))
122  {
123  bool ok;
124  this->setTransponderCode(transponderCode.toInt(&ok));
125  }
126  else { Q_ASSERT_X(false, "CTransponder::setTransponderCode", "illegal transponder value"); }
127  }
128 
129  bool CTransponder::isValidTransponderCode(const QString &transponderCode)
130  {
131  if (transponderCode.isEmpty() || transponderCode.length() > 4) return false;
132  bool number;
133  int tc = transponderCode.toInt(&number);
134  if (!number) return false;
135  if (tc < 0 || tc > 7777) return false;
136  thread_local const QRegularExpression rx("^[0-7]{1,4}$");
137  return rx.match(transponderCode).hasMatch();
138  }
139 
140  bool CTransponder::isValidTransponderCode(qint32 transponderCode)
141  {
142  if (transponderCode < 0 || transponderCode > 7777) return false;
143  return CTransponder::isValidTransponderCode(QString::number(transponderCode));
144  }
145 
147  {
148  return CTransponder(transponderCode, mode);
149  }
150 
152  {
153  static const QString i("Ident");
154  static const QString s("Standby");
155  static const QString mc("Mode C");
156  static const QString ms("Mode S");
157  static const QString m1("Mil.Mode 1");
158  static const QString m2("Mil.Mode 2");
159  static const QString m3("Mil.Mode 3");
160  static const QString m4("Mil.Mode 4");
161  static const QString m5("Mil.Mode 5");
162 
163  switch (mode)
164  {
165  case StateIdent: return i;
166  case StateStandby: return s;
167  case ModeC: return mc;
168  case ModeS: return ms;
169  case ModeMil1: return m1;
170  case ModeMil2: return m2;
171  case ModeMil3: return m3;
172  case ModeMil4: return m4;
173  case ModeMil5: return m5;
174  default: qFatal("Illegal Transponder Mode");
175  }
176  return i;
177  }
178 
180  {
181  static const QString i("I");
182  static const QString s("S");
183  static const QString mc("C");
184  static const QString ms("S");
185  static const QString m1("1");
186  static const QString m2("2");
187  static const QString m3("3");
188  static const QString m4("4");
189  static const QString m5("5");
190 
191  switch (mode)
192  {
193  case StateIdent: return i;
194  case StateStandby: return s;
195  case ModeC: return mc;
196  case ModeS: return ms;
197  case ModeMil1: return m1;
198  case ModeMil2: return m2;
199  case ModeMil3: return m3;
200  case ModeMil4: return m4;
201  case ModeMil5: return m5;
202  default: qFatal("Illegal Transponder Mode");
203  }
204  return i;
205  }
206 
208  {
209  if (index.isMyself()) { return QVariant::fromValue(*this); }
210  const ColumnIndex i = index.frontCasted<ColumnIndex>();
211  switch (i)
212  {
213  case IndexMode: return QVariant::fromValue(this->getTransponderMode());
214  case IndexModeAsString: return QVariant::fromValue(this->getModeAsString());
215  case IndexTransponderCode: return QVariant::fromValue(this->getTransponderCode());
216  case IndexTransponderCodeFormatted: return QVariant::fromValue(this->getTransponderCodeFormatted());
217  case IndexTransponderCodeAndModeFormatted:
218  return QVariant::fromValue(this->getTransponderCodeAndModeFormatted());
219  default: break;
220  }
221 
222  Q_ASSERT_X(false, "CTransponder", "index unknown");
223  const QString m = QString("no property, index ").append(index.toQString());
224  return QVariant::fromValue(m);
225  }
226 
227  void CTransponder::setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
228  {
229  if (index.isMyself())
230  {
231  (*this) = variant.value<CTransponder>();
232  return;
233  }
234  const ColumnIndex i = index.frontCasted<ColumnIndex>();
235  switch (i)
236  {
237  case IndexMode: m_transponderMode = variant.toInt(); break;
238  case IndexModeAsString: this->setTransponderMode(modeFromString(variant.toString())); break;
239  case IndexTransponderCode:
240  case IndexTransponderCodeFormatted:
241  if (variant.canConvert<int>()) { this->setTransponderCode(variant.toInt()); }
242  else { this->setTransponderCode(variant.toString()); }
243  break;
244  case IndexTransponderCodeAndModeFormatted:
245  default: Q_ASSERT_X(false, "CTransponder", "index unknown"); break;
246  }
247  }
248 } // namespace swift::misc::aviation
Non-owning reference to a CPropertyIndex with a subset of its features.
QString toQString(bool i18n=false) const
Cast as QString.
CastType frontCasted() const
First element casted to given type, usually the PropertIndex enum.
bool isMyself() const
Myself index, used with nesting.
QString getTransponderCodeAndModeFormatted() const
Formatted with code / mode.
static bool isValidTransponderCode(const QString &transponderCode)
Is valid transponder code?
static CTransponder getStandardTransponder(qint32 transponderCode, TransponderMode mode)
Transponder unit.
static void registerMetadata()
Register metadata.
Definition: transponder.cpp:15
void setModeAsString(const QString &mode)
Transponder mode as string.
Definition: transponder.h:92
void setTransponderCode(int transponderCode)
Set transponder code.
Definition: transponder.h:116
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
static const QString & modeAsShortString(CTransponder::TransponderMode mode)
Transponder mode as short string.
static TransponderMode modeFromString(const QString &modeString)
Mode from string.
Definition: transponder.cpp:82
int getTransponderCode() const
Transponder code.
Definition: transponder.h:107
bool setTransponderMode(TransponderMode mode)
Set transponder mode.
Definition: transponder.cpp:97
void toggleTransponderMode()
Transponder mode toggled.
Definition: transponder.cpp:68
QString convertToQString(bool i18n=false) const
Cast as QString.
Definition: transponder.cpp:77
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
static const QString & modeAsString(TransponderMode mode)
Transponder mode as string.
bool validValues() const
Are set values valid?
Definition: transponder.cpp:49
bool isInNormalSendingMode() const
In any sending mode such as MIL1 oder ModeS.
Definition: transponder.cpp:51
QString getModeAsString() const
Transponder mode as string.
Definition: transponder.h:77
CTransponder()
Default constructor.
Definition: transponder.h:59
@ StateStandby
not a real mode, more a state
Definition: transponder.h:33
@ StateIdent
not a real mode, more a state
Definition: transponder.h:39
TransponderMode getTransponderMode() const
Transponder mode.
Definition: transponder.h:95
QString getTransponderCodeFormatted() const
Transponder code.
static void registerMetadata()
Register metadata.
Definition: mixinmetatype.h:56
#define SWIFT_DEFINE_VALUEOBJECT_MIXINS(Namespace, Class)
Explicit template definition of mixins for a CValueObject subclass.
Definition: valueobject.h:67