From 969600b65d59b15cde5d9b7f4c52171c2e071409 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sun, 3 Feb 2019 21:37:30 +0100 Subject: [PATCH] Ref T472, category model/view + tree view --- .../models/aircraftcategorylistmodel.cpp | 40 +++++++ .../models/aircraftcategorylistmodel.h | 39 +++++++ .../models/aircraftcategorytreemodel.cpp | 109 ++++++++++++++++++ .../models/aircraftcategorytreemodel.h | 57 +++++++++ src/blackgui/models/allmodelcontainers.h | 1 + src/blackgui/models/allmodels.h | 1 + src/blackgui/models/listmodelbaseaviation.cpp | 1 + src/blackgui/models/listmodeldbobjects.cpp | 3 + .../views/aircraftcategorytreeview.cpp | 108 +++++++++++++++++ src/blackgui/views/aircraftcategorytreeview.h | 77 +++++++++++++ src/blackgui/views/aircraftcategoryview.cpp | 27 +++++ src/blackgui/views/aircraftcategoryview.h | 35 ++++++ src/blackgui/views/viewbaseaviation.cpp | 1 + src/blackgui/views/viewdbobjects.cpp | 1 + 14 files changed, 500 insertions(+) create mode 100644 src/blackgui/models/aircraftcategorylistmodel.cpp create mode 100644 src/blackgui/models/aircraftcategorylistmodel.h create mode 100644 src/blackgui/models/aircraftcategorytreemodel.cpp create mode 100644 src/blackgui/models/aircraftcategorytreemodel.h create mode 100644 src/blackgui/views/aircraftcategorytreeview.cpp create mode 100644 src/blackgui/views/aircraftcategorytreeview.h create mode 100644 src/blackgui/views/aircraftcategoryview.cpp create mode 100644 src/blackgui/views/aircraftcategoryview.h diff --git a/src/blackgui/models/aircraftcategorylistmodel.cpp b/src/blackgui/models/aircraftcategorylistmodel.cpp new file mode 100644 index 000000000..53bf73ac2 --- /dev/null +++ b/src/blackgui/models/aircraftcategorylistmodel.cpp @@ -0,0 +1,40 @@ +/* Copyright (C) 2019 + * Swift Project Community / Contributors + * + * This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "blackgui/models/aircraftcategorylistmodel.h" +#include "blackgui/models/columnformatters.h" +#include "blackgui/models/columns.h" +#include "blackmisc/db/datastore.h" +#include "blackmisc/timestampbased.h" + +#include +#include + +using namespace BlackMisc::Aviation; + +namespace BlackGui +{ + namespace Models + { + CAircraftCategoryListModel::CAircraftCategoryListModel(QObject *parent) : + CListModelDbObjects("AircraftCategoryListModel", parent) + { + m_columns.addColumn(CColumn::standardString("id", CAircraftCategory::IndexDbIntegerKey, CDefaultFormatter::alignRightVCenter())); + m_columns.addColumn(CColumn::standardString("level", CAircraftCategory::IndexLevelString)); + m_columns.addColumn(CColumn::standardString("path", CAircraftCategory::IndexPath)); + m_columns.addColumn(CColumn::standardString("name", CAircraftCategory::IndexName)); + m_columns.addColumn(CColumn::standardString("description", CAircraftCategory::IndexDescription)); + m_columns.addColumn(CColumn::standardString("changed", CAircraftCategory::IndexUtcTimestampFormattedYmdhms)); + + // default sort order + this->setSortColumnByPropertyIndex(CAircraftCategory::IndexLevelString); + m_sortOrder = Qt::AscendingOrder; + } + } // ns +} // ns diff --git a/src/blackgui/models/aircraftcategorylistmodel.h b/src/blackgui/models/aircraftcategorylistmodel.h new file mode 100644 index 000000000..d27f051dc --- /dev/null +++ b/src/blackgui/models/aircraftcategorylistmodel.h @@ -0,0 +1,39 @@ +/* Copyright (C) 2019 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKGUI_MODELS_AIRCRAFTCATEGORYLISTMODEL_H +#define BLACKGUI_MODELS_AIRCRAFTCATEGORYLISTMODEL_H + +#include "blackmisc/aviation/aircraftcategorylist.h" +#include "blackmisc/aviation/aircraftcategory.h" +#include "blackgui/models/listmodeldbobjects.h" +#include "blackgui/blackguiexport.h" + +namespace BlackGui +{ + namespace Models + { + //! Airport list model + class BLACKGUI_EXPORT CAircraftCategoryListModel : + public CListModelDbObjects + { + Q_OBJECT + + public: + //! Constructor + explicit CAircraftCategoryListModel(QObject *parent = nullptr); + + //! Destructor + virtual ~CAircraftCategoryListModel() {} + }; + } +} +#endif // guard diff --git a/src/blackgui/models/aircraftcategorytreemodel.cpp b/src/blackgui/models/aircraftcategorytreemodel.cpp new file mode 100644 index 000000000..45cc01f28 --- /dev/null +++ b/src/blackgui/models/aircraftcategorytreemodel.cpp @@ -0,0 +1,109 @@ +/* Copyright (C) 2019 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "blackgui/models/aircraftcategorytreemodel.h" +#include "blackgui/models/columnformatters.h" +#include "blackgui/models/columns.h" +#include "blackmisc/compare.h" +#include "blackmisc/icon.h" +#include "blackmisc/variant.h" +#include "blackmisc/propertyindex.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace BlackMisc; +using namespace BlackMisc::PhysicalQuantities; +using namespace BlackMisc::Aviation; + +namespace BlackGui +{ + namespace Models + { + CAircraftCategoryTreeModel::CAircraftCategoryTreeModel(QObject *parent) : QStandardItemModel(parent) + { + m_columns.addColumn(CColumn::standardString("description", CAircraftCategory::IndexDescription)); + m_columns.addColumn(CColumn::standardString("changed", CAircraftCategory::IndexUtcTimestampFormattedYmdhms)); + } + + void CAircraftCategoryTreeModel::updateContainer(const CAircraftCategoryList &categories) + { + if (categories.isEmpty()) + { + CAircraftCategoryTreeModel::clear(); + return; + } + + m_categories = categories; + m_categories.sortByLevel(); + QStandardItemModel::clear(); + QMap items; + this->setColumnCount(m_columns.size() + 1); + + for (const CAircraftCategory &category : m_categories) + { + QList categoryRow; + + // ownership of QStandardItem is taken by model + QStandardItem *si = new QStandardItem( + category.isAssignable() ? CIcons::paperPlane16() : CIcons::folder16(), + category.getLevelAndName() + ); + si->setEditable(false); + categoryRow.push_back(si); + + // add all clumns + for (const CColumn &column : m_columns.columns()) + { + const CPropertyIndex i(column.getPropertyIndex()); + const CVariant v(category.propertyByIndex(i)); + + if (column.getFormatter()->supportsRole(Qt::DecorationRole)) + { + const QIcon icon = column.getFormatter()->decorationRole(v).toPixmap(); + si = new QStandardItem(icon, QString()); + } + else if (column.getFormatter()->supportsRole(Qt::DisplayRole)) + { + const CVariant f = column.getFormatter()->displayRole(v); + si = new QStandardItem(f.toQString(true)); + } + if (!si) { continue; } + si->setEditable(false); // make not editable + categoryRow.push_back(si); + } // columns + + // add all items + if (categoryRow.isEmpty()) { continue; } + if (category.isFirstLevel()) + { + this->invisibleRootItem()->appendRow(categoryRow); + } + else + { + const int p = category.getDepth() - 1; + items[p]->appendRow(categoryRow); + } + items.insert(category.getDepth(), categoryRow.front()); + } + } + + void CAircraftCategoryTreeModel::clear() + { + m_categories.clear(); + QStandardItemModel::clear(); + } + } // namespace +} // namespace diff --git a/src/blackgui/models/aircraftcategorytreemodel.h b/src/blackgui/models/aircraftcategorytreemodel.h new file mode 100644 index 000000000..d126874bb --- /dev/null +++ b/src/blackgui/models/aircraftcategorytreemodel.h @@ -0,0 +1,57 @@ +/* Copyright (C) 2019 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKGUI_MODELS_AIRCRAFTCATEGORYTREEMODEL_H +#define BLACKGUI_MODELS_AIRCRAFTCATEGORYTREEMODEL_H + +#include "columns.h" +#include "blackmisc/aviation/aircraftcategorylist.h" +#include "blackgui/blackguiexport.h" + +#include + +namespace BlackGui +{ + namespace Models + { + //! ATC list model + class BLACKGUI_EXPORT CAircraftCategoryTreeModel : public QStandardItemModel + { + Q_OBJECT + + public: + //! Constructor + explicit CAircraftCategoryTreeModel(QObject *parent = nullptr); + + //! Destructor + virtual ~CAircraftCategoryTreeModel() override {} + + //! Set columns + void setColumns(const CColumns &columns) { m_columns.setColumns(columns); } + + //! Update container + void updateContainer(const BlackMisc::Aviation::CAircraftCategoryList &categories); + + //! Clear everything + //! \remark hiding QStandardItemModel::clear() + void clear(); + + //! Get container + const BlackMisc::Aviation::CAircraftCategoryList &container() const { return m_categories; } + + private: + CColumns m_columns { "CAircraftCategoryTreeModel" }; + BlackMisc::Aviation::CAircraftCategoryList m_categories; + }; + } // ns +} // ns + +#endif // guard diff --git a/src/blackgui/models/allmodelcontainers.h b/src/blackgui/models/allmodelcontainers.h index f56c16377..c0b97bc83 100644 --- a/src/blackgui/models/allmodelcontainers.h +++ b/src/blackgui/models/allmodelcontainers.h @@ -16,6 +16,7 @@ #include "blackmisc/simulation/simulatedaircraftlist.h" #include "blackmisc/simulation/matchingstatistics.h" #include "blackmisc/aviation/aircrafticaocodelist.h" +#include "blackmisc/aviation/aircraftcategorylist.h" #include "blackmisc/aviation/airlineicaocodelist.h" #include "blackmisc/aviation/airportlist.h" #include "blackmisc/aviation/atcstationlist.h" diff --git a/src/blackgui/models/allmodels.h b/src/blackgui/models/allmodels.h index e18182c3c..d3e4a3e32 100644 --- a/src/blackgui/models/allmodels.h +++ b/src/blackgui/models/allmodels.h @@ -12,6 +12,7 @@ #include "blackgui/models/actionhotkeylistmodel.h" #include "blackgui/models/aircrafticaolistmodel.h" +#include "blackgui/models/aircraftcategorylistmodel.h" #include "blackgui/models/aircraftmodellistmodel.h" #include "blackgui/models/aircraftpartslistmodel.h" #include "blackgui/models/aircraftsituationlistmodel.h" diff --git a/src/blackgui/models/listmodelbaseaviation.cpp b/src/blackgui/models/listmodelbaseaviation.cpp index 00e4a4870..fbc398d59 100644 --- a/src/blackgui/models/listmodelbaseaviation.cpp +++ b/src/blackgui/models/listmodelbaseaviation.cpp @@ -19,6 +19,7 @@ namespace BlackGui template class CListModelBase; template class CListModelBase; template class CListModelBase; + template class CListModelBase; template class CListModelBase; template class CListModelBase; template class CListModelBase; diff --git a/src/blackgui/models/listmodeldbobjects.cpp b/src/blackgui/models/listmodeldbobjects.cpp index 77680bb14..fc51a906e 100644 --- a/src/blackgui/models/listmodeldbobjects.cpp +++ b/src/blackgui/models/listmodeldbobjects.cpp @@ -16,6 +16,8 @@ #include "blackmisc/simulation/distributor.h" #include "blackmisc/aviation/aircrafticaocodelist.h" #include "blackmisc/aviation/aircrafticaocode.h" +#include "blackmisc/aviation/aircraftcategorylist.h" +#include "blackmisc/aviation/aircraftcategory.h" #include "blackmisc/aviation/airlineicaocodelist.h" #include "blackmisc/aviation/airlineicaocode.h" #include "blackmisc/aviation/liverylist.h" @@ -114,6 +116,7 @@ namespace BlackGui template class CListModelDbObjects; template class CListModelDbObjects; template class CListModelDbObjects; + template class CListModelDbObjects; template class CListModelDbObjects; template class CListModelDbObjects; template class CListModelDbObjects; diff --git a/src/blackgui/views/aircraftcategorytreeview.cpp b/src/blackgui/views/aircraftcategorytreeview.cpp new file mode 100644 index 000000000..2a860bbf9 --- /dev/null +++ b/src/blackgui/views/aircraftcategorytreeview.cpp @@ -0,0 +1,108 @@ +/* Copyright (C) 2018 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "blackgui/views/aircraftcategorytreeview.h" +#include "blackgui/models/aircraftcategorytreemodel.h" +#include "blackgui/menus/menuaction.h" +#include "blackmisc/icons.h" +#include "blackconfig/buildconfig.h" + +#include +#include +#include +#include +#include + +using namespace BlackMisc; +using namespace BlackMisc::Aviation; +using namespace BlackGui::Models; + +namespace BlackGui +{ + namespace Views + { + CAircraftCategoryTreeView::CAircraftCategoryTreeView(QWidget *parent) : QTreeView(parent) + { + this->setModel(new CAircraftCategoryTreeModel(this)); + this->setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, &CAircraftCategoryTreeView::customContextMenuRequested, this, &CAircraftCategoryTreeView::customMenu); + connect(this, &CAircraftCategoryTreeView::expanded, this, &CAircraftCategoryTreeView::onExpanded); + } + + void CAircraftCategoryTreeView::updateContainer(const CAircraftCategoryList &categories) + { + if (!this->categoryModel()) { return; } + this->categoryModel()->updateContainer(categories); + this->expandAll(); + } + + void CAircraftCategoryTreeView::clear() + { + if (!this->categoryModel()) { return; } + this->categoryModel()->clear(); + } + + void CAircraftCategoryTreeView::setColumns(const CColumns &columns) + { + if (this->categoryModel()) { this->categoryModel()->setColumns(columns); } + } + + void CAircraftCategoryTreeView::fullResizeToContents() + { + for (int c = 0; c < this->model()->columnCount(); c++) + { + this->resizeColumnToContents(c); + } + } + + const CAircraftCategoryTreeModel *CAircraftCategoryTreeView::categoryModel() const + { + return qobject_cast(this->model()); + } + + CAircraftCategoryTreeModel *CAircraftCategoryTreeView::categoryModel() + { + return qobject_cast(this->model()); + } + + CAircraftCategory CAircraftCategoryTreeView::selectedObject() const + { + const QModelIndex index = this->currentIndex(); + const QVariant data = this->model()->data(index.siblingAtColumn(0)); // supposed to be the callsign + const CAircraftCategoryTreeModel *model = this->categoryModel(); + if (!model) { return CAircraftCategory(); } + return model->container().frontOrDefault(); + } + + QString CAircraftCategoryTreeView::suffixForIndex(const QModelIndex &index) + { + const QVariant data = this->model()->data(index); // supposed to be the suffix + return data.toString(); + } + + void CAircraftCategoryTreeView::onExpanded(const QModelIndex &index) + { + Q_UNUSED(index); + this->fullResizeToContents(); + } + + void CAircraftCategoryTreeView::customMenu(const QPoint &point) + { + if (!this->categoryModel()) { return; } + if (this->categoryModel()->container().isEmpty()) { return; } + + QMenu *menu = new QMenu(this); // menu + QAction *resize = new QAction(CIcons::resize16(), "Resize", this); + connect(resize, &QAction::triggered, this, &CAircraftCategoryTreeView::fullResizeToContents); + + menu->addAction(resize); + menu->popup(this->viewport()->mapToGlobal(point)); + } + } // namespace +} // namespace diff --git a/src/blackgui/views/aircraftcategorytreeview.h b/src/blackgui/views/aircraftcategorytreeview.h new file mode 100644 index 000000000..6add0ab07 --- /dev/null +++ b/src/blackgui/views/aircraftcategorytreeview.h @@ -0,0 +1,77 @@ +/* Copyright (C) 2018 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKGUI_VIEWS_AIRCRAFTCATEGORYTREEVIEW_H +#define BLACKGUI_VIEWS_AIRCRAFTCATEGORYTREEVIEW_H + +#include "blackgui/blackguiexport.h" +#include "blackmisc/aviation/aircraftcategorylist.h" + +#include +#include +#include +#include +#include + +namespace BlackGui +{ + namespace Models + { + class CAircraftCategoryTreeModel; + class CColumns; + } + + namespace Views + { + //! ATC stations view + class BLACKGUI_EXPORT CAircraftCategoryTreeView : public QTreeView + { + Q_OBJECT + + public: + //! Constructor + explicit CAircraftCategoryTreeView(QWidget *parent = nullptr); + + //! Update container + void updateContainer(const BlackMisc::Aviation::CAircraftCategoryList &categories); + + //! Clear + void clear(); + + //! Set columns + void setColumns(const Models::CColumns &columns); + + //! Resize all columns + void fullResizeToContents(); + + private: + //! Used model + const Models::CAircraftCategoryTreeModel *categoryModel() const; + + //! Used model + BlackGui::Models::CAircraftCategoryTreeModel *categoryModel(); + + //! The selected object + BlackMisc::Aviation::CAircraftCategory selectedObject() const; + + //! Suffix for index + QString suffixForIndex(const QModelIndex &index); + + //! Expanded + void onExpanded(const QModelIndex &index); + + //! Custom menu + void customMenu(const QPoint &point); + }; + } // ns +} // ns + +#endif // guard diff --git a/src/blackgui/views/aircraftcategoryview.cpp b/src/blackgui/views/aircraftcategoryview.cpp new file mode 100644 index 000000000..ec1bec302 --- /dev/null +++ b/src/blackgui/views/aircraftcategoryview.cpp @@ -0,0 +1,27 @@ +/* Copyright (C) 2019 + * swift Project Community / Contributors + * + * This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "blackgui/views/aircraftcategoryview.h" +#include "blackgui/views/viewbase.h" + +using namespace BlackMisc; +using namespace BlackGui::Models; + +namespace BlackGui +{ + namespace Views + { + CAircraftCategoryView::CAircraftCategoryView(QWidget *parent) : + CViewWithDbObjects(parent) + { + this->standardInit(new CAircraftCategoryListModel(this)); + this->setMenu(MenuDefaultDbViews); + } + } +} // namespace diff --git a/src/blackgui/views/aircraftcategoryview.h b/src/blackgui/views/aircraftcategoryview.h new file mode 100644 index 000000000..23f229298 --- /dev/null +++ b/src/blackgui/views/aircraftcategoryview.h @@ -0,0 +1,35 @@ +/* Copyright (C) 2019 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKGUI_VIEWS_AIRCRAFTCATEGORYVIEW_H +#define BLACKGUI_VIEWS_AIRCRAFTCATEGORYVIEW_H + +#include "blackgui/models/aircraftcategorylistmodel.h" +#include "blackgui/views/viewdbobjects.h" +#include "blackgui/blackguiexport.h" + +namespace BlackGui +{ + namespace Views + { + //! Aircraft ICAO codes view + class BLACKGUI_EXPORT CAircraftCategoryView : + public CViewWithDbObjects + { + Q_OBJECT + + public: + //! Constructor + explicit CAircraftCategoryView(QWidget *parent = nullptr); + }; + } // ns +} // ns +#endif // guard diff --git a/src/blackgui/views/viewbaseaviation.cpp b/src/blackgui/views/viewbaseaviation.cpp index cb1f5501a..50e95d530 100644 --- a/src/blackgui/views/viewbaseaviation.cpp +++ b/src/blackgui/views/viewbaseaviation.cpp @@ -18,6 +18,7 @@ namespace BlackGui template class CViewBase; template class CViewBase; template class CViewBase; + template class CViewBase; template class CViewBase; template class CViewBase; template class CViewBase; diff --git a/src/blackgui/views/viewdbobjects.cpp b/src/blackgui/views/viewdbobjects.cpp index e27c5c724..4516a1a32 100644 --- a/src/blackgui/views/viewdbobjects.cpp +++ b/src/blackgui/views/viewdbobjects.cpp @@ -233,6 +233,7 @@ namespace BlackGui // see here for the reason of thess forward instantiations // https://isocpp.org/wiki/faq/templates#separate-template-fn-defn-from-decl template class CViewWithDbObjects; + template class CViewWithDbObjects; template class CViewWithDbObjects; template class CViewWithDbObjects; template class CViewWithDbObjects;