#include "WindowAppUiScene.h"
#include "WindowAppUiFrame.h"
#include "UiManager.h"
#include "WindowRuntime.h"
#include "selectwidget.h"
#include "VPControls.h"
#include "WindowAppItemRefLine.h"
VControlObject* WindowAppUiScene::m_pCurrentObject = nullptr;
WindowAppUiScene::WindowAppUiScene(QGraphicsView* parent /*= nullptr*/)
: QGraphicsScene(parent)
, m_pUiFrame(nullptr)
, m_pUiView((WindowAppUiView*)parent)
{
// For Test
//QLineEdit* newButton = new QLineEdit(nullptr);
//this->addWidget(newButton);
//newButton->resize(130, 20);
//newButton->move(100, 100);
// 为参考线管理器绑定指针
m_RefLineManager.bindScene(this);
// 为等宽线管理器绑定指针
m_IsoLineManager.bindScene(this);
}
///
/// 清空所有控件焦点
///
void WindowAppUiScene::clearFocus()
{
//将原有焦点窗体全部设置成无焦点
for (SelectWidget* w : m_SelectControls)
{
w->setDrawPoint(false);
}
}
///
/// 当控件被按下时
///
///
void WindowAppUiScene::widgetPressed(QWidget* widget)
{
//清空所有控件的焦点
clearFocus();
// qDebug() << "WindowAppUiScene::widgetPressed";
//设置当前按下的控件选中效果
for (SelectWidget* w : m_SelectControls)
{
if (w->getWidget() == widget)
{
// 设置选中效果
w->setDrawPoint(true);
m_pCurrentWidget = widget;
//设置自动加载该控件的所有属性
// m_pOwner->ui.objectController->setObject(nullptr);
m_pUiFrame->ui.objectController->setObject(widget);
// 获取控件最新的尺寸和位置信息
OBJECT_SYNC_PROPERTY syncInfo;
syncInfo.type = OBJECT_SYNC_TYPE::SYNC_GEOMETRY;
syncInfo.value = widget->geometry();
// 更新到属性表中
m_pUiFrame->ui.objectController->syncToObject(widget, syncInfo);
// 2022-5-22 设置当前用户选择的控件信息,用于后续绑定需要
m_pCurrentObject = m_pUiFrame->ui.objectController->vobject();
// 2022-10-21,按下时记录控件当前位置,用于比较鼠标抬起后是否移动
m_oldPos = m_pCurrentWidget->pos();
// 2022-10-21,按下时记录控件当前尺寸,用于比较鼠标抬起后是否变更了尺寸
m_oldGeometry = m_pCurrentWidget->geometry();
break;
}
}
}
///
/// 当控件释放时
///
///
void WindowAppUiScene::widgetRelease(QWidget* widget)
{
// 首先进行控件的自动对齐
// this->autoAlignToGrid(widget);
// 释放控件时,无论如何都清空所有的参考线
m_RefLineManager.clear();
// 同时清空所有的等宽线
m_IsoLineManager.clear();
//设置自动加载该控件的所有属性
// m_pOwner->ui.objectController->setObject(nullptr);
m_pUiFrame->ui.objectController->setObject(widget);
// 获取控件最新的尺寸和位置信息
OBJECT_SYNC_PROPERTY syncInfo;
syncInfo.type = OBJECT_SYNC_TYPE::SYNC_GEOMETRY;
syncInfo.value = widget->geometry();
// 更新到属性表中
m_pUiFrame->ui.objectController->syncToObject(widget, syncInfo);
// 2022-10-21,抬起时记录控件当前位置,用于比较鼠标抬起后是否移动
this->checkCurrentControlMove();
// 2022-10-21,抬起时记录控件当前尺寸,用于比较鼠标抬起后是否缩放
this->checkCurrentControlZoom();
}
///
/// 当控件删除时
///
///
void WindowAppUiScene::widgetDelete(QWidget* widget)
{
// 从数据结构中删除关联
g_pUiManager->deleteControl(widget);
// 从界面中删除控件
for (int i = 0; i < m_SelectControls.count(); i++)
{
if (m_SelectControls.at(i)->getWidget() == widget)
{
// 需要清空SelectWidget自身,否则会造成崩溃问题
m_SelectControls.at(i)->deleteLater();
m_SelectControls.removeAt(i);
break;
}
}
// 2021-12-26增加,删除本控件相关的属性表数据结构
m_pUiFrame->ui.objectController->delObject(widget);
// 2021-12-28增加,在Runtime中删除控件相关数据结构
g_pRuntime->releaseControl(widget);
}
///
/// 当控件移动时
///
///
void WindowAppUiScene::widgetMove(QWidget* widget)
{
// qDebug() << "WindowAppUiScene::widgetMove - " << widget;
// 检查控件参考线
this->checkRefLine(widget);
}
///
/// 2022-9-16,当控件拉伸时(用于绘制等宽线)
///
///
///
void WindowAppUiScene::widgetStretch(QWidget* widget, STRETCH_DIRECTION dir)
{
// qDebug() << "WindowAppUiScene::widgetStretch - " << widget <<" Direction:" << (int)dir;
this->checkIsoLine(widget, dir);
}
///
/// 2022-8-14 控件移动时,处理参考线相关
///
///
void WindowAppUiScene::checkRefLine(QWidget* widget)
{
// 遍历所有的控件,然后通过RefLineManager处理所有控件之间的参考线
for (SelectWidget* w : m_SelectControls)
{
// 排除自身
if (widget == w->m_pWidget)
{
continue;
}
// 当前选中控件、和UI界面中的其他控件
m_RefLineManager.check(widget, w->m_pWidget);
}
}
///
/// 2022-9-16 控件被拉伸时,进行等宽线相关的实时计算
///
///
void WindowAppUiScene::checkIsoLine(QWidget* widget, STRETCH_DIRECTION dir)
{
QList dstWidgets;
// 遍历所有的控件,选出需要及逆行等宽线判断的其他所有控件
for (SelectWidget* w : m_SelectControls)
{
// 排除自身
if (widget != w->m_pWidget)
{
dstWidgets.push_back(w->m_pWidget);
}
}
// 开始处理等宽线相关事宜
m_IsoLineManager.check(widget, dstWidgets, dir);
}
///
/// 2022-10-22,检查当前控件是否移动
///
void WindowAppUiScene::checkCurrentControlMove()
{
// 比较鼠标抬起后是否移动
QPoint curPos = m_pCurrentWidget->pos();
// 如果移动了,则记录这次动作,用于执行Redo
if (curPos != m_oldPos)
{
UiControlMoveCommand* controlMoveCommand = new UiControlMoveCommand(
this,
m_pCurrentObject->m_strID,
m_oldPos,
curPos
);
this->m_CommandManager.executeCommand(controlMoveCommand, true);
m_oldPos = curPos;
}
}
///
/// 2022-10-22,检查当前控件是否缩放
///
void WindowAppUiScene::checkCurrentControlZoom()
{
// 比较鼠标抬起后尺寸是否变化
QRect curGeometry = m_pCurrentWidget->geometry();
// 如果尺寸不同了,则记录这次动作,用于执行Redo
if (curGeometry != m_oldGeometry)
{
UiControlZoomCommand* controlZoomCommand = new UiControlZoomCommand(
this,
m_pCurrentObject->m_strID,
m_oldGeometry,
curGeometry
);
this->m_CommandManager.executeCommand(controlZoomCommand, true);
m_oldGeometry = curGeometry;
}
}
///
/// 将生成的控件选入列表中
///
///
///
///
void WindowAppUiScene::addSelection(
VControlObject* pControl,
VALUE_TYPE type,
CONTROL_PROPERTY* pProperty,
CONTROL_PROPERTY_EX* pPropertyEx /* = nullptr */
)
{
SelectWidget* select = new SelectWidget(m_pUiView);
// 绑定控件选中消息
connect(select, SIGNAL(widgetPressed(QWidget*)), this, SLOT(widgetPressed(QWidget*)));
// 绑定控件释放消息
connect(select, SIGNAL(widgetRelease(QWidget*)), this, SLOT(widgetRelease(QWidget*)));
// 绑定控件移动消息
connect(select, SIGNAL(widgetMove(QWidget*)), this, SLOT(widgetMove(QWidget*)));
// 绑定控件拉伸消息
connect(select, SIGNAL(widgetStretch(QWidget*, STRETCH_DIRECTION)), this, SLOT(widgetStretch(QWidget*, STRETCH_DIRECTION)));
//// Delete快捷键的删除消息
//connect(select, SIGNAL(widgetDelete(QWidget*)), this, SLOT(widgetDelete(QWidget*)));
select->setWidget(pControl->m_pWidget);
select->m_Type = type;
// 2022-10-6,控件ID
select->m_strID = pControl->m_strID;
// 2021-10-5增加,绑定控件属性
select->m_pProperty = pProperty;
select->m_pPropertyEx = pPropertyEx;
// this->addWidget(pControl->m_pWidget);
// 加入选择控件列表中
m_SelectControls.append(select);
// 直接选中控件,并且显示对应属性框
widgetPressed(pControl->m_pWidget);
}
/////
///// 新建自定义控件
/////
/////
/////
//VControlObject* WindowAppUiScene::newControl(
// int row,
// const QPoint& newPt,
// const QString& controlID,
// const QSize& newSize,
// CONTROL_PROPERTY* prop,
// CONTROL_PROPERTY_EX* propex
//)
//{
// // 将界面中用户选择的行数转换成对应的valueType
// VALUE_TYPE controlType = (VALUE_TYPE)(row + (int)VALUE_TYPE::Control_Base + 1);
//
// return this->newControl(controlType, newPt, controlID, newSize, prop, propex);
//}
///
/// 新建自定义控件(按类型)
///
///
///
///
///
VControlObject* WindowAppUiScene::newControl(
VALUE_TYPE controlType,
const QPoint& newPt,
const QString& controlID,
const QSize& newSize,
CONTROL_PROPERTY* prop /*= nullptr*/,
CONTROL_PROPERTY_EX* propex /*= nullptr */
)
{
VControlObject* pNewControl = nullptr;
switch (controlType)
{
case VALUE_TYPE::Control_Label:
{
pNewControl = new VLabel(nullptr, newPt, newSize, prop);
}
break;
case VALUE_TYPE::Control_Button:
{
pNewControl = new VButton(nullptr, newPt, newSize, prop);
}
break;
case VALUE_TYPE::Control_CheckBox:
{
pNewControl = new VCheckBox(nullptr, newPt, newSize, prop);
// 绑定CheckBox变动信号
connect(pNewControl->m_pWidget, SIGNAL(stateChanged(int)), this, SLOT(onVCheckChanged(int)));
}
break;
case VALUE_TYPE::Control_RadioBox:
{
pNewControl = new VRadioBox(nullptr, newPt, newSize, prop);
// 绑定RadioBox变动信号
connect(pNewControl->m_pWidget, SIGNAL(toggled(bool)), this, SLOT(onVRadioChanged(bool)));
}
break;
case VALUE_TYPE::Control_Groupbox:
{
pNewControl = new VGroupBox(nullptr, newPt, newSize, prop);
}
break;
case VALUE_TYPE::Control_Image:
{
pNewControl = new VImageControl(nullptr, newPt, newSize, prop, propex);
// 2022-9-11 为刷新链接绑定默认值(系统的执行次数)
pNewControl->bindDefaultRefreshDataLink();
//pNewControl->m_pWidget = new HWndUnit(nullptr);
//pNewControl->m_pWidget->resize(DEFAULT_IMAGE_SIZE);
//pNewControl->m_pWidget->move(newPt);
}
break;
case VALUE_TYPE::Control_LineEdit:
{
pNewControl = new VLineEdit(nullptr, newPt, newSize, prop);
//pNewControl->m_pWidget = new QLineEdit(nullptr);
//pNewControl->m_pWidget->resize(DEFAULT_EDIT_SIZE);
//pNewControl->m_pWidget->move(newPt);
// 注册文字变更消息用于同步
connect(pNewControl->m_pWidget, SIGNAL(textChanged(QString)), this, SLOT(onVEditChanged(QString)));
}
break;
case VALUE_TYPE::Control_Listbox:
{
pNewControl = new VListBox(nullptr, newPt, newSize, prop);
// 绑定ListBox变动信号
connect(pNewControl->m_pWidget, SIGNAL(currentRowChanged(int)), this, SLOT(onVListChanged(int)));
}
break;
case VALUE_TYPE::Control_ComboBox:
{
pNewControl = new VComboBox(nullptr, newPt, newSize, prop);
// 绑定ComboBox变动信号
connect(pNewControl->m_pWidget, SIGNAL(currentIndexChanged(int)), this, SLOT(onVComboChanged(int)));
}
break;
case VALUE_TYPE::Control_Value:
{
pNewControl = new ValueControl(nullptr, newPt, newSize, prop);
// 注册文字变更消息用于同步至Value
connect(pNewControl->m_pWidget, SIGNAL(textChanged(QString)), this, SLOT(onValueControlChanged(QString)));
// 2022-9-11 Value控件需要绑定默认的DataLink
pNewControl->bindDefaultDataLink();
}
break;
case VALUE_TYPE::Control_PieChart:
{
pNewControl = new VPieChart(nullptr, newPt, newSize, prop, propex);
// 2022-9-11 为刷新链接绑定默认值(系统的执行次数)
pNewControl->bindDefaultRefreshDataLink();
}
break;
case VALUE_TYPE::Control_CustomPlot:
{
pNewControl = new VCustomPlot(nullptr, newPt, newSize, prop, propex);
// 2022-9-11 为刷新链接绑定默认值(系统的执行次数)
pNewControl->bindDefaultRefreshDataLink();
}
break;
case VALUE_TYPE::Control_Table:
{
pNewControl = new VTableControl(nullptr, newPt, newSize, prop, propex);
}
break;
case VALUE_TYPE::Control_Result:
{
pNewControl = new VResult(nullptr, newPt, newSize, prop);
// 注册文字变更消息用于同步至Value
connect(pNewControl->m_pWidget, SIGNAL(textChanged(QString)), this, SLOT(onResultControlChanged(QString)));
// 2022-9-11 Value控件需要绑定默认的DataLink
pNewControl->bindDefaultDataLink();
}
break;
default:
qWarning() << "[UI] WindowAppUiScene::newControl - invalid control type:" << static_cast(controlType);
return nullptr;
}
// 创建失败,应该不会发生
if (pNewControl == nullptr)
{
qWarning() << "[UI] WindowAppUiScene::newControl - Create control failed, type " << static_cast(controlType);
return nullptr;
}
// 2022-8-10,将控件的位置进行自动对齐
// this->autoAlignToGrid(pNewControl->m_pWidget);
// 将控件加入到界面中
// Scene无法添加有父窗体的控件,只能先设置为nulltpr了,如果这里不设置为nullptr,前面建立的时候设置为nullptr的话,带来的问题更多
// pNewControl->m_pWidget->setParent(nullptr);
// 保存ProxyWidget指针,方便后续操作控件
pNewControl->m_pProxyWidget = this->addWidget(pNewControl->m_pWidget);
// 2022-10-6,如果没有为控件指定ID的话,则为本控件生成新的唯一UUID
if (controlID.isEmpty())
{
pNewControl->m_strID = QUuid::createUuid().toString();
}
// 否则就直接把当前ID赋值
else
{
pNewControl->m_strID = controlID;
}
if (pNewControl->isComplexControl())
{
// 将控件加入到选中列表中
addSelection(
pNewControl,
controlType,
&pNewControl->m_Property,
&pNewControl->m_PropertyEx
);
}
else
{
// 将控件加入到选中列表中
addSelection(
pNewControl,
controlType,
&pNewControl->m_Property,
nullptr
);
}
// 2022-10-7,将向UI Manager注册本控件从WindowAppUiView中移到了这里
g_pUiManager->regiterNewControl(pNewControl, this->m_pUiView);
// 2022-2-4 返回新控件指针
return pNewControl;
}
///
/// 获取本界面中的所有控件
///
///
QList WindowAppUiScene::getAllControls()
{
return this->m_SelectControls;
}
///
/// 刷新指定控件(用于更新属性表)
///
///
void WindowAppUiScene::refreshControl(QWidget* pControl)
{
// widgetRelease(pControl);
// 2022-9-15 只刷新当前控件的属性表,防止Runtime同步到UI时,属性表乱跳的bug
if (pControl == m_pCurrentWidget)
{
m_pUiFrame->ui.objectController->setObject(pControl);
}
}
///
/// 刷新指定控件的选中效果(用于适配属性表更新后的选中效果更新)
///
///
void WindowAppUiScene::refreshDrawPoint(QWidget* pControl)
{
//清空所有控件的焦点
clearFocus();
//设置当前按下的控件有焦点
for (SelectWidget* w : m_SelectControls)
{
if (w->getWidget() == pControl)
{
// 需要按照最新的控件形状信息重新设置选中效果
w->setWidget(pControl);
// 设置选中效果
w->setDrawPoint(true);
m_pCurrentWidget = pControl;
break;
}
}
}
///
/// 2022-10-21,获取指定ID号的控件SelectWidget
///
///
///
SelectWidget* WindowAppUiScene::getSelectWidgetByID(const QString& strID)
{
for (SelectWidget* w : m_SelectControls)
{
if (w->m_strID == strID)
{
return w;
}
}
return nullptr;
}
///
/// 排序到最前
///
void WindowAppUiScene::zorderTopCurrentControl()
{
if (getCurrentControl() == nullptr || getCurrentControl()->getItem() == nullptr)
{
return;
}
int nSize = getAllControls().size();
getCurrentControl()->getItem()->setZValue(nSize + 1);
}
///
/// 排序到最底
///
void WindowAppUiScene::zorderBottomCurrentControl()
{
if (getCurrentControl() == nullptr || getCurrentControl()->getItem() == nullptr)
{
return;
}
getCurrentControl()->getItem()->setZValue(0);
}
///
/// 排序到前一个
///
void WindowAppUiScene::zorderUpCurrentControl()
{
if (getCurrentControl() == nullptr || getCurrentControl()->getItem() == nullptr)
{
return;
}
qreal zValue = getCurrentControl()->getItem()->zValue();
getCurrentControl()->getItem()->setZValue(zValue + 1);
}
///
/// 排序到后一个
///
void WindowAppUiScene::zorderDownCurrentControl()
{
if (getCurrentControl() == nullptr || getCurrentControl()->getItem() == nullptr)
{
return;
}
qreal zValue = getCurrentControl()->getItem()->zValue();
getCurrentControl()->getItem()->setZValue(zValue - 1);
}
///
/// 删除当前控件
///
void WindowAppUiScene::deleteCurrentControl()
{
qDebug() << "WindowAppUiScene::deleteCurrentControl";
if (m_pCurrentWidget != nullptr)
{
// 删除控件
widgetDelete(m_pCurrentWidget);
// 释放控件
m_pCurrentWidget->deleteLater();
m_pCurrentWidget = nullptr;
this->m_pCurrentObject = nullptr;
m_pUiFrame->ui.objectController->setObject(nullptr);
}
}
///
/// 2022-10-7 删除指定ID的控件(用于在Undo体系中)
///
///
void WindowAppUiScene::deleteControlByID(const QString& strID)
{
// 首先根据ID号找到这个控件
QWidget* delWidget = nullptr;
for (SelectWidget* w : m_SelectControls)
{
if (w->m_strID == strID)
{
delWidget = w->m_pWidget;
break;
}
}
bool bIsCurrent = false;
if (delWidget != nullptr)
{
if (delWidget == m_pCurrentWidget)
{
bIsCurrent = true;
}
// 删除控件
widgetDelete(delWidget);
// 释放控件
delWidget->deleteLater();
delWidget = nullptr;
// 如果删掉的控件正好是当前控件,那么需要清空一下当前控件的信息
if (bIsCurrent)
{
this->m_pCurrentObject = nullptr;
this->m_pCurrentWidget = nullptr;
m_pUiFrame->ui.objectController->setObject(nullptr);
}
}
}
///
/// 序列化支持
///
///
///
///
bool WindowAppUiScene::serialized(QDataStream& dataStream, bool in /*= true*/)
{
// 输入
if (in)
{
// 读入控件总数量
int nControlCount = 0;
dataStream >> nControlCount;
// 读取所有控件信息并且添加对应的控件
for (int i = 0; i < nControlCount; i++)
{
// 坐标
QPoint pt;
dataStream >> pt;
// 尺寸
QSize size;
dataStream >> size;
// 类型
VALUE_TYPE type;
dataStream >> type;
// 2022-10-6,控件ID
QString strID;
dataStream >> strID;
// Property;
CONTROL_PROPERTY property;
dataStream >> property;
// PropertyEx;
int ex = 0;
dataStream >> ex;
// 复杂控件
if (ex != 0)
{
CONTROL_PROPERTY_EX propertyex;
dataStream >> propertyex;
// 生成新的控件
VControlObject* pNewControl = this->newControl(type, pt, strID, size , &property, &propertyex);
// 还原复杂控件中的DataLink关系
g_pUiManager->restoreDataLinks(propertyex, pNewControl);
}
// 简单控件
else
{
// 生成新的控件
VControlObject* pNewControl = this->newControl(type, pt, strID, size, &property, nullptr);
// 还原简单控件中的DataLink关系
g_pUiManager->restoreDataLinks(property, pNewControl);
}
}
}
// 输出
else
{
// 写入窗体名称
dataStream << m_pUiView->m_strPageName;
// 写入控件总数量
dataStream << this->m_SelectControls.size();
// 遍历本页面所有控件
for (SelectWidget* pControl : this->m_SelectControls)
{
// ----- 写入控件基础信息
// 坐标
dataStream << pControl->m_pWidget->pos();
// 尺寸
dataStream << pControl->m_pWidget->size();
// 类型
dataStream << pControl->m_Type;
// 2022-10-6,控件ID
dataStream << pControl->m_strID;
// ----- 存储Property信息
dataStream << *pControl->m_pProperty;
// ----- 存储PropertyEx信息
if (pControl->m_pPropertyEx != nullptr)
{
dataStream << 1;
dataStream << *pControl->m_pPropertyEx;
}
else
{
dataStream << 0;
}
}
}
return true;
}
//=====================================================================
//
// 子控件同步相关
//
//=====================================================================
///
/// 当Edit控件内容变更时
///
///
void WindowAppUiScene::onVEditChanged(const QString& strText)
{
vDebug() << strText;
VLineEdit* pSender = qobject_cast(sender());
// 向Dll中的Tool同步
g_pUiManager->syncToDll(pSender, UI_SYNC_MSG::EDIT_TEXT_CHANGED);
// 向Runtime同步
g_pUiManager->syncToRuntime(pSender->m_pWidget, UI_SYNC_MSG::EDIT_TEXT_CHANGED);
// 2022-9-14 如果属性表显示的是当前控件,才需要更新,否则不需要更新
if (m_pCurrentWidget == pSender)
{
// 2022-2-14增加,还需要向属性表同步
OBJECT_SYNC_PROPERTY syncInfo;
syncInfo.type = OBJECT_SYNC_TYPE::SYNC_TITLE;
syncInfo.value = strText;
m_pUiFrame->ui.objectController->syncToObject(pSender, syncInfo);
}
}
///
/// ComboBox变更消息
///
///
void WindowAppUiScene::onVComboChanged(const int nIndex)
{
Q_UNUSED(nIndex);
vDebug() << nIndex;
VComboBox* pSender = qobject_cast(sender());
// 向Dll中的Tool同步
g_pUiManager->syncToDll(pSender, UI_SYNC_MSG::COMBO_SEL_CHANGED);
// 向Runtime同步
g_pUiManager->syncToRuntime(pSender->m_pWidget, UI_SYNC_MSG::COMBO_SEL_CHANGED);
}
///
/// ListBox变更消息
///
///
void WindowAppUiScene::onVListChanged(const int nRow)
{
Q_UNUSED(nRow);
vDebug() << nRow;
VListBox* pSender = qobject_cast(sender());
// 向Dll中的Tool同步
g_pUiManager->syncToDll(pSender, UI_SYNC_MSG::LIST_SEL_CHANGED);
// 向Runtime同步
g_pUiManager->syncToRuntime(pSender->m_pWidget, UI_SYNC_MSG::LIST_SEL_CHANGED);
}
///
/// RadioBox变更消息
///
///
void WindowAppUiScene::onVRadioChanged(bool checked)
{
Q_UNUSED(checked);
}
///
/// CheckBox变更消息
///
///
void WindowAppUiScene::onVCheckChanged(int state)
{
Q_UNUSED(state);
}
///
/// 当ValueControl内容变更时
///
///
void WindowAppUiScene::onValueControlChanged(const QString& strText)
{
// Q_UNUSED(strText);
ValueControl* pSender = qobject_cast(sender());
vDebug() << pSender << " - ChangedTo:" << pSender->getText();
// 向Value同步
g_pUiManager->syncToValue(pSender);
// 向Runtime同步
g_pUiManager->syncToRuntime(pSender->m_pWidget, UI_SYNC_MSG::VALUE_CHANGED);
// 2022-9-14 如果属性表显示的是当前控件,才需要更新,否则不需要更新
if (m_pCurrentWidget == pSender)
{
// 2022-9-8 增加,还需要向属性表同步
OBJECT_SYNC_PROPERTY syncInfo;
syncInfo.type = OBJECT_SYNC_TYPE::SYNC_TITLE;
syncInfo.value = strText;
m_pUiFrame->ui.objectController->syncToObject(pSender, syncInfo);
}
}
///
/// 当ValueControl内容变更时
///
///
void WindowAppUiScene::onResultControlChanged(const QString& strText)
{
// Q_UNUSED(strText);
VResult* pSender = qobject_cast(sender());
vDebug() << pSender << " - ChangedTo:" << pSender->getText();
// 向Value同步
//g_pUiManager->syncToValue(pSender);
// 向Runtime同步
g_pUiManager->syncToRuntime(pSender->m_pWidget, UI_SYNC_MSG::VALUE_CHANGED);
// 2022-9-14 如果属性表显示的是当前控件,才需要更新,否则不需要更新
if (m_pCurrentWidget == pSender)
{
// 2022-9-8 增加,还需要向属性表同步
OBJECT_SYNC_PROPERTY syncInfo;
syncInfo.type = OBJECT_SYNC_TYPE::SYNC_TITLE;
syncInfo.value = strText;
m_pUiFrame->ui.objectController->syncToObject(pSender, syncInfo);
}
}
///
/// 检查所有的属性和扩展属性是否有效
///
///
bool WindowAppUiScene::checkAllProperties()
{
for (SelectWidget* sw : m_SelectControls)
{
//// Property 中的数据连接(仅简单控件需要检查)
//if (!ValueControl::isComplexControl(sw->m_Type))
//{
// const CONTROL_PROPERTY* prop = sw->m_pProperty;
// if (prop == nullptr)
// {
// continue;
// }
// // 检查数据连接
// const DataLink& dl = prop->m_DataLink;
// if (dl.bForce && !dl.isValid())
// {
// CRITICAL_MESSAGE("Property datalink[" + dl.title + \
// "] invalid in page[" + this->m_strPageName + "].");
// return false;
// }
//}
// PropertyEx 中的数据链接(仅复杂控件需要检查)
if (ValueControl::isComplexControl(sw->m_Type))
{
// 检查本页面中的属性设置是否正确(数据链接仅检查必填项)
const CONTROL_PROPERTY_EX* px = sw->m_pPropertyEx;
if (px == nullptr)
{
continue;
}
// 检查索引链接
if (px->m_refreshLink.bForce && !px->m_refreshLink.isValid())
{
CRITICAL_MESSAGE("Property refresh datalink[" + px->m_refreshLink.title + \
"] invalid in page[" + this->m_strPageName + "].");
return false;
}
// 检查主数据链接
for (const DataLink& dataLink : px->m_mainDataLinks)
{
if (dataLink.bForce && !dataLink.isValid())
{
CRITICAL_MESSAGE("Property main datalink[" + dataLink.title + \
"] invalid in page[" + this->m_strPageName + "].");
return false;
}
}
// 检查子分组中的数据链接
for (int i = 0; i < px->m_groups.size(); i++)
{
const PROPERTY_EX_SUBGROUPS& subGroups = px->m_groups[i].subGroups;
for (int j = 0; j < subGroups.size(); j++)
{
for (const DataLink& dataLink : subGroups[j].dataLinks)
{
if (dataLink.bForce && !dataLink.isValid())
{
CRITICAL_MESSAGE("Property datalink[" + dataLink.title + \
"] invalid in page[" + this->m_strPageName + "].");
return false;
}
}
}
}
}
}
return true;
}