Files
pilotclient/src/blackgui/menus/aircraftmodelmenus.cpp

374 lines
15 KiB
C++

/* Copyright (C) 2016
* 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 "aircraftmodelmenus.h"
#include "blackgui/guiapplication.h"
#include "blackgui/components/dbmappingcomponent.h"
#include "blackgui/components/dbmappingcomponentaware.h"
#include "blackcore/webdataservices.h"
#include "blackcore/db/databaseutils.h"
#include "blackmisc/verify.h"
#include "blackmisc/icons.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/simulation/aircraftmodelutils.h"
#include <QDesktopServices>
using namespace BlackMisc;
using namespace BlackMisc::Simulation;
using namespace BlackGui;
using namespace BlackGui::Views;
using namespace BlackGui::Models;
using namespace BlackGui::Components;
using namespace BlackCore::Db;
namespace BlackGui
{
namespace Menus
{
const CLogCategoryList &IAircraftModelViewMenu::getLogCategories()
{
static const CLogCategoryList cats { CLogCategory::guiComponent() };
return cats;
}
CAircraftModelView *IAircraftModelViewMenu::modelView() const
{
CAircraftModelView *mv = qobject_cast<CAircraftModelView *>(parent());
Q_ASSERT_X(mv, Q_FUNC_INFO, "no view");
return mv;
}
const CAircraftModelList &IAircraftModelViewMenu::getAircraftModels() const
{
const CAircraftModelView *mv = modelView();
Q_ASSERT_X(mv, Q_FUNC_INFO, "no view");
return mv->container();
}
const CAircraftModelList &IAircraftModelViewMenu::getAllOrAllFilteredAircraftModels(bool *filtered) const
{
const CAircraftModelView *mv = modelView();
Q_ASSERT_X(mv, Q_FUNC_INFO, "no view");
return mv->containerOrFilteredContainer(filtered);
}
CAircraftModelList IAircraftModelViewMenu::getSelectedAircraftModels() const
{
const CAircraftModelView *mv = modelView();
Q_ASSERT_X(mv, Q_FUNC_INFO, "no view");
return mv->selectedObjects();
}
CShowSimulatorFileMenu::CShowSimulatorFileMenu(CAircraftModelView *modelView, COverlayMessagesFrame *messageFrame, bool separator) :
IAircraftModelViewMenu(modelView, separator), m_messageFrame(messageFrame)
{ }
const CLogCategoryList &CShowSimulatorFileMenu::getLogCategories()
{
static const CLogCategoryList cats { CLogCategory::guiComponent() };
return cats;
}
void CShowSimulatorFileMenu::customMenu(CMenuActions &menuActions)
{
CAircraftModelView *mv = modelView();
Q_ASSERT_X(mv, Q_FUNC_INFO, "no view");
if (mv->hasSingleSelectedRow())
{
const CAircraftModel model(mv->selectedObject());
if (model.hasFileName() || (!model.getIconPath().isEmpty() && this->m_messageFrame))
{
menuActions.addMenuSimulator();
if (this->m_messageFrame)
{
if (!model.getIconPath().isEmpty())
{
this->m_iconAction = menuActions.addAction(this->m_iconAction, CIcons::appAircraft16(), "Display icon", CMenuAction::pathSimulator(), { this, &CShowSimulatorFileMenu::ps_displayIcon });
}
}
this->m_fileAction = menuActions.addAction(this->m_fileAction, CIcons::text16(), "Open simulator file", CMenuAction::pathSimulator(), { this, &CShowSimulatorFileMenu::ps_showSimulatorFile });
}
}
this->nestedCustomMenu(menuActions);
}
void CShowSimulatorFileMenu::ps_showSimulatorFile()
{
const CAircraftModelView *mv = modelView();
if (!mv->hasSingleSelectedRow()) { return; }
const CAircraftModel model(mv->selectedObject());
if (!model.hasFileName()) { return; }
if (QFile::exists(model.getFileName()))
{
const QUrl url = QUrl::fromLocalFile(model.getFileName());
QDesktopServices::openUrl(url);
}
}
void CShowSimulatorFileMenu::ps_displayIcon()
{
const CAircraftModelView *mv = modelView();
if (!mv->hasSingleSelectedRow()) { return; }
const CAircraftModel model(mv->selectedObject());
if (model.getIconPath().isEmpty()) { return; }
CStatusMessage msg(this);
const CPixmap pm(model.loadIcon(msg));
if (msg.isSuccess())
{
this->m_messageFrame->showOverlayImage(pm);
}
else
{
msg.setCategories(getLogCategories());
CLogMessage::preformatted(msg);
}
}
// --------------------------------- with DB data ---------------------------------
CConsolidateWithDbDataMenu::CConsolidateWithDbDataMenu(CAircraftModelView *modelView, QObject *modelsTarget, bool separator) :
IAircraftModelViewMenu(modelView, separator), m_modelsTarget(modelsTarget)
{
// it can be the target is not yet known
if (modelsTarget)
{
bool ok = modelsTargetSetable() || modelsTargetUpdatable();
Q_ASSERT_X(ok, Q_FUNC_INFO, "Neither setable nor updatable");
Q_UNUSED(ok);
}
}
const CLogCategoryList &CConsolidateWithDbDataMenu::getLogCategories()
{
static const CLogCategoryList cats { CLogCategory::mapping(), CLogCategory::guiComponent() };
return cats;
}
void CConsolidateWithDbDataMenu::customMenu(CMenuActions &menuActions)
{
const CAircraftModelView *mv = modelView();
if (mv->isEmpty()) { this->nestedCustomMenu(menuActions); return; }
if (!sGui->hasWebDataServices()) { this->nestedCustomMenu(menuActions); return; }
menuActions.addMenuConsolidateModels();
this->m_consolidateAll = menuActions.addAction(this->m_consolidateAll, CIcons::databaseEdit16(), "All with DB data", CMenuAction::pathViewModelsConsolidate(), { this, &CConsolidateWithDbDataMenu::ps_consolidateData });
if (mv->hasSelection())
{
this->m_consolidateSelected = menuActions.addAction(this->m_consolidateSelected, CIcons::databaseEdit16(), "Selected with DB data", CMenuAction::pathViewModelsConsolidate(), { this, &CConsolidateWithDbDataMenu::ps_consolidateSelectedData });
}
this->nestedCustomMenu(menuActions);
}
void CConsolidateWithDbDataMenu::ps_consolidateData()
{
BLACK_VERIFY_X(sGui, Q_FUNC_INFO, "Missing sGui");
if (!sGui->hasWebDataServices()) { return; }
const CAircraftModelList dbModels(sGui->getWebDataServices()->getModels());
if (dbModels.isEmpty())
{
CLogMessage(this).warning("No DB models to consolidate with");
return;
}
if (!this->modelsTargetSetable())
{
CLogMessage(this).warning("No setable target");
return;
}
this->modelView()->showLoadIndicator();
bool filtered = false;
CAircraftModelList models(this->getAllOrAllFilteredAircraftModels(&filtered));
const int c = CDatabaseUtils::consolidateModelsWithDbDataAllowsGuiRefresh(models, true, true);
if (c > 0 && this->modelsTargetSetable() && this->modelsTargetUpdatable())
{
if (filtered)
{
this->modelsTargetUpdatable()->updateModels(models);
CLogMessage(this).info("Consolidated %1/%2 filtered models with DB") << c << models.size();
}
else
{
this->modelsTargetSetable()->setModels(models);
CLogMessage(this).info("Consolidated %1/%2 models with DB") << c << models.size();
}
}
else
{
CLogMessage(this).info("No data consolidated with DB");
this->modelView()->hideLoadIndicator();
}
}
void CConsolidateWithDbDataMenu::ps_consolidateSelectedData()
{
Q_ASSERT_X(sGui, Q_FUNC_INFO, "Missing sGui");
if (!sGui->hasWebDataServices()) { return; }
CAircraftModelList models(this->getSelectedAircraftModels());
if (models.isEmpty()) { return; }
if (!this->modelsTargetUpdatable())
{
CLogMessage(this).warning("No updatable target");
return;
}
int c = CDatabaseUtils::consolidateModelsWithDbDataAllowsGuiRefresh(models, true, true);
if (c > 0 && this->modelsTargetUpdatable())
{
this->modelsTargetUpdatable()->updateModels(models);
}
}
IModelsSetable *CConsolidateWithDbDataMenu::modelsTargetSetable() const
{
return qobject_cast<IModelsSetable *>(this->m_modelsTarget);
}
IModelsUpdatable *CConsolidateWithDbDataMenu::modelsTargetUpdatable() const
{
return qobject_cast<IModelsUpdatable *>(this->m_modelsTarget);
}
// --------------------------------- with simulator models ---------------------------------
CConsolidateWithSimulatorModels::CConsolidateWithSimulatorModels(CAircraftModelView *modelView, QObject *modelsTarget, bool separator) :
IAircraftModelViewMenu(modelView, separator), m_modelsTarget(modelsTarget)
{
// it can be the target is not yet known
if (modelsTarget)
{
bool ok = modelsTargetSetable() || modelsTargetUpdatable();
Q_ASSERT_X(ok, Q_FUNC_INFO, "Neither setable nor updatable");
Q_UNUSED(ok);
}
}
const CLogCategoryList &CConsolidateWithSimulatorModels::getLogCategories()
{
static const CLogCategoryList cats { CLogCategory::mapping(), CLogCategory::guiComponent() };
return cats;
}
void CConsolidateWithSimulatorModels::customMenu(CMenuActions &menuActions)
{
const CAircraftModelView *mv = modelView();
if (mv->isEmpty()) { this->nestedCustomMenu(menuActions); return; }
if (!sGui->hasWebDataServices()) { this->nestedCustomMenu(menuActions); return; }
menuActions.addMenuConsolidateModels();
this->m_consolidateAll = menuActions.addAction(this->m_consolidateAll, CIcons::appModels16(), "All with simulator models", CMenuAction::pathViewModelsConsolidate(), { this, &CConsolidateWithSimulatorModels::ps_consolidateData });
if (mv->hasSelection())
{
this->m_consolidateSelected = menuActions.addAction(this->m_consolidateSelected, CIcons::appModels16(), "Selected with simulator models", CMenuAction::pathViewModelsConsolidate(), { this, &CConsolidateWithSimulatorModels::ps_consolidateSelectedData });
}
this->nestedCustomMenu(menuActions);
}
void CConsolidateWithSimulatorModels::ps_consolidateData()
{
bool filtered = false;
const CAircraftModelList models(this->getAllOrAllFilteredAircraftModels(&filtered));
if (models.isEmpty()) { return; }
const int i = this->modelView()->showLoadIndicator();
const CAircraftModelList consolidated = CDatabaseUtils::consolidateModelsWithSimulatorModelsAllowsGuiRefresh(models, this->getSimulatorModels(), true);
const CSimulatorInfo sim(this->getSimulator());
if (!filtered)
{
this->modelsTargetSetable()->setModels(consolidated, sim);
}
else
{
if (!this->modelsTargetUpdatable())
{
CLogMessage(this).warning("No updatable target");
}
else
{
this->modelsTargetUpdatable()->updateModels(consolidated, sim);
}
}
this->modelView()->hideLoadIndicator(i);
}
void CConsolidateWithSimulatorModels::ps_consolidateSelectedData()
{
Q_ASSERT_X(sGui, Q_FUNC_INFO, "Missing sGui");
const CAircraftModelList models(this->getSelectedAircraftModels());
if (models.isEmpty()) { return; }
if (!this->modelsTargetUpdatable())
{
CLogMessage(this).warning("No updatable target");
return;
}
const int i = this->modelView()->showLoadIndicator();
const CAircraftModelList consolidated = CDatabaseUtils::consolidateModelsWithSimulatorModelsAllowsGuiRefresh(models, this->getSimulatorModels(), true);
const CSimulatorInfo sim(this->getSimulator());
this->modelsTargetUpdatable()->updateModels(consolidated, sim);
this->modelView()->hideLoadIndicator(i);
}
CAircraftModelList CConsolidateWithSimulatorModels::getSimulatorModels() const
{
CDbMappingComponent *mc = this->getMappingComponent();
Q_ASSERT_X(mc, Q_FUNC_INFO, "No mapping component");
const CSimulatorInfo sim = this->getSimulator();
mc->setOwnModelsSimulator(sim);
return mc->getOwnModels();
}
CSimulatorInfo CConsolidateWithSimulatorModels::getSimulator() const
{
const ISimulatorSelectable *s = this->simulatorSelectable();
Q_ASSERT_X(s, Q_FUNC_INFO, "No ISimulatorSelectable");
const CSimulatorInfo sim = s->getSelectedSimulator();
Q_ASSERT_X(sim.isSingleSimulator(), Q_FUNC_INFO, "Need single simulator");
return sim;
}
IModelsPerSimulatorSetable *CConsolidateWithSimulatorModels::modelsTargetSetable() const
{
return qobject_cast<IModelsPerSimulatorSetable *>(this->m_modelsTarget);
}
IModelsPerSimulatorUpdatable *CConsolidateWithSimulatorModels::modelsTargetUpdatable() const
{
return qobject_cast<IModelsPerSimulatorUpdatable *>(this->m_modelsTarget);
}
ISimulatorSelectable *CConsolidateWithSimulatorModels::simulatorSelectable() const
{
return qobject_cast<ISimulatorSelectable *>(this->m_modelsTarget);
}
Components::CDbMappingComponent *CConsolidateWithSimulatorModels::getMappingComponent() const
{
// try to cast target
CDbMappingComponent *mc = nullptr;
CDbMappingComponentAware *mca = qobject_cast<CDbMappingComponentAware *>(this->m_modelsTarget);
if (mca)
{
mc = mca->getMappingComponent();
}
if (!mc)
{
mc = qobject_cast<CDbMappingComponent *>(this->m_modelsTarget);
}
return mc;
}
} // ns
} // ns