diff --git a/src/blackgui/components/flightplancomponent.cpp b/src/blackgui/components/flightplancomponent.cpp
index c6d8628aa..1b8d76414 100644
--- a/src/blackgui/components/flightplancomponent.cpp
+++ b/src/blackgui/components/flightplancomponent.cpp
@@ -108,21 +108,25 @@ namespace BlackGui
ui->le_EquipmentSuffix->setCompleter(completer);
CUpperCaseEventFilter *ef = new CUpperCaseEventFilter(ui->pte_Route);
+ ef->setOnlyAscii();
ui->pte_Route->installEventFilter(ef);
ef = new CUpperCaseEventFilter(ui->pte_Remarks);
+ ef->setOnlyAscii();
ui->pte_Remarks->installEventFilter(ef);
ef = new CUpperCaseEventFilter(ui->pte_AdditionalRemarks);
+ ef->setOnlyAscii();
ui->pte_AdditionalRemarks->installEventFilter(ef);
- ef = new CUpperCaseEventFilter(ui->pte_RemarksGenerated);
- ui->pte_RemarksGenerated->installEventFilter(ef);
+ // readonly
+ // ef = new CUpperCaseEventFilter(ui->pte_RemarksGenerated);
+ // ui->pte_RemarksGenerated->installEventFilter(ef);
// connect
- connect(ui->pb_Send, &QPushButton::pressed, this, &CFlightPlanComponent::sendFlightPlan, Qt::QueuedConnection);
- connect(ui->pb_Load, &QPushButton::pressed, this, &CFlightPlanComponent::loadFlightPlanFromNetwork, Qt::QueuedConnection);
+ connect(ui->pb_Send, &QPushButton::pressed, this, &CFlightPlanComponent::sendFlightPlan, Qt::QueuedConnection);
+ connect(ui->pb_Load, &QPushButton::pressed, this, &CFlightPlanComponent::loadFlightPlanFromNetwork, Qt::QueuedConnection);
connect(ui->pb_Reset, &QPushButton::pressed, this, &CFlightPlanComponent::resetFlightPlan, Qt::QueuedConnection);
connect(ui->pb_ValidateFlightPlan, &QPushButton::pressed, this, &CFlightPlanComponent::validateFlightPlan, Qt::QueuedConnection);
connect(ui->tb_SyncWithSimulator, &QPushButton::released, this, &CFlightPlanComponent::syncWithSimulator, Qt::QueuedConnection);
- connect(ui->pb_Prefill, &QPushButton::pressed, this, &CFlightPlanComponent::anticipateValues, Qt::QueuedConnection);
+ connect(ui->pb_Prefill, &QPushButton::pressed, this, &CFlightPlanComponent::anticipateValues, Qt::QueuedConnection);
connect(ui->pb_SimBrief, &QPushButton::pressed, this, &CFlightPlanComponent::loadFromSimBrief, Qt::QueuedConnection);
connect(ui->cb_VoiceCapabilities, &QComboBox::currentTextChanged, this, &CFlightPlanComponent::currentTextChangedToBuildRemarks, Qt::QueuedConnection);
@@ -267,6 +271,10 @@ namespace BlackGui
this->showOverlayMessage(m);
}
+ if (!flightPlan.getRemarks().isEmpty())
+ {
+ this->setRemarksUIValues(flightPlan.getRemarks());
+ }
}
const CLogCategoryList &CFlightPlanComponent::getLogCategories()
@@ -931,6 +939,47 @@ namespace BlackGui
}
}
+ void CFlightPlanComponent::setRemarksUIValues(const QString &remarks)
+ {
+ if (remarks.isEmpty()) { return; }
+ const QString r = remarks.toUpper();
+
+ if (remarks.contains("/V"))
+ {
+ CGuiUtility::setComboBoxValueByContainingString(ui->cb_VoiceCapabilitiesFirstPage, "FULL");
+ CGuiUtility::setComboBoxValueByContainingString(ui->cb_VoiceCapabilities, "FULL");
+ }
+ else if (remarks.contains("/T"))
+ {
+ CGuiUtility::setComboBoxValueByContainingString(ui->cb_VoiceCapabilitiesFirstPage, "TEXT ONLY");
+ CGuiUtility::setComboBoxValueByContainingString(ui->cb_VoiceCapabilities, "FULL");
+ }
+ else if (remarks.contains("/R"))
+ {
+ CGuiUtility::setComboBoxValueByContainingString(ui->cb_VoiceCapabilitiesFirstPage, "RECEIVE");
+ CGuiUtility::setComboBoxValueByContainingString(ui->cb_VoiceCapabilities, "RECEIVE");
+ }
+
+ if (remarks.contains("NAV/GPSRNAV"))
+ {
+ CGuiUtility::setComboBoxValueByContainingString(ui->cb_NavigationEquipment, "GPS OR FMC");
+ }
+ else if (remarks.contains("NAV/VORNDB"))
+ {
+ CGuiUtility::setComboBoxValueByContainingString(ui->cb_NavigationEquipment, "DIRECT VOR");
+ }
+
+ const int selcal = remarks.indexOf("SEL/");
+ if (selcal >= 0 && remarks.length() > selcal + 7)
+ {
+ const QString code = remarks.mid(selcal + 4, 4);
+ if (code.length() == 4)
+ {
+ ui->frp_SelcalCode->setSelcal(code);
+ }
+ }
+ }
+
void CFlightPlanComponent::loadFromSimBrief()
{
if (!sGui || sGui->isShuttingDown()) { return; }
@@ -1059,7 +1108,10 @@ namespace BlackGui
{
ui->cb_VoiceCapabilities->setCurrentText(text);
const QString r = CFlightPlanRemarks::replaceVoiceCapabilities(CFlightPlanRemarks::textToVoiceCapabilitiesRemarks(text), ui->pte_Remarks->toPlainText());
- ui->pte_Remarks->setPlainText(r);
+ if (ui->pte_Remarks->toPlainText() != r)
+ {
+ ui->pte_Remarks->setPlainText(r);
+ }
}
}
} // namespace
diff --git a/src/blackgui/components/flightplancomponent.h b/src/blackgui/components/flightplancomponent.h
index 5d25eb7bc..9f22fb025 100644
--- a/src/blackgui/components/flightplancomponent.h
+++ b/src/blackgui/components/flightplancomponent.h
@@ -224,6 +224,9 @@ namespace BlackGui
//! Update the remarks histories
void updateRemarksHistories();
+ //! Set remark values
+ void setRemarksUIValues(const QString &remarks);
+
//! Load from SimBrief
void loadFromSimBrief();
diff --git a/src/blackgui/components/flightplancomponent.ui b/src/blackgui/components/flightplancomponent.ui
index f99234114..2e7f4847d 100644
--- a/src/blackgui/components/flightplancomponent.ui
+++ b/src/blackgui/components/flightplancomponent.ui
@@ -6,8 +6,8 @@
0
0
- 425
- 512
+ 392
+ 510
@@ -42,9 +42,9 @@
0
- 0
- 404
- 493
+ -15
+ 371
+ 504
@@ -110,345 +110,7 @@
- -
-
-
- 4
-
-
- ICAO, e.g. EDDF
-
-
-
- -
-
-
- &Reset
-
-
-
- :/pastel/icons/pastel/16/arrow-refresh.png:/pastel/icons/pastel/16/arrow-refresh.png
-
-
-
- -
-
-
- 1. Type
-
-
-
- -
-
-
- 5. Departure airport
-
-
- true
-
-
-
- -
-
-
- 2. Callsign
-
-
- false
-
-
- true
-
-
-
- -
-
-
- ICAO, e.g. A321
-
-
-
- -
-
-
- 99:99
-
-
- 00:00
-
-
- 5
-
-
- hh:mm e.g. 02:30
-
-
-
- -
-
-
- 6. Departure time
-
-
- true
-
-
-
- -
-
-
- 99:99
-
-
- 00:00
-
-
- hh:mm e.g. 02:30
-
-
-
- -
-
-
- pilot's name
-
-
- 14. Pilot / homebase
-
-
- true
-
-
-
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 10
-
-
-
-
- -
-
-
- goto generator page
-
-
- goto gen.
-
-
-
- -
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
-
- 40
-
-
- true
-
-
- e.g. DLH1331
-
-
-
- -
-
-
- Synchronize with simulator
-
-
- Synchronize with simulator
-
-
-
- :/diagona/icons/diagona/icons/arrow-circle-225.png:/diagona/icons/diagona/icons/arrow-circle-225.png
-
-
-
-
-
-
- -
-
-
- true
-
-
- homebase (read only)
-
-
-
- -
-
-
-
-
-
- equipment code help
-
-
- equipment code help
-
-
- ...
-
-
-
- :/pastel/icons/pastel/16/help.png:/pastel/icons/pastel/16/help.png
-
-
-
- -
-
-
- 1
-
-
- equip.code
-
-
-
-
-
- -
-
-
- 7. Cruising altitude
-
-
- true
-
-
-
- -
-
-
- Load flight plan from network
-
-
- Download
-
-
-
- :/diagona/icons/diagona/icons/network-cloud.png:/diagona/icons/diagona/icons/network-cloud.png
-
-
-
- -
-
-
- Save to disk
-
-
- Save
-
-
-
- :/pastel/icons/pastel/16/disk.png:/pastel/icons/pastel/16/disk.png
-
-
-
-
-
-
- 13. Alternate airport
-
-
- true
-
-
-
- -
-
-
- Estimated time enroute
-
-
- 10. Est.time enroute
-
-
- true
-
-
-
- -
-
-
- true
-
-
- sent time will go here (read only)
-
-
-
- -
-
-
-
- 16777215
- 75
-
-
-
- true
-
-
- enter remarks here or use "generator"
-
-
-
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 10
-
-
-
-
- -
-
-
- True airspeed
-
-
- 4. TAS
-
-
- true
-
-
-
- -
4
@@ -458,45 +120,17 @@
- -
-
-
- Send flight plan to network
+
-
+
+
+ 40
-
- Send
-
-
-
- :/diagona/icons/diagona/icons/network-cloud.png:/diagona/icons/diagona/icons/network-cloud.png
+
+ e.g. 100 kts
- -
-
-
-
-
-
- -
-
-
- altitude formats
-
-
- altitude formats
-
-
- ...
-
-
-
- :/pastel/icons/pastel/16/help.png:/pastel/icons/pastel/16/help.png
-
-
-
-
-
- -
+
-
@@ -557,6 +191,26 @@
+ -
+
+
+ 12. Fuel on board
+
+
+ true
+
+
+
+ -
+
+
+ goto generator page
+
+
+ goto gen.
+
+
+
-
@@ -573,28 +227,321 @@
- -
+
-
+
+
+
+ 16777215
+ 75
+
+
+
+ true
+
+
+
+ -
+
+
+ 11.remarks
+
+
+
+ -
+
+
+ pilot's name
+
+
+ 14. Pilot / homebase
+
+
+ true
+
+
+
+ -
+
+
+ copy from generator page
+
+
+ from gen.
+
+
+
+ -
+
+
-
+
+
+ equipment code help
+
+
+ equipment code help
+
+
+ ...
+
+
+
+ :/pastel/icons/pastel/16/help.png:/pastel/icons/pastel/16/help.png
+
+
+
+ -
+
+
+ 1
+
+
+ equip.code
+
+
+
+
+
+ -
+
+
+ 1. Type
+
+
+
+ -
+
+
+ 99:99
+
+
+ 00:00
+
+
+ 5
+
+
+
+ -
+
+
+ Estimated time enroute
+
+
+ 10. Est.time enroute
+
+
+ true
+
+
+
+ -
+
+
+ True airspeed
+
+
+ 4. TAS
+
+
+ true
+
+
+
+ -
+
+
+ true
+
+
+ homebase (read only)
+
+
+
+ -
+
+
+ true
+
+
+ sent time will go here (read only)
+
+
+
+ -
+
+
+ ICAO, e.g. A321
+
+
+
+ -
Sent
- -
-
-
- Load from disk
-
+
-
+
- Load
+ 5. Departure airport
-
-
- :/pastel/icons/pastel/16/disk.png:/pastel/icons/pastel/16/disk.png
+
+ true
- -
+
-
+
+
+ true
+
+
+ pilot's name (read only)
+
+
+
+ -
+
+
+
+ 16777215
+ 75
+
+
+
+ true
+
+
+ enter remarks here or use "generator"
+
+
+
+ -
+
+
+ 13. Alternate airport
+
+
+ true
+
+
+
+ -
+
+
+ 99:99
+
+
+ 00:00
+
+
+ 5
+
+
+ hh:mm e.g. 02:30
+
+
+
+ -
+
+
+ 9. Destination airport
+
+
+ true
+
+
+
+ -
+
+
+ true
+
+
+ P/ICAO/S
+
+
+
+ -
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ 40
+
+
+ true
+
+
+ e.g. DLH1331
+
+
+
+ -
+
+
+ Synchronize with simulator
+
+
+ Synchronize with simulator
+
+
+
+ :/diagona/icons/diagona/icons/arrow-circle-225.png:/diagona/icons/diagona/icons/arrow-circle-225.png
+
+
+
+
+
+
+ -
+
+
+ 4
+
+
+ ICAO, e.g. EDDF
+
+
+
+ -
+
+
+ 2. Callsign
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+ 7. Cruising altitude
+
+
+ true
+
+
+
+ -
-
@@ -613,7 +560,51 @@
- -
+
-
+
+
-
+
+
+ -
+
+
+ altitude formats
+
+
+ altitude formats
+
+
+ ...
+
+
+
+ :/pastel/icons/pastel/16/help.png:/pastel/icons/pastel/16/help.png
+
+
+
+
+
+ -
+
+
+ 4
+
+
+ ICAO, e.g. EDDF
+
+
+
+ -
+
+
+ 6. Departure time
+
+
+ true
+
+
+
+ -
8. Route
@@ -623,150 +614,157 @@
- -
-
-
-
- 16777215
- 75
-
-
-
- true
-
-
-
- -
-
+
-
+
99:99
00:00
-
- 5
-
-
-
- -
-
-
- true
-
- P/ICAO/S
-
-
-
- -
-
-
- 40
-
-
- e.g. 100 kts
-
-
-
- -
-
-
- Anticipate (guess) some values
-
-
- &Prefill
-
-
-
- :/diagona/icons/diagona/icons/compass--pencil.png:/diagona/icons/diagona/icons/compass--pencil.png
-
-
-
- -
-
-
- copy from generator page
-
-
- from gen.
-
-
-
- -
-
-
- 12. Fuel on board
-
-
- true
-
-
-
- -
-
-
- 9. Destination airport
-
-
- true
-
-
-
- -
-
-
- true
-
-
- pilot's name (read only)
-
-
-
- -
-
-
- 4
-
-
- ICAO, e.g. EDDF
-
-
-
- -
-
-
- 11.remarks
-
-
-
- -
-
-
- strict &check
-
-
-
- -
-
-
- SimBrief
-
-
-
- -
-
-
- &Validate
-
-
-
- :/diagona/icons/diagona/icons/abacus.png:/diagona/icons/diagona/icons/abacus.png
+ hh:mm e.g. 02:30
+ -
+
+
+
+ 0
+ 100
+
+
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
-
+
+
+ strict check
+
+
+ strict &check
+
+
+
+ -
+
+
+ SimBrief
+
+
+
+ -
+
+
+ &Reset
+
+
+
+ :/pastel/icons/pastel/16/arrow-refresh.png:/pastel/icons/pastel/16/arrow-refresh.png
+
+
+
+ -
+
+
+ Save to disk
+
+
+ Save
+
+
+
+ :/pastel/icons/pastel/16/disk.png:/pastel/icons/pastel/16/disk.png
+
+
+
+ -
+
+
+ Load flight plan from network
+
+
+ Download
+
+
+
+ :/diagona/icons/diagona/icons/network-cloud.png:/diagona/icons/diagona/icons/network-cloud.png
+
+
+
+ -
+
+
+ Send flight plan to network
+
+
+ Send
+
+
+
+ :/diagona/icons/diagona/icons/network-cloud.png:/diagona/icons/diagona/icons/network-cloud.png
+
+
+
+ -
+
+
+ Load from disk
+
+
+ Load
+
+
+
+ :/pastel/icons/pastel/16/disk.png:/pastel/icons/pastel/16/disk.png
+
+
+
+ -
+
+
+ Anticipate (guess) some values
+
+
+ &Prefill
+
+
+
+ :/diagona/icons/diagona/icons/compass--pencil.png:/diagona/icons/diagona/icons/compass--pencil.png
+
+
+
+ -
+
+
+ &Validate
+
+
+
+ :/diagona/icons/diagona/icons/abacus.png:/diagona/icons/diagona/icons/abacus.png
+
+
+
+
+
+
@@ -800,8 +798,8 @@
0
0
- 415
- 482
+ 382
+ 480
@@ -1089,14 +1087,7 @@
-
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
-
+
-
@@ -1260,12 +1251,6 @@ p, li { white-space: pre-wrap; }
le_PilotsName
le_PilotsHomeBase
le_LastSent
- pb_Prefill
- pb_Reset
- pb_Send
- pb_Load
- pb_SaveDisk
- pb_LoadDisk
sa_RemarksGenerator
le_AirlineOperator
le_AircraftRegistration
diff --git a/src/blackgui/eventfilter.cpp b/src/blackgui/eventfilter.cpp
index 52d9b2384..256761bf8 100644
--- a/src/blackgui/eventfilter.cpp
+++ b/src/blackgui/eventfilter.cpp
@@ -24,21 +24,30 @@ namespace BlackGui
// processing proceed as it may be a control (e.g. cursor movement)
// key. Otherwise convert the text to upper case and insert it at
// the current cursor position.
+ QPlainTextEdit *pte = qobject_cast(object);
+ if (!pte) { return false; }
+ if (pte->isReadOnly()) { return false; }
+
if (e->text().length() == 1)
{
- QPlainTextEdit *pte = qobject_cast(object);
- if (!pte) { return false; }
-
const QChar c = e->text().front();
- if (!c.isLower()) { return false; }
- if (!c.isLetter()) { return false; }
+ if (m_illegalChars.contains(c)) { return true; }
+ if (c.isLetter())
+ {
+ const ushort unicode = c.unicode();
+ if (m_onlyAscii && unicode > 127) { return true; }
- pte->insertPlainText(e->text().toUpper());
-
- // return true to prevent further processing
- return true;
- }
- }
+ pte->insertPlainText(e->text().toUpper());
+ // return true to prevent further processing
+ return true;
+ }
+ else
+ {
+ // all codes like backspace etc.
+ return false;
+ }
+ } // length
+ } // key event
}
return false;
}
diff --git a/src/blackgui/eventfilter.h b/src/blackgui/eventfilter.h
index 35367a66f..f6ca4e014 100644
--- a/src/blackgui/eventfilter.h
+++ b/src/blackgui/eventfilter.h
@@ -23,9 +23,19 @@ namespace BlackGui
public:
using QObject::QObject;
+ //! Not allowed characters
+ void setIllegalCharacters(const QString &illegal) { m_illegalChars = illegal; }
+
+ //! Allow only ASCII
+ void setOnlyAscii() { m_onlyAscii = true; }
+
protected:
//! Filter
bool eventFilter(QObject *object, QEvent *event);
+
+ private:
+ QString m_illegalChars;
+ bool m_onlyAscii = false;
};
} // namespace
diff --git a/src/blackgui/guiutility.cpp b/src/blackgui/guiutility.cpp
index 8fd97201d..ed0891146 100644
--- a/src/blackgui/guiutility.cpp
+++ b/src/blackgui/guiutility.cpp
@@ -245,6 +245,36 @@ namespace BlackGui
return false;
}
+ bool CGuiUtility::setComboBoxValueByContainingString(QComboBox *box, const QString &candidate, const QString &unspecified)
+ {
+ if (!box) { return false; }
+ if (!candidate.isEmpty())
+ {
+ for (int i = 0; i < box->count(); i++)
+ {
+ const QString t(box->itemText(i));
+ if (t.contains(candidate, Qt::CaseInsensitive))
+ {
+ box->setCurrentIndex(i);
+ return true;
+ }
+ }
+ }
+
+ // not found
+ if (unspecified.isEmpty()) { return false; }
+ for (int i = 0; i < box->count(); i++)
+ {
+ const QString t(box->itemText(i));
+ if (t.contains(unspecified, Qt::CaseInsensitive))
+ {
+ box->setCurrentIndex(i);
+ return true;
+ }
+ }
+ return false;
+ }
+
bool CGuiUtility::hasSwiftVariantMimeType(const QMimeData *mime)
{
return mime && mime->hasFormat(swiftJsonDragAndDropMimeType());
diff --git a/src/blackgui/guiutility.h b/src/blackgui/guiutility.h
index 1accdaf67..4c89918c3 100644
--- a/src/blackgui/guiutility.h
+++ b/src/blackgui/guiutility.h
@@ -100,6 +100,9 @@ namespace BlackGui
//! Find best match in comboBox
static bool setComboBoxValueByStartingString(QComboBox *box, const QString &candidate, const QString &unspecified = QString());
+ //! Find best match in comboBox
+ static bool setComboBoxValueByContainingString(QComboBox *box, const QString &candidate, const QString &unspecified = QString());
+
//! Mime data with swift type
static bool hasSwiftVariantMimeType(const QMimeData *mime);
diff --git a/src/blackmisc/aviation/flightplan.cpp b/src/blackmisc/aviation/flightplan.cpp
index 4893727a6..7af892aab 100644
--- a/src/blackmisc/aviation/flightplan.cpp
+++ b/src/blackmisc/aviation/flightplan.cpp
@@ -45,6 +45,14 @@ namespace BlackMisc
if (parse) { this->parseFlightPlanRemarks(); }
}
+ bool CFlightPlanRemarks::setSelcalCode(const QString &selcal)
+ {
+ if (m_selcalCode == selcal || selcal.length() != 4) { return false; }
+ const QString r = CFlightPlanRemarks::replaceRemark(m_remarks, QStringLiteral("SEL/"), QStringLiteral("SEL/%1").arg(selcal));
+ m_remarks = r;
+ return true;
+ }
+
void CFlightPlanRemarks::setVoiceCapabilities(const CVoiceCapabilities &capabilities)
{
m_voiceCapabilities = capabilities;
@@ -67,9 +75,9 @@ namespace BlackMisc
const QString s =
(m_registration.isEmpty() ? QString() : u"reg.: " % m_registration.toQString(i18n))
% (!this->hasValidAirlineIcao() ? QString() : u" airline: " % m_airlineIcao.getDesignator())
- % (m_radioTelephony.isEmpty() ? QString() : u" radio tel.:" % m_radioTelephony)
- % (m_flightOperator.isEmpty() ? QString() : u" operator: " % m_flightOperator)
- % (!m_selcalCode.isValid() ? QString() : u" SELCAL: " % m_selcalCode.getCode())
+ % (m_radioTelephony.isEmpty() ? QString() : u" radio tel.:" % m_radioTelephony)
+ % (m_flightOperator.isEmpty() ? QString() : u" operator: " % m_flightOperator)
+ % (!m_selcalCode.isValid() ? QString() : u" SELCAL: " % m_selcalCode.getCode())
% u" voice: " % m_voiceCapabilities.toQString(i18n);
return s.simplified().trimmed();
}
@@ -111,13 +119,13 @@ namespace BlackMisc
m_isParsed = true;
if (m_remarks.isEmpty()) { return; }
const QString remarks = m_remarks.toUpper();
- const QString callsign = CCallsign::unifyCallsign(this->cut(remarks, "REG/")); // registration is a callsign
+ const QString callsign = CCallsign::unifyCallsign(this->getRemark(remarks, "REG/")); // registration is a callsign
if (CCallsign::isValidAircraftCallsign(callsign)) { m_registration = CCallsign(callsign, CCallsign::Aircraft); }
m_voiceCapabilities = m_voiceCapabilities.isUnknown() ? CVoiceCapabilities(m_remarks) : m_voiceCapabilities;
- m_flightOperator = this->cut(remarks, "OPR/"); // operator, e.g. British airways, sometimes people use ICAO code here
- m_selcalCode = CSelcal(this->cut(remarks, "SEL/"));
- m_radioTelephony = cut(remarks, "CALLSIGN/"); // used similar to radio telephony
- if (m_radioTelephony.isEmpty()) { m_radioTelephony = cut(remarks, "RT/"); }
+ m_flightOperator = this->getRemark(remarks, "OPR/"); // operator, e.g. British airways, sometimes people use ICAO code here
+ m_selcalCode = CSelcal(this->getRemark(remarks, "SEL/"));
+ m_radioTelephony = getRemark(remarks, "CALLSIGN/"); // used similar to radio telephony
+ if (m_radioTelephony.isEmpty()) { m_radioTelephony = getRemark(remarks, "RT/"); }
if (!m_flightOperator.isEmpty() && CAirlineIcaoCode::isValidAirlineDesignator(m_flightOperator))
{
// if people use ICAO code as flight operator swap with airline ICAO
@@ -151,7 +159,7 @@ namespace BlackMisc
this->parseFlightPlanRemarks(true);
}
- QString CFlightPlanRemarks::cut(const QString &remarks, const QString &marker)
+ QString CFlightPlanRemarks::getRemark(const QString &remarks, const QString &marker)
{
const int maxIndex = remarks.size() - 1;
int f = remarks.indexOf(marker);
@@ -168,12 +176,32 @@ namespace BlackMisc
int to1 = remarks.indexOf(nextMarker, f + 1); // for case 2,3
if (to1 < 0) { to1 = maxIndex + 1; }
int to2 = remarks.indexOf('/', f + 1); // for case 1
- if (to2 < 0) { to2 = maxIndex + 1; } // no more end markes, ends after last character
+ if (to2 < 0) { to2 = maxIndex + 1; } // no more end markers, ends after last character
const int to = qMin(to1, to2);
const QString cut = remarks.mid(f, to - f).simplified();
return cut;
}
+ QString CFlightPlanRemarks::replaceRemark(const QString &remarks, const QString &marker, const QString &newRemark)
+ {
+ QString r(remarks);
+ const int maxIndex = remarks.size() - 1;
+ int f = remarks.indexOf(marker);
+ if (f >= 0)
+ {
+ f += marker.length();
+ if (maxIndex <= f) { return remarks; }
+ thread_local const QRegularExpression nextMarker("\\s+\\w*/|$");
+ int to1 = remarks.indexOf(nextMarker, f + 1); // for case 2,3
+ if (to1 < 0) { to1 = maxIndex + 1; }
+ int to2 = remarks.indexOf('/', f + 1); // for case 1
+ if (to2 < 0) { to2 = maxIndex + 1; } // no more end markers, ends after last character
+ const int to = qMin(to1, to2);
+ r.remove(f, to - f);
+ }
+ return r.isEmpty() ? newRemark : r % u" " % newRemark;
+ }
+
const CLogCategoryList &CFlightPlan::getLogCategories()
{
static const CLogCategoryList cats { CLogCategory::flightPlan() };
@@ -538,11 +566,24 @@ namespace BlackMisc
const int b = equipment.indexOf('-');
const int e = equipment.indexOf('/');
+ CFlightPlanRemarks r = fp.getFlightPlanRemarks();
+ bool remarksChanged = false;
if (e > b && e >= 0 && b >= 0 && equipment.size() > e)
{
- CFlightPlanRemarks r = fp.getFlightPlanRemarks();
const QString icao = equipment.mid(b + 1, e - b - 1);
r.setIcaoEquipmentCodes(icao);
+ remarksChanged = true;
+ }
+
+ const QString selcal = aircraft.firstChildElement("selcal").text();
+ if (selcal.length() == 4)
+ {
+ const bool c = r.setSelcalCode(selcal);
+ remarksChanged = c || remarksChanged;
+ }
+
+ if (remarksChanged)
+ {
fp.setFlightPlanRemarks(r);
}
}
diff --git a/src/blackmisc/aviation/flightplan.h b/src/blackmisc/aviation/flightplan.h
index 18ccc8037..babc76b4c 100644
--- a/src/blackmisc/aviation/flightplan.h
+++ b/src/blackmisc/aviation/flightplan.h
@@ -72,6 +72,9 @@ namespace BlackMisc
//! SELCAL code
const CSelcal &getSelcalCode() const { return m_selcalCode; }
+ //! SELCAL code
+ bool setSelcalCode(const QString &selcal);
+
//! Get registration (a callsign, but normally not the flight callsign)
const CCallsign &getRegistration() const { return m_registration; }
@@ -141,7 +144,10 @@ namespace BlackMisc
);
//! Cut the remarks part
- static QString cut(const QString &remarks, const QString &marker);
+ static QString getRemark(const QString &remarks, const QString &marker);
+
+ //! Replace a remark part
+ static QString replaceRemark(const QString &remarks, const QString &marker, const QString &newRemark);
};
//! Value object for a flight plan