diff --git a/src/blackgui/components/dbmappingcomponent.cpp b/src/blackgui/components/dbmappingcomponent.cpp index cd051231c..7644ea070 100644 --- a/src/blackgui/components/dbmappingcomponent.cpp +++ b/src/blackgui/components/dbmappingcomponent.cpp @@ -12,6 +12,7 @@ #include "blackgui/components/dbautostashingcomponent.h" #include "blackgui/components/dbmodelmappingmodifycomponent.h" #include "blackgui/components/modelmatchercomponent.h" +#include "blackgui/menus/aircraftmodelmenus.h" #include "blackgui/guiapplication.h" #include "blackgui/guiutility.h" #include "blackgui/shortcut.h" @@ -50,11 +51,19 @@ namespace BlackGui this->ui->tvp_AircraftModelsForVPilot->setAircraftModelMode(CAircraftModelListModel::VPilotRuleModel); this->ui->tvp_AircraftModelsForVPilot->addFilterDialog(); - // own models + // model menus + ui->comp_OwnAircraftModels->view()->setCustomMenu(new CShowSimulatorFileMenu(ui->comp_OwnAircraftModels->view(), this, true)); ui->comp_OwnAircraftModels->view()->setCustomMenu(new CMergeWithVPilotMenu(this)); ui->comp_OwnAircraftModels->view()->setCustomMenu(new COwnModelSetMenu(this, true)); ui->comp_OwnAircraftModels->view()->setCustomMenu(new CModelStashToolsMenu(this, false)); + ui->comp_OwnModelSet->view()->setCustomMenu(new CShowSimulatorFileMenu(ui->comp_OwnModelSet->view(), this, true)); + ui->comp_OwnModelSet->view()->setCustomMenu(new CModelStashToolsMenu(this, true)); + + ui->comp_StashAircraft->view()->setCustomMenu(new CShowSimulatorFileMenu(ui->comp_StashAircraft->view(), this, true)); + ui->comp_StashAircraft->view()->setCustomMenu(new CApplyDbDataMenu(this, true)); + ui->comp_StashAircraft->view()->setCustomMenu(new CModelStashToolsMenu(this, false)); + // connects connect(ui->editor_Model, &CModelMappingForm::requestStash, this, &CDbMappingComponent::ps_stashCurrentModel); @@ -75,6 +84,10 @@ namespace BlackGui connect(ui->comp_OwnModelSet->view(), &CAircraftModelView::doubleClicked, this, &CDbMappingComponent::ps_onModelRowSelected); + // initial values + this->ps_onModelSetCountChanged(ui->comp_OwnModelSet->view()->rowCount(), ui->comp_OwnModelSet->view()->hasFilter()); + this->ps_onStashCountChanged(ui->comp_StashAircraft->view()->rowCount(), ui->comp_StashAircraft->view()->hasFilter()); + // how to display forms ui->editor_AircraftIcao->setSelectOnly(); ui->editor_Distributor->setSelectOnly(); @@ -82,7 +95,6 @@ namespace BlackGui this->ui->tw_ModelsToBeMapped->setTabIcon(TabStash, CIcons::appDbStash16()); this->ui->tw_ModelsToBeMapped->setTabIcon(TabOwnModels, CIcons::appModels16()); - this->ui->comp_StashAircraft->view()->setCustomMenu(new CApplyDbDataMenu(this)); // custom menu this->setContextMenuPolicy(Qt::CustomContextMenu); @@ -99,12 +111,13 @@ namespace BlackGui void CDbMappingComponent::initVPilotLoading() { - bool canUseVPilot = true; // general flag if vPilot can be used/not used + const bool canUseVPilot = true; // general flag if vPilot can be used/not used this->m_withVPilot = canUseVPilot && this->m_swiftDbUser.get().isMappingAdmin(); static const QString tabName(this->ui->tw_ModelsToBeMapped->tabText(TabVPilot)); if (this->m_vPilot1stInit && canUseVPilot) { + this->m_vPilot1stInit = false; connect(this->ui->tvp_AircraftModelsForVPilot, &CAircraftModelView::doubleClicked, this, &CDbMappingComponent::ps_onModelRowSelected); connect(this->ui->tvp_AircraftModelsForVPilot, &CAircraftModelView::rowCountChanged, this, &CDbMappingComponent::ps_onVPilotCountChanged); connect(&m_vPilotReader, &CVPilotRulesReader::readFinished, this, &CDbMappingComponent::ps_onLoadVPilotDataFinished); @@ -119,10 +132,9 @@ namespace BlackGui this->ui->tvp_AircraftModelsForVPilot->addFilterDialog(); const CAircraftModelList vPilotModels(m_vPilotReader.getAsModelsFromCache()); this->ui->tvp_AircraftModelsForVPilot->updateContainerMaybeAsync(vPilotModels); - int noModels = vPilotModels.size(); + const int noModels = vPilotModels.size(); CLogMessage(this).info("%1 cached vPilot models loaded") << noModels; } - this->m_vPilot1stInit = false; this->ui->tab_VPilot->setEnabled(this->m_withVPilot); this->ui->tab_VPilot->setVisible(this->m_withVPilot); if (this->m_withVPilot) @@ -750,49 +762,54 @@ namespace BlackGui { CDbMappingComponent *mapComp = mappingComponent(); Q_ASSERT_X(mapComp, Q_FUNC_INFO, "no mapping component"); - bool canConnectDb = sGui->getWebDataServices()->canConnectSwiftDb(); - if (canConnectDb) + const bool canConnectDb = sGui->getWebDataServices()->canConnectSwiftDb(); + if (!canConnectDb) { this->nestedCustomMenu(menu); return; } + + if (!mapComp->currentModelView()->isEmpty() && mapComp->currentModelView()->getMenu().testFlag(CViewBaseNonTemplate::MenuCanStashModels)) { - if (!mapComp->currentModelView()->isEmpty() && mapComp->currentModelView()->getMenu().testFlag(CViewBaseNonTemplate::MenuCanStashModels)) + QMenu *stashMenu = new QMenu("Stash tools", &menu); + int dbModels = sGui->getWebDataServices()->getModelsCount(); + if (dbModels > 0) { - QMenu *stashMenu = new QMenu("Stash tools", &menu); - int dbModels = sGui->getWebDataServices()->getModelsCount(); - if (dbModels > 0) - { - // we have keys and data by which we could delete them from view - const QString msgDelete("Delete " + QString::number(dbModels) + " DB model(s) from " + mapComp->currentTabText()); - stashMenu->addAction(CIcons::delete16(), msgDelete, mapComp, &CDbMappingComponent::ps_removeDbModelsFromView); - } + // we have keys and data by which we could delete them from view + const QString msgDelete("Delete " + QString::number(dbModels) + " DB model(s) from " + mapComp->currentTabText()); + stashMenu->addAction(CIcons::delete16(), msgDelete, mapComp, &CDbMappingComponent::ps_removeDbModelsFromView); + } - const QString msgAutoStash("Auto stashing"); - stashMenu->addAction(CIcons::appDbStash16(), msgAutoStash, mapComp, &CDbMappingComponent::ps_displayAutoStashingDialog); + const QString msgAutoStash("Auto stashing"); + stashMenu->addAction(CIcons::appDbStash16(), msgAutoStash, mapComp, &CDbMappingComponent::ps_displayAutoStashingDialog); - if (mapComp->m_autoStashDialog && mapComp->m_autoStashDialog->isCompleted()) - { - stashMenu->addAction(CIcons::appDbStash16(), "Last auto stash run", mapComp->m_autoStashDialog.data(), &CDbAutoStashingComponent::showLastResults); - } + if (mapComp->m_autoStashDialog && mapComp->m_autoStashDialog->isCompleted()) + { + stashMenu->addAction(CIcons::appDbStash16(), "Last auto stash run", mapComp->m_autoStashDialog.data(), &CDbAutoStashingComponent::showLastResults); + } - // auto filter in DB views - QAction *a = stashMenu->addAction(CIcons::filter16(), "Auto filtering in DB views (on/off)", mapComp, &CDbMappingComponent::ps_toggleAutoFiltering); - a->setCheckable(true); - a->setChecked(mapComp->m_autoFilterInDbViews); + // auto filter in DB views + QAction *a = stashMenu->addAction(CIcons::filter16(), "Auto filtering in DB views (on/off)", mapComp, &CDbMappingComponent::ps_toggleAutoFiltering); + a->setCheckable(true); + a->setChecked(mapComp->m_autoFilterInDbViews); - // add menu - if (stashMenu->isEmpty()) - { - menu.deleteLater(); - } - else - { - this->addSeparator(menu); - menu.addMenu(stashMenu); - stashMenu->setIcon(CIcons::appDbStash16()); - } + // add menu + if (stashMenu->isEmpty()) + { + menu.deleteLater(); + } + else + { + this->addSeparator(menu); + menu.addMenu(stashMenu); + stashMenu->setIcon(CIcons::appDbStash16()); } } this->nestedCustomMenu(menu); } + void CDbMappingComponent::CModelStashToolsMenu::addSeparator(QMenu &menu) const + { + if (this->previousMenuItemContains("Stash", menu, Qt::CaseInsensitive)) { return; } + IMenuDelegate::addSeparator(menu); + } + CDbMappingComponent *CDbMappingComponent::CModelStashToolsMenu::mappingComponent() const { return qobject_cast(this->parent()); @@ -825,7 +842,7 @@ namespace BlackGui this->addSeparator(menu); // stash view and selection - QMenu *subMenu = menu.addMenu(CIcons::database16(), "Apply DB data (to selected)"); + QMenu *subMenu = menu.addMenu(CIcons::database16(), "Apply editor DB data (to selected)"); QAction *a = nullptr; a = subMenu->addAction(CIcons::appAircraftIcao16(), "Current aircraft ICAO", mapComp, &CDbMappingComponent::ps_applyDbData); @@ -840,12 +857,18 @@ namespace BlackGui // a = subMenu->addAction(CIcons::appAirlineIcao16(), "Current airline ICAO", mapComp, &CDbMappingComponent::ps_applyDbData); // a->setData(CAirlineIcaoCode().getClassName()); - menu.addAction(CIcons::databaseTable16(), "Modify model data", mapComp, &CDbMappingComponent::ps_applyDbData); + menu.addAction(CIcons::databaseTable16(), "Modify DB model data", mapComp, &CDbMappingComponent::ps_applyDbData); a->setData(CAircraftModel().getClassName()); } this->nestedCustomMenu(menu); } + void CDbMappingComponent::CApplyDbDataMenu::addSeparator(QMenu &menu) const + { + if (this->previousMenuItemContains("DB", menu)) { return; } + IMenuDelegate::addSeparator(menu); + } + CDbMappingComponent *CDbMappingComponent::CApplyDbDataMenu::mappingComponent() const { return qobject_cast(this->parent()); diff --git a/src/blackgui/components/dbmappingcomponent.h b/src/blackgui/components/dbmappingcomponent.h index 4d7e3b3bb..02452240b 100644 --- a/src/blackgui/components/dbmappingcomponent.h +++ b/src/blackgui/components/dbmappingcomponent.h @@ -291,6 +291,10 @@ namespace BlackGui //! \copydoc IMenuDelegate::customMenu virtual void customMenu(QMenu &menu) const override; + protected: + //! \copydoc IMenuDelegate::addSeparator + virtual void addSeparator(QMenu &menu) const override; + private: //! Mapping component CDbMappingComponent *mappingComponent() const; @@ -325,6 +329,10 @@ namespace BlackGui //! \copydoc IMenuDelegate::customMenu virtual void customMenu(QMenu &menu) const override; + protected: + //! \copydoc IMenuDelegate::addSeparator + virtual void addSeparator(QMenu &menu) const override; + private: //! Mapping component CDbMappingComponent *mappingComponent() const; diff --git a/src/blackgui/components/dbownmodelscomponent.cpp b/src/blackgui/components/dbownmodelscomponent.cpp index 3dea8722c..4dba12d7b 100644 --- a/src/blackgui/components/dbownmodelscomponent.cpp +++ b/src/blackgui/components/dbownmodelscomponent.cpp @@ -33,7 +33,6 @@ namespace BlackGui ui->tvp_OwnAircraftModels->setAircraftModelMode(CAircraftModelListModel::OwnSimulatorModelMapping); ui->tvp_OwnAircraftModels->addFilterDialog(); ui->tvp_OwnAircraftModels->setDisplayAutomatically(true); - ui->tvp_OwnAircraftModels->setCustomMenu(new CShowSimulatorFileMenu(ui->tvp_OwnAircraftModels, false), true); connect(ui->tvp_OwnAircraftModels, &CAircraftModelView::requestUpdate, this, &CDbOwnModelsComponent::ps_requestOwnModelsUpdate); diff --git a/src/blackgui/components/dbownmodelsetcomponent.cpp b/src/blackgui/components/dbownmodelsetcomponent.cpp index 51fe55903..135d8fcd8 100644 --- a/src/blackgui/components/dbownmodelsetcomponent.cpp +++ b/src/blackgui/components/dbownmodelsetcomponent.cpp @@ -32,13 +32,15 @@ namespace BlackGui ui(new Ui::CDbOwnModelSetComponent) { ui->setupUi(this); - ui->tvp_OwnModelSet->setAircraftModelMode(CAircraftModelListModel::OwnSimulatorModelMapping); + ui->tvp_OwnModelSet->setAircraftModelMode(CAircraftModelListModel::OwnModelSet); ui->tvp_OwnModelSet->menuRemoveItems(CAircraftModelView::MenuDisplayAutomaticallyAndRefresh | CAircraftModelView::MenuStashing | CAircraftModelView::MenuBackend | CAircraftModelView::MenuRefresh); ui->tvp_OwnModelSet->menuAddItems(CAircraftModelView::MenuRemoveSelectedRows | CAircraftModelView::MenuClear); ui->tvp_OwnModelSet->addFilterDialog(); ui->tvp_OwnModelSet->setCustomMenu(new CLoadModelsMenu(this)); ui->tvp_OwnModelSet->setJsonLoad(CAircraftModelView::AllowOnlySingleSimulator | CAircraftModelView::ReduceToOneSimulator); - ui->tvp_OwnModelSet->setCustomMenu(new CMergeWithDbDataMenu(ui->tvp_OwnModelSet, this, false)); + ui->tvp_OwnModelSet->setCustomMenu(new CMergeWithDbDataMenu(ui->tvp_OwnModelSet, this, true)); + ui->tvp_OwnModelSet->menuAddItems(CAircraftModelView::MenuOrderable); + ui->tvp_OwnModelSet->initAsOrderable(); connect(ui->pb_CreateNewSet, &QPushButton::clicked, this, &CDbOwnModelSetComponent::ps_buttonClicked); connect(ui->pb_LoadExistingSet, &QPushButton::clicked, this, &CDbOwnModelSetComponent::ps_buttonClicked); diff --git a/src/blackgui/editors/liveryform.ui b/src/blackgui/editors/liveryform.ui index 6ab0bccc2..ae04d4914 100644 --- a/src/blackgui/editors/liveryform.ui +++ b/src/blackgui/editors/liveryform.ui @@ -7,7 +7,7 @@ 0 0 221 - 416 + 422 @@ -197,22 +197,7 @@ - - - - 0 - - - 0 - - - 0 - - - 0 - - - + diff --git a/src/blackgui/menus/aircraftmodelmenus.cpp b/src/blackgui/menus/aircraftmodelmenus.cpp index 9e5256904..ff9386f41 100644 --- a/src/blackgui/menus/aircraftmodelmenus.cpp +++ b/src/blackgui/menus/aircraftmodelmenus.cpp @@ -10,6 +10,7 @@ #include "aircraftmodelmenus.h" #include "blackgui/guiapplication.h" #include "blackmisc/icons.h" +#include "blackmisc/logmessage.h" #include "blackmisc/simulation/aircraftmodelutils.h" #include @@ -44,15 +45,32 @@ namespace BlackGui return mv->selectedObjects(); } + CShowSimulatorFileMenu::CShowSimulatorFileMenu(CAircraftModelView *modelView, COverlayMessagesFrame *messageFrame, bool separator) : + IAircraftModelViewMenu(modelView, separator), m_messageFrame(messageFrame) + { } + void CShowSimulatorFileMenu::customMenu(QMenu &menu) const { CAircraftModelView *mv = modelView(); Q_ASSERT_X(mv, Q_FUNC_INFO, "no view"); - if (mv->hasSelection()) + if (mv->hasSingleSelectedRow()) { - this->addSeparator(menu); - menu.addAction(CIcons::text16(), "Open simulator file", this, &CShowSimulatorFileMenu::ps_showSimulatorFile); + const CAircraftModel model(mv->selectedObject()); + if (model.hasFileName() || (!model.getIconPath().isEmpty() && this->m_messageFrame)) + { + this->addSeparator(menu); + if (this->m_messageFrame) + { + const CAircraftModel model(mv->selectedObject()); + if (!model.getIconPath().isEmpty()) + { + this->addSeparator(menu); + menu.addAction(CIcons::appAircraft16(), "Display icon", this, &CShowSimulatorFileMenu::ps_displayIcon); + } + } + menu.addAction(CIcons::text16(), "Open simulator file", this, &CShowSimulatorFileMenu::ps_showSimulatorFile); + } } this->nestedCustomMenu(menu); } @@ -60,21 +78,32 @@ namespace BlackGui void CShowSimulatorFileMenu::ps_showSimulatorFile() const { const CAircraftModelView *mv = modelView(); - if (!mv->hasSelection()) { return; } - const CAircraftModelList models(getSelectedAircraftModels().findWithFileName()); - if (models.isEmpty()) { return; } - int trails = 0; - - for (const CAircraftModel &model : models) + if (!mv->hasSingleSelectedRow()) { return; } + const CAircraftModel model(mv->selectedObject()); + if (!model.hasFileName()) { return; } + if (QFile::exists(model.getFileName())) { - trails++; - if (QFile::exists(model.getFileName())) - { - const QString url("file:///" + model.getFileName()); - QDesktopServices::openUrl(QUrl(url)); - break; - } - if (trails > 10) { break; } + const QString url("file:///" + model.getFileName()); + QDesktopServices::openUrl(QUrl(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; + const CPixmap pm(model.loadIcon(msg)); + if (msg.isSuccess()) + { + this->m_messageFrame->showOverlayImage(pm); + } + else + { + msg.setCategories(getLogCategories()); + CLogMessage::preformatted(msg); } } @@ -135,6 +164,14 @@ namespace BlackGui } } + void CMergeWithDbDataMenu::addSeparator(QMenu &menu) const + { + // when the menu before us is a DB menu, we ignore the separator + if (!this->m_separator) { return; } + if (this->previousMenuItemContains("DB", menu)) { return; } + IAircraftModelViewMenu::addSeparator(menu); + } + IModelsSetable *CMergeWithDbDataMenu::modelsTargetSetable() const { return qobject_cast(this->m_modelsTarget); diff --git a/src/blackgui/menus/aircraftmodelmenus.h b/src/blackgui/menus/aircraftmodelmenus.h index 3c4341ae4..85fbef900 100644 --- a/src/blackgui/menus/aircraftmodelmenus.h +++ b/src/blackgui/menus/aircraftmodelmenus.h @@ -12,6 +12,7 @@ #include "menudelegate.h" #include "blackgui/views/aircraftmodelview.h" +#include "blackgui/overlaymessagesframe.h" #include "blackmisc/simulation/aircraftmodelinterfaces.h" #include "blackmisc/simulation/fscommon/vpilotrulesreader.h" #include @@ -48,14 +49,17 @@ namespace BlackGui public: //! Constructor - using IAircraftModelViewMenu::IAircraftModelViewMenu; + CShowSimulatorFileMenu(BlackGui::Views::CAircraftModelView *modelView, BlackGui::COverlayMessagesFrame *messageFrame, bool separator = true); //! \copydoc IMenuDelegate::customMenu virtual void customMenu(QMenu &menu) const override; private slots: - //! Open simulator file - void ps_showSimulatorFile() const; + void ps_showSimulatorFile() const; //!< simulator file + void ps_displayIcon(); //!< aircraft icon if any + + private: + BlackGui::COverlayMessagesFrame *m_messageFrame = nullptr; }; //! Merge with DB data @@ -77,10 +81,14 @@ namespace BlackGui void ps_mergeData(); void ps_mergeSelectedData(); + protected: + //! \copydoc IMenuDelegate::addSeparator + virtual void addSeparator(QMenu &menu) const override; + private: - BlackMisc::Simulation::IModelsSetable *modelsTargetSetable() const; + BlackMisc::Simulation::IModelsSetable *modelsTargetSetable() const; BlackMisc::Simulation::IModelsUpdatable *modelsTargetUpdatable() const; - QObject *m_modelsTarget = nullptr; //!< optional target for setting/updating the models + QObject *m_modelsTarget = nullptr; //!< optional target for setting/updating the models }; } // ns } // ns diff --git a/src/blackgui/menus/menudelegate.h b/src/blackgui/menus/menudelegate.h index 3359972d1..ea5c075e7 100644 --- a/src/blackgui/menus/menudelegate.h +++ b/src/blackgui/menus/menudelegate.h @@ -10,9 +10,12 @@ #ifndef BLACKGUI_MENUS_MENUDELEGATE_H #define BLACKGUI_MENUS_MENUDELEGATE_H +#include "blackmisc/logcategorylist.h" #include #include +using namespace BlackMisc; + namespace BlackGui { namespace Menus @@ -37,6 +40,13 @@ namespace BlackGui //! Destructor virtual ~IMenuDelegate() {} + //! Log categories + const CLogCategoryList &getLogCategories() + { + static const CLogCategoryList cats({CLogCategory::guiComponent()}); + return cats; + } + protected: //! Constructor IMenuDelegate(QWidget *parent = nullptr, bool separator = false) : @@ -50,12 +60,20 @@ namespace BlackGui } //! Add separator - void addSeparator(QMenu &menu) const + virtual void addSeparator(QMenu &menu) const { if (!m_separator || menu.isEmpty()) { return; } menu.addSeparator(); } + //! Does the previous (menu) item contain string? + bool previousMenuItemContains(const QString &str, const QMenu &menu, Qt::CaseSensitivity cs = Qt::CaseSensitive) const + { + if (menu.isEmpty() || str.isEmpty()) { return false; } + const QString t(menu.actions().last()->text()); + return t.contains(str, cs); + } + IMenuDelegate *m_nestedDelegate = nullptr; //!< nested delegate if any bool m_separator = false; //!< at end, terminate with separator }; diff --git a/src/blackgui/overlaymessages.cpp b/src/blackgui/overlaymessages.cpp index 4e9bd181d..0e533b43c 100644 --- a/src/blackgui/overlaymessages.cpp +++ b/src/blackgui/overlaymessages.cpp @@ -131,6 +131,28 @@ namespace BlackGui this->display(timeOutMs); } + void COverlayMessages::showOverlayImage(const CPixmap &image, int timeOutMs) + { + this->showOverlayImage(image.toPixmap(), timeOutMs); + } + + void COverlayMessages::showOverlayImage(const QPixmap &image, int timeOutMs) + { + this->setModeToImage(); + QSize sizeAvailable = this->ui->fr_StatusMessagesComponentsInner->size(); + if (sizeAvailable.width() < 300) + { + // first time inner frame is not giving correct size, workaround + sizeAvailable = this->size() * 0.9; + } + + this->ui->lbl_Image->setText(""); + this->ui->lbl_Image->setPixmap( + image.scaled(sizeAvailable, Qt::KeepAspectRatio, Qt::FastTransformation) + ); + this->display(timeOutMs); + } + void COverlayMessages::showOverlayVariant(const BlackMisc::CVariant &variant, int timeOutMs) { if (variant.canConvert()) @@ -145,6 +167,14 @@ namespace BlackGui { showOverlayTextMessage(variant.value(), timeOutMs); } + else if (variant.canConvert()) + { + showOverlayImage(variant.value(), timeOutMs); + } + else if (variant.canConvert()) + { + showOverlayImage(variant.value(), timeOutMs); + } Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported type"); } @@ -172,6 +202,12 @@ namespace BlackGui this->setHeader("Text message"); } + void COverlayMessages::setModeToImage() + { + this->ui->sw_StatusMessagesComponent->setCurrentWidget(this->ui->pg_Image); + this->setHeader("Image"); + } + void COverlayMessages::setConfirmationMessage(const QString &message) { if (message.isEmpty()) diff --git a/src/blackgui/overlaymessages.h b/src/blackgui/overlaymessages.h index 23fa78282..9905f4b89 100644 --- a/src/blackgui/overlaymessages.h +++ b/src/blackgui/overlaymessages.h @@ -15,6 +15,7 @@ #include "blackgui/blackguiexport.h" #include "blackmisc/network/textmessage.h" #include "blackmisc/statusmessagelist.h" +#include "blackmisc/pixmap.h" #include "blackmisc/variant.h" #include #include @@ -55,6 +56,9 @@ namespace BlackGui //! Single Text message mode void setModeToTextMessage(); + //! Display image + void setModeToImage(); + //! Set header text void setHeaderText(const QString &header); @@ -81,6 +85,12 @@ namespace BlackGui //! Info message, based on text message void showOverlayTextMessage(const BlackMisc::Network::CTextMessage &textMessage, int timeOutMs = -1); + //! Image + void showOverlayImage(const BlackMisc::CPixmap &image, int timeOutMs = -1); + + //! Image + void showOverlayImage(const QPixmap &image, int timeOutMs = -1); + //! Display one of the supported types void showOverlayVariant(const BlackMisc::CVariant &variant, int timeOutMs = -1); diff --git a/src/blackgui/overlaymessages.ui b/src/blackgui/overlaymessages.ui index c66cb231b..a3483778d 100644 --- a/src/blackgui/overlaymessages.ui +++ b/src/blackgui/overlaymessages.ui @@ -114,7 +114,7 @@ - 2 + 1 @@ -148,6 +148,23 @@ + + + + + + + 0 + 0 + + + + image will go here + + + + + diff --git a/src/blackgui/overlaymessagesframe.cpp b/src/blackgui/overlaymessagesframe.cpp index 26c00765f..10b06c3ad 100644 --- a/src/blackgui/overlaymessagesframe.cpp +++ b/src/blackgui/overlaymessagesframe.cpp @@ -70,6 +70,13 @@ namespace BlackGui this->repaint(); } + void COverlayMessagesFrame::showOverlayImage(const BlackMisc::CPixmap &pixmap, int timeOutMs) + { + this->initInnerFrame(); + this->m_overlayMessages->showOverlayImage(pixmap, timeOutMs); + this->repaint(); + } + void COverlayMessagesFrame::paintEvent(QPaintEvent *event) { bool s = CStyleSheetUtility::useStyleSheetInDerivedWidget(this, QStyle::PE_Widget); diff --git a/src/blackgui/overlaymessagesframe.h b/src/blackgui/overlaymessagesframe.h index 8c240323f..9a3c8c30f 100644 --- a/src/blackgui/overlaymessagesframe.h +++ b/src/blackgui/overlaymessagesframe.h @@ -41,10 +41,11 @@ namespace BlackGui //! \copydoc COverlayMessages::showOverlayMessagesWithConfirmation void showOverlayMessagesWithConfirmation( const BlackMisc::CStatusMessageList &messages, - const QString &confirmationMessage, - std::function okLambda, - int defaultButton = QMessageBox::Cancel, - int timeOutMs = -1); + const QString &confirmationMessage, + std::function okLambda, + int defaultButton = QMessageBox::Cancel, + int timeOutMs = -1 + ); public slots: //! \copydoc COverlayMessages::showOverlayMessages @@ -59,6 +60,9 @@ namespace BlackGui //! \copydoc COverlayMessages::showOverlayVariant void showOverlayVariant(const BlackMisc::CVariant &variant, int timeOutMs = -1); + //! \copydoc COverlayMessages::showOverlayImage + void showOverlayImage(const BlackMisc::CPixmap &pixmap, int timeOutMs = -1); + protected: //! \copydoc QFrame::paintEvent virtual void paintEvent(QPaintEvent *event) override; diff --git a/src/blackmisc/simulation/aircraftmodelsetloader.h b/src/blackmisc/simulation/aircraftmodelsetloader.h index a6d26f407..bdd05b717 100644 --- a/src/blackmisc/simulation/aircraftmodelsetloader.h +++ b/src/blackmisc/simulation/aircraftmodelsetloader.h @@ -49,6 +49,10 @@ namespace BlackMisc //! \threadsafe BlackMisc::Simulation::CAircraftModelList getAircraftModels() const; + //! The loaded models for given simulator + //! \threadsafe + BlackMisc::Simulation::CAircraftModelList getAircraftModels(const BlackMisc::Simulation::CSimulatorInfo &simulator) const; + //! Count of loaded models //! \threadsafe int getAircraftModelsCount() const { return getAircraftModels().size(); } diff --git a/src/blackmisc/simulation/fscommon/aircraftcfgentries.cpp b/src/blackmisc/simulation/fscommon/aircraftcfgentries.cpp index 2852183a8..4fa1fec51 100644 --- a/src/blackmisc/simulation/fscommon/aircraftcfgentries.cpp +++ b/src/blackmisc/simulation/fscommon/aircraftcfgentries.cpp @@ -10,6 +10,7 @@ #include "aircraftcfgentries.h" #include "blackmisc/variant.h" #include +#include using namespace BlackMisc; using namespace BlackMisc::Aviation; @@ -120,7 +121,7 @@ namespace BlackMisc model.setFileName(this->getFileName()); model.setName(this->getSimName()); model.setUtcTimestamp(this->getUtcTimestamp()); // aircraft.cfg file last modified - model.setIconPath(this->getThumbnailFileName()); + model.setIconPath(this->getThumbnailFileNameChecked()); const QString designator(CAircraftIcaoCode::normalizeDesignator(getAtcModel())); CAircraftIcaoCode aircraft( @@ -143,7 +144,7 @@ namespace BlackMisc return model; } - QString CAircraftCfgEntries::getThumbnailFileName() const + QString CAircraftCfgEntries::getThumbnailFileNameGuess() const { if (this->m_texture.isEmpty()) { return ""; } if (this->m_fileName.isEmpty()) { return ""; } @@ -151,6 +152,14 @@ namespace BlackMisc return fn; } + QString CAircraftCfgEntries::getThumbnailFileNameChecked() const + { + const QString f(getThumbnailFileNameGuess()); + if (f.isEmpty()) { return ""; } + if (QFile(f).exists()) { return f; } + return ""; + } + CVariant CAircraftCfgEntries::propertyByIndex(const BlackMisc::CPropertyIndex &index) const { if (index.isMyself()) { return CVariant::from(*this); } diff --git a/src/blackmisc/simulation/fscommon/aircraftcfgentries.h b/src/blackmisc/simulation/fscommon/aircraftcfgentries.h index c0708fa66..af4a14dc6 100644 --- a/src/blackmisc/simulation/fscommon/aircraftcfgentries.h +++ b/src/blackmisc/simulation/fscommon/aircraftcfgentries.h @@ -155,7 +155,11 @@ namespace BlackMisc BlackMisc::Simulation::CAircraftModel toAircraftModel() const; //! Thumbnail.jpg path if possible - QString getThumbnailFileName() const; + QString getThumbnailFileNameGuess() const; + + //! Thumbnail.jpg path if possible, and checked if file exists + //! \remark checks file existence, consider I/O load + QString getThumbnailFileNameChecked() const; //! \copydoc BlackMisc::Mixin::Index::propertyByIndex BlackMisc::CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;