diff --git a/src/blackgui/components/atcstationcomponent.cpp b/src/blackgui/components/atcstationcomponent.cpp index dccd73cda..283c7abda 100644 --- a/src/blackgui/components/atcstationcomponent.cpp +++ b/src/blackgui/components/atcstationcomponent.cpp @@ -81,6 +81,7 @@ namespace BlackGui // set station mode ui->tvp_AtcStationsOnline->setStationMode(CAtcStationListModel::StationsOnline); ui->tvp_AtcStationsBooked->setStationMode(CAtcStationListModel::StationsBooked); + ui->tvp_AtcStationsOnlineTree->setColumns(ui->tvp_AtcStationsOnline->getColumns()); // menus ui->tvp_AtcStationsOnline->menuRemoveItems(CAtcStationView::MenuClear); @@ -378,19 +379,8 @@ namespace BlackGui void CAtcStationComponent::updateTreeView() { - //! \fixme EXPERIMENTAL CODE: change model so we can directly use hierarchies - QAbstractItemModel *old = (ui->tvp_AtcStationsOnlineTree->model()); - ui->tvp_AtcStationsOnlineTree->setModel( - ui->tvp_AtcStationsOnline->derivedModel()->toAtcTreeModel() - ); - if (old) { old->deleteLater(); } // delete old model replaced by current model - if (!ui->tvp_AtcStationsOnlineTree->model()) { return; } - - ui->tvp_AtcStationsOnlineTree->expandAll(); - for (int i = 0; i < ui->tvp_AtcStationsOnlineTree->model()->columnCount(); i++) - { - ui->tvp_AtcStationsOnlineTree->resizeColumnToContents(i); - } + ui->tvp_AtcStationsOnlineTree->updateContainer(ui->tvp_AtcStationsOnline->container()); + ui->tvp_AtcStationsOnlineTree->fullResizeToContents(); } void CAtcStationComponent::initCompleters() @@ -450,8 +440,7 @@ namespace BlackGui void CAtcStationComponent::clearOnlineViews() { ui->tvp_AtcStationsOnline->clear(); - QAbstractItemModel *treeModelOld = (ui->tvp_AtcStationsOnlineTree->model()); - if (treeModelOld) { CGuiUtility::clearModel(treeModelOld); } + ui->tvp_AtcStationsOnlineTree->clear(); } void CAtcStationComponent::showOverlayInlineTextMessage() diff --git a/src/blackgui/models/atcstationtreemodel.cpp b/src/blackgui/models/atcstationtreemodel.cpp index 91531b5d1..d84196bc2 100644 --- a/src/blackgui/models/atcstationtreemodel.cpp +++ b/src/blackgui/models/atcstationtreemodel.cpp @@ -57,10 +57,16 @@ namespace BlackGui void CAtcStationTreeModel::updateContainer(const CAtcStationList &stations) { + if (stations.isEmpty()) + { + CAtcStationTreeModel::clear(); + return; + } + m_stations = stations.sortedByAtcSuffixSortOrderAndDistance(); m_stationsBySuffix = m_stations.splitPerSuffix(); m_suffixes = m_stations.getSuffixes(); - this->clear(); + QStandardItemModel::clear(); int visibleColumns = 0; for (const QString &suffix : m_suffixes) @@ -104,5 +110,19 @@ namespace BlackGui } this->setColumnCount(visibleColumns); } + + void CAtcStationTreeModel::clear() + { + m_stations.clear(); + m_stationsBySuffix.clear(); + m_suffixes.clear(); + QStandardItemModel::clear(); + } + + void CAtcStationTreeModel::changedAtcStationConnectionStatus(const CAtcStation &station, bool added) + { + Q_UNUSED(station); + Q_UNUSED(added); + } } // namespace } // namespace diff --git a/src/blackgui/models/atcstationtreemodel.h b/src/blackgui/models/atcstationtreemodel.h index 097006951..765b37ce4 100644 --- a/src/blackgui/models/atcstationtreemodel.h +++ b/src/blackgui/models/atcstationtreemodel.h @@ -35,12 +35,16 @@ namespace BlackGui //! Destructor virtual ~CAtcStationTreeModel() override {} - //! Set station mode + //! Set columns void setColumns(const CColumns &columns) { m_columns.setColumns(columns); } //! Update container void updateContainer(const BlackMisc::Aviation::CAtcStationList &stations); + //! Clear everything + //! \remark hiding QStandardItemModel::clear() + void clear(); + //! Get container const BlackMisc::Aviation::CAtcStationList &container() const { return m_stations; } diff --git a/src/blackgui/views/atcstationtreeview.cpp b/src/blackgui/views/atcstationtreeview.cpp index 639271a14..d900c9c69 100644 --- a/src/blackgui/views/atcstationtreeview.cpp +++ b/src/blackgui/views/atcstationtreeview.cpp @@ -31,14 +31,43 @@ namespace BlackGui { CAtcStationTreeView::CAtcStationTreeView(QWidget *parent) : QTreeView(parent) { + this->setModel(new CAtcStationTreeModel(this)); this->setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &CAtcStationTreeView::customContextMenuRequested, this, &CAtcStationTreeView::customMenu); + connect(this, &CAtcStationTreeView::expanded, this, &CAtcStationTreeView::onExpanded); } void CAtcStationTreeView::changedAtcStationConnectionStatus(const CAtcStation &station, bool added) { - Q_UNUSED(station); - Q_UNUSED(added); + if (!this->stationModel()) { return; } + this->stationModel()->changedAtcStationConnectionStatus(station, added); + } + + void CAtcStationTreeView::updateContainer(const CAtcStationList &stations) + { + if (!this->stationModel()) { return; } + this->storeState(); + this->stationModel()->updateContainer(stations); + this->restoreState(); + } + + void CAtcStationTreeView::clear() + { + if (!this->stationModel()) { return; } + this->stationModel()->clear(); + } + + void CAtcStationTreeView::setColumns(const CColumns &columns) + { + if (this->stationModel()) { this->stationModel()->setColumns(columns); } + } + + void CAtcStationTreeView::fullResizeToContents() + { + for (int c = 0; c < this->model()->columnCount(); c++) + { + this->resizeColumnToContents(c); + } } const CAtcStationTreeModel *CAtcStationTreeView::stationModel() const @@ -46,35 +75,83 @@ namespace BlackGui return qobject_cast(this->model()); } + CAtcStationTreeModel *CAtcStationTreeView::stationModel() + { + return qobject_cast(this->model()); + } + CAtcStation CAtcStationTreeView::selectedObject() const { const QModelIndex index = this->currentIndex(); - const QVariant data = this->model()->data(index.siblingAtColumn(0)); // supposed to be the callsign + // Qt 5.11 or later const QVariant data = this->model()->data(index.siblingAtColumn(0)); // supposed to be the callsign + const QVariant data = this->model()->data(index.sibling(index.row(), 0)); // supposed to be the callsign const QString callsign = data.toString(); const CAtcStationTreeModel *model = this->stationModel(); if (!model) { return CAtcStation(); } return model->container().findFirstByCallsign(CCallsign(callsign, CCallsign::Atc)); - } + } + + QString CAtcStationTreeView::suffixForIndex(const QModelIndex &index) + { + const QVariant data = this->model()->data(index); // supposed to be the suffix + return data.toString(); + } + + void CAtcStationTreeView::onExpanded(const QModelIndex &index) + { + Q_UNUSED(index); + this->fullResizeToContents(); + } void CAtcStationTreeView::customMenu(const QPoint &point) { + if (!this->stationModel()) { return; } + if (this->stationModel()->container().isEmpty()) { return; } + QMenu *menu = new QMenu(this); // menu QAction *com1 = new QAction(CIcons::appCockpit16(), "Tune in COM1", this); QAction *com2 = new QAction(CIcons::appCockpit16(), "Tune in COM2", this); QAction *text = new QAction(CIcons::appTextMessages16(), "Show text messages", this); + QAction *resize = new QAction(CIcons::resize16(), "Resize", this); connect(com1, &QAction::triggered, this, &CAtcStationTreeView::tuneInAtcCom1); connect(com2, &QAction::triggered, this, &CAtcStationTreeView::tuneInAtcCom2); connect(text, &QAction::triggered, this, &CAtcStationTreeView::requestTextMessage); + connect(resize, &QAction::triggered, this, &CAtcStationTreeView::fullResizeToContents); menu->addAction(com1); menu->addAction(com2); menu->addAction(text); + menu->addSeparator(); + menu->addAction(resize); menu->popup(this->viewport()->mapToGlobal(point)); } + void CAtcStationTreeView::storeState() + { + m_expanded.clear(); + for (int row = 0; row < this->model()->rowCount(); ++row) + { + const QModelIndex i = this->model()->index(row, 0); + const bool expanded = this->isExpanded(i); + const QString suffix = this->suffixForIndex(i); + m_expanded.insert(suffix, expanded); + } + } + + void CAtcStationTreeView::restoreState() + { + for (int row = 0; row < this->model()->rowCount(); ++row) + { + const QModelIndex i = this->model()->index(row, 0); + const QString suffix = this->suffixForIndex(i); // suffix of new data + const bool expanded = m_expanded.value(suffix, true); // default expanded + this->setExpanded(i, expanded); + } + } + void CAtcStationTreeView::tuneInAtcCom1() { const CAtcStation s(this->selectedObject()); diff --git a/src/blackgui/views/atcstationtreeview.h b/src/blackgui/views/atcstationtreeview.h index db100a4aa..5cf574095 100644 --- a/src/blackgui/views/atcstationtreeview.h +++ b/src/blackgui/views/atcstationtreeview.h @@ -21,10 +21,17 @@ #include #include #include +#include +#include namespace BlackGui { - namespace Models { class CAtcStationTreeModel; } + namespace Models + { + class CAtcStationTreeModel; + class CColumns; + } + namespace Views { //! ATC stations view @@ -39,6 +46,18 @@ namespace BlackGui //! \copydoc Models::CAtcStationListModel::changedAtcStationConnectionStatus void changedAtcStationConnectionStatus(const BlackMisc::Aviation::CAtcStation &station, bool added); + //! Update container + void updateContainer(const BlackMisc::Aviation::CAtcStationList &stations); + + //! Clear + void clear(); + + //! Set columns + void setColumns(const Models::CColumns &columns); + + //! Resize all columns + void fullResizeToContents(); + signals: //! Request some dummy ATC stations void testRequestDummyAtcOnlineStations(int number); @@ -53,15 +72,34 @@ namespace BlackGui //! Used model const Models::CAtcStationTreeModel *stationModel() const; + //! Used model + Models::CAtcStationTreeModel *stationModel(); + //! The selected object BlackMisc::Aviation::CAtcStation selectedObject() const; + //! Suffix for index + QString suffixForIndex(const QModelIndex &index); + + //! Expanded + void onExpanded(const QModelIndex &index); + //! Custom menu void customMenu(const QPoint &point); + //! Store state + void storeState(); + + //! Restore state + void restoreState(); + + //! Tune in/invoke @{ void tuneInAtcCom1(); void tuneInAtcCom2(); void requestTextMessage(); + //! @} + + QMap m_expanded; //!< suffix/expanded }; } // ns } // ns