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:
Klaus Basan
2015-03-13 01:53:37 +01:00
parent aee2b2495f
commit 269c65b578
73 changed files with 1301 additions and 1311 deletions

View File

@@ -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;
};
}

View File

@@ -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;
}

View File

@@ -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"))
{

View File

@@ -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

View File

@@ -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

View File

@@ -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;
};
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);
};
}

View File

@@ -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)

View File

@@ -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;

View File

@@ -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

View File

@@ -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))

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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.

View File

@@ -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);
}
}