swift
aircraftcomponent.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 <QPointer>
7 #include <QString>
8 #include <QTabBar>
9 #include <QTimer>
10 
11 #include "ui_aircraftcomponent.h"
12 
16 #include "gui/guiapplication.h"
17 #include "gui/guiutility.h"
18 #include "gui/infoarea.h"
21 #include "gui/views/viewbase.h"
22 #include "misc/network/fsdsetup.h"
23 #include "misc/network/server.h"
24 
25 using namespace swift::gui;
26 using namespace swift::gui::views;
27 using namespace swift::gui::models;
28 using namespace swift::gui::settings;
29 using namespace swift::core;
30 using namespace swift::core::context;
31 using namespace swift::misc::network;
32 using namespace swift::misc::simulation;
33 using namespace swift::misc::physical_quantities;
34 
35 namespace swift::gui::components
36 {
37  CAircraftComponent::CAircraftComponent(QWidget *parent) : QTabWidget(parent), ui(new Ui::CAircraftComponent)
38  {
39  ui->setupUi(this);
40 
41  Q_ASSERT(sGui->getIContextNetwork());
42  Q_ASSERT(sGui->getIContextSimulator());
43  Q_ASSERT(sGui->getIContextOwnAircraft());
44 
45  this->setCurrentIndex(0);
46  this->tabBar()->setExpanding(false);
47  this->tabBar()->setUsesScrollButtons(true);
48  ui->tvp_AircraftInRange->setAircraftMode(CSimulatedAircraftListModel::NetworkMode);
49  ui->tvp_AircraftInRange->configureMenu(true, true, false, true, true, true);
50 
51  connect(ui->tvp_AircraftInRange, &CSimulatedAircraftView::modelDataChangedDigest, this,
52  &CAircraftComponent::onRowCountChanged);
53  connect(ui->tvp_AircraftInRange, &CSimulatedAircraftView::requestTextMessageWidget, this,
55  connect(sGui->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this,
56  &CAircraftComponent::onConnectionStatusChanged, Qt::QueuedConnection);
57  connect(sGui->getIContextOwnAircraft(), &IContextOwnAircraft::movedAircraft, this,
58  &CAircraftComponent::onOwnAircraftMoved, Qt::QueuedConnection);
59  connect(&m_updateTimer, &QTimer::timeout, this, &CAircraftComponent::update);
60 
61  this->onSettingsChanged();
62  m_updateTimer.start();
63  }
64 
66 
68  {
69  Q_ASSERT(ui->tvp_AircraftInRange);
70  return ui->tvp_AircraftInRange->rowCount();
71  }
72 
74  {
76  const bool c = connect(this->getParentInfoArea(), &CInfoArea::changedInfoAreaTabBarIndex, this,
77  &CAircraftComponent::onInfoAreaTabBarChanged, Qt::QueuedConnection);
78  Q_ASSERT_X(c, Q_FUNC_INFO, "failed connect");
79  Q_ASSERT_X(parentDockableWidget, Q_FUNC_INFO, "missing parent");
80  return c && parentDockableWidget;
81  }
82 
84  {
85  if (!sGui || sGui->isShuttingDown()) { return; }
86 
87  // count < 1 checks if view already has been updated
89  {
90  const bool visible = (this->isVisibleWidget() && this->currentWidget() == ui->tb_AircraftInRange);
91  if (this->countAircraftInView() < 1 || visible)
92  {
93  ui->tvp_AircraftInRange->updateContainerMaybeAsync(sGui->getIContextNetwork()->getAircraftInRange());
94  }
95  }
96 
97  m_updateCounter++;
98  }
99 
101  {
102  const int tabIndex = static_cast<int>(tab);
103  this->setCurrentIndex(tabIndex);
104  }
105 
106  void CAircraftComponent::updateViews()
107  {
108  if (!sGui || sGui->isShuttingDown() || !sGui->getIContextNetwork() || !sGui->getIContextSimulator()) { return; }
109  ui->tvp_AircraftInRange->updateContainerMaybeAsync(sGui->getIContextNetwork()->getAircraftInRange());
110  }
111 
112  void CAircraftComponent::onInfoAreaTabBarChanged(int index)
113  {
114  // ignore in those cases
115  if (!this->isVisibleWidget()) return;
116  if (this->isParentDockWidgetFloating()) return;
117  if (!sGui->getIContextNetwork()->isConnected()) return;
118 
119  // here I know I am the selected widget, update, but keep GUI responsive (hence I use a timer)
120  QPointer<CAircraftComponent> myself(this);
121  QTimer::singleShot(1000, this, [=] {
122  if (!myself) { return; }
123  myself->update();
124  });
125  Q_UNUSED(index)
126  }
127 
128  void CAircraftComponent::onRowCountChanged(int count, bool withFilter)
129  {
130  Q_UNUSED(count)
131  Q_UNUSED(withFilter)
132  const int ac = this->indexOf(ui->tb_AircraftInRange);
133  QString acs = this->tabBar()->tabText(ac);
135  }
136 
137  void CAircraftComponent::onConnectionStatusChanged(const CConnectionStatus &from, const CConnectionStatus &to)
138  {
139  Q_UNUSED(from)
140  if (to.isDisconnected()) { ui->tvp_AircraftInRange->clear(); }
141  else if (to.isConnected())
142  {
143  if (sGui && sGui->getIContextNetwork())
144  {
145  const CServer server = sGui->getIContextNetwork()->getConnectedServer();
146  const bool sendFast = server.getFsdSetup().sendInterimPositions();
147  ui->tvp_AircraftInRange->configureMenuFastPositionUpdates(sendFast);
148  }
149  }
150  }
151 
152  void CAircraftComponent::onSettingsChanged()
153  {
154  const CViewUpdateSettings settings = m_settings.get();
155  const int ms = settings.getAircraftUpdateTime().toMs();
156  m_updateTimer.setInterval(ms);
157  }
158 
159  void CAircraftComponent::onOwnAircraftMoved(const CLength &distance)
160  {
161  Q_UNUSED(distance)
162  this->updateViews();
163  }
164 } // namespace swift::gui::components
const context::IContextOwnAircraft * getIContextOwnAircraft() const
Direct access to contexts if a CCoreFacade has been initialized.
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::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 isConnected() const =0
Network connected?
Specialized class for dock widgets serving as info area.
CInfoArea * getParentInfoArea() const
The parent info area.
bool isParentDockWidgetFloating() const
Is the parent dockable widget floating?
virtual bool setParentDockWidgetInfoArea(CDockWidgetInfoArea *parentDockableWidget)
Corresponding dockable widget in info area.
static QString replaceTabCountValue(const QString &oldName, int count)
Replace count in name such as "stations (4)".
Definition: guiutility.cpp:522
void changedInfoAreaTabBarIndex(int index)
Tab bar changed.
virtual bool setParentDockWidgetInfoArea(swift::gui::CDockWidgetInfoArea *parentDockableWidget)
Corresponding dockable widget in info area.
void requestTextMessageWidget(const swift::misc::aviation::CCallsign &callsign)
Request a text message.
void update()
Update aircraft/airport view.
int countAircraftInView() const
Aircraft in range.
Settings about view update rates.
const swift::misc::physical_quantities::CTime & getAircraftUpdateTime() const
Get time.
T get() const
Get a copy of the current value.
Definition: valuecache.h:408
Value object encapsulating information about a connection status.
bool isConnected() const
Query status.
bool isDisconnected() const
Query status.
bool sendInterimPositions() const
FSD setup flags.
Definition: fsdsetup.h:103
Value object encapsulating information of a server.
Definition: server.h:28
const CFsdSetup & getFsdSetup() const
Get FSD setup.
Definition: server.h:140
Physical unit length (length)
Definition: length.h:18
int toMs() const
Convenience functions when used with timers etc.
Definition: time.cpp:117
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.
Definition: actionbind.cpp:7
High level reusable GUI components.
Definition: aboutdialog.cpp:13
Models to be used with views, mainly QTableView.
Views, mainly QTableView.
GUI related classes.
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...
Definition: threadutils.h:30