mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 14:55:36 +08:00
268 lines
9.4 KiB
C++
268 lines
9.4 KiB
C++
#include "mainwindow.h"
|
|
#include "ui_mainwindow.h"
|
|
|
|
using namespace BlackCore;
|
|
using namespace BlackMisc;
|
|
using namespace BlackGui;
|
|
using namespace BlackMisc::Network;
|
|
using namespace BlackMisc::Aviation;
|
|
using namespace BlackMisc::PhysicalQuantities;
|
|
using namespace BlackMisc::Geo;
|
|
using namespace BlackMisc::Settings;
|
|
|
|
/*
|
|
* Text messages received
|
|
*/
|
|
void MainWindow::textMessageReceived(const CTextMessageList &messages, bool sending)
|
|
{
|
|
if (messages.isEmpty()) return;
|
|
foreach(CTextMessage message, messages)
|
|
{
|
|
QString m = message.asString(true, true, "\t");
|
|
this->ui->te_TextMessagesAll->append(m);
|
|
|
|
m = message.asString(true, false, "\t");
|
|
if (message.isSendToUnicom()) this->ui->te_TextMessagesUnicom->append(m);
|
|
|
|
// check for own COM frequencies
|
|
if (message.isRadioMessage())
|
|
{
|
|
if (message.isSendToFrequency(this->m_ownAircraft.getCom1System().getFrequencyActive()))
|
|
this->ui->te_TextMessagesCOM1->append(m);
|
|
if (message.isSendToFrequency(this->m_ownAircraft.getCom2System().getFrequencyActive()))
|
|
this->ui->te_TextMessagesCOM2->append(m);
|
|
}
|
|
|
|
// individual channel text messages
|
|
if (message.isPrivateMessage()) this->addPrivateChannelTextMessage(message, sending);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Add new text message tab
|
|
*/
|
|
QWidget *MainWindow::addNewTextMessageTab(const QString &tabName)
|
|
{
|
|
QWidget *newTab = new QWidget(this->ui->tw_TextMessages);
|
|
QPushButton *closeButton = new QPushButton("Close", newTab);
|
|
QVBoxLayout *layout = new QVBoxLayout(newTab);
|
|
QTextEdit *textEdit = new QTextEdit(newTab);
|
|
textEdit->setReadOnly(true);
|
|
textEdit->setWordWrapMode(QTextOption::NoWrap);
|
|
layout->addWidget(textEdit);
|
|
layout->addWidget(closeButton);
|
|
newTab->setLayout(layout);
|
|
int index = this->ui->tw_TextMessages->addTab(newTab, tabName);
|
|
this->connect(closeButton, SIGNAL(released()), this, SLOT(closeTextMessageTab()));
|
|
this->ui->tw_TextMessages->setCurrentIndex(index);
|
|
return newTab;
|
|
}
|
|
|
|
/*
|
|
* Add a private channel text message
|
|
*/
|
|
void MainWindow::addPrivateChannelTextMessage(const CTextMessage &textMessage, bool sending)
|
|
{
|
|
if (!textMessage.isPrivateMessage()) return;
|
|
CCallsign cs = sending ? textMessage.getRecipient() : textMessage.getSender();
|
|
if (cs.isEmpty()) return;
|
|
QWidget *tab = this->findTextMessageTabByName(cs.getStringAsSet());
|
|
if (tab == nullptr) tab = this->findTextMessageTabByName(cs.asString());
|
|
if (tab == nullptr) tab = this->addNewTextMessageTab(cs.getStringAsSet());
|
|
Q_ASSERT(tab != nullptr);
|
|
QTextEdit *textEdit = tab->findChild<QTextEdit *>();
|
|
Q_ASSERT(textEdit != nullptr);
|
|
if (textEdit == nullptr) return; // do not crash, though this situation could not happen
|
|
textEdit->append(textMessage.asString(true, false, "\t"));
|
|
}
|
|
|
|
/*
|
|
* Message tab by name
|
|
*/
|
|
QWidget *MainWindow::findTextMessageTabByName(const QString &name)
|
|
{
|
|
if (name.isEmpty()) return nullptr;
|
|
QString n = name.trimmed();
|
|
for (int index = 0; index < this->ui->tw_TextMessages->count(); index++)
|
|
{
|
|
QString tabName = this->ui->tw_TextMessages->tabText(index);
|
|
if (tabName.indexOf(n, 0, Qt::CaseInsensitive) < 0) continue;
|
|
QWidget *tab = this->ui->tw_TextMessages->widget(index);
|
|
return tab;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
/*
|
|
* Selected tab text
|
|
*/
|
|
CTextMessage MainWindow::getTextMessageStubForChannel()
|
|
{
|
|
CTextMessage tm;
|
|
int index = this->ui->tw_TextMessages->currentIndex();
|
|
if (index < 0) return tm;
|
|
if (index == this->ui->tw_TextMessages->indexOf(this->ui->tb_TextMessagesAll)) return tm;
|
|
|
|
// from
|
|
tm.setSender(this->m_ownAircraft.getCallsign());
|
|
|
|
if (index == this->ui->tw_TextMessages->indexOf(this->ui->tb_TextMessagesCOM1) ||
|
|
index == this->ui->tw_TextMessages->indexOf(this->ui->tb_TextMessagesCOM2) ||
|
|
index == this->ui->tw_TextMessages->indexOf(this->ui->tb_TextMessagesUnicom))
|
|
{
|
|
// frequency text message
|
|
if (index == this->ui->tw_TextMessages->indexOf(this->ui->tb_TextMessagesCOM1))
|
|
{
|
|
tm.setFrequency(this->m_ownAircraft.getCom1System().getFrequencyActive());
|
|
}
|
|
else if (index == this->ui->tw_TextMessages->indexOf(this->ui->tb_TextMessagesCOM2))
|
|
{
|
|
tm.setFrequency(this->m_ownAircraft.getCom2System().getFrequencyActive());
|
|
}
|
|
else if (index == this->ui->tw_TextMessages->indexOf(this->ui->tb_TextMessagesUnicom))
|
|
{
|
|
tm.setFrequency(CPhysicalQuantitiesConstants::FrequencyUnicom());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
QString selectedTabText = this->ui->tw_TextMessages->tabText(index);
|
|
bool isNumber;
|
|
double frequency = selectedTabText.toDouble(&isNumber);
|
|
if (isNumber)
|
|
{
|
|
CFrequency radioFrequency = CFrequency(frequency, CFrequencyUnit::MHz());
|
|
if (CComSystem::isValidCivilAviationFrequency(radioFrequency))
|
|
{
|
|
tm.setFrequency(radioFrequency);
|
|
}
|
|
else
|
|
{
|
|
CCallsign recipient(selectedTabText);
|
|
tm.setRecipient(recipient);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CCallsign recipient(selectedTabText);
|
|
tm.setRecipient(recipient);
|
|
}
|
|
}
|
|
return tm; // now valid message stub with receiver
|
|
}
|
|
|
|
/*
|
|
* Close message tab
|
|
*/
|
|
void MainWindow::closeTextMessageTab()
|
|
{
|
|
QObject *sender = QObject::sender();
|
|
QWidget *parentWidget = qobject_cast<QWidget *>(sender->parent());
|
|
int index = -1;
|
|
|
|
while (index < 0 && parentWidget)
|
|
{
|
|
index = this->ui->tw_TextMessages->indexOf(parentWidget);
|
|
parentWidget = parentWidget->parentWidget();
|
|
}
|
|
if (index >= 0) this->ui->tw_TextMessages->removeTab(index);
|
|
}
|
|
|
|
/*
|
|
* Command entered
|
|
*/
|
|
void MainWindow::commandEntered()
|
|
{
|
|
// TODO: just a first draft of the command line parser
|
|
// needs to be refactored, as soon as a first version works
|
|
|
|
QString cmdLine = this->ui->le_TextMessagesInput->text().simplified();
|
|
if (cmdLine.isEmpty()) return;
|
|
QList<QString> parts = cmdLine.toLower().split(' ');
|
|
if (parts.length() < 1) return;
|
|
QString cmd = parts[0].startsWith('.') ? parts[0].toLower() : "";
|
|
if (cmd == ".m" || cmd == ".msg")
|
|
{
|
|
if (!this->m_contextNetworkAvailable || !this->m_contextNetwork->isConnected())
|
|
{
|
|
this->displayStatusMessage(CStatusMessage(CStatusMessage::TypeTrafficNetwork, CStatusMessage::SeverityError, "network needs to be connected"));
|
|
return;
|
|
}
|
|
if (parts.length() < 3)
|
|
{
|
|
this->displayStatusMessage(CStatusMessage(CStatusMessage::TypeValidation, CStatusMessage::SeverityError, "incorrect message"));
|
|
return;
|
|
}
|
|
QString p = parts[1].trimmed();
|
|
|
|
// select current tab by command
|
|
if (p == "c1" || p == "com1")
|
|
{
|
|
this->ui->tw_TextMessages->setCurrentWidget(this->ui->tb_TextMessagesCOM1);
|
|
}
|
|
else if (p == "c2" || p == "com2")
|
|
{
|
|
this->ui->tw_TextMessages->setCurrentWidget(this->ui->tb_TextMessagesCOM2);
|
|
}
|
|
else if (p == "u" || p == "unicom" || p == "uni")
|
|
{
|
|
this->ui->tw_TextMessages->setCurrentWidget(this->ui->tb_TextMessagesUnicom);
|
|
}
|
|
else
|
|
{
|
|
QWidget *tab = this->findTextMessageTabByName(p.trimmed());
|
|
if (tab == nullptr) tab = this->addNewTextMessageTab(p.trimmed().toUpper());
|
|
this->ui->tw_TextMessages->setCurrentWidget(tab);
|
|
}
|
|
CTextMessage tm = this->getTextMessageStubForChannel();
|
|
int index = cmdLine.indexOf(tm.getRecipient().getStringAsSet(), 0, Qt::CaseInsensitive);
|
|
if (index < 0)
|
|
{
|
|
this->displayStatusMessage(
|
|
CStatusMessage(CStatusMessage::TypeValidation, CStatusMessage::SeverityError,
|
|
"incomplete message")
|
|
);
|
|
return;
|
|
}
|
|
QString msg(cmdLine.mid(index + tm.getRecipient().asString().length() + 1));
|
|
tm.setMessage(msg);
|
|
if (tm.isEmpty()) return;
|
|
if (!this->isContextNetworkAvailableCheck()) return;
|
|
CTextMessageList tml(tm);
|
|
this->m_contextNetwork->sendTextMessages(tml);
|
|
this->textMessageReceived(tml, true);
|
|
this->ui->le_TextMessagesInput->setText("");
|
|
}
|
|
else if (cmd.startsWith("."))
|
|
{
|
|
// dump CMDs
|
|
}
|
|
else
|
|
{
|
|
// single line, no command
|
|
// just send
|
|
if (!this->m_contextNetwork->isConnected())
|
|
{
|
|
this->displayStatusMessage(CStatusMessage(CStatusMessage::TypeTrafficNetwork, CStatusMessage::SeverityError, "network needs to be connected"));
|
|
return;
|
|
}
|
|
|
|
int index = this->ui->tw_TextMessages->currentIndex();
|
|
if (index < 0 || index == this->ui->tw_TextMessages->indexOf(this->ui->tb_TextMessagesAll))
|
|
{
|
|
this->displayStatusMessage(CStatusMessage(CStatusMessage::TypeValidation, CStatusMessage::SeverityError, "incorrect channel"));
|
|
}
|
|
else
|
|
{
|
|
CTextMessage tm = this->getTextMessageStubForChannel();
|
|
tm.setMessage(cmdLine);
|
|
if (tm.isEmpty()) return;
|
|
if (!this->isContextNetworkAvailableCheck()) return;
|
|
CTextMessageList tml(tm);
|
|
this->m_contextNetwork->sendTextMessages(tml);
|
|
this->textMessageReceived(tml, true);
|
|
this->ui->le_TextMessagesInput->setText("");
|
|
}
|
|
}
|
|
}
|