Files
qt6-migration-pipeline/Lts/Common/LtsWidgets/lts_dialog.h
T

474 lines
9.9 KiB
C++
Executable File

#pragma once
#include "lts_base.h"
#include "lts_widgets_export.h"
#include "ui_requirement.h"
#include "lts_dialog_button_box.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <QPushButton>
#include <QLineEdit>
#include <QComboBox>
#include <QCheckBox>
#include <QSpinBox>
#include <QDateTimeEdit>
#include <QSlider>
#include <QPlainTextEdit>
#include <QTextEdit>
#include <QWidget>
#include <QRadioButton>
#include <QPointer>
#include <QDebug>
namespace LtsWidgets
{
class TopicInfo
{
public:
int entityId() const { return m_entityId; }
const QString &topicName() const { return m_topicName; }
bool isLocked() const { return m_locked; }
bool isValid() const { return m_valid; }
void setEntity(int entityId) { m_entityId = entityId; }
void setTopicName(const QString &topicName) { m_topicName = topicName; }
void setLocked(bool locked = true) { m_locked = locked; }
void setValid() { m_valid = true; }
private:
QString m_topicName;
int m_entityId{0};
bool m_locked{false};
bool m_valid{false};
};
class LtsBaseLayoutWidget;
class LtsDialogHelper;
class LtsProgressDialogHelper;
class LtsDialogButtonBox;
class LtsToolBarArea;
class OverlayContainer;
enum class ButtonCombination
{
OkApplyCancel,
OkCancel,
CloseOnly,
SeamlessDialog,
};
class LTSWIDGETS_EXPORT LtsDialog : public QWidget
{
Q_OBJECT
Q_PROPERTY(bool unchangeable READ unchangeable WRITE setUnchangeable)
public:
static int s_object_count;
explicit LtsDialog(QWidget *parent = nullptr, ButtonCombination buttonCombination = ButtonCombination::CloseOnly, bool closeable = true);
~LtsDialog();
LtsDialogHelper *getHelper();
bool hasUnsavedChanges() const { return m_changesMade || m_currentlyBlocking; }
virtual void retranslate() = 0;
void closeRequest();
void setUnchangeable(bool unchangeable = true);
bool unchangeable() const { return m_unchangeableDialog; }
bool addDialog(LtsDialog *dialog, const QString &menuGroup, const QString &identifier, const LayoutArea &layoutArea = LayoutArea::eDialogTab, bool setClosable = true, bool focusNewTab = true);
Q_DECL_DEPRECATED bool addDialogFixed(LtsDialog *dialog, const char *menuGroupUntranslated, const QString &identifier, const LayoutArea &layoutArea = LayoutArea::eDialogTab, bool setClosable = true, bool focusNewTab = true);
bool focusDialog(const QString &menuGroup, const QString &identifier, const LayoutArea &layoutArea);
bool amIFocused() const;
void setBaseLayoutWidget(LtsBaseLayoutWidget *baseLayoutWidget);
void __unchange__() { resetChanges(); }
void setClosable(bool closable) { m_isClosable = closable; }
bool isClosable() const { return m_isClosable; }
virtual void aboutToClose() {}
void setMenuGroup(const QString &menuGroup) { m_menuGroup = menuGroup; }
const QString &menuGroup() const { return m_menuGroup; }
void setIdentifier(const QString &identifier);
virtual void tableColumnOrganiserSetting(){};
const QString &identifier() const { return m_identifier; }
void setOverlay(QWidget *widget);
void unsetOverlay();
static inline void setMinWidthForWidgetHelper(QWidget *w)
{
int width = w->sizeHint().width();
w->setMinimumWidth(width);
}
QString windowTitle() const
{
return m_title;
}
void tryLockTopicNew();
virtual void tryLockTopicNew (const QString &topicName, int entityId = -1);
void triggerTopicLock();
void setOnlineHelpFilename(const QString &fileName);
void setCurrentlyBlocking(bool currentlyBlocking = true) { m_currentlyBlocking = currentlyBlocking; }
signals:
void startMainSelect(LtsWidgets::LayoutArea);
void endMainSelect(LtsWidgets::LayoutArea);
void signalChangesMade();
void signalHide(QObject *object);
void signalChangesReset();
void signalFocused();
void visibilityChanged(bool visible);
void signalLockTopic(const LtsWidgets::TopicInfo &topicInfo);
void signalShowOnlineHelp(const QString &fileName);
protected:
void translate(const QString &title);
template <typename T>
void translate(T *ui, const QString &title)
{
translate(title);
if (ui)
ui->retranslateUi(this);
m_uiRequirements->retranslate();
}
void hideEvent(QHideEvent *event) override
{
QWidget::hideEvent(event);
emit visibilityChanged(false);
}
template <typename T>
void translate(T *ui, const QString &custom, bool isNew, const QString &title)
{
QString newTitle;
if (!isNew)
{
if (unchangeable())
{
if (custom.isEmpty())
newTitle = (tr("Show %1").arg(title));
else
newTitle = (tr("Show %1: %2").arg(title, custom));
}
else
{
if (custom.isEmpty())
newTitle = (tr("Edit %1").arg(title));
else
newTitle = (tr("Edit %1: %2").arg(title, custom));
tryLockTopicNew();
}
}
else
{
newTitle = (tr("New %1").arg(title));
m_buttonBox->getButton(LtsWidgets::DialogButton::Apply)->hide();
m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->setText(tr("Create"));
}
translate(ui, newTitle);
}
template <typename T>
void translate(T* ui, const QString &customUniqueTopicName, int topicId, const QString &custom, const QString &title)
{
Q_UNUSED(customUniqueTopicName);
initTopicLockHandler(customUniqueTopicName, topicId);
translate(ui, custom ,
(topicId < 1 ),
title);
}
template <typename T, typename S>
void translate(T *ui, const S &data, const QString &custom, const QString &title)
{
translate(ui, QString::fromUtf8(typeid(data).name()), data.id(), custom , title);
}
template <typename T, typename S>
void translate(T *ui, const S &data, const QString &title)
{
translate(ui, data, QString::fromStdString(data.name()), title);
}
virtual void dialogCanceled() {}
LtsBaseLayoutWidget* baseLayoutWidget();
void setNoTopicLock() { m_noLockTopic = true; }
private:
friend class LtsDialogHelper;
bool m_changesMade;
bool m_currentlyBlocking { false };
bool m_firstShow;
QPointer<LtsBaseLayoutWidget> m_baseLayoutWidget;
bool m_isClosable;
TopicInfo m_topicInfo;
public:
QString m_topicLockedBy;
private:
bool m_noLockTopic;
bool m_unchangeableDialog;
QPointer<LtsDialogHelper> m_dialogHelper;
QString m_title;
QString m_onlineHelpFileName;
QString m_menuGroup;
QString m_identifier;
QPointer<OverlayContainer> m_overlayContainer;
QPointer<QWidget> m_overlayWidget;
bool _apply();
void _close();
void _discard();
void _hide();
void resetChanges();
void addDebugMenuButton();
void tryLockTopic();
void initTopicLockHandler(const QString &topicName, int entityId);
void setWindowTitle(const QString &title);
void updateWindowTitle();
void addConnections(QWidget *widget);
template <typename WidgetType, typename SignalFunc>
bool addChangesMadeSignal(QWidget *widget, SignalFunc signal)
{
WidgetType *concreteWidget = qobject_cast<WidgetType *>(widget);
if (!concreteWidget)
return false;
connect(concreteWidget, signal, this, &LtsDialog::slotChangesMade);
return true;
}
template <typename WidgetType>
void setWidgetsReadonly(bool readonly)
{
const auto children = findChildren<WidgetType *>();
for (WidgetType *widget : children )
{
widget->setProperty("lastReadOnlyState", widget->isReadOnly());
widget->setReadOnly(readonly);
}
}
template <typename WidgetType>
void setWidgetsDisabled(bool disabled)
{
const auto children = findChildren<WidgetType *>();
for (WidgetType *widget : children)
{
widget->setProperty("lastEnabledState", widget->isEnabled());
widget->setEnabled(!disabled);
}
}
template <typename WidgetType>
void restoreReadonly()
{
const auto children = findChildren<WidgetType *>();
for (WidgetType *widget : children)
{
QVariant lastState = widget->property("lastReadOnlyState");
if (lastState.isValid() && !lastState.isNull() && lastState.canConvert(QMetaType::Bool))
widget->setReadOnly(lastState.toBool());
}
}
template <typename WidgetType>
void restoreEnabled()
{
const auto children = findChildren<WidgetType *>();
for (WidgetType *widget : children)
{
QVariant lastState = widget->property("lastEnabledState");
if (lastState.isValid() && !lastState.isNull() && lastState.canConvert(QMetaType::Bool))
widget->setEnabled(lastState.toBool());
}
}
public slots:
void slotChangesMade();
void slotHide();
void slotLock(const QString &lockedBy);
void slotUnlock();
private slots:
void slotApply();
void slotOkay();
void slotClose();
void onReadOnlyButtonClicked();
protected:
virtual void lock();
virtual void unlock();
virtual bool apply() { return true; }
void showEvent(QShowEvent *event) override;
Button askApplyDiscardCancel();
LtsDialogButtonBox *m_buttonBox;
UiRequirementList *m_uiRequirements;
NGL::INGLLogger &m_logger;
};
template<typename T>
T *initDialog(T *dialog)
{
if (!dialog->init())
{
dialog->deleteLater();
return nullptr;
}
return dialog;
}
template<typename T, typename ... F>
T *initDialog(T *dialog, F&&... f)
{
if (!dialog->init(std::forward<F>(f)...))
{
dialog->deleteLater();
return nullptr;
}
return dialog;
}
template<typename T, typename ... F>
T *createThrowableDialog(F&&... f)
{
T *dlg = nullptr;
try
{
dlg = new T(std::forward<F>(f)...);
}
catch (const char *s)
{
fprintf(stderr, "Dialog could not be created: %s\n", s);
return nullptr;
}
catch (const QString &msg)
{
fprintf(stderr, "Dialog could not be created: %s\n", msg.toStdString().c_str());
return nullptr;
}
catch (...)
{
fprintf(stderr, "Dialog could not be created: unknown error\n");
return nullptr;
}
return dlg;
}
}