12 #include <QPushButton>
13 #include <QStringListModel>
17 #include "ui_mappingcomponent.h"
41 using namespace swift::misc::simulation;
42 using namespace swift::misc::network;
43 using namespace swift::misc::aviation;
44 using namespace swift::misc::physical_quantities;
46 using namespace swift::core::context;
50 using namespace swift::gui::settings;
54 const QStringList &CMappingComponent::getLogCategories()
60 CMappingComponent::CMappingComponent(QWidget *parent)
63 Q_ASSERT_X(
sGui, Q_FUNC_INFO,
"need sGui");
68 ui->tw_SpecializedViews->setCurrentIndex(0);
70 ui->tvp_AircraftModels->setAircraftModelMode(CAircraftModelListModel::OwnAircraftModelClient);
71 ui->tvp_AircraftModels->setResizeMode(CAircraftModelView::ResizingOff);
72 ui->tvp_AircraftModels->addFilterDialog();
73 ui->tvp_AircraftModels->menuRemoveItems(CAircraftModelView::MenuBackend);
74 ui->tvp_AircraftModels->menuAddItems(CAircraftModelView::MenuDisableModelsTemp);
76 ui->tvp_RenderedAircraft->setAircraftMode(CSimulatedAircraftListModel::RenderedMode);
77 ui->tvp_RenderedAircraft->setResizeMode(CAircraftModelView::ResizingOnce);
78 ui->tvp_RenderedAircraft->menuAddItems(CAircraftModelView::MenuDisableModelsTemp);
81 &CMappingComponent::onNetworkConnectionStatusChanged);
83 connect(ui->tvp_AircraftModels, &CAircraftModelView::requestUpdate,
this,
84 &CMappingComponent::onModelsUpdateRequested);
85 connect(ui->tvp_AircraftModels, &CAircraftModelView::modelDataChanged,
this,
86 &CMappingComponent::onRowCountChanged);
87 connect(ui->tvp_AircraftModels, &CAircraftModelView::requestTempDisableModelsForMatching,
this,
88 &CMappingComponent::onTempDisableModelsForMatchingRequested);
90 connect(ui->tvp_RenderedAircraft, &CSimulatedAircraftView::modelDataChanged,
this,
91 &CMappingComponent::onRowCountChanged);
92 connect(ui->tvp_RenderedAircraft, &CSimulatedAircraftView::clicked,
this,
93 &CMappingComponent::onAircraftSelectedInView);
94 connect(ui->tvp_RenderedAircraft, &CSimulatedAircraftView::requestUpdate,
this,
95 &CMappingComponent::tokenBucketUpdate);
96 connect(ui->tvp_RenderedAircraft, &CSimulatedAircraftView::requestTextMessageWidget,
this,
98 connect(ui->tvp_RenderedAircraft, &CSimulatedAircraftView::requestTempDisableModelsForMatching,
this,
99 &CMappingComponent::onTempDisableModelsForMatchingRequested);
101 connect(ui->pb_SaveAircraft, &QPushButton::clicked,
this, &CMappingComponent::onSaveAircraft);
102 connect(ui->pb_ResetAircraft, &QPushButton::clicked,
this, &CMappingComponent::onResetAircraft);
103 connect(ui->pb_LoadModels, &QPushButton::clicked,
this, &CMappingComponent::onModelsUpdateRequested);
104 connect(ui->pb_DoMatchingAgain, &QPushButton::clicked,
this, &CMappingComponent::doMatchingsAgain);
107 m_currentMappingsViewDelegate =
new CCheckBoxDelegate(
":/diagona/icons/diagona/icons/tick.png",
108 ":/diagona/icons/diagona/icons/cross.png",
this);
109 ui->tvp_RenderedAircraft->setItemDelegateForColumn(0, m_currentMappingsViewDelegate);
116 connect(ui->cb_AircraftIconDisplayed, &QCheckBox::stateChanged,
this,
117 &CMappingComponent::onModelPreviewChanged);
120 ui->completer_ModelStrings->setSourceVisible(CAircraftModelStringCompleter::OwnModels,
false);
121 ui->completer_ModelStrings->selectSource(CAircraftModelStringCompleter::ModelSet);
124 connect(&m_updateTimer, &QTimer::timeout,
this, &CMappingComponent::timerUpdate);
125 m_updateTimer.setObjectName(this->objectName() +
"::updateTimer");
126 ui->tvp_AircraftModels->setDisplayAutomatically(
false);
127 this->settingsChanged();
130 ui->comp_SimulatorSelector->setRememberSelection(
false);
132 ui->comp_SimulatorSelector->setToConnectedSimulator();
134 &CMappingComponent::onModelSetSimulatorChanged);
138 &CMappingComponent::onModelSetChanged, Qt::QueuedConnection);
140 &CMappingComponent::tokenBucketUpdateAircraft, Qt::QueuedConnection);
142 &CMappingComponent::tokenBucketUpdateAircraft, Qt::QueuedConnection);
144 &CMappingComponent::tokenBucketUpdate, Qt::QueuedConnection);
146 &CMappingComponent::onAddingRemoteAircraftFailed, Qt::QueuedConnection);
148 &CMappingComponent::onSimulatorPluginChanged, Qt::QueuedConnection);
150 &CMappingComponent::onSimulatorStatusChanged, Qt::QueuedConnection);
152 &CMappingComponent::onRemoteAircraftModelChanged, Qt::QueuedConnection);
154 &CMappingComponent::tokenBucketUpdateAircraft, Qt::QueuedConnection);
156 &CMappingComponent::tokenBucketUpdateAircraft, Qt::QueuedConnection);
158 &CMappingComponent::tokenBucketUpdateAircraft, Qt::QueuedConnection);
160 &CMappingComponent::tokenBucketUpdate, Qt::QueuedConnection);
162 &CMappingComponent::onConnectionStatusChanged, Qt::QueuedConnection);
164 connect(ui->tw_SpecializedViews, &QTabWidget::currentChanged,
this, &CMappingComponent::onTabWidgetChanged);
167 connect(ui->tvp_RenderedAircraft, &CAircraftModelView::objectChanged,
this,
168 &CMappingComponent::onChangedSimulatedAircraftInView, Qt::QueuedConnection);
172 QPointer<CMappingComponent> myself(
this);
175 const CSimulatorInfo simulator(myself->getConnectedOrSelectedSimulator());
176 myself->onModelSetSimulatorChanged(simulator);
177 myself->onModelSetChanged(simulator);
185 Q_ASSERT(ui->tvp_RenderedAircraft);
186 return ui->tvp_RenderedAircraft->rowCount();
191 Q_ASSERT(ui->tvp_AircraftModels);
192 return ui->tvp_AircraftModels->rowCount();
197 const int tabIndex =
static_cast<int>(tab);
198 ui->tw_SpecializedViews->setCurrentIndex(tabIndex);
203 Q_ASSERT(ui->tvp_AircraftModels);
204 return ui->tvp_AircraftModels->container().findModelsStartingWith(modelName, cs);
207 void CMappingComponent::onModelSetChanged(
const CSimulatorInfo &dummy)
212 const CSimulatorInfo simulator(ui->comp_SimulatorSelector->getValue());
213 const bool changed = ui->completer_ModelStrings->setSimulator(simulator);
214 if (!changed) {
return; }
216 if (ui->tvp_AircraftModels->displayAutomatically()) { this->onModelsUpdateRequested(); }
219 CLogMessage(
this).
info(u
"Model set loaded ('%1'), you can update the model view")
220 << simulator.toQString(
true);
224 void CMappingComponent::onRowCountChanged(
int count,
bool withFilter)
227 Q_UNUSED(withFilter);
228 const int am = ui->tw_SpecializedViews->indexOf(ui->tb_AircraftModels);
229 const int cm = ui->tw_SpecializedViews->indexOf(ui->tb_CurrentMappings);
230 const QString amf = ui->tvp_AircraftModels->derivedModel()->hasFilter() ?
"F" :
"";
231 QString a = ui->tw_SpecializedViews->tabBar()->tabText(am);
232 QString c = ui->tw_SpecializedViews->tabBar()->tabText(cm);
235 ui->tw_SpecializedViews->tabBar()->setTabText(am, a);
236 ui->tw_SpecializedViews->tabBar()->setTabText(cm, c);
239 void CMappingComponent::onChangedSimulatedAircraftInView(
const CVariant &
object,
const CPropertyIndex &index)
241 if (!index.
contains(CSimulatedAircraft::IndexEnabled)) {
return; }
245 if (!saFromBackend.hasValidCallsign()) {
return; }
247 if (saFromBackend.isEnabled() == nowEnabled) {
return; }
249 << (nowEnabled ?
"enable" :
"disable") << saFromBackend.getCallsign().toQString();
253 void CMappingComponent::onAircraftSelectedInView(
const QModelIndex &index)
256 ui->cb_AircraftEnabled->setChecked(simAircraft.
isEnabled());
258 ui->completer_ModelStrings->setModel(simAircraft.
getModel());
261 CCallsign CMappingComponent::validateRenderedCallsign()
263 const QString cs = ui->le_Callsign->text().trimmed();
264 if (!CCallsign::isValidAircraftCallsign(cs))
272 const bool hasCallsign = ui->tvp_RenderedAircraft->container().containsCallsign(callsign);
276 << callsign.asString();
283 void CMappingComponent::onModelSetSimulatorChanged(
const CSimulatorInfo &simulator)
285 if (!
sGui || this->isSimulatorAvailable()) {
return; }
293 Q_UNUSED(pluginInfo);
294 ui->comp_SimulatorSelector->setToConnectedSimulator(50);
297 void CMappingComponent::onSimulatorStatusChanged(
int status)
299 const ISimulator::SimulatorStatus simStatus =
static_cast<ISimulator::SimulatorStatus
>(status);
304 ui->comp_SimulatorSelector->setToConnectedSimulator(50);
308 void CMappingComponent::doMatchingsAgain()
310 using namespace std::chrono_literals;
316 const QString info = QStringLiteral(
"Triggered re-matching of %1 aircraft").arg(rematchedNumber);
321 void CMappingComponent::onSaveAircraft()
327 const CCallsign callsign(this->validateRenderedCallsign());
328 if (callsign.isEmpty()) {
return; }
329 const QString modelString = ui->completer_ModelStrings->getModelString();
330 if (modelString.isEmpty())
338 bool hasModel = ui->tvp_AircraftModels->container().containsModelString(modelString);
347 CStatusMessage(
this).validationError(u
"Invalid model for mapping, reloading model set"),
349 if (ui->tvp_AircraftModels->isEmpty()) { this->onModelsUpdateRequested(); }
355 const bool enabled = ui->cb_AircraftEnabled->isChecked();
356 bool changed =
false;
371 if (models.
size() > 1)
380 << modelString << model.getModelString();
384 model.setModelType(CAircraftModel::TypeManuallySet);
385 CLogMessage(
this).
info(u
"Requesting changes for '%1'") << callsign.asString();
392 if (aircraftFromBackend.
isEnabled() != enabled)
403 void CMappingComponent::onResetAircraft()
405 using namespace std::chrono_literals;
411 const CCallsign callsign(this->validateRenderedCallsign());
412 if (callsign.isEmpty()) {
return; }
419 void CMappingComponent::onModelPreviewChanged(
int state)
425 void CMappingComponent::onModelsUpdateRequested()
431 const bool hasDisabledModels = !disabledModels.
isEmpty();
433 ui->tvp_AircraftModels->setHighlightColor(Qt::red);
434 ui->tvp_AircraftModels->setHighlight(hasDisabledModels);
435 ui->tvp_AircraftModels->setHighlightModels(disabledModels);
436 ui->tvp_AircraftModels->updateContainerMaybeAsync(modelSet);
437 ui->tw_SpecializedViews->setCurrentIndex(TabAircraftModels);
440 void CMappingComponent::onTempDisableModelsForMatchingRequested(
const CAircraftModelList &models)
442 if (models.
isEmpty()) {
return; }
449 this->onModelsUpdateRequested();
453 void CMappingComponent::onRemoteAircraftModelChanged(
const CSimulatedAircraft &aircraft,
456 if (CIdentifiable::isMyIdentifier(originator)) {
return; }
457 this->tokenBucketUpdateAircraft(aircraft);
465 this->tokenBucketUpdate();
466 ui->tvp_RenderedAircraft->clear();
474 ui->tvp_RenderedAircraft->configureMenuFastPositionUpdates(sendFast);
479 CSimulatorInfo CMappingComponent::getConnectedOrSelectedSimulator()
const
482 return ui->comp_SimulatorSelector->getValue();
485 bool CMappingComponent::isSimulatorAvailable()
const
491 void CMappingComponent::showAircraftModelDetails(
bool show)
493 QList<int> sizes = ui->sp_MappingComponentSplitter->sizes();
494 Q_ASSERT_X(sizes.size() == 2, Q_FUNC_INFO,
"Wrong splitter sizes");
495 const int total = sizes[0] + sizes[1];
496 QList<int> newSizes({ 0, 0 });
499 newSizes[0] = qRound(total * 0.8);
500 newSizes[1] = qRound(total * 0.2);
507 ui->sp_MappingComponentSplitter->setSizes(newSizes);
510 void CMappingComponent::onAddingRemoteAircraftFailed(
const CSimulatedAircraft &aircraft,
bool disabled,
513 this->tokenBucketUpdate();
520 void CMappingComponent::onTabWidgetChanged(
int index)
524 const bool show = (w == TabAircraftModels) || (w == TabRenderedAircraft);
525 this->showAircraftModelDetails(show);
528 void CMappingComponent::updateRenderedAircraftView(
bool forceUpdate)
531 m_updateTimer.start();
534 m_missedRenderedAircraftUpdate =
true;
538 m_missedRenderedAircraftUpdate =
false;
539 m_updateTimer.start();
543 ui->tvp_RenderedAircraft->updateContainerMaybeAsync(aircraft);
545 else { ui->tvp_RenderedAircraft->clear(); }
548 void CMappingComponent::timerUpdate()
551 this->updateRenderedAircraftView(
false);
557 this->tokenBucketUpdate();
560 void CMappingComponent::tokenBucketUpdate()
563 this->updateRenderedAircraftView(
true);
566 void CMappingComponent::settingsChanged()
570 m_updateTimer.setInterval(ms);
578 ui->tvp_RenderedAircraft->clear();
579 m_updateTimer.stop();
583 ui->comp_SimulatorSelector->setReadOnly(
true);
584 m_updateTimer.start();
const context::IContextNetwork * getIContextNetwork() const
Direct access to contexts if a CCoreFacade has been initialized.
bool isShuttingDown() const
Is application shutting down?
const context::IContextSimulator * getIContextSimulator() const
Direct access to contexts if a CCoreFacade has been initialized.
virtual swift::misc::simulation::CSimulatedAircraft getAircraftInRangeForCallsign(const swift::misc::aviation::CCallsign &callsign) const =0
Aircraft for given callsign.
virtual bool updateAircraftModel(const swift::misc::aviation::CCallsign &callsign, const swift::misc::simulation::CAircraftModel &model, const swift::misc::CIdentifier &originator)=0
Change model (for remote aircraft)
virtual bool updateAircraftEnabled(const swift::misc::aviation::CCallsign &callsign, bool enabledForRendering)=0
Enable/disable rendering.
virtual swift::misc::simulation::CSimulatedAircraftList getAircraftInRange() const =0
Aircraft list.
virtual swift::misc::network::CServer getConnectedServer() const =0
Server which is connected, if not connected empty default object.
virtual bool resetToModelMatchingAircraft(const swift::misc::aviation::CCallsign &callsign)=0
Reset model by matching it again.
virtual bool isKnownModelInSet(const QString &modelstring) const =0
Known model?
virtual void disableModelsForMatching(const swift::misc::simulation::CAircraftModelList &removedModels, bool incremental)=0
Remove a model for matching.
virtual swift::misc::simulation::CAircraftModelList getDisabledModelsForMatching() const =0
The disabled models for matching.
bool isSimulatorAvailable() const
Simulator avialable (driver available)?
virtual int doMatchingsAgain()=0
Repeat all matchings.
virtual swift::misc::simulation::CAircraftModelList getModelSetModelsStartingWith(const QString &modelString) const =0
Models for model string.
virtual swift::misc::simulation::CAircraftModelList getModelSet() const =0
Installed models in simulator eco system.
bool isSimulatorSimulating() const
Is available simulator simulating? Returns false if no simulator is available.
virtual ISimulator::SimulatorStatus getSimulatorStatus() const =0
Simulator combined status.
virtual void setModelSetLoaderSimulator(const swift::misc::simulation::CSimulatorInfo &simulator)=0
Set the model set loader simulator directly.
static QString replaceTabCountValue(const QString &oldName, int count)
Replace count in name such as "stations (4)".
void closeOverlay()
Close button clicked.
bool showOverlayHTMLMessage(const QString &htmlMessage, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
HTML message.
bool showOverlayMessage(const swift::misc::CStatusMessage &message, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show single message.
void setForceSmall(bool force)
Force small (smaller layout)
void setReducedInfo(bool reduced)
Display reduced information.
Using this class provides a QFrame with the overlay functionality already integrated.
void requestTextMessageWidget(const swift::misc::aviation::CCallsign &callsign)
Request a text message widget.
void setTab(TabWidget tab)
Set tab.
int countAircraftModels() const
Numer of models.
int countCurrentMappings() const
Number of current mappings.
void requestValidationDialog()
Request the validation dialog.
virtual ~CMappingComponent()
Destructor.
swift::misc::simulation::CAircraftModelList findModelsStartingWith(const QString &modelName, Qt::CaseSensitivity cs)
Find models starting with.
void changed(const swift::misc::simulation::CSimulatorInfo &simulator)
Value has been changed.
Settings about view update rates.
const swift::misc::physical_quantities::CTime & getRenderingUpdateTime() const
Get time.
CheckBox for single column.
Base class with a member CIdentifier to be inherited by a class which has an identity in the environm...
const CIdentifier & identifier() const
Get identifier.
Value object encapsulating information identifying a component of a modular distributed swift process...
static const QString & guiComponent()
GUI components.
static const QString & mapping()
Mapping.
Class for emitting a log message.
Derived & validationError(const char16_t(&format)[N])
Set the severity to error, providing a format string, and adding the validation category.
Derived & validationInfo(const char16_t(&format)[N])
Set the severity to info, providing a format string, and adding the validation category.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
bool contains(int index) const
Contains index?
size_type size() const
Returns number of elements in the sequence.
reference front()
Access the first element.
bool isEmpty() const
Synonym for empty.
Streamable status message, e.g.
bool tryConsume(int numTokens=1, qint64 msSinceEpoch=-1)
Try to consume a number of tokens.
Wrapper around QVariant which provides transparent access to CValueObject methods of the contained ob...
Value object encapsulating information of a callsign.
const QString & asString() const
Get callsign (normalized)
QString getCallsignsAsString(const QString &separator, bool sorted=false) const
Get callsigns as strings.
QString toQString(bool i18n=false) const
Cast as QString.
Value object encapsulating information about a connection status.
bool isConnected() const
Query status.
bool isDisconnected() const
Query status.
bool sendInterimPositions() const
FSD setup flags.
Value object encapsulating information of a server.
const CFsdSetup & getFsdSetup() const
Get FSD setup.
int toMs() const
Convenience functions when used with timers etc.
Aircraft model (used by another pilot, my models on disk)
Value object encapsulating a list of aircraft models.
CAircraftModelList findByModelString(const QString &modelString, Qt::CaseSensitivity sensitivity=Qt::CaseInsensitive) const
Find by model string.
bool containsModelString(const QString &modelString, Qt::CaseSensitivity sensitivity=Qt::CaseInsensitive) const
Contains model string?
Comprehensive information of an aircraft.
const aviation::CCallsign & getCallsign() const
Get callsign.
const simulation::CAircraftModel & getModel() const
Get model (model used for mapping)
bool isEnabled() const
Enabled? Enable means it shall be displayed in the simulator.
const QString & getModelString() const
Get model string.
Value object encapsulating a list of aircraft.
Simple hardcoded info about the corresponding simulator.
Describing a simulator plugin.
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
Backend services of the swift project, like dealing with the network or the simulators.
High level reusable GUI components.
Filter to search data sets.
Models to be used with views, mainly QTableView.
Views, mainly QTableView.
Free functions in swift::misc.
auto singleShot(int msec, QObject *target, F &&task)
Starts a single-shot timer which will call a task in the thread of the given object when it times out...