Ref T171, callsign completer class

* completer used in 3 places, makes sense to encapsulate as class
* automatically updating from network context
This commit is contained in:
Klaus Basan
2017-10-13 19:55:17 +02:00
parent dafb3b0569
commit a51f696bee
3 changed files with 251 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
/* Copyright (C) 2017
* 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 "callsigncompleter.h"
#include "ui_callsigncompleter.h"
#include "blackcore/context/contextnetwork.h"
#include "blackgui/guiapplication.h"
#include "blackgui/led.h"
#include "blackgui/uppercasevalidator.h"
#include <QStringListModel>
using namespace BlackMisc;
using namespace BlackMisc::Aviation;
using namespace BlackCore;
using namespace BlackCore::Context;
namespace BlackGui
{
namespace Components
{
CCallsignCompleter::CCallsignCompleter(QWidget *parent) :
QFrame(parent),
ui(new Ui::CCallsignCompleter)
{
Q_ASSERT_X(sGui, Q_FUNC_INFO, "Need sGui");
Q_ASSERT_X(sGui->getIContextNetwork(), Q_FUNC_INFO, "Need network context");
ui->setupUi(this);
CUpperCaseValidator *ucv = new CUpperCaseValidator(ui->le_Callsign);
ui->le_Callsign->setValidator(ucv);
ui->led_Status->setToolTips("connected", "disconnected");
ui->led_Status->setShape(CLedWidget::Rounded);
ui->led_Status->setToolTips("network connected", "network disconnected", "data");
ui->led_Status->setShape(CLedWidget::Rounded);
connect(ui->le_Callsign, &QLineEdit::editingFinished, this, &CCallsignCompleter::onEditingFinished);
connect(sGui->getIContextNetwork(), &IContextNetwork::changedAircraftInRange, &m_dsAircraftsInRangeChanged, &CDigestSignal::inputSignal);
connect(sGui->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this, &CCallsignCompleter::onChangedConnectionStatus, Qt::QueuedConnection);
m_dsAircraftsInRangeChanged.inputSignal(); // trigger
}
CCallsignCompleter::~CCallsignCompleter()
{ }
BlackMisc::Aviation::CCallsign CCallsignCompleter::getCallsign() const
{
const QString csString = ui->le_Callsign->text().trimmed().toUpper();
if (!this->isValidKnownCallsign(csString)) { return CCallsign(); }
return CCallsign(csString);
}
QString CCallsignCompleter::getRawCallsignString() const
{
return ui->le_Callsign->text();
}
bool CCallsignCompleter::hasValidCallsign() const
{
const QString csString = ui->le_Callsign->text().trimmed().toUpper();
return this->isValidKnownCallsign(csString);
}
void CCallsignCompleter::updateCallsignsFromContext()
{
if (!sGui || sGui->isShuttingDown()) { return; }
if (!sGui->getIContextNetwork()) { return; }
m_validCallsigns = sGui->getIContextNetwork()->getAircraftInRangeCallsigns();
const QStringList modelData = m_validCallsigns.getCallsignStrings(true);
if (!m_currentCompleter)
{
m_currentCompleter = new QCompleter(modelData, ui->le_Callsign);
ui->le_Callsign->setCompleter(m_currentCompleter);
}
else
{
QStringListModel *model = qobject_cast<QStringListModel *>(m_currentCompleter->model());
Q_ASSERT(model);
model->setStringList(modelData);
}
ui->led_Status->setTriState(500);
}
void CCallsignCompleter::onEditingFinished()
{
const CCallsign cs = this->getCallsign();
emit this->editingFinished();
if (cs.isValid())
{
emit this->validCallsignEntered();
}
}
void CCallsignCompleter::onChangedAircraftInRange()
{
this->updateCallsignsFromContext();
}
void CCallsignCompleter::onChangedConnectionStatus(INetwork::ConnectionStatus from, INetwork::ConnectionStatus to)
{
Q_UNUSED(from);
const bool on = (INetwork::Connected == to);
ui->led_Status->setOn(on);
ui->le_Callsign->clear();
ui->le_Callsign->setEnabled(on);
if (!on)
{
QStringListModel *model = qobject_cast<QStringListModel *>(m_currentCompleter->model());
Q_ASSERT(model);
model->setStringList(QStringList());
}
}
bool CCallsignCompleter::isValidKnownCallsign(const QString &callsignString) const
{
if (m_validCallsigns.isEmpty()) { return false; }
if (!CCallsign::isValidAircraftCallsign(callsignString)) { return false; }
return m_validCallsigns.contains(CCallsign(callsignString));
}
} // ns
} // ns

View File

@@ -0,0 +1,73 @@
/* Copyright (C) 2017
* 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_CALLSIGNCOMPLETER_H
#define BLACKGUI_COMPONENTS_CALLSIGNCOMPLETER_H
#include "blackgui/blackguiexport.h"
#include "blackmisc/digestsignal.h"
#include "blackmisc/aviation/callsignset.h"
#include "blackcore/network.h"
#include <QFrame>
#include <QScopedPointer>
#include <QTimer>
#include <QCompleter>
namespace Ui { class CCallsignCompleter; }
namespace BlackGui
{
namespace Components
{
/**
* Completer for aircraft callsigns
*/
class BLACKGUI_EXPORT CCallsignCompleter : public QFrame
{
Q_OBJECT
public:
//! Ctor
explicit CCallsignCompleter(QWidget *parent = nullptr);
//! Dtor
virtual ~CCallsignCompleter();
//! Get the entered callsign
BlackMisc::Aviation::CCallsign getCallsign() const;
//! String as entered
QString getRawCallsignString() const;
//! Is valid callsign?
bool hasValidCallsign() const;
signals:
//! Callsign entered
void validCallsignEntered();
//! Editing finished
void editingFinished();
private:
void updateCallsignsFromContext();
void onEditingFinished();
void onChangedAircraftInRange();
void onChangedConnectionStatus(BlackCore::INetwork::ConnectionStatus from, BlackCore::INetwork::ConnectionStatus to);
bool isValidKnownCallsign(const QString &callsignString) const;
QScopedPointer <Ui::CCallsignCompleter> ui;
QCompleter *m_currentCompleter = nullptr;
BlackMisc::Aviation::CCallsignSet m_validCallsigns;
BlackMisc::CDigestSignal m_dsAircraftsInRangeChanged { this, &CCallsignCompleter::onChangedAircraftInRange, 5000, 5 };
};
} // ns
} // ns
#endif // guard

View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CCallsignCompleter</class>
<widget class="QFrame" name="CCallsignCompleter">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>91</width>
<height>22</height>
</rect>
</property>
<property name="windowTitle">
<string>Frame</string>
</property>
<layout class="QHBoxLayout" name="hl_CallsignCompleter">
<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_Callsign">
<property name="placeholderText">
<string>callsign</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="BlackGui::CLedWidget" name="led_Status" native="true"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>BlackGui::CLedWidget</class>
<extends>QWidget</extends>
<header>blackgui/led.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>