refs #288, first version of login screen

* login component
* preparation of main window for new component
This commit is contained in:
Klaus Basan
2014-11-10 20:54:38 +01:00
committed by Roland Winklmeier
parent 49be1c2bb7
commit 86167e14c5
6 changed files with 1091 additions and 22 deletions

View File

@@ -0,0 +1,372 @@
/* Copyright (C) 2013
* 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 "logincomponent.h"
#include "ui_logincomponent.h"
#include "blackcore/context_network.h"
#include "blackcore/context_settings.h"
#include "blackcore/context_ownaircraft.h"
#include "blackcore/context_audio.h"
#include "blackcore/network.h"
#include "blackmisc/logmessage.h"
#include "../uppercasevalidator.h"
#include <QIntValidator>
using namespace BlackMisc;
using namespace BlackMisc::Aviation;
using namespace BlackMisc::Network;
using namespace BlackCore;
using namespace BlackGui;
namespace BlackGui
{
namespace Components
{
CLoginComponent::CLoginComponent(QWidget *parent) :
QFrame(parent),
ui(new Ui::CLoginComponent)
{
ui->setupUi(this);
setOkButtonString(false);
connect(this->ui->bb_OkCancel, &QDialogButtonBox::rejected, this, &CLoginComponent::ps_loginCancelled);
connect(this->ui->bb_OkCancel, &QDialogButtonBox::accepted, this, &CLoginComponent::ps_toggleNetworkConnection);
connect(this->ui->pb_OtherServersGotoSettings, &QPushButton::pressed, this, &CLoginComponent::requestNetworkSettings);
this->ui->lblp_SimulatorModel->setToolTips("available", "unavailable");
this->ui->lblp_SimulatorModel->setPixmapUnticked(CIcons::empty());
this->ui->lblp_AircraftCombinedType->setToolTips("ok", "wrong");
this->ui->lblp_AircraftIcaoAirline->setToolTips("ok", "wrong");
this->ui->lblp_AircraftIcaoDesignator->setToolTips("ok", "wrong");
this->ui->lblp_Callsign->setToolTips("ok", "wrong");
this->ui->lblp_VatsimHomeAirport->setToolTips("ok", "wrong");
this->ui->lblp_VatsimId->setToolTips("ok", "wrong");
this->ui->lblp_VatsimPassword->setToolTips("ok", "wrong");
this->ui->lblp_VatsimRealName->setToolTips("ok", "wrong");
// Settings loaded
this->loadFromSettings();
// Remark: The validators affect the signals such as returnPressed, editingFinished
// So I use no ranges in the CUpperCaseValidators, as this disables the signals for invalid values
// VATSIM
this->ui->le_VatsimId->setValidator(new QIntValidator(100000, 9999999, this));
connect(ui->le_VatsimId, &QLineEdit::editingFinished, this, &CLoginComponent::ps_validateVatsimValues);
this->ui->le_VatsimHomeAirport->setValidator(new CUpperCaseValidator(this));
connect(ui->le_VatsimHomeAirport, &QLineEdit::editingFinished, this, &CLoginComponent::ps_validateVatsimValues);
connect(ui->le_VatsimPassword, &QLineEdit::editingFinished, this, &CLoginComponent::ps_validateVatsimValues);
connect(ui->le_VatsimRealName, &QLineEdit::editingFinished, this, &CLoginComponent::ps_validateVatsimValues);
// own aircraft
this->ui->le_Callsign->setMaxLength(10);
this->ui->le_Callsign->setValidator(new CUpperCaseValidator(this));
connect(ui->le_Callsign, &QLineEdit::editingFinished, this, &CLoginComponent::ps_validateAircraftValues);
this->ui->le_AircraftCombinedType->setMaxLength(3);
this->ui->le_AircraftCombinedType->setValidator(new CUpperCaseValidator(this));
connect(ui->le_AircraftCombinedType, &QLineEdit::editingFinished, this, &CLoginComponent::ps_validateAircraftValues);
this->ui->le_AircraftIcaoAirline->setMaxLength(5);
this->ui->le_AircraftIcaoAirline->setValidator(new CUpperCaseValidator(this));
connect(ui->le_AircraftIcaoAirline, &QLineEdit::editingFinished, this, &CLoginComponent::ps_validateAircraftValues);
this->ui->le_AircraftIcaoDesignator->setMaxLength(5);
this->ui->le_AircraftIcaoDesignator->setValidator(new CUpperCaseValidator(this));
connect(ui->le_AircraftIcaoDesignator, &QLineEdit::editingFinished, this, &CLoginComponent::ps_validateAircraftValues);
// server GUI element
this->ui->frp_CurrentServer->setReadOnly(true);
this->ui->frp_CurrentServer->showPasswordField(false);
}
CLoginComponent::~CLoginComponent()
{ }
void CLoginComponent::mainInfoAreaChanged(const QWidget *currentWidget)
{
if (currentWidget != this && currentWidget != this->parentWidget())
{
this->m_visible = false;
}
else
{
if (this->m_visible)
{
// re-trigger! treat as same as OK
this->ps_toggleNetworkConnection();
}
else
{
this->m_visible = true;
bool isConnected = this->getIContextNetwork()->isConnected();
this->setGuiVisibility(isConnected);
this->setOkButtonString(isConnected);
}
}
}
void CLoginComponent::runtimeHasBeenSet()
{
Q_ASSERT(getIContextNetwork());
Q_ASSERT(getIContextSettings());
connect(getIContextNetwork(), &IContextNetwork::vatsimDataFileRead, this, &CLoginComponent::ps_onVatsimDataFileLoaded);
connect(getIContextSettings(), &IContextSettings::changedSettings, this, &CLoginComponent::ps_onSettingsChanged);
// inital setup, if data already available
ps_validateAircraftValues();
ps_validateVatsimValues();
ps_onVatsimDataFileLoaded();
CServerList otherServers = this->getIContextSettings()->getNetworkSettings().getTrafficNetworkServers();
this->ui->cbp_OtherServers->setServers(otherServers);
}
void CLoginComponent::ps_loginCancelled()
{
emit loginOrLogoffCancelled();
}
void CLoginComponent::ps_toggleNetworkConnection()
{
Q_ASSERT(this->getIContextNetwork());
Q_ASSERT(this->getIContextOwnAircraft());
Q_ASSERT(this->getIContextAudio());
bool isConnected = this->getIContextNetwork()->isConnected();
CStatusMessage msg;
if (!isConnected)
{
bool vatsimLogin = (this->ui->tw_Network->currentWidget() == this->ui->pg_NetworkVatsim);
if (!this->ps_validateAircraftValues())
{
CLogMessage(this).warning("Invalid aircraft data, login not possible");
return;
}
if (vatsimLogin && !this->ps_validateVatsimValues())
{
CLogMessage(this).warning("Invalid VATSIM data, login not possible");
return;
}
CGuiAircraftValues aircraftValues = this->getAircraftValuesFromGui();
CAircraft ownAircraft = this->getIContextOwnAircraft()->getOwnAircraft();
CAircraftIcao icao = ownAircraft.getIcaoInfo();
icao.setAircraftDesignator(aircraftValues.ownAircraftIcaoTypeDesignator);
icao.setAirlineDesignator(aircraftValues.ownAircraftIcaoAirline);
icao.setAircraftCombinedType(aircraftValues.ownAircraftCombinedType);
ownAircraft.setIcaoInfo(icao);
ownAircraft.setCallsign(aircraftValues.ownCallsign);
// set latest ICAO, callsign
this->getIContextOwnAircraft()->updateIcaoData(ownAircraft.getIcaoInfo(), loginOriginator());
this->getIContextOwnAircraft()->updateCallsign(ownAircraft.getCallsign(), loginOriginator());
// Login mode
INetwork::LoginMode mode = ui->gbp_LoginMode->getLoginMode();
switch (mode)
{
case INetwork::LoginStealth:
CLogMessage(this).info("login in stealth mode");
break;
case INetwork::LoginAsObserver:
CLogMessage(this).info("login in observer mode");
break;
}
// Server
CServer currentServer;
if (vatsimLogin)
{
currentServer = this->getCurrentVatsimServer();
CUser vatsimUser = this->getUserFromVatsimGuiValues();
currentServer.setUser(vatsimUser);
}
else
{
currentServer = this->getCurrentOtherServer();
}
this->ui->frp_CurrentServer->setServer(currentServer);
// Login
msg = this->getIContextNetwork()->connectToNetwork(currentServer, static_cast<uint>(mode));
}
else
{
// disconnect from network
this->getIContextAudio()->leaveAllVoiceRooms();
msg = this->getIContextNetwork()->disconnectFromNetwork();
}
// log message and trigger events
CLogMessage(this).statusMessage(msg);
if (msg.isSeverityInfoOrLess())
{
emit loginOrLogoffSuccessful();
}
else
{
emit loginOrLogoffCancelled();
}
}
void CLoginComponent::ps_onVatsimDataFileLoaded()
{
Q_ASSERT(getIContextNetwork());
Q_ASSERT(getIContextSettings());
CServerList vatsimFsdServers = this->getIContextNetwork()->getVatsimFsdServers();
if (vatsimFsdServers.isEmpty()) { return; }
this->ui->cbp_VatsimServer->setServers(vatsimFsdServers);
}
void CLoginComponent::setGuiValuesFromAircraft(const CAircraft &ownAircraft)
{
CAircraftIcao icao = ownAircraft.getIcaoInfo();
this->ui->le_Callsign->setText(ownAircraft.getCallsignAsString());
this->ui->le_AircraftIcaoDesignator->setText(icao.getAircraftDesignator());
this->ui->le_AircraftIcaoAirline->setText(icao.getAirlineDesignator());
this->ui->le_AircraftCombinedType->setText(icao.getAircraftCombinedType());
}
void CLoginComponent::loadFromSettings()
{
//! \todo replace with loading from settings when completed
this->ui->le_Callsign->setText("BLACK");
this->ui->le_AircraftIcaoDesignator->setText("C172");
this->ui->le_AircraftIcaoAirline->setText("GA");
this->ui->le_AircraftCombinedType->setText("L1P");
this->ui->le_VatsimId->setText("1288459");
this->ui->le_VatsimPassword->setText("4769");
this->ui->le_VatsimHomeAirport->setText("LOWI");
this->ui->le_VatsimRealName->setText("Black Swift");
}
CLoginComponent::CGuiAircraftValues CLoginComponent::getAircraftValuesFromGui() const
{
CGuiAircraftValues values;
values.ownCallsign = this->ui->le_Callsign->text().trimmed().toUpper();
values.ownAircraftIcaoTypeDesignator = this->ui->le_AircraftIcaoDesignator->text().trimmed().toUpper();
values.ownAircraftIcaoAirline = this->ui->le_AircraftIcaoAirline->text().trimmed().toUpper();
values.ownAircraftCombinedType = this->ui->le_AircraftCombinedType->text().trimmed().toUpper();
values.ownAircraftSimulatorModel = this->ui->le_SimulatorModel->text().trimmed().toUpper();
return values;
}
CLoginComponent::CVatsimValues CLoginComponent::getVatsimValuesFromGui() const
{
CVatsimValues values;
values.vatsimHomeAirport = this->ui->le_VatsimHomeAirport->text().trimmed().toUpper();
values.vatsimId = this->ui->le_VatsimId->text().trimmed();
values.vatsimPassword = this->ui->le_VatsimPassword->text().trimmed().toUpper();
values.vatsimRealName = this->ui->le_VatsimRealName->text().simplified().trimmed().toUpper();
return values;
}
CUser CLoginComponent::getUserFromVatsimGuiValues() const
{
CVatsimValues values = getVatsimValuesFromGui();
CUser user(values.vatsimId, values.vatsimRealName, "", values.vatsimPassword, getCallsignFromGui());
return user;
}
CCallsign CLoginComponent::getCallsignFromGui() const
{
CCallsign cs(this->ui->le_Callsign->text().trimmed().toUpper());
return cs;
}
CServer CLoginComponent::getCurrentVatsimServer() const
{
return this->ui->cbp_VatsimServer->currentServer();
}
CServer CLoginComponent::getCurrentOtherServer() const
{
return this->ui->cbp_OtherServers->currentServer();
}
void CLoginComponent::setOkButtonString(bool connected)
{
QString s = connected ? "Disconnect" : "Connect";
this->ui->bb_OkCancel->button(QDialogButtonBox::Ok)->setText(s);
}
void CLoginComponent::setGuiVisibility(bool connected)
{
this->ui->gbp_LoginMode->setVisible(!connected);
this->ui->gb_OwnAircraft->setVisible(!connected);
this->ui->gb_Network->setVisible(!connected);
this->ui->gb_CurrentServer->setVisible(connected);
}
bool CLoginComponent::ps_validateAircraftValues()
{
CGuiAircraftValues values = getAircraftValuesFromGui();
bool validCombinedType = CAircraftIcao::isValidCombinedType(values.ownAircraftCombinedType);
this->ui->lblp_AircraftCombinedType->setTicked(validCombinedType);
bool validAirlineDesignator = values.ownAircraftIcaoAirline.isEmpty() || CAircraftIcao::isValidAirlineDesignator(values.ownAircraftIcaoAirline);
this->ui->lblp_AircraftIcaoAirline->setTicked(validAirlineDesignator);
bool validIcaoDesignator = CAircraftIcao::isValidDesignator(values.ownAircraftIcaoTypeDesignator);
this->ui->lblp_AircraftIcaoDesignator->setTicked(validIcaoDesignator);
bool validCallsign = CCallsign::isValidCallsign(values.ownCallsign);
this->ui->lblp_Callsign->setTicked(validCallsign);
bool validSimulatorModel = !values.ownAircraftSimulatorModel.isEmpty();
this->ui->lblp_SimulatorModel->setTicked(validSimulatorModel);
// model intentionally ignored
return validCombinedType && validAirlineDesignator && validIcaoDesignator && validCallsign;
}
bool CLoginComponent::ps_validateVatsimValues()
{
CVatsimValues values = getVatsimValuesFromGui();
bool validVatsimId = CUser::isValidVatsimId(values.vatsimId);
this->ui->lblp_VatsimId->setTicked(validVatsimId);
bool validHomeAirport = values.vatsimHomeAirport.isEmpty() || CAirportIcao::isValidIcaoDesignator(values.vatsimHomeAirport);
this->ui->lblp_VatsimHomeAirport->setTicked(validHomeAirport);
bool validVatsimPassword = !values.vatsimPassword.isEmpty();
this->ui->lblp_VatsimPassword->setTicked(validVatsimPassword);
bool validRealUserName = !values.vatsimRealName.isEmpty();
this->ui->lblp_VatsimRealName->setTicked(validRealUserName);
return validVatsimId && validHomeAirport && validVatsimPassword && validRealUserName;
}
void CLoginComponent::ps_onSettingsChanged(uint settingsType)
{
if (settingsType != static_cast<uint>(IContextSettings::SettingsNetwork)) { return; }
CServerList otherServers = this->getIContextSettings()->getNetworkSettings().getTrafficNetworkServers();
this->ui->cbp_OtherServers->setServers(otherServers);
}
const QString &CLoginComponent::loginOriginator()
{
// string is generated once, the timestamp allows to use multiple
// components (as long as they are not generated at the same ms)
static const QString o = QString("LOGINCOMCOMPONENT:").append(QString::number(QDateTime::currentMSecsSinceEpoch()));
return o;
}
} // namespace
} // namespace

View File

@@ -0,0 +1,140 @@
/* Copyright (C) 2013
* 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_LOGINCOMPONENT_H
#define BLACKGUI_LOGINCOMPONENT_H
#include "enableforruntime.h"
#include "blackmisc/avaircraft.h"
#include "blackmisc/nwserver.h"
#include <QFrame>
#include <QScopedPointer>
namespace Ui { class CLoginComponent; }
namespace BlackGui
{
namespace Components
{
//! Login component
class CLoginComponent :
public QFrame,
public CEnableForRuntime
{
Q_OBJECT
public:
//! Constructor
explicit CLoginComponent(QWidget *parent = nullptr);
//! Destructor
~CLoginComponent();
signals:
//! Login
void loginOrLogoffSuccessful();
//! Cancelled
void loginOrLogoffCancelled();
//! Request network settings
void requestNetworkSettings();
public slots:
//! Main info area chnaged
void mainInfoAreaChanged(const QWidget *currentWidget);
protected:
//! \copydoc CEnableForRuntime::runtimeHasBeenSet
virtual void runtimeHasBeenSet() override;
private slots:
//! Login cancelled
void ps_loginCancelled();
//! Login requested
void ps_toggleNetworkConnection();
//! VATSIM data file was loaded
void ps_onVatsimDataFileLoaded();
//! Validate aircaft
bool ps_validateAircraftValues();
//! Validate VATSIM credentials
bool ps_validateVatsimValues();
//! Settings have been changed
void ps_onSettingsChanged(uint settingsType);
private:
//! GUI aircraft values, formatted
struct CGuiAircraftValues
{
QString ownCallsign;
QString ownAircraftIcaoTypeDesignator;
QString ownAircraftIcaoAirline;
QString ownAircraftCombinedType;
QString ownAircraftSimulatorModel;
};
//! VATSIM login data
struct CVatsimValues
{
QString vatsimId;
QString vatsimPassword;
QString vatsimRealName;
QString vatsimHomeAirport;
};
//! GUI values from aircraft
void setGuiValuesFromAircraft(const BlackMisc::Aviation::CAircraft &ownAircraft);
//! Load from settings
void loadFromSettings();
//! Values from GUI
CGuiAircraftValues getAircraftValuesFromGui() const;
//! Values from GUI
CVatsimValues getVatsimValuesFromGui() const;
//! User from VATSIM data
BlackMisc::Network::CUser getUserFromVatsimGuiValues() const;
//! Callsign from GUI
BlackMisc::Aviation::CCallsign getCallsignFromGui() const;
//! Selected server (VATSIM)
BlackMisc::Network::CServer getCurrentVatsimServer() const;
//! Selected server (others)
BlackMisc::Network::CServer getCurrentOtherServer() const;
//! Set OK button string
void setOkButtonString(bool connected);
//! Show/hide elements as appropriate
void setGuiVisibility(bool connected);
//! Identifies sender of cockpit updates
static const QString &loginOriginator();
bool m_visible = false; //!< is this component selected?
QScopedPointer<Ui::CLoginComponent> ui;
};
} // namespace
} // namespace
#endif // guard

View File

@@ -0,0 +1,540 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CLoginComponent</class>
<widget class="QFrame" name="CLoginComponent">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>463</width>
<height>412</height>
</rect>
</property>
<property name="windowTitle">
<string>Frame</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="vl_LoginComponent">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="QGroupBox" name="gb_Network">
<property name="title">
<string>Network</string>
</property>
<layout class="QGridLayout" name="gl_Network">
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="1" column="0" colspan="2">
<widget class="QTabWidget" name="tw_Network">
<property name="tabPosition">
<enum>QTabWidget::North</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="pg_NetworkVatsim">
<property name="toolTip">
<string>Login at VATSIM</string>
</property>
<attribute name="title">
<string>VATSIM</string>
</attribute>
<layout class="QGridLayout" name="gl_tabVatsim">
<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>0</number>
</property>
<property name="horizontalSpacing">
<number>6</number>
</property>
<item row="1" column="5">
<widget class="BlackGui::CTickLabel" name="lblp_VatsimPassword">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="1" colspan="4">
<widget class="QLineEdit" name="le_VatsimRealName"/>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="le_VatsimHomeAirport">
<property name="maxLength">
<number>4</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="lbl_VatsimHomeAirport">
<property name="text">
<string>Home airport</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="lbl_VatsimServer">
<property name="text">
<string>Server</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lbl_VatsimRealName">
<property name="text">
<string>Real name</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLineEdit" name="le_VatsimPassword">
<property name="echoMode">
<enum>QLineEdit::PasswordEchoOnEdit</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lbl_VatsimId">
<property name="text">
<string>Id:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="le_VatsimId"/>
</item>
<item row="1" column="3">
<widget class="QLabel" name="lbl_VatsimPassword">
<property name="text">
<string>Password</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="4">
<widget class="BlackGui::CServerListSelector" name="cbp_VatsimServer"/>
</item>
<item row="1" column="2">
<widget class="BlackGui::CTickLabel" name="lblp_VatsimId">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="BlackGui::CTickLabel" name="lblp_VatsimRealName">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="5">
<widget class="BlackGui::CTickLabel" name="lblp_VatsimHomeAirport">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="pg_OtherServers">
<attribute name="title">
<string>Other servers</string>
</attribute>
<layout class="QFormLayout" name="fl_OtherServers">
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>6</number>
</property>
<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="0" column="0">
<widget class="QLabel" name="lbl_OtherServers">
<property name="text">
<string>Server</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="BlackGui::CServerListSelector" name="cbp_OtherServers"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lbl_OtherServersEdit">
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="pb_OtherServersGotoSettings">
<property name="text">
<string>goto settings</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="BlackGui::CLoginModeButtons" name="gbp_LoginMode">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="title">
<string/>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_OwnAircraft">
<property name="title">
<string>Own aircraft</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gl_OwnAircraft">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>10</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item row="3" column="0">
<widget class="QLabel" name="lbl_AircraftIcaoAirline">
<property name="toolTip">
<string>e.g. DLH, LHA, ...</string>
</property>
<property name="text">
<string>ICAO airline</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lbl_SimulatorModel">
<property name="text">
<string>Model</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="le_AircraftIcaoAirline">
<property name="toolTip">
<string>e.g. DLH</string>
</property>
<property name="inputMask">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="maxLength">
<number>6</number>
</property>
<property name="placeholderText">
<string/>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QLineEdit" name="le_AircraftCombinedType">
<property name="toolTip">
<string>e.g. L2J</string>
</property>
<property name="inputMask">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="maxLength">
<number>3</number>
</property>
<property name="placeholderText">
<string/>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLabel" name="lbl_AircraftCombinedType">
<property name="toolTip">
<string>e.g. L2J, L1P, ....</string>
</property>
<property name="text">
<string>Aircraft type</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lbl_Callsign">
<property name="text">
<string>Callsign</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="le_Callsign">
<property name="toolTip">
<string>e.g. DEMBZ</string>
</property>
<property name="inputMethodHints">
<set>Qt::ImhUppercaseOnly</set>
</property>
<property name="inputMask">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="maxLength">
<number>10</number>
</property>
<property name="placeholderText">
<string/>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLineEdit" name="le_AircraftIcaoDesignator">
<property name="toolTip">
<string>e.g. B737</string>
</property>
<property name="inputMask">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="maxLength">
<number>6</number>
</property>
<property name="placeholderText">
<string/>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="lbl_AircraftIcaoDesignator">
<property name="toolTip">
<string>e.g. B737, A320, F18</string>
</property>
<property name="text">
<string>ICAO designator</string>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="BlackGui::CTickLabel" name="lblp_AircraftIcaoDesignator">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="BlackGui::CTickLabel" name="lblp_AircraftIcaoAirline">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="5">
<widget class="BlackGui::CTickLabel" name="lblp_AircraftCombinedType">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="BlackGui::CTickLabel" name="lblp_Callsign">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1" colspan="4">
<widget class="QLineEdit" name="le_SimulatorModel">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="BlackGui::CTickLabel" name="lblp_SimulatorModel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_CurrentServer">
<property name="title">
<string>Current server</string>
</property>
<layout class="QVBoxLayout" name="vl_CurrentServer">
<property name="spacing">
<number>3</number>
</property>
<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>
<widget class="BlackGui::CServerForm" name="frp_CurrentServer">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="vs_LoginComponent">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="bb_OkCancel">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
<property name="centerButtons">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>BlackGui::CTickLabel</class>
<extends>QLabel</extends>
<header>blackgui/ticklabel.h</header>
</customwidget>
<customwidget>
<class>BlackGui::CLoginModeButtons</class>
<extends>QGroupBox</extends>
<header>blackgui/loginmodebuttons.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>BlackGui::CServerListSelector</class>
<extends>QComboBox</extends>
<header>blackgui/serverlistselector.h</header>
</customwidget>
<customwidget>
<class>BlackGui::CServerForm</class>
<extends>QFrame</extends>
<header>blackgui/serverform.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>tw_Network</tabstop>
<tabstop>le_VatsimId</tabstop>
<tabstop>le_VatsimPassword</tabstop>
<tabstop>le_VatsimRealName</tabstop>
<tabstop>le_VatsimHomeAirport</tabstop>
<tabstop>cbp_VatsimServer</tabstop>
<tabstop>le_SimulatorModel</tabstop>
<tabstop>le_Callsign</tabstop>
<tabstop>le_AircraftIcaoDesignator</tabstop>
<tabstop>le_AircraftIcaoAirline</tabstop>
<tabstop>le_AircraftCombinedType</tabstop>
<tabstop>cbp_OtherServers</tabstop>
<tabstop>pb_OtherServersGotoSettings</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>