Files
qt-migration-legatus/qt5-before/dlbo/Lts/Services/AudioVideoManagement/rt_state.cpp
T
torstenandCopilot 7173785915 Qt6 Migration: Complete migration with DDS/RTI support and build validation
Major Changes:
- Merged latest Qt5 devel content from dlbo (292 files changed, 7 new dirs)
- Consolidated forward-declarations and include folders
- Removed unneeded modules per Niklas' repo check list

Build System Fixes:
- Fixed CMake VERSION_GREATER syntax in ParticipantManagement/CMakeLists.txt
- Added VLC packages (libvlc-dev, vlc-plugin-base) to docker_build.sh
- Added PostgreSQL dev packages (libpq-dev, postgresql-server-dev-all) to Dockerfile
- Fixed locale warnings (ANSI_X3.4-1968 → C.UTF-8)
- Fixed ArcGIS SDK path warnings when BUILD_ARCGIS=OFF

Code Generation Fixes:
- Fixed IDL enum collisions (PortType→CorePortType/DdsutPortType, PdmEventType)
- Fixed Grantlee template svc_translation.cpp.grantlee:
  - Changed {{ idl_enum.name }}_def:: to {{ idl_enum.name }}::
  - Fixed .underlying() calls for C++11 scoped enums (enum class)
- Removed generated files from repo (moc_*, *_dtc.h, *_ftc.h)

Validation:
- BUILD_RTI=ON: SUCCESS
- BUILD_RTI=OFF: SUCCESS
- C++17 standard maintained for RTI 7.7 compatibility
- Ubuntu 26.04 Docker environment verified

Remaining Warnings (expected):
- BgViewer, KDChart, KDReports, Poppler-Qt6 not found (optional features)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-15 18:20:26 +00:00

244 lines
6.7 KiB
C++

/**
* @RDE_HEADER@
* RtState
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Fröbel, NLE, 2018-12-16
*/
#include "rt_state.h"
#include <QString>
#include <QtGlobal>
#include <utility>
#include <algorithm>
#include <sstream>
#include <QDebug>
namespace AudioVideoManagement
{
namespace
{
int toIndex(AvaRtPos p)
{
return p - AvaRtPos::min();
}
} // anonymous namespace
RtState::Key RtState::Key::createFrom(const RtState::RadioCircuit &radioCircuit)
{
return {radioCircuit.radioSystem, radioCircuit.id};
}
bool RtState::Key::operator==(const RtState::Key &other) const
{
return std::make_pair(radioSystem, id) == std::make_pair(other.radioSystem, other.id);
}
bool RtState::Key::operator<(const Key &other) const
{
return std::make_pair(radioSystem, id) < std::make_pair(other.radioSystem, other.id);
}
void RtState::setRadioCircuits(const QVector<RadioCircuit> &radioCircuits)
{
std::map<Key, CircuitState> newCircuits;
for (const auto &radioCircuit: radioCircuits)
{
Q_ASSERT(!radioCircuit.name.empty());
// If we know the new radio circuit already, we keep the CircuitState.
const Key key = Key::createFrom(radioCircuit);
CircuitState state{radioCircuit.name}; // default
auto found = m_radioCircuits.find(key);
bool alreadyKnown = found != m_radioCircuits.end();
if (alreadyKnown)
{
// Use the known state; but in any case use the (possibly) new name.
state = found->second;
state.name = radioCircuit.name;
}
auto insertResult = newCircuits.insert(std::make_pair(key, state));
Q_ASSERT(insertResult.second);
}
m_radioCircuits = std::move(newCircuits);
std::array<PosState, AvaRtPos::count()> newStates;
const auto count = std::min(static_cast<int>(radioCircuits.size()), AvaRtPos::count());
for (int i = 0; i < count; ++i)
{
const Key key = Key::createFrom(radioCircuits.at(i));
auto found = std::find_if(m_states.begin(), m_states.end(), [&key] (const PosState &s) { return s.key == key; });
bool isSelected = found != m_states.end();
if (isSelected)
newStates.at(i) = *found;
else
newStates.at(i) = PosState{key};
}
m_states = std::move(newStates);
}
void RtState::changeName(const RtState::RadioCircuit &radioCircuit)
{
Key key{radioCircuit.radioSystem, radioCircuit.id};
auto found = m_radioCircuits.find(key);
Q_ASSERT(found != m_radioCircuits.end());
if (found == m_radioCircuits.end())
{
qWarning() << "RtState::changeName: radio circuit not found!";
return;
}
found->second.name = radioCircuit.name;
}
void RtState::setSumChannel(AvaSumChannel sumChannel)
{
m_sumChannel = sumChannel;
}
void RtState::setSelection(AvaRtPos pos, const std::string &name, AvaRtButtonState s)
{
if (name.empty())
{
// The assertion does not always hold. AVS_Workstation may send us a button state
// other than AvaRtButtonState::None even when no radio circuit is selected.
// In that case we set the button state to AvaRtButtonState::None anyway.
// Fixed in AVS since Rev. 588.
Q_ASSERT(s == AvaRtButtonState::None);
m_states.at(toIndex(pos)) = PosState{};
return;
}
auto found = findRadioCircuit(name);
Q_ASSERT(found != m_radioCircuits.end());
if (found == m_radioCircuits.end())
{
qWarning() << "RtState::setSelection: radio circuit not found!";
return;
}
m_states.at(toIndex(pos)) = PosState{found->first, s};
}
void RtState::setVolume(const std::string &name, AvaVolume volume)
{
auto it = findRadioCircuit(name);
Q_ASSERT(it != m_radioCircuits.end());
if (it == m_radioCircuits.end())
{
qWarning() << "RtState::setVolume: radio circuit not found!";
return;
}
it->second.volume = volume;
}
std::string RtState::toCommand() const
{
std::ostringstream availableCircuits;
for (const auto &keyValue: m_radioCircuits)
availableCircuits << keyValue.second.toCommandPart() << ' ';
std::ostringstream selectedCircuits;
std::ostringstream states;
for (const auto &s: m_states)
{
selectedCircuits << s.toCommandSelectionPart(m_radioCircuits) << ' ';
states << s.toCommandStatePart() << ' ';
}
static const QString command = QStringLiteral(R"(setRtProfile "Default" "%1" "%2" "%3" %4)");
return command.arg(QString::fromStdString(availableCircuits.str()),
QString::fromStdString(selectedCircuits.str()),
QString::fromStdString(states.str()),
QString::number(static_cast<int>(m_sumChannel))).toStdString();
}
std::vector<std::string> RtState::allRadioCircuits() const
{
std::vector<std::string> allCircuits;
allCircuits.reserve(m_radioCircuits.size());
for (const auto &keyValue: m_radioCircuits)
allCircuits.push_back(keyValue.second.name);
return allCircuits;
}
std::vector<std::string> RtState::selectedRadioCircuits() const
{
std::vector<std::string> selectedCircuits;
selectedCircuits.reserve(m_states.size());
auto isFirstChannel = [](AvaSumChannel sc, AvaRtButtonState bs)
{
switch (sc)
{
case AvaSumChannel::Left:
return bs == AvaRtButtonState::Right;
case AvaSumChannel::Right:
return bs == AvaRtButtonState::Left;
};
return false;
};
for (const PosState &state: m_states)
{
if (state.key)
{
if (isFirstChannel(m_sumChannel, state.buttonState))
selectedCircuits.insert(selectedCircuits.begin(), m_radioCircuits.find(*state.key)->second.name);
else
selectedCircuits.push_back(m_radioCircuits.find(*state.key)->second.name);
}
}
return selectedCircuits;
}
std::map<RtState::Key, RtState::CircuitState>::iterator RtState::findRadioCircuit(const std::string &name)
{
auto withName = [&name] (const std::map<Key, CircuitState>::value_type &keyValue) { return keyValue.second.name == name; };
return std::find_if(m_radioCircuits.begin(), m_radioCircuits.end(), withName);
}
RtState::CircuitState::CircuitState(const std::string &name_):
name(name_)
{}
std::string RtState::CircuitState::toCommandPart() const
{
return QStringLiteral("15 %1 {%2}").arg(QString::number(static_cast<int>(volume)), QString::fromStdString(name)).toStdString();
}
RtState::PosState::PosState(const Key &key_, AvaRtButtonState s)
: key(key_)
, buttonState(s)
{}
std::string RtState::PosState::toCommandSelectionPart(const std::map<Key, CircuitState> &radioCircuits) const
{
std::string name;
if (key)
name = radioCircuits.find(*key)->second.name;
return QStringLiteral("{%1}").arg(QString::fromStdString(name)).toStdString();
}
std::string RtState::PosState::toCommandStatePart() const
{
return std::to_string(static_cast<int>(buttonState));
}
} // namespace AudioVideoManagement