Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Common/LtsWidgets/lts_dialog.cpp
T
torstenandCopilot bafed3705f Qt6 migration: LtsWidgets API fixes, LtsWebSocket logger init, RTI Docker install
- LtsWidgets: Fixed Qt6 API compatibility issues
  - QWheelEvent::delta() → angleDelta().y()
  - QStyleOption::init() → initFrom()
  - QComboBox activated signal signature change
  - QTextCodec removal (UTF-8 default in Qt6)
  - Missing widget includes added

- LtsWebSocket: Fixed m_logger reference initialization
  - Added NGLLoggerBootstrap includes
  - Proper initialization in constructor initializer lists

- CMake: Added BUILD_LTSWEBSOCKET option for temporary exclusion

- Docker: RTI Connext permanent installation script added
  - ci/install-rti-in-docker.sh for persistent RTI setup
  - Removes need for volume mounting RTI into container

- BUILD options: FilterManagement, RTI, Codification, Grantlee, LtsWebSocket
  can be disabled for partial builds during migration

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-08-19 14:04:26 +02:00

700 lines
19 KiB
C++

#include "lts_dialog.h"
#include "lts_base_layout_widget.h"
#include "lts_date_time_edit.h"
#include "lts_dialog_button_box.h"
#include "lts_dialog_helper.h"
#include "lts_message_dialog.h"
#include "lts_progress_dialog_helper.h"
#include <LtsSession/lts_session_data.h>
#include <QCheckBox>
#include <QColor>
#include <QComboBox>
#include <QDateTimeEdit>
#include <QDebug>
#include <QHBoxLayout>
#include <QInputDialog>
#include <QLineEdit>
#include <QListView>
#include <QListWidget>
#include <QMenu>
#include <QMetaMethod>
#include <QPainter>
#include <QPlainTextEdit>
#include <QProgressBar>
#include <QRadioButton>
#include <QScrollArea>
#include <QScroller>
#include <QSlider>
#include <QSpinBox>
#include <QTableView>
#include <QTableWidget>
#include <QTextEdit>
#include <QWidget>
namespace LtsWidgets
{
int LtsDialog::s_object_count = 0;
class OverlayContainer : public QWidget
{
Q_OBJECT
public:
OverlayContainer(QWidget* parent);
protected:
void paintEvent(QPaintEvent* e) override;
};
OverlayContainer::OverlayContainer(QWidget* parent) : QWidget(parent)
{
setAttribute(Qt::WA_TranslucentBackground);
}
void OverlayContainer::paintEvent(QPaintEvent* e)
{
QPainter p(this);
p.fillRect(rect(), {80, 80, 80, 200});
QWidget::paintEvent(e);
}
LtsDialog::LtsDialog(QWidget* parent, ButtonCombination buttonCombination, bool closeable)
: QWidget(), m_changesMade(false), m_firstShow(true), m_baseLayoutWidget(nullptr), m_isClosable(closeable),
m_noLockTopic(false), m_unchangeableDialog(false), m_dialogHelper(new LtsDialogHelper(nullptr)), m_topicInfo(),
m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("LtsWidget.LtsDialog")), m_buttonBox(nullptr),
m_uiRequirements(new UiRequirementList())
{
Q_UNUSED(parent);
s_object_count++;
m_dialogHelper->setDialog(this);
m_buttonBox = m_dialogHelper->getButtonBox();
addDebugMenuButton();
connect(m_buttonBox->getButton(DialogButton::Close), &QPushButton::clicked, this, &LtsDialog::slotClose);
switch (buttonCombination)
{
case ButtonCombination::OkCancel: {
m_buttonBox->getButton(DialogButton::Close)->setText(tr("Cancel"));
connect(m_buttonBox->getButton(DialogButton::Ok), &QPushButton::clicked, this, &LtsDialog::slotOkay);
break;
}
case ButtonCombination::OkApplyCancel: {
m_buttonBox->getButton(DialogButton::Close)->setText(tr("Cancel"));
connect(m_buttonBox->getButton(DialogButton::Ok), &QPushButton::clicked, this, &LtsDialog::slotOkay);
connect(m_buttonBox->getButton(DialogButton::Apply), &QPushButton::clicked, this, &LtsDialog::slotApply);
m_buttonBox->getButton(DialogButton::Apply)->setVisible(true);
break;
}
case ButtonCombination::CloseOnly: {
m_buttonBox->getButton(DialogButton::Ok)->setVisible(false);
setUnchangeable();
break;
}
default:
case ButtonCombination::SeamlessDialog: {
m_buttonBox->setVisible(false);
setContentsMargins(0, 0, 0, 0);
m_dialogHelper->setContentsMargins(0, 0, 0, 0);
QLayout* l = m_dialogHelper->layout();
if (l)
{
l->setContentsMargins(0, 0, 0, 0);
}
else
{
qWarning() << "LtsDialog::c_tor: Dialog Helper has no layout to set margins";
}
break;
}
}
if (!closeable)
{
m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->setVisible(false);
m_buttonBox->getButton(LtsWidgets::DialogButton::Close)->setVisible(false);
}
}
LtsDialog::~LtsDialog()
{
delete m_uiRequirements;
if (m_overlayWidget)
m_overlayWidget->setParent(nullptr);
s_object_count--;
}
void LtsDialog::setOverlay(QWidget* widget)
{
if (m_overlayContainer)
{
if (m_overlayWidget)
{
m_overlayWidget->hide();
m_overlayWidget->setParent(nullptr);
m_overlayWidget->hide();
m_overlayWidget = nullptr;
}
m_overlayContainer->hide();
m_overlayContainer->setParent(nullptr);
m_overlayContainer->hide();
m_overlayContainer->deleteLater();
m_overlayContainer = nullptr;
}
OverlayContainer* overlayContainer = new OverlayContainer(m_dialogHelper);
connect(m_dialogHelper.data(), &LtsDialogHelper::signalSizeChanged, overlayContainer,
[overlayContainer](const QSize& size) { overlayContainer->setGeometry(QRect(QPoint(0, 0), size)); });
overlayContainer->setGeometry(QRect(QPoint(0, 0), m_dialogHelper->size()));
m_overlayContainer = overlayContainer;
QHBoxLayout* l = new QHBoxLayout;
m_overlayContainer->setLayout(l);
widget->setAutoFillBackground(true);
l->addWidget(widget, 0, Qt::AlignCenter);
widget->show();
connect(widget, &QWidget::destroyed, m_overlayContainer.data(), &QObject::deleteLater);
m_overlayWidget = widget;
m_overlayContainer->show();
m_overlayContainer->raise();
}
void LtsDialog::unsetOverlay()
{
if (m_overlayWidget)
m_overlayWidget->setParent(nullptr);
if (!m_overlayContainer)
return;
m_overlayContainer->setParent(nullptr);
m_overlayContainer->deleteLater();
}
LtsDialogHelper* LtsDialog::getHelper()
{
return m_dialogHelper;
}
LtsBaseLayoutWidget* LtsDialog::baseLayoutWidget()
{
return m_baseLayoutWidget;
}
void LtsDialog::setOnlineHelpFilename(const QString& fileName)
{
m_onlineHelpFileName = fileName;
QPushButton* btn = m_buttonBox->getButton(DialogButton::Help);
if (btn == nullptr)
return;
if (LtsSessionData::LtsSessionData::getInstance()->isTablet() && strcmp(PROJECTBUILD, "guez") == 0)
return;
connect(btn, &QPushButton::clicked, this, [this]() { emit signalShowOnlineHelp(m_onlineHelpFileName); });
btn->setVisible(true);
}
void LtsDialog::addDebugMenuButton()
{
#ifdef LTS_DEBUG
QMenu* menu = new QMenu(this);
menu->addAction(QStringLiteral("simulate changes"), this, &LtsDialog::slotChangesMade);
menu->addAction(QStringLiteral("unchange"), this, &LtsDialog::__unchange__);
menu->addAction(QStringLiteral("retranslate"), this, &LtsDialog::retranslate);
menu->addAction(QStringLiteral("force unlock"), this, [this]() { setUnchangeable(false); });
menu->addAction(QStringLiteral("set unchangeable"), this, [this]() { setUnchangeable(); });
menu->addAction(QStringLiteral("try lock"), this, &LtsDialog::tryLockTopic);
menu->addAction(QStringLiteral("set closable"), this, [this]() { m_isClosable = true; });
menu->addAction(QStringLiteral("set unclosable"), this, [this]() { m_isClosable = false; });
menu->addAction(QStringLiteral("clear requirements"), this, [this] { m_uiRequirements->clear(); });
menu->addAction(QStringLiteral("enable all button box buttons"), this, [this]() {
const auto children = m_buttonBox->findChildren<QPushButton*>();
for (QPushButton* pb : children)
pb->setEnabled(true);
});
menu->addAction(QStringLiteral("show button box button .."), this, [this]() {
QString buttonObjectName = QInputDialog::getText(this, QString(), QStringLiteral("Enter button object name"));
if (buttonObjectName.isEmpty())
return;
const QList<QPushButton*> buttons = m_buttonBox->findChildren<QPushButton*>(buttonObjectName);
int btnCount = buttons.count();
if (btnCount == 0)
{
LtsMessageDialog::showMessage(this, QStringLiteral("button not found"));
return;
}
if (btnCount > 1)
{
QStringList buttonStringList;
buttonStringList.reserve(buttons.size());
for (QPushButton* pb : buttons)
buttonStringList += pb->objectName();
LtsMessageDialog::showMessage(
this, QStringLiteral("button ambiguous: %1").arg(buttonStringList.join(QStringLiteral(", "))));
return;
}
buttons.at(0)->setVisible(true);
});
QPushButton* debugBtn = m_buttonBox->getButton(DialogButton::_debug_);
debugBtn->setMenu(menu);
debugBtn->setVisible(true);
#endif
}
void LtsDialog::updateWindowTitle()
{
QString completeTitle = m_title;
if (m_changesMade)
completeTitle.insert(0, QStringLiteral("\u2022"));
if (!m_topicLockedBy.isEmpty())
completeTitle.push_back(QString(QStringLiteral(" - READ-ONLY (%1)")).arg(m_topicLockedBy));
QWidget::setWindowTitle(completeTitle);
if (m_dialogHelper != nullptr)
m_dialogHelper->setWindowTitle(completeTitle);
}
void LtsDialog::setWindowTitle(const QString& title)
{
m_title = title;
updateWindowTitle();
}
void LtsDialog::setBaseLayoutWidget(LtsBaseLayoutWidget* baseLayoutWidget)
{
m_baseLayoutWidget = baseLayoutWidget;
}
void LtsDialog::setIdentifier(const QString& identifier)
{
m_identifier = identifier;
tableColumnOrganiserSetting();
}
void LtsDialog::addConnections(QWidget* widget)
{
if (addChangesMadeSignal<QLineEdit>(widget, &QLineEdit::textChanged))
return;
if (addChangesMadeSignal<QDateTimeEdit>(widget, &QDateTimeEdit::dateTimeChanged))
return;
if (addChangesMadeSignal<QComboBox>(widget, &QComboBox::currentTextChanged))
return;
if (addChangesMadeSignal<QCheckBox>(widget, &QCheckBox::stateChanged))
return;
if (addChangesMadeSignal<QSpinBox>(widget, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged)))
return;
if (addChangesMadeSignal<QDoubleSpinBox>(
widget, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged)))
return;
if (addChangesMadeSignal<QSlider>(widget, &QSlider::valueChanged))
return;
if (addChangesMadeSignal<QPlainTextEdit>(widget, &QPlainTextEdit::textChanged))
return;
if (addChangesMadeSignal<QTextEdit>(widget, &QTextEdit::textChanged))
return;
if (addChangesMadeSignal<QAbstractButton>(widget, &QAbstractButton::toggled))
return;
if (addChangesMadeSignal<LtsDateTimeEdit>(widget, &LtsDateTimeEdit::dateTimeChanged))
return;
}
void LtsDialog::setUnchangeable(bool unchangeable)
{
m_unchangeableDialog = unchangeable;
}
bool LtsDialog::addDialogFixed(LtsDialog* dialog, const char* menuGroupUntranslated, const QString& identifier,
const LayoutArea& layoutArea, bool setClosable, bool focusNewTab)
{
return addDialog(dialog, tr(menuGroupUntranslated), identifier, layoutArea, setClosable, focusNewTab);
}
bool LtsDialog::addDialog(LtsDialog* dialog, const QString& menuGroup, const QString& identifier,
const LayoutArea& layoutArea, bool setClosable, bool focusNewTab)
{
if (!m_baseLayoutWidget)
{
qCritical() << "LtsDialog: addDialog: no base layout set - cannot add Dialog !";
return false;
}
return m_baseLayoutWidget->addWidget(dialog, menuGroup, identifier, layoutArea, setClosable, focusNewTab);
}
bool LtsDialog::amIFocused() const
{
if (!m_baseLayoutWidget)
{
qCritical() << "LtsDialog: addDialog: no base layout set - cannot check for focus!";
return false;
}
return m_baseLayoutWidget->isDialogFocused(this);
}
bool LtsDialog::focusDialog(const QString& menuGroup, const QString& identifier, const LayoutArea& layoutArea)
{
if (!m_baseLayoutWidget)
{
qCritical() << "LtsDialog: addDialog: no base layout set - cannot focus Dialog !";
return false;
}
return m_baseLayoutWidget->focusTab(menuGroup, identifier, layoutArea);
}
void LtsDialog::showEvent(QShowEvent* event)
{
emit visibilityChanged(true);
bool tmp = m_unchangeableDialog;
if (!m_firstShow)
{
QWidget::showEvent(event);
return;
}
m_unchangeableDialog = true;
m_firstShow = false;
QList<QWidget*> listenWidgets = findChildren<QWidget*>();
for (auto i = listenWidgets.begin(); i != listenWidgets.end(); ++i)
{
QWidget* widget = *i;
QVariant isConst = widget->property("const");
if (isConst.isValid() && isConst.toBool())
continue;
if (!tmp)
addConnections(widget);
#ifdef TABLET_MODE
LtsWidgets::addTouchScroll(widget);
#endif
}
QWidget::showEvent(event);
m_unchangeableDialog = tmp;
}
void LtsDialog::tryLockTopic()
{
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START";
if (!m_topicInfo.isValid())
return;
if (m_topicInfo.isLocked())
{
WARNING_LOG(m_logger) << Q_FUNC_INFO << " tried to lock with an already locked topic info, return";
return;
}
if (m_noLockTopic)
return;
bool bIsConnected = isSignalConnected(QMetaMethod::fromSignal(&LtsDialog::signalLockTopic));
DEBUG_LOG(m_logger) << Q_FUNC_INFO << " signalLockTopic(): "
<< ", TopicName =" << m_topicInfo.topicName() << ", entity =" << m_topicInfo.entityId()
<< ", signalLockTopic isConnected=" << bIsConnected;
if (bIsConnected)
{
emit signalLockTopic(m_topicInfo);
m_topicInfo.setLocked();
}
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END";
}
void LtsDialog::initTopicLockHandler(const QString& topicName, int entityId)
{
m_topicInfo.setTopicName(topicName);
m_topicInfo.setEntity(entityId);
m_topicInfo.setValid();
}
void LtsDialog::tryLockTopicNew()
{
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START";
tryLockTopic();
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END";
}
void LtsDialog::tryLockTopicNew(const QString& topicName, int entityId)
{
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START"
<< ", topicName='" << topicName << "'"
<< ", entityId=" << entityId;
if (m_topicInfo.entityId() != entityId)
{
DEBUG_LOG(m_logger) << Q_FUNC_INFO << " topicName='" << topicName << "'"
<< " change from " << m_topicInfo.entityId() << " to " << entityId;
m_topicInfo.setLocked(false);
}
m_topicInfo.setTopicName(topicName);
m_topicInfo.setEntity(entityId);
m_topicInfo.setValid();
tryLockTopic();
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END"
<< ", topicName='" << topicName << "'"
<< ", entityId=" << entityId;
}
void LtsDialog::triggerTopicLock()
{
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START"
<< " !!trigger!!";
tryLockTopic();
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END";
}
void LtsDialog::translate(const QString& title)
{
bool isAlreadyUnchangeable = unchangeable();
if (!isAlreadyUnchangeable)
setUnchangeable(true);
setWindowTitle(title);
if (!isAlreadyUnchangeable)
setUnchangeable(false);
{
bool isNowAlreadyUnchangeable = unchangeable();
QPushButton* b = m_buttonBox->getButton(DialogButton::ReadOnly);
if (b)
{
connect(b, &QPushButton::clicked, this, &LtsDialog::onReadOnlyButtonClicked, Qt::UniqueConnection);
b->setVisible(isNowAlreadyUnchangeable && !m_topicLockedBy.isEmpty());
if (b->isVisible())
b->setToolTip(tr("Locked by: %1").arg(m_topicLockedBy));
else
b->setToolTip({});
}
}
}
void LtsDialog::slotLock(const QString& lockedBy)
{
setUnchangeable(true);
m_topicLockedBy = lockedBy;
lock();
retranslate();
}
void LtsDialog::slotUnlock()
{
setUnchangeable(false);
m_topicLockedBy.clear();
unlock();
retranslate();
}
void LtsDialog::lock()
{
setWidgetsReadonly<QLineEdit>(true);
setWidgetsReadonly<QDateTimeEdit>(true);
setWidgetsReadonly<QSpinBox>(true);
setWidgetsReadonly<QDoubleSpinBox>(true);
setWidgetsReadonly<QPlainTextEdit>(true);
setWidgetsReadonly<QTextEdit>(true);
setWidgetsDisabled<QComboBox>(true);
setWidgetsDisabled<QCheckBox>(true);
setWidgetsDisabled<QRadioButton>(true);
setWidgetsDisabled<QSlider>(true);
setWidgetsDisabled<QTableView>(true);
setWidgetsDisabled<QTableWidget>(true);
setWidgetsDisabled<QListView>(true);
setWidgetsDisabled<QListWidget>(true);
setWidgetsDisabled<QPushButton>(true);
}
void LtsDialog::unlock()
{
restoreReadonly<QLineEdit>();
restoreReadonly<QDateTimeEdit>();
restoreReadonly<QSpinBox>();
restoreReadonly<QDoubleSpinBox>();
restoreReadonly<QPlainTextEdit>();
restoreReadonly<QTextEdit>();
restoreEnabled<QComboBox>();
restoreEnabled<QCheckBox>();
restoreEnabled<QRadioButton>();
restoreEnabled<QSlider>();
restoreEnabled<QTableView>();
restoreEnabled<QTableWidget>();
restoreEnabled<QListView>();
restoreEnabled<QListWidget>();
}
void LtsDialog::slotChangesMade()
{
if (m_unchangeableDialog)
return;
m_changesMade = true;
updateWindowTitle();
m_buttonBox->getButton(DialogButton::Ok)->setEnabled(true);
m_buttonBox->getButton(DialogButton::Apply)->setEnabled(true);
emit signalChangesMade();
}
void LtsDialog::resetChanges()
{
m_changesMade = false;
updateWindowTitle();
m_buttonBox->getButton(DialogButton::Ok)->setEnabled(false);
m_buttonBox->getButton(DialogButton::Apply)->setEnabled(false);
emit signalChangesReset();
}
bool LtsDialog::_apply()
{
if (m_uiRequirements->checkRequirements(this) && apply())
{
resetChanges();
return true;
}
return false;
}
Button LtsDialog::askApplyDiscardCancel()
{
return LtsMessageDialog::askApplyDiscardCancel(this);
}
void LtsDialog::slotApply()
{
_apply();
}
void LtsDialog::slotOkay()
{
if (_apply())
_close();
}
void LtsDialog::slotHide()
{
_hide();
}
void LtsDialog::slotClose()
{
if ((m_changesMade) && (!m_unchangeableDialog))
{
switch (askApplyDiscardCancel())
{
case Button::Apply:
slotOkay();
break;
case Button::Discard:
_discard();
break;
default:
break;
}
}
else
{
_close();
}
}
void LtsDialog::onReadOnlyButtonClicked()
{
if (m_topicLockedBy.isEmpty())
return;
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Locked by: %1").arg(m_topicLockedBy));
}
void LtsDialog::closeRequest()
{
slotClose();
}
void LtsDialog::_hide()
{
if (m_dialogHelper != nullptr)
{
emit signalHide(m_dialogHelper);
}
}
void LtsDialog::_close()
{
resetChanges();
aboutToClose();
if (m_dialogHelper != nullptr)
m_dialogHelper->close();
}
void LtsDialog::_discard()
{
dialogCanceled();
_close();
}
} // namespace LtsWidgets
#include "lts_dialog.moc"