refs #780, encapsulate model string completer in class

* use it in mapping component
* support DB, own model set and installed models for completion
This commit is contained in:
Klaus Basan
2016-10-22 04:22:50 +02:00
parent 67f5b38391
commit 86b8230bf7
5 changed files with 504 additions and 99 deletions

View File

@@ -0,0 +1,158 @@
/* 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 "aircraftmodelstringcompleter.h"
#include "ui_aircraftmodelstringcompleter.h"
#include "blackgui/guiapplication.h"
#include "blackgui/uppercasevalidator.h"
#include "blackcore/webdataservices.h"
#include "blackcore/context/contextsimulator.h"
#include <QRadioButton>
#include <QStringListModel>
using namespace BlackCore;
using namespace BlackCore::Context;
namespace BlackGui
{
namespace Components
{
CAircraftModelStringCompleter::CAircraftModelStringCompleter(QWidget *parent) :
QFrame(parent),
ui(new Ui::CAircraftModelStringCompleter)
{
Q_ASSERT_X(sGui, Q_FUNC_INFO, "missing sGui");
Q_ASSERT_X(sGui->hasWebDataServices(), Q_FUNC_INFO, "missing web services");
ui->setupUi(this);
ui->le_modelString->setValidator(new CUpperCaseValidator(ui->le_modelString));
connect(ui->le_modelString, &QLineEdit::editingFinished, this, &CAircraftModelStringCompleter::ps_textChanged);
connect(sGui->getWebDataServices(), &CWebDataServices::allSwiftDbDataRead, this, &CAircraftModelStringCompleter::ps_swiftWebDataRead);
connect(ui->rb_Db, &QRadioButton::clicked, this, &CAircraftModelStringCompleter::ps_initGui);
connect(ui->rb_ModelSet, &QRadioButton::clicked, this, &CAircraftModelStringCompleter::ps_initGui);
connect(ui->rb_OwnModels, &QRadioButton::clicked, this, &CAircraftModelStringCompleter::ps_initGui);
if (sGui->getIContextSimulator())
{
connect(sGui->getIContextSimulator(), &IContextSimulator::simulatorStatusChanged, this, &CAircraftModelStringCompleter::ps_simulatorConnected);
}
}
CAircraftModelStringCompleter::~CAircraftModelStringCompleter()
{ }
QString CAircraftModelStringCompleter::getModelString() const
{
return ui->le_modelString->text();
}
void CAircraftModelStringCompleter::showSourceSelection(bool show)
{
ui->wi_SourceSelection->setVisible(!show);
}
void CAircraftModelStringCompleter::setText(const QString &completersString)
{
if (ui->le_modelString->text() == completersString) { return; }
ui->le_modelString->setText(completersString);
}
void CAircraftModelStringCompleter::setModel(const BlackMisc::Simulation::CAircraftModel &model)
{
this->setText(model.getModelString());
}
void CAircraftModelStringCompleter::setSourceVisible(CompleterSource source, bool visible)
{
if (source.testFlag(DB)) { ui->rb_Db->setVisible(visible); }
if (source.testFlag(ModelSet)) { ui->rb_ModelSet->setVisible(visible); }
if (source.testFlag(OwnModels)) { ui->rb_OwnModels->setVisible(visible); }
}
void CAircraftModelStringCompleter::selectSource(CAircraftModelStringCompleter::CompleterSourceFlag source)
{
switch (source)
{
case DB: ui->rb_Db->setChecked(true); break;
case ModelSet: ui->rb_ModelSet->setChecked(true); break;
case OwnModels: ui->rb_OwnModels->setChecked(true); break;
default: ui->rb_ModelSet->setChecked(true); break;
}
}
void CAircraftModelStringCompleter::clear()
{
ui->le_modelString->clear();
}
void CAircraftModelStringCompleter::setCompleter()
{
QStringList modelStrings;
if (ui->rb_Db->isChecked())
{
modelStrings = sGui->getWebDataServices()->getModelStrings();
}
else if (ui->rb_ModelSet->isChecked())
{
if (!this->m_completerOwnModels)
{
const QStringList modelStrings = sGui->getIContextSimulator()->getInstalledModels().getModelStringList();
this->m_completerModelSet = new QCompleter(modelStrings, this);
setCompleterParameters(this->m_completerModelSet);
}
ui->le_modelString->setCompleter(this->m_completerOwnModels);
}
else if (ui->rb_OwnModels->isChecked())
{
if (!this->m_completerOwnModels)
{
const QStringList modelStrings = sGui->getIContextSimulator()->getInstalledModels().getModelStringList();
this->m_completerOwnModels = new QCompleter(modelStrings, this);
setCompleterParameters(this->m_completerOwnModels);
}
ui->le_modelString->setCompleter(this->m_completerOwnModels);
modelStrings = sGui->getIContextSimulator()->getModelSet().getModelStringList();
}
ui->le_modelString->setCompleter(new QCompleter(modelStrings, this));
ui->le_modelString->setPlaceholderText(QString("model strings (%1)").arg(modelStrings.size()));
}
void CAircraftModelStringCompleter::setCompleterParameters(QCompleter *completer)
{
completer->setCaseSensitivity(Qt::CaseInsensitive);
completer->setWrapAround(true);
completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
completer->setCompletionMode(QCompleter::InlineCompletion);
}
void CAircraftModelStringCompleter::ps_textChanged()
{
emit this->modelStringChanged();
}
void CAircraftModelStringCompleter::ps_initGui()
{
this->setCompleter();
}
void CAircraftModelStringCompleter::ps_simulatorConnected(int status)
{
// reinit because sim changed
Q_UNUSED(status);
this->ps_initGui();
}
void CAircraftModelStringCompleter::ps_swiftWebDataRead()
{
this->ps_initGui();
}
} // ns
} // ns

View File

@@ -0,0 +1,100 @@
/* 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_COMPLETER_AIRCRAFTMODELSTRINGCOMPLETER_H
#define BLACKGUI_COMPLETER_AIRCRAFTMODELSTRINGCOMPLETER_H
#include "blackmisc/simulation/aircraftmodel.h"
#include <QFrame>
#include <QScopedPointer>
#include <QCompleter>
#include <QFlags>
namespace Ui { class CAircraftModelStringCompleter; }
namespace BlackGui
{
namespace Components
{
/*!
* Completer for model strings
*/
class CAircraftModelStringCompleter : public QFrame
{
Q_OBJECT
public:
//! Sources for string completion
enum CompleterSourceFlag {
DB,
ModelSet,
OwnModels
};
Q_DECLARE_FLAGS(CompleterSource, CompleterSourceFlag)
//! Constructor
explicit CAircraftModelStringCompleter(QWidget *parent = nullptr);
//! Destructor
~CAircraftModelStringCompleter();
//! The model string
QString getModelString() const;
//! Show the selection buttons
void showSourceSelection(bool show);
//! Set text
void setText(const QString &completersString);
//! Set model
void setModel(const BlackMisc::Simulation::CAircraftModel &model);
//! Show/hide radio buttons
void setSourceVisible(CompleterSource source, bool visible);
//! Set the currently selected source
void selectSource(CompleterSourceFlag source);
//! Clear
void clear();
signals:
//! Model has been changed
void modelStringChanged();
private:
//! Set the completer
void setCompleter();
//! How completer behaves
static void setCompleterParameters(QCompleter *completer);
private slots:
//! Value has been changed
void ps_textChanged();
//! Init the GUI
void ps_initGui();
//! Simulator connected
void ps_simulatorConnected(int status);
//! All swift data have been read
void ps_swiftWebDataRead();
private:
QScopedPointer <Ui::CAircraftModelStringCompleter> ui;
};
} // ns
} // ns
#endif // guard

View File

@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CAircraftModelStringCompleter</class>
<widget class="QFrame" name="CAircraftModelStringCompleter">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>301</width>
<height>22</height>
</rect>
</property>
<property name="windowTitle">
<string>Frame</string>
</property>
<layout class="QHBoxLayout" name="hl_ModelStringCompleter">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLineEdit" name="le_modelString">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="placeholderText">
<string>model string</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="wi_SourceSelection" native="true">
<layout class="QHBoxLayout" name="hl_SourceSelection">
<property name="leftMargin">
<number>4</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QRadioButton" name="rb_Db">
<property name="text">
<string>DB</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rb_ModelSet">
<property name="toolTip">
<string>own model set</string>
</property>
<property name="text">
<string>set</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rb_OwnModels">
<property name="toolTip">
<string>all installed models</string>
</property>
<property name="text">
<string>inst.</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -196,21 +196,21 @@ namespace BlackGui
const CSimulatedAircraft simAircraft = ui->tvp_SimulatedAircraft->at(index);
ui->cb_AircraftEnabled->setChecked(simAircraft.isEnabled());
ui->le_Callsign->setText(simAircraft.getCallsign().asString());
ui->le_AircraftModel->setText(simAircraft.getModel().getModelString());
ui->completer_ModelStrings->setModel(simAircraft.getModel());
}
void CMappingComponent::ps_onModelSelectedInView(const QModelIndex &index)
{
const CAircraftModel model = ui->tvp_AircraftModels->at(index);
ui->le_AircraftModel->setText(model.getModelString());
ui->completer_ModelStrings->setModel(model);
if (ui->cb_AircraftIconDisplayed->isChecked())
{
const int MaxHeight = 125;
ui->lbl_AircraftIconDisplayed->setText("");
ui->lbl_AircraftIconDisplayed->setToolTip(model.getDescription());
QString modelString(model.getModelString());
CPixmap pm = sGui->getIContextSimulator()->iconForModel(modelString);
const QString modelString(model.getModelString());
CPixmap pm = sGui->getIContextSimulator()->iconForModel(modelString);
if (pm.isNull())
{
ui->lbl_AircraftIconDisplayed->setPixmap(CIcons::crossWhite16());
@@ -233,7 +233,7 @@ namespace BlackGui
void CMappingComponent::ps_onSaveAircraft()
{
QString cs = ui->le_Callsign->text().trimmed();
const QString cs = ui->le_Callsign->text().trimmed();
if (!CCallsign::isValidAircraftCallsign(cs))
{
CLogMessage(this).validationError("Invalid callsign for mapping");
@@ -248,7 +248,7 @@ namespace BlackGui
return;
}
QString modelString = ui->le_AircraftModel->text().trimmed();
const QString modelString = ui->completer_ModelStrings->getModelString();
if (modelString.isEmpty())
{
CLogMessage(this).validationError("Missing model for mapping");
@@ -320,16 +320,8 @@ namespace BlackGui
void CMappingComponent::ps_onModelsUpdateRequested()
{
CAircraftModelList ml(sGui->getIContextSimulator()->getInstalledModels());
const CAircraftModelList ml(sGui->getIContextSimulator()->getInstalledModels());
ui->tvp_AircraftModels->updateContainer(ml);
// model completer
this->m_modelCompleter->setModel(new QStringListModel(ml.getModelStringList(), this->m_modelCompleter));
this->m_modelCompleter->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
this->m_modelCompleter->setCaseSensitivity(Qt::CaseInsensitive);
this->m_modelCompleter->setWrapAround(true);
this->m_modelCompleter->setCompletionMode(QCompleter::InlineCompletion);
ui->le_AircraftModel->setCompleter(this->m_modelCompleter);
}
void CMappingComponent::ps_onRemoteAircraftModelChanged(const CSimulatedAircraft &aircraft, const CIdentifier &originator)

View File

@@ -13,13 +13,7 @@
<property name="windowTitle">
<string>Mapping component</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gl_MappingComponent" columnstretch="0,0,1,3,0">
<layout class="QVBoxLayout" name="vl_MappingComponent">
<property name="leftMargin">
<number>0</number>
</property>
@@ -32,44 +26,8 @@
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>3</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="lbl_AircraftIcon">
<property name="text">
<string>Icon</string>
</property>
</widget>
</item>
<item row="1" column="2" colspan="3" alignment="Qt::AlignLeft">
<widget class="QLabel" name="lbl_AircraftIconDisplayed">
<property name="text">
<string>aircraft icon will go here</string>
</property>
</widget>
</item>
<item row="1" column="1" alignment="Qt::AlignRight">
<widget class="QCheckBox" name="cb_AircraftIconDisplayed">
<property name="toolTip">
<string>show / hide icon</string>
</property>
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0" colspan="5">
<item>
<widget class="QTabWidget" name="tw_ListViews">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
@@ -130,12 +88,6 @@
</property>
<item>
<widget class="BlackGui::Views::CAircraftModelView" name="tvp_AircraftModels">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
@@ -149,43 +101,140 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tb_MatchingLog">
<attribute name="title">
<string>Matching log</string>
</attribute>
<layout class="QVBoxLayout" name="vl_MatchingLog">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="BlackGui::Components::CModelMatcherLogComponent" name="comp_MatchingLog">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="2" column="3">
<widget class="QLineEdit" name="le_AircraftModel"/>
</item>
<item row="2" column="2">
<widget class="QLineEdit" name="le_Callsign">
<property name="maxLength">
<number>15</number>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lbl_Aircraft">
<property name="text">
<string>Aircraft</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QPushButton" name="pb_SaveAircraft">
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
<item row="2" column="1" alignment="Qt::AlignRight">
<widget class="QCheckBox" name="cb_AircraftEnabled">
<property name="toolTip">
<string>enabled / disable</string>
</property>
<property name="text">
<string/>
<item>
<widget class="QFrame" name="fr_AircraftModifications">
<property name="minimumSize">
<size>
<width>0</width>
<height>75</height>
</size>
</property>
<layout class="QGridLayout" name="gl_AircraftModifications">
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item row="1" column="2">
<widget class="QLineEdit" name="le_Callsign">
<property name="maxLength">
<number>15</number>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="placeholderText">
<string>callsign</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QPushButton" name="pb_SaveAircraft">
<property name="text">
<string>save</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="cb_AircraftIconDisplayed">
<property name="toolTip">
<string>show / hide icon</string>
</property>
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lbl_Aircraft">
<property name="text">
<string>Aircraft</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="cb_AircraftEnabled">
<property name="toolTip">
<string>enabled / disable</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lbl_AircraftIcon">
<property name="text">
<string>Icon</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QPushButton" name="pb_ResetAircraft">
<property name="text">
<string>reset</string>
</property>
</widget>
</item>
<item row="0" column="2" colspan="2">
<widget class="QLabel" name="lbl_AircraftIconDisplayed">
<property name="text">
<string>icon will go here</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="5">
<widget class="BlackGui::Components::CAircraftModelStringCompleter" name="completer_ModelStrings">
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
@@ -201,6 +250,18 @@
<extends>QTableView</extends>
<header>blackgui/views/simulatedaircraftview.h</header>
</customwidget>
<customwidget>
<class>BlackGui::Components::CModelMatcherLogComponent</class>
<extends>QFrame</extends>
<header>blackgui/components/modelmatcherlogcomponent.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>BlackGui::Components::CAircraftModelStringCompleter</class>
<extends>QFrame</extends>
<header>blackgui/components/aircraftmodelstringcompleter.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>