mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-26 02:35:38 +08:00
As of workshop RW/KB, improved / fixed text messages
Also refs #351 * messages can be formatted with style sheet * fixed: removed command from message * added originator to command line * msg parsing now in core * using ITimestampBased for text messages and status messages * allow to resize rows to content (view base) * model / views for text messages * removed old qt stylesheets
This commit is contained in:
@@ -166,7 +166,7 @@ namespace BlackCore
|
||||
virtual bool isAudioLoopbackEnabled() const = 0;
|
||||
|
||||
//! Command line was entered
|
||||
virtual bool parseCommandLine(const QString &commandLine) = 0;
|
||||
virtual bool parseCommandLine(const QString &commandLine, const QString &orignator) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -167,9 +167,10 @@ namespace BlackCore
|
||||
}
|
||||
|
||||
//! \copydoc IContextAudio::parseCommandLine
|
||||
virtual bool parseCommandLine(const QString &commandLine) override
|
||||
virtual bool parseCommandLine(const QString &commandLine, const QString &originator) override
|
||||
{
|
||||
Q_UNUSED(commandLine);
|
||||
Q_UNUSED(originator);
|
||||
logEmptyContextWarning(Q_FUNC_INFO);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -470,17 +470,18 @@ namespace BlackCore
|
||||
return this->m_audioMixer->hasMixerConnection(IAudioMixer::InputMicrophone, IAudioMixer::OutputOutputDevice1);
|
||||
}
|
||||
|
||||
bool CContextAudio::parseCommandLine(const QString &commandLine)
|
||||
bool CContextAudio::parseCommandLine(const QString &commandLine, const QString &originator)
|
||||
{
|
||||
static CSimpleCommandParser parser(
|
||||
Q_UNUSED(originator);
|
||||
if (commandLine.isEmpty()) { return false; }
|
||||
CSimpleCommandParser parser(
|
||||
{
|
||||
".vol", ".volume", // output volume
|
||||
".mute", // mute
|
||||
".unmute" // unmute
|
||||
});
|
||||
if (commandLine.isEmpty()) return false;
|
||||
parser.parse(commandLine);
|
||||
if (!parser.isKnownCommand()) return false;
|
||||
if (!parser.isKnownCommand()) { return false; }
|
||||
|
||||
if (parser.matchesCommand(".mute"))
|
||||
{
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace BlackCore
|
||||
//! </pre>
|
||||
//! @}
|
||||
//! \copydoc IContextAudio::parseCommandLine
|
||||
virtual bool parseCommandLine(const QString &commandLine) override;
|
||||
virtual bool parseCommandLine(const QString &commandLine, const QString &originator) override;
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
|
||||
@@ -199,9 +199,9 @@ namespace BlackCore
|
||||
/*
|
||||
* Parse command line
|
||||
*/
|
||||
bool CContextAudioProxy::parseCommandLine(const QString &commandLine)
|
||||
bool CContextAudioProxy::parseCommandLine(const QString &commandLine, const QString &originator)
|
||||
{
|
||||
return this->m_dBusInterface->callDBusRet<bool>(QLatin1Literal("parseCommandLine"), commandLine);
|
||||
return this->m_dBusInterface->callDBusRet<bool>(QLatin1Literal("parseCommandLine"), commandLine, originator);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace BlackCore
|
||||
virtual bool isAudioLoopbackEnabled() const override;
|
||||
|
||||
//! \copydoc IContextOwnAircraft::parseCommandLine
|
||||
virtual bool parseCommandLine(const QString &commandLine) override;
|
||||
virtual bool parseCommandLine(const QString &commandLine, const QString &originator) override;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -125,6 +125,12 @@ namespace BlackCore
|
||||
//! Text messages received (also private chat messages, rfaio channel messages)
|
||||
void textMessagesReceived(const BlackMisc::Network::CTextMessageList &textMessages);
|
||||
|
||||
//! A superivisor text message was received
|
||||
void supervisorTextMessageReceived(const BlackMisc::Network::CTextMessage &message);
|
||||
|
||||
//! Text message sent (by me)
|
||||
void textMessageSent(const BlackMisc::Network::CTextMessage &sentMessage);
|
||||
|
||||
public slots:
|
||||
|
||||
//! Reload bookings from booking service
|
||||
@@ -195,7 +201,7 @@ namespace BlackCore
|
||||
virtual BlackMisc::Aviation::CFlightPlan loadFlightPlanFromNetwork(const BlackMisc::Aviation::CCallsign &callsign) const = 0;
|
||||
|
||||
//! Command line was entered
|
||||
virtual bool parseCommandLine(const QString &commandLine) = 0;
|
||||
virtual bool parseCommandLine(const QString &commandLine, const QString &originator) = 0;
|
||||
|
||||
//! Get METAR, if not available request it (code such as EDDF, KLAX)
|
||||
virtual BlackMisc::Aviation::CInformationMessage getMetar(const BlackMisc::Aviation::CAirportIcao &airportIcaoCode) = 0;
|
||||
|
||||
@@ -199,9 +199,10 @@ namespace BlackCore
|
||||
}
|
||||
|
||||
//! \copydoc IContextNetwork::parseCommandLine
|
||||
virtual bool parseCommandLine(const QString &commandLine) override
|
||||
virtual bool parseCommandLine(const QString &commandLine, const QString &originator) override
|
||||
{
|
||||
Q_UNUSED(commandLine);
|
||||
Q_UNUSED(originator);
|
||||
logEmptyContextWarning(Q_FUNC_INFO);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,9 @@ namespace BlackCore
|
||||
// 1. Init by "network driver"
|
||||
this->m_network = new CNetworkVatlib(this->getRuntime()->getCContextOwnAircraft(), this);
|
||||
connect(this->m_network, &INetwork::connectionStatusChanged, this, &CContextNetwork::ps_fsdConnectionStatusChanged);
|
||||
connect(this->m_network, &INetwork::textMessagesReceived, this, &CContextNetwork::ps_fsdTextMessageReceived);
|
||||
connect(this->m_network, &INetwork::textMessagesReceived, this, &CContextNetwork::textMessagesReceived);
|
||||
connect(this->m_network, &INetwork::textMessagesReceived, this, &CContextNetwork::ps_checkForSupervisiorTextMessage);
|
||||
connect(this->m_network, &INetwork::textMessageSent, this, &CContextNetwork::textMessageSent);
|
||||
|
||||
// 2. VATSIM bookings
|
||||
this->m_vatsimBookingReader = new CVatsimBookingReader(this, this->getRuntime()->getIContextSettings()->getNetworkSettings().getBookingServiceUrl());
|
||||
@@ -225,9 +227,90 @@ namespace BlackCore
|
||||
return INetwork::isPendingStatus(this->m_currentStatus);
|
||||
}
|
||||
|
||||
bool CContextNetwork::parseCommandLine(const QString &commandLine)
|
||||
bool CContextNetwork::parseCommandLine(const QString &commandLine, const QString &originator)
|
||||
{
|
||||
Q_UNUSED(commandLine);
|
||||
Q_UNUSED(originator;)
|
||||
if (commandLine.isEmpty()) { return false; }
|
||||
CSimpleCommandParser parser({ ".msg", ".m" });
|
||||
parser.parse(commandLine);
|
||||
if (!parser.isKnownCommand()) { return false; }
|
||||
if (parser.matchesCommand(".msg", ".m"))
|
||||
{
|
||||
if (!this->getIContextNetwork()->isConnected())
|
||||
{
|
||||
CLogMessage(this).validationError("Network needs to be connected");
|
||||
return false;
|
||||
}
|
||||
else if (!this->getIContextOwnAircraft())
|
||||
{
|
||||
CLogMessage(this).validationError("No own aircraft data, no text message can be sent");
|
||||
return false;
|
||||
}
|
||||
if (parser.countParts() < 3)
|
||||
{
|
||||
CLogMessage(this).validationError("Incorrect message");
|
||||
return false;
|
||||
}
|
||||
QString receiver = parser.part(1).trimmed(); // receiver
|
||||
|
||||
// set receiver
|
||||
CSimulatedAircraft ownAircraft(this->getIContextOwnAircraft()->getOwnAircraft());
|
||||
if (ownAircraft.getCallsign().isEmpty())
|
||||
{
|
||||
CLogMessage(this).validationError("No own callsign");
|
||||
return false;
|
||||
}
|
||||
|
||||
CTextMessage tm;
|
||||
tm.setSenderCallsign(ownAircraft.getCallsign());
|
||||
|
||||
if (receiver == "c1" || receiver == "com1")
|
||||
{
|
||||
tm.setFrequency(ownAircraft.getCom1System().getFrequencyActive());
|
||||
}
|
||||
else if (receiver == "c2" || receiver == "com2")
|
||||
{
|
||||
tm.setFrequency(ownAircraft.getCom2System().getFrequencyActive());
|
||||
}
|
||||
else if (receiver == "u" || receiver == "unicom" || receiver == "uni")
|
||||
{
|
||||
tm.setFrequency(CPhysicalQuantitiesConstants::FrequencyUnicom());
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isNumber;
|
||||
double frequencyMhz = receiver.toDouble(&isNumber);
|
||||
if (isNumber)
|
||||
{
|
||||
CFrequency radioFrequency = CFrequency(frequencyMhz, CFrequencyUnit::MHz());
|
||||
if (CComSystem::isValidCivilAviationFrequency(radioFrequency))
|
||||
{
|
||||
tm.setFrequency(radioFrequency);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLogMessage(this).validationError("Wrong COM frequency for text message");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CCallsign toCallsign(receiver);
|
||||
tm.setRecipientCallsign(toCallsign);
|
||||
}
|
||||
}
|
||||
|
||||
QString msg(parser.remainingStringAfter(2));
|
||||
tm.setMessage(msg);
|
||||
if (tm.isEmpty())
|
||||
{
|
||||
CLogMessage(this).validationError("No text message body");
|
||||
return false;
|
||||
}
|
||||
CTextMessageList tml(tm);
|
||||
this->sendTextMessages(tml);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -350,10 +433,16 @@ namespace BlackCore
|
||||
emit vatsimDataFileRead();
|
||||
}
|
||||
|
||||
void CContextNetwork::ps_fsdTextMessageReceived(const CTextMessageList &messages)
|
||||
void CContextNetwork::ps_checkForSupervisiorTextMessage(const CTextMessageList &messages)
|
||||
{
|
||||
if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << messages; }
|
||||
this->textMessagesReceived(messages); // relay
|
||||
if (messages.containsPrivateMessages())
|
||||
{
|
||||
CTextMessageList supMessages(messages.getSupervisorMessages());
|
||||
for (const CTextMessage &m : supMessages)
|
||||
{
|
||||
emit supervisorTextMessageReceived(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const CAircraft &CContextNetwork::ownAircraft() const
|
||||
|
||||
@@ -121,8 +121,14 @@ namespace BlackCore
|
||||
*/
|
||||
bool isPendingConnection() const;
|
||||
|
||||
//! \addtogroup commandline
|
||||
//! @{
|
||||
//! <pre>
|
||||
//! .m .msg message text
|
||||
//! </pre>
|
||||
//! @}
|
||||
//! \copydoc IContextNetwork::parseCommandLine
|
||||
virtual bool parseCommandLine(const QString &commandLine) override;
|
||||
virtual bool parseCommandLine(const QString &commandLine, const QString &originator) override;
|
||||
|
||||
//! \copydoc IContextNetwork::sendTextMessages()
|
||||
virtual void sendTextMessages(const BlackMisc::Network::CTextMessageList &textMessages) override;
|
||||
@@ -235,6 +241,9 @@ namespace BlackCore
|
||||
//! Data file has been read
|
||||
void ps_dataFileRead();
|
||||
|
||||
//! Check if a supervisor message was received
|
||||
void ps_checkForSupervisiorTextMessage(const BlackMisc::Network::CTextMessageList &messages);
|
||||
|
||||
/*!
|
||||
* \brief Connection status changed?
|
||||
* \param from old status
|
||||
@@ -242,8 +251,6 @@ namespace BlackCore
|
||||
*/
|
||||
void ps_fsdConnectionStatusChanged(INetwork::ConnectionStatus from, INetwork::ConnectionStatus to);
|
||||
|
||||
//! Radio text messages received
|
||||
void ps_fsdTextMessageReceived(const BlackMisc::Network::CTextMessageList &messages);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,9 @@ namespace BlackCore
|
||||
s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(),
|
||||
"textMessagesReceived", this, SIGNAL(textMessagesReceived(BlackMisc::Network::CTextMessageList)));
|
||||
Q_ASSERT(s);
|
||||
s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(),
|
||||
"textMessageSent", this, SIGNAL(textMessageSent(BlackMisc::Network::CTextMessage)));
|
||||
Q_ASSERT(s);
|
||||
s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(),
|
||||
"vatsimDataFileRead", this, SIGNAL(vatsimDataFileRead()));
|
||||
Q_ASSERT(s);
|
||||
@@ -211,9 +214,9 @@ namespace BlackCore
|
||||
return this->m_dBusInterface->callDBusRet<bool>(QLatin1Literal("isConnected"));
|
||||
}
|
||||
|
||||
bool CContextNetworkProxy::parseCommandLine(const QString &commandLine)
|
||||
bool CContextNetworkProxy::parseCommandLine(const QString &commandLine, const QString &originator)
|
||||
{
|
||||
return this->m_dBusInterface->callDBusRet<bool>(QLatin1Literal("commandLineEntered"), commandLine);
|
||||
return this->m_dBusInterface->callDBusRet<bool>(QLatin1Literal("commandLineEntered"), commandLine, originator);
|
||||
}
|
||||
|
||||
void CContextNetworkProxy::sendTextMessages(const CTextMessageList &textMessages)
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace BlackCore
|
||||
virtual bool isConnected() const override;
|
||||
|
||||
//! \copydoc IContextNetwork::parseCommandLine
|
||||
virtual bool parseCommandLine(const QString &commandLine) override;
|
||||
virtual bool parseCommandLine(const QString &commandLine, const QString &originator) override;
|
||||
|
||||
//! \copydoc IContextNetwork::sendTextMessages()
|
||||
virtual void sendTextMessages(const BlackMisc::Network::CTextMessageList &textMessages) override;
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace BlackCore
|
||||
virtual void enableAutomaticVoiceRoomResolution(bool enable) = 0;
|
||||
|
||||
//! Parse command line
|
||||
virtual bool parseCommandLine(const QString &commandLine) = 0;
|
||||
virtual bool parseCommandLine(const QString &commandLine, const QString &originator) = 0;
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
|
||||
@@ -225,15 +225,17 @@ namespace BlackCore
|
||||
return aircraft;
|
||||
}
|
||||
|
||||
bool CContextOwnAircraft::parseCommandLine(const QString &commandLine)
|
||||
bool CContextOwnAircraft::parseCommandLine(const QString &commandLine, const QString &originator)
|
||||
{
|
||||
static CSimpleCommandParser parser(
|
||||
Q_UNUSED(originator);
|
||||
if (commandLine.isEmpty()) { return false; }
|
||||
CSimpleCommandParser parser(
|
||||
{
|
||||
".x", ".xpdr", // transponder
|
||||
".com1", ".com2", // com1, com2 frequencies
|
||||
".c1", ".c2", // com1, com2 frequencies
|
||||
".selcal"
|
||||
});
|
||||
if (commandLine.isEmpty()) { return false; }
|
||||
parser.parse(commandLine);
|
||||
if (!parser.isKnownCommand()) { return false; }
|
||||
|
||||
@@ -256,7 +258,7 @@ namespace BlackCore
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (parser.commandStartsWith("com"))
|
||||
else if (parser.commandStartsWith("com") || parser.commandStartsWith("c"))
|
||||
{
|
||||
CFrequency frequency(parser.toDouble(1), CFrequencyUnit::MHz());
|
||||
if (CComSystem::isValidComFrequency(frequency))
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace BlackCore
|
||||
//! </pre>
|
||||
//! @}
|
||||
//! \copydoc IContextOwnAircraft::parseCommandLine
|
||||
virtual bool parseCommandLine(const QString &commandLine) override;
|
||||
virtual bool parseCommandLine(const QString &commandLine, const QString &originator) override;
|
||||
|
||||
protected:
|
||||
//! Constructor, with link to runtime
|
||||
|
||||
@@ -99,9 +99,9 @@ namespace BlackCore
|
||||
this->m_dBusInterface->callDBus(QLatin1Literal("enableAutomaticVoiceRoomResolution"), enable);
|
||||
}
|
||||
|
||||
bool CContextOwnAircraftProxy::parseCommandLine(const QString &commandLine)
|
||||
bool CContextOwnAircraftProxy::parseCommandLine(const QString &commandLine, const QString &originator)
|
||||
{
|
||||
return this->m_dBusInterface->callDBusRet<bool>(QLatin1Literal("parseCommandLine"), commandLine);
|
||||
return this->m_dBusInterface->callDBusRet<bool>(QLatin1Literal("parseCommandLine"), commandLine, originator);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace BlackCore
|
||||
virtual void enableAutomaticVoiceRoomResolution(bool enable);
|
||||
|
||||
//! \copydoc IContextOwnAircraft::parseCommandLine
|
||||
virtual bool parseCommandLine(const QString &commandLine) override;
|
||||
virtual bool parseCommandLine(const QString &commandLine, const QString &originator) override;
|
||||
|
||||
protected:
|
||||
//! \brief Constructor
|
||||
|
||||
@@ -137,12 +137,12 @@ namespace BlackCore
|
||||
BlackCore::registerMetadata();
|
||||
}
|
||||
|
||||
bool CRuntime::parseCommandLine(const QString commandLine)
|
||||
bool CRuntime::parseCommandLine(const QString commandLine, const QString &originator)
|
||||
{
|
||||
bool handled = false;
|
||||
if (this->getIContextAudio()) { handled = handled || this->getIContextAudio()->parseCommandLine(commandLine); }
|
||||
if (this->getIContextNetwork()) { handled = handled || this->getIContextNetwork()->parseCommandLine(commandLine); }
|
||||
if (this->getIContextOwnAircraft()) { handled = handled || this->getIContextOwnAircraft()->parseCommandLine(commandLine); }
|
||||
if (this->getIContextAudio()) { handled = handled || this->getIContextAudio()->parseCommandLine(commandLine, originator); }
|
||||
if (this->getIContextNetwork()) { handled = handled || this->getIContextNetwork()->parseCommandLine(commandLine, originator); }
|
||||
if (this->getIContextOwnAircraft()) { handled = handled || this->getIContextOwnAircraft()->parseCommandLine(commandLine, originator); }
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace BlackCore
|
||||
|
||||
public slots:
|
||||
//! Parse command line in all contexts
|
||||
bool parseCommandLine(const QString commandLine);
|
||||
bool parseCommandLine(const QString commandLine, const QString &originator);
|
||||
|
||||
private:
|
||||
bool m_init = false; /*!< flag */
|
||||
|
||||
@@ -502,6 +502,11 @@ namespace BlackCore
|
||||
*/
|
||||
void textMessagesReceived(const BlackMisc::Network::CTextMessageList &messages);
|
||||
|
||||
/*!
|
||||
* We have sent a text message.
|
||||
*/
|
||||
void textMessageSent(const BlackMisc::Network::CTextMessage &sentMessage);
|
||||
|
||||
/*!
|
||||
* We received a custom packet.
|
||||
* \deprecated As a short cut you can use this signal directly, but it is better to implement the decoding in INetwork and add a new signal.
|
||||
|
||||
@@ -363,15 +363,18 @@ namespace BlackCore
|
||||
{
|
||||
Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected");
|
||||
|
||||
if (messages.isEmpty()) return;
|
||||
if (messages.isEmpty()) { return; }
|
||||
CTextMessageList privateMessages = messages.getPrivateMessages();
|
||||
privateMessages.markAsSent();
|
||||
for (const auto &message : privateMessages)
|
||||
{
|
||||
if (message.getRecipientCallsign().isEmpty()) continue;
|
||||
if (message.getRecipientCallsign().isEmpty()) { continue; }
|
||||
Vat_SendTextMessage(m_net.data(), toFSD(message.getRecipientCallsign()), toFSD(message.getMessage()));
|
||||
emit textMessageSent(message);
|
||||
}
|
||||
|
||||
CTextMessageList radioMessages = messages.getRadioMessages();
|
||||
if (radioMessages.isEmpty()) return;
|
||||
radioMessages.markAsSent();
|
||||
for (const auto &message : radioMessages)
|
||||
{
|
||||
// I could send the same message to n frequencies in one step
|
||||
@@ -380,6 +383,7 @@ namespace BlackCore
|
||||
QVector<int> freqsVec;
|
||||
freqsVec.push_back(message.getFrequency().valueRounded(CFrequencyUnit::kHz(), 0));
|
||||
Vat_SendRadioMessage(m_net.data(), freqsVec.data(), freqsVec.size(), toFSD(message.getMessage()));
|
||||
emit textMessageSent(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user