swift
atcstationtreeview.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2018 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include <QAction>
7 #include <QMenu>
8 #include <QModelIndex>
9 #include <QtGlobal>
10 
11 #include "gui/menus/menuaction.h"
14 #include "misc/aviation/callsign.h"
15 #include "misc/icons.h"
16 
17 using namespace swift::misc;
18 using namespace swift::misc::aviation;
19 using namespace swift::gui::models;
20 
21 namespace swift::gui::views
22 {
23  CAtcStationTreeView::CAtcStationTreeView(QWidget *parent) : COverlayMessagesTreeView(parent)
24  {
25  this->setModel(new CAtcStationTreeModel(this));
26  this->setContextMenuPolicy(Qt::CustomContextMenu);
27  connect(this, &CAtcStationTreeView::customContextMenuRequested, this, &CAtcStationTreeView::customMenu);
28  connect(this, &CAtcStationTreeView::expanded, this, &CAtcStationTreeView::onExpanded, Qt::QueuedConnection);
29  connect(this->selectionModel(), &QItemSelectionModel::selectionChanged, this, &CAtcStationTreeView::onSelected,
30  Qt::QueuedConnection);
31  }
32 
34  {
35  if (!this->stationModel()) { return; }
36  this->stationModel()->changedAtcStationConnectionStatus(station, added);
37  }
38 
40  {
41  if (!this->stationModel()) { return; }
42  this->storeState();
43  this->stationModel()->updateContainer(stations);
44  this->restoreState();
45  }
46 
48  {
49  if (!this->stationModel()) { return; }
50  this->stationModel()->clear();
51  }
52 
53  bool CAtcStationTreeView::isEmpty() const { return this->stationModel()->rowCount() < 1; }
54 
56  {
57  if (this->stationModel()) { this->stationModel()->setColumns(columns); }
58  }
59 
61 
62  void CAtcStationTreeView::fullResizeToContentsImpl()
63  {
64  if (this->isEmpty()) { return; }
65  for (int c = 0; c < this->model()->columnCount(); c++) { this->resizeColumnToContents(c); }
66  }
67 
68  const CAtcStationTreeModel *CAtcStationTreeView::stationModel() const
69  {
70  return qobject_cast<const CAtcStationTreeModel *>(this->model());
71  }
72 
73  CAtcStationTreeModel *CAtcStationTreeView::stationModel()
74  {
75  return qobject_cast<CAtcStationTreeModel *>(this->model());
76  }
77 
78  CAtcStation CAtcStationTreeView::selectedObject() const
79  {
80  const QModelIndex index = this->currentIndex();
81  return this->selectedObject(index);
82  }
83 
84  CAtcStation CAtcStationTreeView::selectedObject(const QModelIndex &index) const
85  {
86  const QVariant data = this->model()->data(index.siblingAtColumn(0)); // supposed to be the callsign
87  const QString callsign = data.toString();
88  const CAtcStationTreeModel *model = this->stationModel();
89  if (!model) { return CAtcStation(); }
90  return model->container().findFirstByCallsign(CCallsign(callsign, CCallsign::Atc));
91  }
92 
93  QString CAtcStationTreeView::suffixForIndex(const QModelIndex &index)
94  {
95  const QVariant data = this->model()->data(index); // supposed to be the suffix
96  return data.toString();
97  }
98 
99  void CAtcStationTreeView::onExpanded(const QModelIndex &index)
100  {
101  Q_UNUSED(index);
102  this->fullResizeToContents();
103  }
104 
105  void CAtcStationTreeView::onSelected(const QItemSelection &selected, const QItemSelection &deselected)
106  {
107  Q_UNUSED(deselected);
108  if (selected.isEmpty()) { return; }
109  const CAtcStation atcStation = this->selectedObject(selected.indexes().front());
110  if (!atcStation.hasCallsign()) { return; }
111  emit this->objectSelected(atcStation);
112  }
113 
114  void CAtcStationTreeView::customMenu(const QPoint &point)
115  {
116  if (!this->stationModel()) { return; }
117  if (this->stationModel()->container().isEmpty()) { return; }
118 
119  QMenu *menu = new QMenu(this); // menu
120 
121  QAction *com1 = new QAction(CIcons::appCockpit16(), "Tune in COM1", this);
122  QAction *com2 = new QAction(CIcons::appCockpit16(), "Tune in COM2", this);
123  QAction *text = new QAction(CIcons::appTextMessages16(), "Show text messages", this);
124  QAction *resize = new QAction(CIcons::resize16(), "Resize", this);
125 
126  connect(com1, &QAction::triggered, this, &CAtcStationTreeView::tuneInAtcCom1);
127  connect(com2, &QAction::triggered, this, &CAtcStationTreeView::tuneInAtcCom2);
128  connect(text, &QAction::triggered, this, &CAtcStationTreeView::requestTextMessage);
129  connect(resize, &QAction::triggered, this, &CAtcStationTreeView::fullResizeToContentsImpl);
130 
131  menu->addAction(com1);
132  menu->addAction(com2);
133  menu->addAction(text);
134  menu->addSeparator();
135  menu->addAction(resize);
136 
137  menu->popup(this->viewport()->mapToGlobal(point));
138  }
139 
140  void CAtcStationTreeView::storeState()
141  {
142  m_expanded.clear();
143  for (int row = 0; row < this->model()->rowCount(); ++row)
144  {
145  const QModelIndex i = this->model()->index(row, 0);
146  const bool expanded = this->isExpanded(i);
147  const QString suffix = this->suffixForIndex(i);
148  m_expanded.insert(suffix, expanded);
149  }
150  }
151 
152  void CAtcStationTreeView::restoreState()
153  {
154  for (int row = 0; row < this->model()->rowCount(); ++row)
155  {
156  const QModelIndex i = this->model()->index(row, 0);
157  const QString suffix = this->suffixForIndex(i); // suffix of new data
158  const bool expanded = m_expanded.value(suffix, true); // default expanded
159  this->setExpanded(i, expanded);
160  }
161  }
162 
163  void CAtcStationTreeView::tuneInAtcCom1()
164  {
165  const CAtcStation s(this->selectedObject());
166  if (s.getCallsign().isEmpty()) { return; }
167  emit this->requestComFrequency(s.getFrequency(), CComSystem::Com1);
168  }
169 
170  void CAtcStationTreeView::tuneInAtcCom2()
171  {
172  const CAtcStation s(this->selectedObject());
173  if (s.getCallsign().isEmpty()) { return; }
174  emit this->requestComFrequency(s.getFrequency(), CComSystem::Com2);
175  }
176 
177  void CAtcStationTreeView::requestTextMessage()
178  {
179  const CAtcStation s(this->selectedObject());
180  if (s.getCallsign().isEmpty()) { return; }
181  emit this->requestTextMessageWidget(s.getCallsign());
182  }
183 } // namespace swift::gui::views
Using this class provides a QTableView with the overlay functionality already integrated.
void setColumns(const CColumns &columns)
Set columns.
void updateContainer(const swift::misc::aviation::CAtcStationList &stations)
Update container.
const swift::misc::aviation::CAtcStationList & container() const
Get container.
void changedAtcStationConnectionStatus(const swift::misc::aviation::CAtcStation &station, bool added)
Used to quickly update single station (better response for the user)
Header data for a table.
Definition: columns.h:160
void objectSelected(const swift::misc::aviation::CAtcStation &station)
This object has been selected.
void requestComFrequency(const swift::misc::physical_quantities::CFrequency &frequency, swift::misc::aviation::CComSystem::ComUnit unit)
Request COM frequency.
void updateContainer(const swift::misc::aviation::CAtcStationList &stations)
Update container.
void requestTextMessageWidget(const swift::misc::aviation::CCallsign &callsign)
Request a text message to.
void fullResizeToContents()
Resize all columns.
void changedAtcStationConnectionStatus(const swift::misc::aviation::CAtcStation &station, bool added)
Used to quickly update single station (better response for the user)
void setColumns(const models::CColumns &columns)
Set columns.
void inputSignal()
Received input signal, or manually trigger.
Value object encapsulating information about an ATC station.
Definition: atcstation.h:38
bool hasCallsign() const
Has callsign?
Definition: atcstation.h:87
Value object for a list of ATC stations.
Value object encapsulating information of a callsign.
Definition: callsign.h:30
OBJ findFirstByCallsign(const CCallsign &callsign, const OBJ &ifNotFound={}) const
Find the first aircraft by callsign, if none return given one.
Models to be used with views, mainly QTableView.
Views, mainly QTableView.
Free functions in swift::misc.