diff --git a/src/blackgui/components/dbautostashingcomponent.cpp b/src/blackgui/components/dbautostashingcomponent.cpp new file mode 100644 index 000000000..43fe1f7ab --- /dev/null +++ b/src/blackgui/components/dbautostashingcomponent.cpp @@ -0,0 +1,301 @@ +/* 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 "ui_dbautostashingcomponent.h" +#include "dbautostashingcomponent.h" +#include "dbmappingcomponent.h" +#include "dbstashcomponent.h" +#include "blackmisc/simulation/aircraftmodellist.h" +#include + +using namespace BlackMisc; +using namespace BlackMisc::Network; +using namespace BlackMisc::Simulation; +using namespace BlackGui::Views; + +namespace BlackGui +{ + namespace Components + { + CDbAutoStashingComponent::CDbAutoStashingComponent(QWidget *parent) : + QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint), + CDbMappingComponentAware(qobject_cast(parent)), + ui(new Ui::CDbAutoStashingComponent) + { + ui->setupUi(this); + this->ui->tvp_StatusMessages->setResizeMode(CAircraftModelView::ResizingAuto); + this->ui->tvp_StatusMessages->menuAddItems(CAircraftModelView::MenuSave); + this->ui->le_MaxModelsStashed->setValidator(new QIntValidator(10, CDbStashComponent::MaxModelPublished, this)); + Q_ASSERT_X(this->getMappingComponent(), Q_FUNC_INFO, "Expect mapping componet"); + } + + CDbAutoStashingComponent::~CDbAutoStashingComponent() + { } + + void CDbAutoStashingComponent::setProvider(IWebDataServicesProvider *webDataReaderProvider) + { + CWebDataServicesAware::setProvider(webDataReaderProvider); + connectDataReadSignal( + this, + std::bind(&CDbAutoStashingComponent::ps_entitiesRead, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3) + ); + } + + void CDbAutoStashingComponent::accept() + { + if (m_state == Running) { return; } + if (m_state == Completed) + { + if (!this->m_modelsToStash.isEmpty()) + { + // this removes previously stashed models + this->getMappingComponent()->replaceStashedModelsUnvalidated(this->m_modelsToStash); + if (this->ui->cb_RemovedChecked->isChecked()) + { + this->currentModelView()->removeModelsWithModelString(this->m_modelsToStash); + } + const CStatusMessage stashedMsg(categgories(), CStatusMessage::SeverityInfo, QString("Auto stashed %1 models").arg(m_modelsToStash.size())); + this->addStatusMessage(stashedMsg); + this->m_modelsToStash.clear(); + } + QDialog::accept(); + } + if (this->getSelectedOrAllCount() < 1) + { + const CStatusMessage m(categgories(), CStatusMessage::SeverityError, "No data, nothing to do"); + this->addStatusMessage(m); + QDialog::accept(); + } + this->tryToStashModels(); + } + + int CDbAutoStashingComponent::exec() + { + this->initGui(); + return QDialog::exec(); + } + + void CDbAutoStashingComponent::showLastResults() + { + this->ui->bb_AutoStashing->setStandardButtons(QDialogButtonBox::Close); + this->setVisible(true); + } + + void CDbAutoStashingComponent::ps_entitiesRead(CEntityFlags::Entity entity, CEntityFlags::ReadState readState, int count) + { + if (!readState != CEntityFlags::ReadFinished) { return; } + Q_UNUSED(count); + Q_UNUSED(entity); + } + + void CDbAutoStashingComponent::initGui() + { + this->m_state = Idle; + this->ui->bb_AutoStashing->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + this->ui->tvp_StatusMessages->clear(); + this->m_noData = 0; + this->m_noValidationFailed = 0; + this->m_noStashed = 0; + this->updateGuiValues(0); + + if (!this->currentModelView()) + { + const CStatusMessage m(categgories(), CStatusMessage::SeverityError, "No data for auto stashing"); + this->addStatusMessage(m); + } + else + { + int selected = this->currentModelView()->selectedRowCount(); + int all = this->currentModelView()->rowCount(); + this->ui->le_Selected->setText(QString::number(selected)); + QString allStr(QString::number(all)); + if (all > CDbStashComponent::MaxModelPublished) + { + allStr += " (Max." + QString::number(CDbStashComponent::MaxModelPublished) + ")"; + } + this->ui->le_All->setText(allStr); + if (this->ui->le_MaxModelsStashed->text().isEmpty()) + { + this->ui->le_MaxModelsStashed->setText(all > 100 ? "100" : ""); + } + if (selected > 0) + { + this->ui->rb_Selected->setChecked(true); + this->ui->rb_Selected->setEnabled(true); + } + else + { + this->ui->rb_All->setChecked(true); + this->ui->rb_Selected->setEnabled(false); + } + } + } + + void CDbAutoStashingComponent::updateGuiValues(int percent) + { + if (percent > 100) { percent = 100; } + if (percent < 0) { percent = 0; } + this->ui->pb_StashingProgress->setValue(percent); + this->ui->le_Stashed->setText(QString::number(this->m_noStashed)); + this->ui->le_NoData->setText(QString::number(this->m_noData)); + this->ui->le_ValidationFailed->setText(QString::number(this->m_noValidationFailed)); + } + + int CDbAutoStashingComponent::getSelectedOrAllCount() const + { + if (!this->currentModelView()) { return 0; } + if (this->ui->rb_Selected->isChecked()) + { + return this->currentModelView()->selectedRowCount(); + } + else + { + return this->currentModelView()->rowCount(); + } + } + + const CAircraftModelView *CDbAutoStashingComponent::currentModelView() const + { + return this->getMappingComponent()->currentModelView(); + } + + CAircraftModelView *CDbAutoStashingComponent::currentModelView() + { + return this->getMappingComponent()->currentModelView(); + } + + void CDbAutoStashingComponent::addStatusMessage(const CStatusMessage &msg) + { + if (msg.isEmpty()) { return; } + this->ui->tvp_StatusMessages->insert(msg); + } + + void CDbAutoStashingComponent::addStatusMessage(const CStatusMessage &msg, const CAircraftModel &model) + { + if (msg.isEmpty()) { return; } + if (model.hasModelString()) + { + CStatusMessage prefixMessage(msg); + prefixMessage.prependMessage(QString(model.getModelString() + ", " + model.getMembersDbStatus() + ": ")); + this->ui->tvp_StatusMessages->insert(prefixMessage); + } + else + { + this->ui->tvp_StatusMessages->insert(msg); + } + } + + void CDbAutoStashingComponent::tryToStashModels() + { + Q_ASSERT_X(this->currentModelView(), Q_FUNC_INFO, "No view"); + const CAircraftModelList models(this->ui->rb_Selected->isChecked() ? this->currentModelView()->selectedObjects() : this->currentModelView()->containerOrFilteredContainer()); + if (models.isEmpty()) { return; } + + // we have data and are good to go + this->m_state = Running; + const int all = models.size(); + + // maximum + const QString maxStr(this->ui->le_MaxModelsStashed->text()); + bool okMaxStr = true; + int max = maxStr.isEmpty() ? CDbStashComponent::MaxModelPublished : maxStr.toInt(&okMaxStr); + if (!okMaxStr || max > all) { max = all; } + + // override description + const QString description(this->ui->le_Description->text().trimmed()); + + int c = 0; + CAircraftModelList autoStashed; + for (const CAircraftModel &model : models) + { + CAircraftModel stashModel(model); + bool stashed = this->tryToStashModel(stashModel); + if (stashed) + { + if (!description.isEmpty()) { stashModel.setDescription(description); } + autoStashed.push_back(stashModel); + } + + c++; + if (c % 25 == 0) + { + Q_ASSERT_X(c <= all, Q_FUNC_INFO, "illegal numbers"); + QCoreApplication::processEvents(QEventLoop::AllEvents, 100); + + int percent = c * 100 / all; + if (max < all) + { + int maxPercent = autoStashed.size() * 100 / max; + if (maxPercent > percent) { percent = maxPercent; } + } + this->updateGuiValues(percent); + } + if (autoStashed.size() >= max) { break; } + } + + this->updateGuiValues(100); + QCoreApplication::processEvents(QEventLoop::AllEvents, 100); + + const CStatusMessage stashedMsg(categgories(), CStatusMessage::SeverityInfo, QString("Ready to auto stashed %1 models").arg(autoStashed.size())); + this->addStatusMessage(stashedMsg); + this->m_modelsToStash = autoStashed; + this->m_state = Completed; + } + + bool CDbAutoStashingComponent::tryToStashModel(Simulation::CAircraftModel &model) + { + bool stashed = false; + + //! Some upfront tests + if (!model.hasModelString()) + { + this->addStatusMessage(CStatusMessage(this->categgories(), CStatusMessage::SeverityError, "No model string")); + this->m_noData++; + } + else if (!model.hasAircraftDesignator()) + { + this->addStatusMessage(CStatusMessage(this->categgories(), CStatusMessage::SeverityError, "No aircraft designator"), model); + this->m_noData++; + } + else if (!model.hasAirlineDesignator() && !model.getLivery().hasValidDbKey()) + { + // if there is no livery (normal) we need an airline + this->addStatusMessage(CStatusMessage(this->categgories(), CStatusMessage::SeverityError, "No airline designator"), model); + this->m_noData++; + } + else + { + // stash here consolidates with DB data and validates + CAircraftModel stashModel(this->getMappingComponent()->consolidateModel(model)); + CStatusMessageList validationMsgs(stashModel.validate(true)); + validationMsgs.removeWarningsAndBelow(); + CStatusMessage msg = validationMsgs.toSingleMessage(); + if (msg.getSeverity() == CStatusMessage::SeverityError) + { + this->m_noValidationFailed++; + } + else + { + msg = CStatusMessage(categgories(), CStatusMessage::SeverityInfo, "Stashed succesfully"); + stashed = true; + this->m_noStashed++; + model = stashModel; + } + this->addStatusMessage(msg, stashModel); + } + return stashed; + } + + const CLogCategoryList &CDbAutoStashingComponent::categgories() + { + static const CLogCategoryList cats(CLogCategoryList(this).join({ CLogCategory::guiComponent() }).join({ CLogCategory::mapping()})); + return cats; + } + } // ns +} // ns diff --git a/src/blackgui/components/dbautostashingcomponent.h b/src/blackgui/components/dbautostashingcomponent.h new file mode 100644 index 000000000..80be535eb --- /dev/null +++ b/src/blackgui/components/dbautostashingcomponent.h @@ -0,0 +1,116 @@ +/* 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_DBAUTOSTASHINGCOMPONENT_H +#define BLACKGUI_COMPONENTS_DBAUTOSTASHINGCOMPONENT_H + +#include "blackcore/webdataservices.h" +#include "dbmappingcomponentaware.h" +#include "blackmisc/logcategorylist.h" +#include "blackgui/views/aircraftmodelview.h" +#include + +namespace Ui { class CDbAutoStashingComponent; } + +namespace BlackGui +{ + namespace Components + { + /*! + * Stashing component + */ + class CDbAutoStashingComponent : + public QDialog, + public BlackMisc::Network::CWebDataServicesAware, + public BlackGui::Components::CDbMappingComponentAware + { + Q_OBJECT + + public: + //! Current state of this component + enum State + { + Idle, + Running, + Completed + }; + + //! Constructor + explicit CDbAutoStashingComponent(QWidget *parent = nullptr); + + //! Destructor + ~CDbAutoStashingComponent(); + + //! \copydoc CWebDataServicesAware::setProvider + virtual void setProvider(BlackMisc::Network::IWebDataServicesProvider *webDataReaderProvider) override; + + //! At least run once and completed + bool isCompleted() const { return m_state == Completed; } + + public slots: + //! \copydoc QDialog::accept + virtual void accept() override; + + //! \copydoc QDialog::exec + virtual int exec() override; + + //! Show last result + void showLastResults(); + + private slots: + //! Data have been read + void ps_entitiesRead(BlackMisc::Network::CEntityFlags::Entity entity, BlackMisc::Network::CEntityFlags::ReadState readState, int count); + + private: + QScopedPointer ui; + + //! Init the component + void initGui(); + + //! Update GUI values + void updateGuiValues(int percent); + + //! Number of all or selected models + int getSelectedOrAllCount() const; + + //! Model view to take models from + const BlackGui::Views::CAircraftModelView *currentModelView() const; + + //! Model view to take models from + BlackGui::Views::CAircraftModelView *currentModelView(); + + //! Add a status message + void addStatusMessage(const BlackMisc::CStatusMessage &msg); + + //! Add a status message for a given model (prefixed) + void addStatusMessage(const BlackMisc::CStatusMessage &msg, const BlackMisc::Simulation::CAircraftModel &model); + + //! Try stashing selected or all models + void tryToStashModels(); + + //! Try stashing a model + //! \param model this model can be updated with consolidated data + //! \return true means stashing is possible + bool tryToStashModel(BlackMisc::Simulation::CAircraftModel &model); + + //! Categories + const BlackMisc::CLogCategoryList &categgories(); + + int m_noStashed = 0; //!< stashed models + int m_noData = 0; //!< not stashed because no data + int m_noValidationFailed = 0; //!< not stashed because validation failed + State m_state = Idle; //!< modus + BlackMisc::Simulation::CAircraftModelList m_modelsToStash; //!< Models about to be stashed + }; + } // ns +} // ns + +#endif // guard diff --git a/src/blackgui/components/dbautostashingcomponent.ui b/src/blackgui/components/dbautostashingcomponent.ui new file mode 100644 index 000000000..94656fade --- /dev/null +++ b/src/blackgui/components/dbautostashingcomponent.ui @@ -0,0 +1,248 @@ + + + CDbAutoStashingComponent + + + + 0 + 0 + 420 + 357 + + + + Auto stashing + + + + + + + + 0 + + + + + + + true + + + all + + + + + + + Remove stashed + + + true + + + + + + + Max stashed: + + + + + + + max.models stashed + + + + + + + QAbstractItemView::NoSelection + + + false + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + All: + + + + + + + true + + + selected + + + + + + + Description: + + + + + + + 255 + + + Override description in model + + + + + + + Selected: + + + true + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + Stashed: + + + + + + + true + + + true + + + stashed models + + + + + + + No data: + + + + + + + true + + + incomplete data + + + + + + + Invalid: + + + + + + + true + + + invalid models + + + + + + + + + + + + + BlackGui::Views::CStatusMessageView + QTableView +
blackgui/views/statusmessageview.h
+
+
+ + + + bb_AutoStashing + accepted() + CDbAutoStashingComponent + accept() + + + 248 + 254 + + + 157 + 274 + + + + + bb_AutoStashing + rejected() + CDbAutoStashingComponent + reject() + + + 316 + 260 + + + 286 + 274 + + + + +