diff --git a/src/blackgui/components/dbliveryselectorcomponent.cpp b/src/blackgui/components/dbliveryselectorcomponent.cpp new file mode 100644 index 000000000..9b6a901ad --- /dev/null +++ b/src/blackgui/components/dbliveryselectorcomponent.cpp @@ -0,0 +1,198 @@ +/* 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 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 "dbliveryselectorcomponent.h" +#include "ui_dbliveryselectorcomponent.h" +#include "blackgui/uppercasevalidator.h" +#include "blackmisc/variant.h" +#include "blackmisc/aviation/liverylist.h" +#include + +using namespace BlackMisc; +using namespace BlackMisc::Aviation; +using namespace BlackMisc::Network; + +namespace BlackGui +{ + namespace Components + { + CDbLiverySelectorComponent::CDbLiverySelectorComponent(QWidget *parent) : + QFrame(parent), + ui(new Ui::CDbLiverySelectorComponent) + { + ui->setupUi(this); + this->setAcceptDrops(true); + this->setAcceptedMetaTypeIds({qMetaTypeId(), qMetaTypeId()}); + + ui->le_Livery->setValidator(new CUpperCaseValidator(this)); + + connect(ui->le_Livery, &QLineEdit::returnPressed, this, &CDbLiverySelectorComponent::ps_dataChanged); + connect(ui->le_Livery, &QLineEdit::returnPressed, this, &CDbLiverySelectorComponent::ps_dataChanged); + } + + CDbLiverySelectorComponent::~CDbLiverySelectorComponent() + { + gracefulShutdown(); + } + + void CDbLiverySelectorComponent::setProvider(IWebDataServicesProvider *webDataReaderProvider) + { + CWebDataServicesAware::setProvider(webDataReaderProvider); + connectDataReadSignal( + this, + std::bind(&CDbLiverySelectorComponent::ps_liveriesRead, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3) + ); + int c = getLiveriesCount(); + if (c > 0) + { + this->ps_liveriesRead(CEntityFlags::LiveryEntity, CEntityFlags::ReadFinished, c); + } + } + + void CDbLiverySelectorComponent::setLivery(const CLivery &livery) + { + QString code(livery.getCombinedCode()); + if (code.isEmpty()) { return; } + if (livery != m_currentLivery) + { + this->ui->le_Livery->setText(code); + m_currentLivery = livery; + emit changedLivery(livery); + } + } + + void CDbLiverySelectorComponent::setlivery(const QString &code) + { + QString liveryCode(code.toUpper().trimmed()); + int s = liveryCode.indexOf(' '); + if (s >= 1) { liveryCode = liveryCode.left(s); } + s = liveryCode.indexOf('('); + if (s >= 1) { liveryCode = liveryCode.left(s).trimmed(); } + + if (this->m_currentLivery.matchesCombinedCode(liveryCode)) { return; } + CLivery d(getLiveries().findByCombinedCode(liveryCode)); + if (d.hasCompleteData()) + { + this->setLivery(d); + } + else + { + this->ui->lbl_Description->setText(""); + this->ui->le_Livery->setText(code); + } + } + + CLivery CDbLiverySelectorComponent::getLivery() const + { + if (!hasProvider()) { return CLivery(); } + QString liveryCode(this->ui->le_Livery->text().trimmed().toUpper()); + CLivery d(getLiveries().findByCombinedCode(liveryCode)); + return d; + } + + void CDbLiverySelectorComponent::setReadOnly(bool readOnly) + { + this->ui->le_Livery->setReadOnly(readOnly); + } + + void CDbLiverySelectorComponent::withLiveryDescription(bool description) + { + this->ui->lbl_Description->setVisible(description); + } + + bool CDbLiverySelectorComponent::isSet() const + { + return this->getLivery().hasCompleteData(); + } + + void CDbLiverySelectorComponent::clear() + { + this->ui->le_Livery->clear(); + } + + void CDbLiverySelectorComponent::dragEnterEvent(QDragEnterEvent *event) + { + if (!event || !acceptDrop(event->mimeData())) { return; } + setBackgroundRole(QPalette::Highlight); + event->acceptProposedAction(); + } + + void CDbLiverySelectorComponent::dragMoveEvent(QDragMoveEvent *event) + { + if (!event || !acceptDrop(event->mimeData())) { return; } + event->acceptProposedAction(); + } + + void CDbLiverySelectorComponent::dragLeaveEvent(QDragLeaveEvent *event) + { + if (!event) { return; } + event->accept(); + } + + void CDbLiverySelectorComponent::dropEvent(QDropEvent *event) + { + if (!event || !acceptDrop(event->mimeData())) { return; } + CVariant valueVariant(toCVariant(event->mimeData())); + if (valueVariant.isValid()) + { + if (valueVariant.canConvert()) + { + CLivery livery(valueVariant.value()); + if (!livery.hasValidDbKey()) { return; } + this->setLivery(livery); + } + else if (valueVariant.canConvert()) + { + CLiveryList liveries(valueVariant.value()); + if (liveries.isEmpty()) { return; } + this->setLivery(liveries.front()); + } + } + } + + void CDbLiverySelectorComponent::ps_liveriesRead(CEntityFlags::Entity entity, CEntityFlags::ReadState readState, int count) + { + if (!hasProvider()) { return; } + if (entity.testFlag(CEntityFlags::LiveryEntity) && readState == CEntityFlags::ReadFinished) + { + if (count > 0) + { + QStringList codes(this->getLiveries().getCombinedCodesPlusInfo(true)); + QCompleter *c = new QCompleter(codes, this); + c->setCaseSensitivity(Qt::CaseInsensitive); + c->setCompletionMode(QCompleter::PopupCompletion); + c->setMaxVisibleItems(10); + this->connect(c, static_cast(&QCompleter::activated), this, &CDbLiverySelectorComponent::ps_completerActivated); + + this->ui->le_Livery->setCompleter(c); + m_completerLiveries.reset(c); // deletes any old completer + } + else + { + this->m_completerLiveries.reset(nullptr); + } + } + } + + void CDbLiverySelectorComponent::ps_dataChanged() + { + if (!hasProvider()) { return; } + QString code(this->ui->le_Livery->text().trimmed().toUpper()); + if (code.isEmpty()) { return; } + CLivery d(this->getLiveries().findByCombinedCode(code)); + this->setLivery(d); + } + + void CDbLiverySelectorComponent::ps_completerActivated(const QString &liveryCode) + { + this->setlivery(liveryCode); + } + + } // ns +} // ns diff --git a/src/blackgui/components/dbliveryselectorcomponent.h b/src/blackgui/components/dbliveryselectorcomponent.h new file mode 100644 index 000000000..19e6c3fe2 --- /dev/null +++ b/src/blackgui/components/dbliveryselectorcomponent.h @@ -0,0 +1,108 @@ +/* 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 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_CDBLIVERYSELECTORCOMPONENT_H +#define BLACKGUI_COMPONENTS_CDBLIVERYSELECTORCOMPONENT_H + +#include "blackmisc/aviation/livery.h" +#include "blackcore/webdataservices.h" +#include "blackgui/dropbase.h" +#include +#include +#include + +namespace Ui { class CDbLiverySelectorComponent; } + + +namespace BlackGui +{ + namespace Components + { + /*! + * Selector for liveries + */ + class CDbLiverySelectorComponent : + public QFrame, + public BlackMisc::Network::CWebDataServicesAware, + public BlackGui::CDropBase + { + Q_OBJECT + + public: + //! Constructor + explicit CDbLiverySelectorComponent(QWidget *parent = nullptr); + + //! Destructor + ~CDbLiverySelectorComponent(); + + //! \copydoc CWebDataReaderAware::setProvider + virtual void setProvider(BlackMisc::Network::IWebDataServicesProvider *webDataReaderProvider) override; + + //! Current livery + void setLivery(const BlackMisc::Aviation::CLivery &livery); + + //! Current livery + void setlivery(const QString &code); + + //! Livery + BlackMisc::Aviation::CLivery getLivery() const; + + //! Show description + void withLiveryDescription(bool description); + + //! Read only + void setReadOnly(bool readOnly); + + //! Set with valid Livery + bool isSet() const; + + //! Clear selection + void clear(); + + public slots: + //! Distributors have been read + void ps_liveriesRead(BlackMisc::Network::CEntityFlags::Entity entity, BlackMisc::Network::CEntityFlags::ReadState readState, int count); + + signals: + //! Distributor was changed + void changedLivery(const BlackMisc::Aviation::CLivery &livery); + + protected: + //! \copydoc QWidget::dragEnterEvent + virtual void dragEnterEvent(QDragEnterEvent *event) override; + + //! \copydoc QWidget::dragMoveEvent + virtual void dragMoveEvent(QDragMoveEvent *event) override; + + //! \copydoc QWidget::dragLeaveEvent + virtual void dragLeaveEvent(QDragLeaveEvent *event) override; + + //! \copydoc QWidget::dropEvent + virtual void dropEvent(QDropEvent *event) override; + + private slots: + //! Data have been changed + void ps_dataChanged(); + + //! Completer activated + void ps_completerActivated(const QString &liveryCode); + + private: + QScopedPointer ui; + QScopedPointer m_completerLiveries; + QMetaObject::Connection m_signalConnection; + BlackMisc::Aviation::CLivery m_currentLivery; + }; + + } // ns +} // ns + +#endif // guard diff --git a/src/blackgui/components/dbliveryselectorcomponent.ui b/src/blackgui/components/dbliveryselectorcomponent.ui new file mode 100644 index 000000000..d8d4ad0b3 --- /dev/null +++ b/src/blackgui/components/dbliveryselectorcomponent.ui @@ -0,0 +1,53 @@ + + + CDbLiverySelectorComponent + + + + 0 + 0 + 163 + 24 + + + + Livery selector + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Livery code + + + + + + + Livery + + + + + + + + diff --git a/src/blackmisc/aviation/livery.cpp b/src/blackmisc/aviation/livery.cpp index 8847d2b1e..f54abc3ad 100644 --- a/src/blackmisc/aviation/livery.cpp +++ b/src/blackmisc/aviation/livery.cpp @@ -53,6 +53,18 @@ namespace BlackMisc m_military(isMilitary) { } + QString CLivery::getCombinedCodePlusInfo() const + { + QString s(getCombinedCode()); + if (!this->getDescription().isEmpty()) + { + s += " ("; + s += this->getDescription(); + s += ")"; + } + return s; + } + bool CLivery::setAirlineIcaoCode(const CAirlineIcaoCode &airlineIcao) { if (m_airline == airlineIcao) { return false; } diff --git a/src/blackmisc/aviation/livery.h b/src/blackmisc/aviation/livery.h index d26edd1d1..34f3a3497 100644 --- a/src/blackmisc/aviation/livery.h +++ b/src/blackmisc/aviation/livery.h @@ -67,6 +67,9 @@ namespace BlackMisc //! Combined code const QString &getCombinedCode() const { return m_combinedCode; } + //! Combined code + QString getCombinedCodePlusInfo() const; + //! Get description. const QString &getDescription() const { return m_description; } diff --git a/src/blackmisc/aviation/liverylist.cpp b/src/blackmisc/aviation/liverylist.cpp index f8febed8d..e7ae8cb80 100644 --- a/src/blackmisc/aviation/liverylist.cpp +++ b/src/blackmisc/aviation/liverylist.cpp @@ -13,6 +13,7 @@ using namespace BlackMisc::PhysicalQuantities; using namespace BlackMisc::Aviation; + namespace BlackMisc { namespace Aviation @@ -57,6 +58,22 @@ namespace BlackMisc }); } + QStringList CLiveryList::getCombinedCodes(bool sort) const + { + if (this->isEmpty()) { return QStringList(); } + QStringList codes = this->transform(Predicates::MemberTransform(&CLivery::getCombinedCode)); + if (sort) { codes.sort(); } + return codes; + } + + QStringList CLiveryList::getCombinedCodesPlusInfo(bool sort) const + { + if (this->isEmpty()) { return QStringList(); } + QStringList codes = this->transform(Predicates::MemberTransform(&CLivery::getCombinedCodePlusInfo)); + if (sort) { codes.sort(); } + return codes; + } + CLivery CLiveryList::smartLiverySelector(const CLivery &liveryPattern) const { // first try on id, that would be perfect diff --git a/src/blackmisc/aviation/liverylist.h b/src/blackmisc/aviation/liverylist.h index 48466219b..97402dffe 100644 --- a/src/blackmisc/aviation/liverylist.h +++ b/src/blackmisc/aviation/liverylist.h @@ -14,8 +14,8 @@ #include "blackmisc/blackmiscexport.h" #include "blackmisc/datastoreobjectlist.h" - #include "blackmisc/aviation/livery.h" +#include namespace BlackMisc { @@ -48,6 +48,12 @@ namespace BlackMisc //! Find livery by combined code CLivery findByCombinedCode(const QString &combinedCode) const; + //! All combined codes + QStringList getCombinedCodes(bool sort = false) const; + + //! All combined codes plus more info + QStringList getCombinedCodesPlusInfo(bool sort = false) const; + //! Find CLivery smartLiverySelector(const CLivery &liveryPattern) const;