/* Copyright (C) 2015 * 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. 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/menus/menuaction.h" #include "blackgui/views/viewdbobjects.h" #include "blackgui/models/aircrafticaolistmodel.h" #include "blackgui/models/aircraftcategorylistmodel.h" #include "blackgui/models/aircraftmodellistmodel.h" #include "blackgui/models/airlineicaolistmodel.h" #include "blackgui/models/countrylistmodel.h" #include "blackgui/models/distributorlistmodel.h" #include "blackgui/models/liverylistmodel.h" #include "blackmisc/simulation/aircraftmodellist.h" #include "blackmisc/simulation/distributor.h" #include "blackmisc/simulation/distributorlist.h" #include "blackmisc/aviation/aircrafticaocodelist.h" #include "blackmisc/aviation/airlineicaocodelist.h" #include "blackmisc/aviation/liverylist.h" #include "blackmisc/icons.h" #include "blackmisc/countrylist.h" #include #include #include #include #include #include using namespace BlackMisc; using namespace BlackGui; using namespace BlackGui::Models; using namespace BlackGui::Menus; namespace BlackGui { namespace Views { template CViewWithDbObjects::CViewWithDbObjects(QWidget *parent) : CViewBase(parent) { // void CViewBaseNonTemplate::m_enabledLoadIndicator = true; // indicator for DB views } template typename CViewWithDbObjects::ObjectType CViewWithDbObjects::latestObject() const { return this->container().latestObject(); } template typename CViewWithDbObjects::ObjectType CViewWithDbObjects::oldestObject() const { return this->container().oldestObject(); } template bool CViewWithDbObjects::selectDbKey(const KeyType &key) { const QSet set({key}); return this->selectDbKeys(set) > 0; } template int CViewWithDbObjects::selectDbKeys(const QSet &keys) { if (keys.isEmpty()) { return 0; } this->clearSelection(); int r = -1; QSet rows; for (const ObjectType &obj : CViewBase::containerOrFilteredContainer()) { r++; if (!obj.hasValidDbKey()) { continue; } if (keys.contains(obj.getDbKey())) { rows.insert(r); } } return this->selectRows(rows); } template QSet::KeyType> CViewWithDbObjects::selectedDbKeys() const { if (!this->hasSelection()) { return QSet(); } const ContainerType selected(this->selectedObjects()); return selected.toDbKeySet(); } template int CViewWithDbObjects::removeDbKeys(const QSet &keys) { if (keys.isEmpty()) { return 0; } if (this->isEmpty()) { return 0; } ContainerType newObjects(this->container()); int delta = newObjects.removeObjectsWithKeys(keys); if (delta > 0) { this->updateContainerMaybeAsync(newObjects); } return delta; } template int CViewWithDbObjects::replaceOrAddObjectsByKey(const ContainerType &container) { if (container.isEmpty()) { return 0; } ContainerType copy(this->container()); int c = copy.replaceOrAddObjectsByKey(container); if (c == 0) { return 0; } this->updateContainerMaybeAsync(copy); return c; } template void CViewWithDbObjects::selectObjects(const ContainerType &selectedObjects) { if (selectedObjects.isEmpty()) { return; } this->selectDbKeys(selectedObjects.toDbKeySet()); } template void CViewWithDbObjects::customMenu(Menus::CMenuActions &menuActions) { // extensions would go here CViewBase::customMenu(menuActions); } template COrderableViewWithDbObjects::COrderableViewWithDbObjects(QWidget *parent) : CViewWithDbObjects::CViewWithDbObjects(parent) { // void } template void COrderableViewWithDbObjects::customMenu(CMenuActions &menuActions) { if (this->m_menus.testFlag(CViewBaseNonTemplate::MenuOrderable) && this->hasSelection()) { const int maxOrder = this->rowCount() - 1; CMenuAction menu = menuActions.addMenuViewOrder(); if (m_menuActions.isEmpty()) { // predefine menus m_menuActions = QList({ nullptr, nullptr, nullptr, nullptr}); if (!m_menuActions[0]) { m_frame = new QFrame(this); QHBoxLayout *layout = new QHBoxLayout(m_frame); layout->setMargin(2); m_frame->setLayout(layout); m_leOrder = new QLineEdit(m_frame); QLabel *icon = new QLabel(m_frame); icon->setPixmap(menu.getPixmap()); layout->addWidget(icon); QLabel *label = new QLabel(m_frame); label->setText("Order:"); layout->addWidget(label); layout->addWidget(m_leOrder); m_validator = new QIntValidator(0, maxOrder, this); m_leOrder->setValidator(m_validator); QWidgetAction *orderAction = new QWidgetAction(this); orderAction->setDefaultWidget(m_frame); QObject::connect(m_leOrder, &QLineEdit::returnPressed, this, &COrderableViewWithDbObjects::orderToLineEdit); m_menuActions[0] = orderAction; } } m_validator->setRange(0, maxOrder); m_leOrder->setPlaceholderText("New order 0-" + QString::number(maxOrder)); menuActions.addAction(m_menuActions[0], CMenuAction::pathViewOrder()); m_menuActions[1] = menuActions.addAction(CIcons::arrowMediumNorth16(), "To top", CMenuAction::pathViewOrder(), { this, &COrderableViewWithDbObjects::orderToTop }); m_menuActions[2] = menuActions.addAction(CIcons::arrowMediumSouth16(), "To bottom", CMenuAction::pathViewOrder(), { this, &COrderableViewWithDbObjects::orderToBottom }); m_menuActions[3] = menuActions.addAction(CIcons::arrowMediumWest16(), "Freeze current order", CMenuAction::pathViewOrder(), { this, &COrderableViewWithDbObjects::freezeCurrentOrder }); } CViewWithDbObjects::customMenu(menuActions); } template void COrderableViewWithDbObjects::selectObjects(const ContainerType &selectedObjects) { if (selectedObjects.isEmpty()) { return; } this->selectDbKeys(selectedObjects.toDbKeySet()); } template void COrderableViewWithDbObjects::moveSelectedItems(int order) { if (this->isEmpty()) { return; } const ContainerType objs(this->selectedObjects()); if (objs.isEmpty()) { return; } this->m_model->moveItems(objs, order); } template void COrderableViewWithDbObjects::orderToTop() { this->moveSelectedItems(0); } template void COrderableViewWithDbObjects::orderToBottom() { int c = this->model()->rowCount() - 1; if (c >= 0) { this->moveSelectedItems(c); } } template void COrderableViewWithDbObjects::orderToLineEdit() { if (this->isEmpty()) { return; } QLineEdit *le = qobject_cast(QObject::sender()); if (!le || le->text().isEmpty()) { return; } const int order = le->text().toInt(); this->moveSelectedItems(order); } template void COrderableViewWithDbObjects::freezeCurrentOrder() { ContainerType objects = this->container(); objects.freezeOrder(); this->updateContainerAsync(objects, false); } // 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; template class CViewWithDbObjects; template class CViewWithDbObjects; template class COrderableViewWithDbObjects; template class COrderableViewWithDbObjects; } // namespace } // namespace