diff --git a/src/blackcore/db/databasewriter.cpp b/src/blackcore/db/databasewriter.cpp index e918b7dc0..08effe2c9 100644 --- a/src/blackcore/db/databasewriter.cpp +++ b/src/blackcore/db/databasewriter.cpp @@ -40,6 +40,11 @@ namespace BlackCore // void } + CStatusMessageList CDatabaseWriter::asyncPublishModel(const CAircraftModel &model) + { + return this->asyncPublishModels(CAircraftModelList({ model })); + } + CStatusMessageList CDatabaseWriter::asyncPublishModels(const CAircraftModelList &models) { CStatusMessageList msgs; diff --git a/src/blackcore/db/databasewriter.h b/src/blackcore/db/databasewriter.h index 7435871b0..c4ccb31df 100644 --- a/src/blackcore/db/databasewriter.h +++ b/src/blackcore/db/databasewriter.h @@ -36,7 +36,10 @@ namespace BlackCore //! Constructor CDatabaseWriter(const BlackMisc::Network::CUrl &baseUrl, QObject *parent); - //! Write model to DB + //! Write models to DB + BlackMisc::CStatusMessageList asyncPublishModel(const BlackMisc::Simulation::CAircraftModel &model); + + //! Write models to DB BlackMisc::CStatusMessageList asyncPublishModels(const BlackMisc::Simulation::CAircraftModelList &models); //! Shutdown @@ -54,10 +57,10 @@ namespace BlackCore void ps_postModelsResponse(QNetworkReply *nwReplyPtr); private: - BlackMisc::Network::CUrl m_modelPublishUrl; - QNetworkReply *m_pendingReply = nullptr; - qint64 m_replyPendingSince = -1; - bool m_shutdown = false; + BlackMisc::Network::CUrl m_modelPublishUrl; + QNetworkReply *m_pendingReply = nullptr; + qint64 m_replyPendingSince = -1; + bool m_shutdown = false; //! Kill the pending reply bool killPendingReply(); diff --git a/src/blackgui/components/dbquickmappingwizard.cpp b/src/blackgui/components/dbquickmappingwizard.cpp new file mode 100644 index 000000000..28d97f8dc --- /dev/null +++ b/src/blackgui/components/dbquickmappingwizard.cpp @@ -0,0 +1,322 @@ +/* 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 "dbquickmappingwizard.h" +#include "ui_dbquickmappingwizard.h" +#include "dbaircrafticaoselectorcomponent.h" +#include "dbairlinenameselectorcomponent.h" +#include "blackgui/views/aircrafticaoview.h" +#include "blackgui/views/liveryview.h" +#include "blackgui/views/distributorview.h" +#include "blackgui/uppercasevalidator.h" +#include "blackgui/guiapplication.h" +#include "blackcore/webdataservices.h" +#include "blackcore/db/databasewriter.h" + +using namespace BlackCore; +using namespace BlackCore::Db; +using namespace BlackMisc; +using namespace BlackMisc::Aviation; +using namespace BlackMisc::Simulation; + +namespace BlackGui +{ + namespace Components + { + CDbQuickMappingWizard::CDbQuickMappingWizard(QWidget *parent) : + QWizard(parent), + ui(new Ui::CDbQuickMappingWizard) + { + Q_ASSERT_X(sGui, Q_FUNC_INFO, "Missing sGui"); + Q_ASSERT_X(sGui->hasWebDataServices(), Q_FUNC_INFO, "Missing web services"); + Q_ASSERT_X(sGui->getWebDataServices()->getDatabaseWriter(), Q_FUNC_INFO, "Missing writer"); + + ui->setupUi(this); + ui->selector_AircraftIcaoCode->setFocus(); + ui->selector_AircraftIcaoCode->displayWithIcaoDescription(false); + ui->selector_AircraftIcaoCode->displayMode(CDbAircraftIcaoSelectorComponent::DisplayCompleterString); + ui->selector_AirlineIcaoCode->displayWithIcaoDescription(false); + ui->editor_AircraftModel->allowDrop(false); + ui->editor_AircraftModel->setReadOnly(true); + + connect(sGui->getWebDataServices(), &CWebDataServices::allSwiftDbDataRead, this, &CDbQuickMappingWizard::ps_webDataRead); + connect(sGui->getWebDataServices()->getDatabaseWriter(), &CDatabaseWriter::publishedModels, this, &CDbQuickMappingWizard::ps_publishedModels); + + connect(this, &CDbQuickMappingWizard::currentIdChanged, this, &CDbQuickMappingWizard::ps_currentWizardPageChanged); + connect(ui->selector_AircraftIcaoCode, &CDbAircraftIcaoSelectorComponent::changedAircraftIcao, this, &CDbQuickMappingWizard::ps_aircraftSelected); + connect(ui->selector_AirlineIcaoCode, &CDbAirlineIcaoSelectorComponent::changedAirlineIcao, this, &CDbQuickMappingWizard::ps_airlineSelected); + connect(ui->selector_AirlineName, &CDbAirlineIcaoSelectorComponent::changedAirlineIcao, this, &CDbQuickMappingWizard::ps_airlineSelected); + + // init if data already available + this->ps_webDataRead(); + } + + CDbQuickMappingWizard::~CDbQuickMappingWizard() + { } + + const CLogCategoryList &CDbQuickMappingWizard::getLogCategories() + { + static const BlackMisc::CLogCategoryList cats { CLogCategory::mapping(), CLogCategory::guiComponent() }; + return cats; + } + + void CDbQuickMappingWizard::presetAircraftIcao(const BlackMisc::Aviation::CAircraftIcaoCode &aircraftIcao) + { + this->clear(); + ui->selector_AircraftIcaoCode->setAircraftIcao(aircraftIcao); + ui->selector_AircraftIcaoCode->setFocus(); + } + + void CDbQuickMappingWizard::presetModel(const BlackMisc::Simulation::CAircraftModel &model) + { + QString ms = model.getModelString(); + if (!model.getDescription().isEmpty()) + { + ms += " ("; + ms += model.getDescription(); + ms += ")"; + } + + this->presetAircraftIcao(model.getAircraftIcaoCode()); + ui->selector_AirlineIcaoCode->setAirlineIcao(model.getAirlineIcaoCode()); + ui->selector_AirlineName->setAirlineIcao(model.getAirlineIcaoCode()); + ui->comp_Distributor->view()->selectDbKey(model.getDistributor().getDbKey()); + ui->le_ModelString->setText(model.hasModelString() ? ms : ""); + ui->selector_AircraftIcaoCode->setFocus(); + + const CLivery livery(model.getLivery()); + if (livery.isColorLivery()) + { + ui->comp_ColorSearch->presetColorLivery(livery); + ui->rb_ColorLivery->setChecked(true); + } + + this->m_model = model; + } + + void CDbQuickMappingWizard::clear() + { + this->m_lastId = 0; + ui->editor_AircraftModel->clear(); + ui->comp_Log->clear(); + this->restart(); + } + + void CDbQuickMappingWizard::setAircraftIcaoFilter() + { + const CAircraftIcaoCode icao(ui->selector_AircraftIcaoCode->getAircraftIcao()); + if (icao.isLoadedFromDb()) + { + ui->comp_AircraftIcao->view()->sortByPropertyIndex(CAircraftIcaoCode::IndexRank); + ui->comp_AircraftIcao->filter(icao); + ui->comp_AircraftIcao->view()->selectDbKey(icao.getDbKey()); + } + } + + void CDbQuickMappingWizard::setAirlineIcaoFilter() + { + const CAirlineIcaoCode icao(ui->selector_AirlineIcaoCode->getAirlineIcao()); + if (icao.isLoadedFromDb()) + { + ui->comp_Livery->view()->sortByPropertyIndex(CLivery::IndexDbIntegerKey); + ui->comp_Livery->filterByAirline(icao); + ui->comp_Livery->view()->selectRow(0); + } + } + + void CDbQuickMappingWizard::setColorFilter() + { + const CLivery colorLivery(ui->comp_ColorSearch->getLivery()); + if (colorLivery.isLoadedFromDb()) + { + ui->comp_Livery->filter(colorLivery); + ui->comp_Livery->view()->selectRow(0); + } + } + + CLivery CDbQuickMappingWizard::getFirstSelectedOrDefaultLivery() const + { + return ui->comp_Livery->view()->firstSelectedOrDefaultObject(); + } + + CAircraftIcaoCode CDbQuickMappingWizard::getFirstSelectedOrDefaultAircraftIcao() const + { + return ui->comp_AircraftIcao->view()->firstSelectedOrDefaultObject(); + } + + BlackMisc::Simulation::CDistributor CDbQuickMappingWizard::getFirstSelectedOrDefaultDistributor() const + { + return ui->comp_Distributor->view()->firstSelectedOrDefaultObject(); + } + + void CDbQuickMappingWizard::ps_webDataRead() + { + if (!sGui || !sGui->hasWebDataServices()) { return; } + } + + void CDbQuickMappingWizard::ps_publishedModels(const CAircraftModelList &modelsPublished, const CAircraftModelList &modelsSkipped, const CStatusMessageList &messages, bool requestSuccessful, bool directWrite) + { + Q_UNUSED(modelsPublished); + Q_UNUSED(modelsSkipped); + Q_UNUSED(directWrite); + CStatusMessageList msgs; + if (requestSuccessful) + { + msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityInfo, "Publishing request sent")); + } + else + { + msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityError, "Publishing request failed")); + } + msgs.push_back(messages); + ui->comp_Log->appendStatusMessagesToList(msgs); + } + + void CDbQuickMappingWizard::ps_currentWizardPageChanged(int id) + { + const bool forward = id > this->m_lastId; + const bool colorMode = ui->rb_ColorLivery->isChecked(); + this->m_lastId = id; + + const Pages page = static_cast(id); + switch (page) + { + case PageAircraftSelect: + { + this->setAircraftIcaoFilter(); + } + break; + case PageColor: + if (!colorMode) + { + forward ? this->next() : this->back(); + } + break; + case PageLiverySelect: + { + if (colorMode) + { + this->setColorFilter(); + } + else + { + this->setAirlineIcaoFilter(); + } + } + break; + case PageConfirmation: + { + ui->editor_AircraftModel->setLivery(this->getFirstSelectedOrDefaultLivery()); + ui->editor_AircraftModel->setDistributor(this->getFirstSelectedOrDefaultDistributor()); + ui->editor_AircraftModel->setAircraftIcao(this->getFirstSelectedOrDefaultAircraftIcao()); + const CStatusMessageList msgs(this->validateData()); + const bool errorFree = !msgs.hasWarningOrErrorMessages(); + ui->fr_ConfirmationOk->setVisible(errorFree); + ui->fr_ConfirmationStillErrors->setVisible(!errorFree); + if (!errorFree) + { + ui->editor_AircraftModel->showOverlayMessages(msgs); + } + } + break; + case PageCredentials: + { + ui->comp_Log->clear(); + } + break; + case PageSendStatus: + { + this->writeModeltoDb(); + } + break; + default: + break; + } + } + + bool CDbQuickMappingWizard::validateCurrentPage() + { + const Pages page = static_cast(this->currentId()); + bool ok = false; + switch (page) + { + case PageConfirmation: + { + const CStatusMessageList msgs(this->validateData()); + ok = !msgs.hasWarningOrErrorMessages(); + } + break; + case PageCredentials: + { + ok = ui->comp_DbLogin->isUserAuthenticated(); + } + break; + default: + { + ok = true; + } + break; + } + + return ok; + } + + CStatusMessageList CDbQuickMappingWizard::validateData() const + { + CStatusMessageList msgs(ui->editor_AircraftModel->validate(true)); + if (ui->le_ModelString->text().isEmpty()) + { + const CStatusMessage error(this, CStatusMessage::SeverityError, "Missing model string", true); + msgs.push_back(error); + } + return msgs; + } + + void CDbQuickMappingWizard::consolidateModel() + { + CAircraftModel model = this->m_model; + model.setAircraftIcaoCode(ui->editor_AircraftModel->getAircraftIcao()); + model.setDistributor(ui->editor_AircraftModel->getDistributor()); + model.setLivery(ui->editor_AircraftModel->getLivery()); + this->m_model = model; + } + + void CDbQuickMappingWizard::writeModeltoDb() + { + this->consolidateModel(); + const CStatusMessageList msgs = sGui->getWebDataServices()->getDatabaseWriter()->asyncPublishModel(this->m_model); + ui->comp_Log->appendStatusMessagesToList(msgs); + } + + void CDbQuickMappingWizard::ps_airlineSelected(const CAirlineIcaoCode &icao) + { + if (icao.isLoadedFromDb()) + { + ui->cb_VirtualAirline->setChecked(icao.isVirtualAirline()); + ui->cb_Military->setChecked(icao.isMilitary()); + ui->selector_AirlineName->setAirlineIcao(icao); + ui->selector_AirlineIcaoCode->setAirlineIcao(icao); + // already trigger sorting, if sorting is already correct it does nothing + // avoids issue with later selection overridden by sorting/filtering + this->setAirlineIcaoFilter(); + } + } + + void CDbQuickMappingWizard::ps_aircraftSelected(const CAircraftIcaoCode &icao) + { + if (icao.isLoadedFromDb()) + { + ui->cb_Military->setChecked(icao.isMilitary()); + // already trigger sorting, if sorting is already correct it does nothing + // avoids issue with later selection overridden by sorting/filtering + this->setAircraftIcaoFilter(); + } + } + } // ns +} // ns diff --git a/src/blackgui/components/dbquickmappingwizard.h b/src/blackgui/components/dbquickmappingwizard.h new file mode 100644 index 000000000..355fd467b --- /dev/null +++ b/src/blackgui/components/dbquickmappingwizard.h @@ -0,0 +1,120 @@ +/* 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. + */ + +//! \file + +#ifndef BLACKGUI_COMPONENTS_DBQUICKMAPPINGWIZARD_H +#define BLACKGUI_COMPONENTS_DBQUICKMAPPINGWIZARD_H + +#include "blackmisc/simulation/aircraftmodel.h" +#include "blackmisc/aviation/aircrafticaocode.h" +#include +#include + +namespace Ui { class CDbQuickMappingWizard; } +namespace BlackGui +{ + namespace Components + { + /*! + * Wizard to quickly provide a single mapping + */ + class CDbQuickMappingWizard : public QWizard + { + Q_OBJECT + + public: + //! The wizard pages + enum Pages + { + PageIntro, + PageAircraftSelect, + PageColor, + PageLiverySelect, + PageDistributorSelect, + PageConfirmation, + PageCredentials, + PageSendStatus + }; + + //! Constructor + explicit CDbQuickMappingWizard(QWidget *parent = nullptr); + + //! Destructor + ~CDbQuickMappingWizard(); + + //! Preset values + void presetAircraftIcao(const BlackMisc::Aviation::CAircraftIcaoCode &aircraftIcao); + + //! Preset a model + void presetModel(const BlackMisc::Simulation::CAircraftModel &model); + + //! Clear wizard + void clear(); + + //! \copydoc QWizard::validateCurrentPage + virtual bool validateCurrentPage() override; + + //! Log categories + static const BlackMisc::CLogCategoryList &getLogCategories(); + + private: + QScopedPointer ui; + int m_lastId = 0; + BlackMisc::Simulation::CAircraftModel m_model; // model to be mapped + + //! Set the filter + void setAircraftIcaoFilter(); + + //! Set the filter + void setAirlineIcaoFilter(); + + //! Set color filter + void setColorFilter(); + + //! Livery assigned + BlackMisc::Aviation::CLivery getFirstSelectedOrDefaultLivery() const; + + //! Aircraft ICAO assigned + BlackMisc::Aviation::CAircraftIcaoCode getFirstSelectedOrDefaultAircraftIcao() const; + + //! Distributor assigned + BlackMisc::Simulation::CDistributor getFirstSelectedOrDefaultDistributor() const; + + //! Validate the data + BlackMisc::CStatusMessageList validateData() const; + + //! Consolidate model data + void consolidateModel(); + + //! Write the model to DB + void writeModeltoDb(); + + private slots: + //! Web data have been read + void ps_webDataRead(); + + //! Models published + void ps_publishedModels(const BlackMisc::Simulation::CAircraftModelList &modelsPublished, + const BlackMisc::Simulation::CAircraftModelList &modelsSkipped, + const BlackMisc::CStatusMessageList &messages, + bool requestSuccessful, bool directWrite); + + //! Current page has been changed + void ps_currentWizardPageChanged(int id); + + //! Airline selected + void ps_airlineSelected(const BlackMisc::Aviation::CAirlineIcaoCode &icao); + + //! Aircraft selected + void ps_aircraftSelected(const BlackMisc::Aviation::CAircraftIcaoCode &icao); + }; + } // ns +} // ns +#endif // guard diff --git a/src/blackgui/components/dbquickmappingwizard.ui b/src/blackgui/components/dbquickmappingwizard.ui new file mode 100644 index 000000000..d04cd5530 --- /dev/null +++ b/src/blackgui/components/dbquickmappingwizard.ui @@ -0,0 +1,600 @@ + + + CDbQuickMappingWizard + + + + 0 + 0 + 800 + 600 + + + + + 800 + 600 + + + + swift Mapping Wizard + + + QWizard::ClassicStyle + + + + Model + + + First description + + + + + + + 20 + + + 3 + + + + + + + + :/own/icons/own/swift3D/sw3DGreen-48.png + + + + + + + <html><head/><body><p>You are about to write a new mapping for your current model to the swift DB. Hereby you agree<br/>with the swift CLA and license terms. For details please consult the swift about and legal page.<br/>Thank you for supporting swift</p></body></html> + + + Qt::RichText + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Model + + + + + + + true + + + model`s unique key + + + + + + + + 0 + 25 + + + + + + + + Aircraft ICAO code + + + + + + + Qt::StrongFocus + + + + + + + + 0 + + + 0 + + + 0 + + + 30 + + + + + + 20 + 16777215 + + + + + + + :/pastel/icons/pastel/16/infomation.png + + + + + + + Hint: You can also search on the next page + + + + + + + + + + Does the aircraft belong to an airline? + + + + + + + + 0 + + + 6 + + + + + no, this is a (small) aircraft without airline livery. Use a color livery instead. + + + + + + + yes, it belongs to an airline or Air Force + + + true + + + + + + + + 12 + + + + + Airline ICAO + + + + + + + Airline name + + + + + + + + 225 + 16777215 + + + + Qt::StrongFocus + + + + + + + Virtual airline? + + + + + + + + + + Military? + + + + + + + + + + + 225 + 16777215 + + + + Qt::StrongFocus + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 20 + 16777215 + + + + + + + :/pastel/icons/pastel/16/infomation.png + + + + + + + Hint: Start virtual airlines with "V", e.g. "VLHA" + + + + + + + + + + + + + + + + + + + Aircraft + + + Please select the ICAO code which best represents yout model + + + + + + + 0 + 300 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + Livery + + + Livery by color + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + <html><head/><body><p>Your aircraft does not belong to an airline.<br/>Select its fuselage and tail color (or its primary and secondary color).</p></body></html> + + + Qt::RichText + + + + + + + + + + + 0 + 60 + + + + + 300 + 16777215 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + Livery + + + Please select the livery best matching your aircraft + + + + + + + 0 + 300 + + + + + + + + + Distributor / package + + + Select the correct package / distributor + + + + + + + + + + Confirmation + + + Check if the data are correct + + + + + + + 0 + 200 + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + You can now send the data to the database. Press the "Next" button. + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + There are still errors. Use the "Back" button and review your selections. + + + + + + + + + + + Credentials + + + Please tell us who you are + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + Status + + + Overall status confirmation + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + BlackGui::Components::CDbAircraftIcaoSelectorComponent + QFrame +
blackgui/components/dbaircrafticaoselectorcomponent.h
+ 1 +
+ + BlackGui::Components::CDbAirlineIcaoSelectorComponent + QFrame +
blackgui/components/dbairlineicaoselectorcomponent.h
+ 1 +
+ + BlackGui::Components::CDbLiveryColorSearch + QFrame +
blackgui/components/dbliverycolorsearch.h
+ 1 +
+ + BlackGui::Components::CDbAircraftIcaoComponent + QFrame +
blackgui/components/dbaircrafticaocomponent.h
+ 1 +
+ + BlackGui::Components::CDbLiveryComponent + QFrame +
blackgui/components/dbliverycomponent.h
+ 1 +
+ + BlackGui::Components::CDbAirlineNameSelectorComponent + QFrame +
blackgui/components/dbairlinenameselectorcomponent.h
+ 1 +
+ + BlackGui::Components::CLogComponent + QFrame +
blackgui/components/logcomponent.h
+ 1 +
+ + BlackGui::Editors::CAircraftModelForm + QFrame +
blackgui/editors/aircraftmodelform.h
+ 1 +
+ + BlackGui::Components::CDbDistributorComponent + QFrame +
blackgui/components/dbdistributorcomponent.h
+ 1 +
+ + BlackGui::Components::CDbLoginComponent + QFrame +
blackgui/components/dblogincomponent.h
+ 1 +
+
+ + le_ModelString + selector_AircraftIcaoCode + rb_ColorLivery + rb_AirlineLivery + selector_AirlineIcaoCode + selector_AirlineName + cb_VirtualAirline + cb_Military + + + + + +
diff --git a/src/blackgui/share/qss/stdwidget.qss b/src/blackgui/share/qss/stdwidget.qss index aa8dad4e5..f7a3f0185 100644 --- a/src/blackgui/share/qss/stdwidget.qss +++ b/src/blackgui/share/qss/stdwidget.qss @@ -50,7 +50,7 @@ QMainWindow::separator:hover { background: transparent; } -/* Dialog, sometime main window */ +/* Dialog, sometimes main window */ QDialog { background-image: url(:/textures/icons/textures/texture-outer.jpg); background-color: darkslategray; @@ -513,6 +513,10 @@ QTableView, QTreeView, QListView { padding:0px; } +QTableView::item:selected { + background-color: blue; +} + QTreeView { show-decoration-selected: 1; }