objectcontroller.cpp 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768
  1. 
  2. #include <QMetaObject>
  3. #include <QMetaProperty>
  4. #include <QVBoxLayout>
  5. #include <QScrollArea>
  6. #include <QApplication>
  7. #include <QDebug>
  8. #include "objectcontroller.h"
  9. #include "qtvariantproperty.h"
  10. #include "qtgroupboxpropertybrowser.h"
  11. #include "qttreepropertybrowser.h"
  12. #include "qtpropertybrowser.h"
  13. #include "variantfactory.h"
  14. #include "variantmanager.h"
  15. #include "vpControls/VTableControl.h"
  16. #include "vpControls/VPieChart.h"
  17. #include "vpControls/VCustomPlot.h"
  18. #include "vpControls/VImageControl.h"
  19. #include "UiManager.h"
  20. // #include "WindowAppUiView.h"
  21. #define PROPERTY_EX_MISC "杂项"
  22. QMap<QString, QString> propertyNamesMap;
  23. class ObjectControllerPrivate
  24. {
  25. // 基础属性的中英文对照表
  26. ObjectControllerPrivate()
  27. {
  28. propertyNamesMap.insert("tip", "提示");
  29. propertyNamesMap.insert("title", "文本");
  30. propertyNamesMap.insert("dataLink", "链接");
  31. propertyNamesMap.insert("textColor", "文本色");
  32. propertyNamesMap.insert("bgColor", "背景色");
  33. propertyNamesMap.insert("Red", "红");
  34. propertyNamesMap.insert("Green", "绿");
  35. propertyNamesMap.insert("Blue", "蓝");
  36. propertyNamesMap.insert("Alpha", "明度");
  37. propertyNamesMap.insert("font", "字体");
  38. propertyNamesMap.insert("enable", "启用");
  39. propertyNamesMap.insert("rowCount", "行数");
  40. propertyNamesMap.insert("colCount", "列数");
  41. propertyNamesMap.insert("borderColor", "边框色");
  42. propertyNamesMap.insert("sliceCount", "分块数");
  43. propertyNamesMap.insert("lineCount", "曲线数");
  44. propertyNamesMap.insert("objCount", "图层数");
  45. propertyNamesMap.insert("tupleCount", "文本数");
  46. propertyNamesMap.insert("displayCount", "显示数");
  47. propertyNamesMap.insert("stringCount", "字符数");
  48. propertyNamesMap.insert("geometry", "形状");
  49. propertyNamesMap.insert("interactions", "交互模式");
  50. propertyNamesMap.insert("drawingMode", "绘图模式");
  51. propertyNamesMap.insert("rangeX", "x轴范围");
  52. propertyNamesMap.insert("rangeY", "y轴范围");
  53. propertyNamesMap.insert("tickCountX", "x网格数");
  54. propertyNamesMap.insert("tickCountY", "y网格数");
  55. m_pVcontrol = nullptr;
  56. q_ptr = nullptr;
  57. m_object = nullptr;
  58. m_browser = nullptr;
  59. m_manager = nullptr;
  60. m_readOnlyManager = nullptr;
  61. }
  62. ObjectController *q_ptr;
  63. Q_DECLARE_PUBLIC(ObjectController)
  64. public:
  65. void expandAll();
  66. void collapseAll();
  67. void saveExpandedState();
  68. void restoreExpandedState();
  69. // 数值变更
  70. void slotValueChanged(QtProperty *property, const QVariant &value);
  71. //=======================================================
  72. // 辅助类型转换函数
  73. int enumToInt(const QMetaEnum &metaEnum, int enumValue) const;
  74. int intToEnum(const QMetaEnum &metaEnum, int intValue) const;
  75. int flagToInt(const QMetaEnum &metaEnum, int flagValue) const;
  76. int intToFlag(const QMetaEnum &metaEnum, int intValue) const;
  77. bool isSubValue(int value, int subValue) const;
  78. bool isPowerOf2(int value) const;
  79. // 获取属性的中文名称
  80. QString chName(const QString& enName);
  81. //=======================================================
  82. // 基础控件相关
  83. // 设置控件属性
  84. void setBasicControlProperties(const QMetaObject* metaObject);
  85. // 设置复杂控件属性
  86. void setComplexControlProperties(const QMetaObject* metaObject);
  87. // 构建新的基础属性表
  88. void buildBasicProperty(const QMetaObject* metaObject, QtProperty*& classProperty);
  89. // 更新基础属性
  90. void changeBasicProperties(QtProperty* property, const QVariant& value);
  91. // 更新基础属性表
  92. void updateBasicProperties(const QMetaObject* metaObject);
  93. // 2022-2-12 更新geometry属性
  94. // (针对geometry专门处理一下,因为这个属性比较特殊,不需要手工处理,只需要刷新一下界面)
  95. void changeGeometryProperty(const QVariant& value);
  96. // 2022-2-13 用户控件到属性表的同步
  97. void syncToPropertyTable(QObject* pControl, const OBJECT_SYNC_PROPERTY& syncInfo);
  98. // 2022-2-14 保存到同步列表中
  99. void saveToSyncProperty(OBJECT_SYNC_TYPE type, QtVariantProperty* prop);
  100. //=======================================================
  101. // 复杂控件相关
  102. // 构建控件扩展属性表
  103. void buildExtendProperty(QtProperty*& objectProperty);
  104. // 构建控件扩展属性表中的主索引部分
  105. void buildPropertyMainLinks(QtProperty*& objectProperty);
  106. // 构建控件扩展属性表中的分组部分
  107. void buildPropertyGroups(QtProperty*& objectProperty);
  108. // 构建控件扩展属性表中的子分组部分(2022-1-25,增加了分组ID)
  109. void buildPropertySubGroup(const int groupID, const PROPERTY_EX_SUBGROUP& prop, QtProperty*& subGroupRoot);
  110. // 修改控件的扩展属性
  111. void changeExtendProperties(QtProperty* property, const QVariant& value);
  112. //// 更新基础属性表
  113. //void updateBasicProperties(const QMetaObject* metaObject);
  114. // 更新扩展属性表
  115. void updateExtendProperties(QtProperty*& objectProperty);
  116. //// 动态增加新的属性项
  117. //void appendExtendPropertiesCount(const int fixCount, const QString& propertyName);
  118. //// 动态减少新的属性项
  119. //void removeExtendPropertiesCount(const int fixCount, const QString& propertyName);
  120. // 动态调整属性项
  121. void updateExtendPropertiesCount(const int newCount, const QString& propertyName);
  122. // 仅展开扩展属性项
  123. void setExtendItemsExpandOnly();
  124. //// 2022-2-7为了解决反序列化时数据链接数值无法自动显示的问题,增加此函数
  125. //void setDataLinkItem(QtVariantProperty*& item, const DataLink& dataLink);
  126. //// 根据类型获取对应的VControlObject指针
  127. //VControlObject* controlObject();
  128. // 当前控件是否是 Table
  129. bool isVTableControl();
  130. // 当前控件是否是 Pie
  131. bool isVPieChart();
  132. // 当前控件是否是 Wave
  133. bool isVCustomPlot();
  134. // 当前控件是否是 Image
  135. bool isVImageControl();
  136. public:
  137. // 绑定的控件对象指针
  138. QObject *m_object;
  139. // Object的VControlObject对象
  140. VControlObject *m_pVcontrol;
  141. // 属性和QMetaObject的双向对应关系(用于简单控件)
  142. // QMap<const QMetaObject *, QtProperty *> m_classToProperty;
  143. // 属性和Index索引的对应关系
  144. QMap<QtProperty *, int> m_propertyToIndex;
  145. // QMetaObject和索引以及对应属性的关系
  146. // QMap<const QMetaObject *, QMap<int, QtVariantProperty *> > m_classToIndexToProperty;
  147. QMap<const QObject*, QMap<int, QtVariantProperty*> > m_objectToIndexToProperty;
  148. // 每个属性是否展开
  149. QMap<QtProperty *, bool> m_propertyToExpanded;
  150. // 属性表顶层节点
  151. QList<QtProperty *> m_topLevelProperties;
  152. // 2021-9-11 修改 此处直接使用 QtTreePropertyBrowser 指针即可
  153. QtTreePropertyBrowser *m_browser;
  154. // 属性数据结构管理者
  155. QtVariantPropertyManager *m_manager;
  156. // 只读属性数据结构管理者
  157. QtVariantPropertyManager *m_readOnlyManager;
  158. // 2021-12-2 属性指针与属性名字对应关系
  159. QMap<QtProperty*, QString> m_propertyToName;
  160. // 2022-1-15,每个控件对应的属性分组根节点
  161. QMap < const QObject*, QVector<QtProperty*>> m_objectToGroups;
  162. // 2021-12-3 控件与对应的扩展子属性组
  163. // QMap < const QObject*, QVector<QtProperty*>> m_objectToSubGroups;
  164. // 2022-1-25,由于此处数据结构变动,Group-SubGroup的关系只能这样定义了
  165. QMap < const QtProperty*, QVector<QtProperty*>> m_groupToSubGroups;
  166. // 2021-12-23 用于保存对象以及扩展属性的对应关系,用于后续更新
  167. QMap<const QObject*, QMap<QString, QtVariantProperty*>> m_objectToNameToProperty;
  168. // 属性和QObject的双向对应关系(用于复杂控件)
  169. QMap<const QObject*, QtProperty*> m_objectToProperty;
  170. // 2022-2-13 使用,用于控件属性到属性表的同步
  171. QMap<const QObject*, QVector<OBJECT_SYNC_PROPERTY>> m_objectToSyncProperty;
  172. };
  173. //=======================================================================
  174. //
  175. // 简单控件属性表处理
  176. //
  177. //=======================================================================
  178. /// <summary>
  179. /// 设置控件属性
  180. /// </summary>
  181. /// <param name="metaObject"></param>
  182. void ObjectControllerPrivate::setBasicControlProperties(const QMetaObject* metaObject)
  183. {
  184. if (!metaObject)
  185. {
  186. return;
  187. }
  188. // 取出属于本控件的控件属性组
  189. QtProperty* objectProperty = m_objectToProperty.value(m_object);
  190. // 重新创建新的属性表
  191. if (!objectProperty)
  192. {
  193. // 首先添加基础属性
  194. buildBasicProperty(metaObject, objectProperty);
  195. }
  196. // 如果之前已经创建过本类型控件的属性表,那么直接从数据结构中更新即可
  197. else
  198. {
  199. // 首先更新基础属性
  200. // updateProperties(metaObject);
  201. }
  202. // 保存根节点
  203. m_topLevelProperties.append(objectProperty);
  204. // 界面中添加此根节点
  205. m_browser->addProperty(objectProperty);
  206. // 基础属性表全部不展开
  207. this->collapseAll();
  208. }
  209. /// <summary>
  210. /// 构建新的基础属性表
  211. /// </summary>
  212. /// <param name="metaObject"></param>
  213. /// <param name="classProperty"></param>
  214. void ObjectControllerPrivate::buildBasicProperty(const QMetaObject *metaObject, QtProperty*& objectProperty)
  215. {
  216. // 清空需要同步的属性关系,重新建立
  217. // m_objectToSyncProperty.clear();
  218. // 获取类名,根据类型名建立属性表根节点
  219. QString className = QLatin1String(metaObject->className());
  220. // 创建根节点
  221. objectProperty = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), className);
  222. // 保存根节点和控件对象的对应关系
  223. m_objectToProperty[m_object] = objectProperty;
  224. int nPropertyCount = metaObject->propertyCount();
  225. int nPropertyOffset = metaObject->propertyOffset();
  226. // 遍历所有的固定属性执行添加
  227. for (int idx = nPropertyOffset; idx < nPropertyCount; idx++)
  228. {
  229. // 取出对应的固定属性
  230. QMetaProperty metaProperty = metaObject->property(idx);
  231. // 取出属性的Type值
  232. int type = metaProperty.userType();
  233. // 准备添加子属性节点(注意要保存带值的子属性,需要用QtVariantProperty类型)
  234. QtVariantProperty* subProperty = 0;
  235. // 翻译后的属性名称
  236. QString propertyName = chName(metaProperty.name());
  237. // 确保是所支持的类型
  238. if (m_manager->isPropertyTypeSupported(type))
  239. {
  240. // 添加属性
  241. subProperty = m_manager->addProperty(type, propertyName);
  242. // 设置值
  243. // 2022-2-8 针对数据连接专门处理了一下,要不直接从metaProperty里读不出来
  244. if (propertyName != "链接")
  245. {
  246. QVariant var = metaProperty.read(m_object);
  247. subProperty->setValue(var);
  248. }
  249. else
  250. {
  251. subProperty->setValue(m_pVcontrol->m_Property.m_DataLink.toString());
  252. }
  253. if (propertyName == "图层数" ||
  254. propertyName == "文本数" ||
  255. propertyName == "显示数" ||
  256. propertyName == "字符数" ||
  257. propertyName == "曲线数"
  258. )
  259. {
  260. subProperty->setAttribute(QLatin1String("minimum"), 0);
  261. subProperty->setAttribute(QLatin1String("maximum"), 10);
  262. subProperty->setAttribute(QLatin1String("singleStep"), 1);
  263. }
  264. // 2022-2-13 如果属性是形状或者标题,则需要额外保存一下
  265. else if (propertyName == "标题")
  266. {
  267. saveToSyncProperty(OBJECT_SYNC_TYPE::SYNC_TITLE, subProperty);
  268. }
  269. else if (propertyName == "形状")
  270. {
  271. saveToSyncProperty(OBJECT_SYNC_TYPE::SYNC_GEOMETRY, subProperty);
  272. //QMap<OBJECT_SYNC_TYPE, QtVariantProperty*> syncProp;
  273. //syncProp.insert(OBJECT_SYNC_TYPE::SYNC_TITLE, subProperty);
  274. //m_objectToSyncProperty.insert(m_object, syncProp);
  275. }
  276. }
  277. // 设置无效属性
  278. else
  279. {
  280. subProperty = m_readOnlyManager->addProperty(QVariant::String, propertyName);
  281. subProperty->setValue(QLatin1String("< Unknown Type >"));
  282. subProperty->setEnabled(false);
  283. }
  284. // 根节点下添加此子节点
  285. objectProperty->addSubProperty(subProperty);
  286. // 保存此子属性和索引值的对应关系
  287. m_propertyToIndex[subProperty] = idx;
  288. // 保存根节点下所有子节点和子属性的对应关系
  289. m_objectToIndexToProperty[m_object][idx] = subProperty;
  290. }
  291. }
  292. /// <summary>
  293. /// 更新基础属性表
  294. /// </summary>
  295. /// <param name="metaObject"></param>
  296. /// <param name="recursive"></param>
  297. void ObjectControllerPrivate::updateBasicProperties(const QMetaObject* metaObject)
  298. {
  299. if (!metaObject)
  300. {
  301. return;
  302. }
  303. // 遍历所有的属性更新数值
  304. for (int idx = metaObject->propertyOffset(); idx < metaObject->propertyCount(); idx++)
  305. {
  306. QMetaProperty metaProperty = metaObject->property(idx);
  307. if (metaProperty.isReadable())
  308. {
  309. // 从数据结构中找到对应的子属性
  310. if (m_objectToIndexToProperty.contains(m_object)
  311. && m_objectToIndexToProperty[m_object].contains(idx))
  312. {
  313. QtVariantProperty* subProperty = m_objectToIndexToProperty[m_object][idx];
  314. // 设置属性值
  315. QVariant propertyValue = metaProperty.read(m_object);
  316. subProperty->setValue(propertyValue);
  317. }
  318. }
  319. }
  320. }
  321. /// <summary>
  322. /// 2022-2-12 更新geometry属性
  323. /// (针对geometry专门处理一下,因为这个属性比较特殊,不需要手工处理,只需要刷新一下界面)
  324. /// </summary>
  325. void ObjectControllerPrivate::changeGeometryProperty(const QVariant& value)
  326. {
  327. // WindowAppUiView* pUiView = g_pUiManager->getViewByControl(m_pVcontrol);
  328. // 按照属性表中的值重新设置控件形状
  329. m_pVcontrol->m_pWidget->setGeometry(value.toRect());
  330. // 界面中刷新此控件
  331. g_pUiManager->refreshControlDrawPoint(m_pVcontrol);
  332. }
  333. /// <summary>
  334. /// 同步指定的属性值到属性表中
  335. /// </summary>
  336. /// <param name="value"></param>
  337. /// <param name="syncType"></param>
  338. void ObjectControllerPrivate::syncToPropertyTable(QObject* pControl, const OBJECT_SYNC_PROPERTY& syncInfo)
  339. {
  340. QtVariantProperty* syncProp = nullptr;
  341. // 找出需要同步的Property指针
  342. QVector<OBJECT_SYNC_PROPERTY>& propInfos = m_objectToSyncProperty[pControl];
  343. for (auto propInfo : propInfos)
  344. {
  345. if (propInfo.type == syncInfo.type)
  346. {
  347. syncProp = propInfo.prop;
  348. break;
  349. }
  350. }
  351. if (syncProp == nullptr)
  352. {
  353. //qWarning() << "[Error] ObjectControllerPrivate::syncToPropertyTable - syncProp is nullptr.";
  354. return;
  355. }
  356. int idx = m_propertyToIndex.value(syncProp);
  357. // 更新MetaObject中的值
  358. const QMetaObject* metaObject = m_object->metaObject();
  359. QMetaProperty metaProperty = metaObject->property(idx);
  360. metaProperty.write(m_object, syncInfo.value);
  361. // 更新对应的属性表
  362. syncProp->setValue(syncInfo.value);
  363. }
  364. /// <summary>
  365. /// 2022-2-14 保存到同步列表中
  366. /// </summary>
  367. /// <param name="type"></param>
  368. /// <param name="prop"></param>
  369. void ObjectControllerPrivate::saveToSyncProperty(OBJECT_SYNC_TYPE type, QtVariantProperty* prop)
  370. {
  371. OBJECT_SYNC_PROPERTY propInfo;
  372. propInfo.type = type;
  373. propInfo.prop = prop;
  374. if (!m_objectToSyncProperty.contains(m_object))
  375. {
  376. QVector<OBJECT_SYNC_PROPERTY> syncProps;
  377. syncProps.push_back(propInfo);
  378. m_objectToSyncProperty.insert(m_object, syncProps);
  379. }
  380. else
  381. {
  382. QVector<OBJECT_SYNC_PROPERTY>& syncProps = m_objectToSyncProperty[m_object];
  383. syncProps.push_back(propInfo);
  384. }
  385. }
  386. //=======================================================================
  387. //
  388. // 复杂控件属性表处理
  389. //
  390. //=======================================================================
  391. /// <summary>
  392. /// 设置复杂控件属性
  393. /// </summary>
  394. void ObjectControllerPrivate::setComplexControlProperties(const QMetaObject* metaObject)
  395. {
  396. if (!m_object)
  397. {
  398. return;
  399. }
  400. // 取出属于本控件的控件属性组
  401. QtProperty* objectProperty = m_objectToProperty.value(m_object);
  402. // 重新创建新的属性表
  403. if (!objectProperty)
  404. {
  405. // 首先建立基础属性
  406. buildBasicProperty(metaObject, objectProperty);
  407. // 继续建立扩展属性
  408. buildExtendProperty(objectProperty);
  409. }
  410. // 如果之前已经创建过本类型控件的属性表,那么直接从数据结构中更新即可
  411. else
  412. {
  413. // 首先更新基础属性
  414. // updateProperties(metaObject);
  415. // 继续更新扩展属性
  416. // updateExtendProperties(objectProperty);
  417. }
  418. // 保存根节点
  419. m_topLevelProperties.append(objectProperty);
  420. // 界面中添加此根节点
  421. m_browser->addProperty(objectProperty);
  422. // 基础属性表全部不展开
  423. this->collapseAll();
  424. // 只展开扩展属性表以及子属性表的部分
  425. this->setExtendItemsExpandOnly();
  426. }
  427. ///// <summary>
  428. ///// 为复杂控件增加其中的基础属性
  429. ///// </summary>
  430. ///// <param name="metaObject"></param>
  431. ///// <param name="classProperty"></param>
  432. //void ObjectControllerPrivate::buildBasicProperties(const QMetaObject* metaObject, QtProperty*& objectProperty)
  433. //{
  434. //
  435. // buildProperties(metaObject, objectProperty);
  436. //
  437. //}
  438. //
  439. //
  440. ///// <summary>
  441. ///// 为复杂控件更新基础属性表
  442. ///// </summary>
  443. ///// <param name="metaObject"></param>
  444. //void ObjectControllerPrivate::updateBasicProperties(const QMetaObject* metaObject)
  445. //{
  446. // this->updateProperties(metaObject);
  447. //}
  448. /// <summary>
  449. /// 构建控件扩展属性表(仅复杂控件才有)
  450. /// </summary>
  451. /// <param name="metaObject"></param>
  452. /// <param name="classProperty"></param>
  453. void ObjectControllerPrivate::buildExtendProperty(QtProperty*& objectProperty)
  454. {
  455. // 构建控件扩展属性表中的主索引部分
  456. this->buildPropertyMainLinks(objectProperty);
  457. // 构建控件扩展属性表中的分组部分
  458. this->buildPropertyGroups(objectProperty);
  459. }
  460. /// <summary>
  461. /// 构建控件扩展属性表中的主索引部分
  462. /// </summary>
  463. /// <param name="objectProperty"></param>
  464. void ObjectControllerPrivate::buildPropertyMainLinks(QtProperty*& objectProperty)
  465. {
  466. // 取出对应的扩展属性
  467. const CONTROL_PROPERTY_EX& propex = m_pVcontrol->m_PropertyEx;
  468. // 建立主索引分类节点
  469. QtProperty* groupRoot = m_manager->addProperty(
  470. QtVariantPropertyManager::groupTypeId(),
  471. propex.m_strTitle
  472. );
  473. // 控件刷新索引链接
  474. QtVariantProperty* item = m_manager->addProperty(
  475. VariantManager::tagDataLinkTypeId(),
  476. propex.m_refreshLink.title
  477. );
  478. // 设置索引连接数值
  479. // this->setDataLinkItem(item, propex.m_refreshLink);
  480. item->setValue(propex.m_refreshLink.toString());
  481. // 保存子项和名字的对应关系
  482. m_propertyToName.insert(item, propex.m_refreshLink.title);
  483. // 添加此主刷新索引
  484. groupRoot->addSubProperty(item);
  485. // 保存本属性对应关系,用于后续查找和更新
  486. m_objectToNameToProperty[m_object][propex.m_refreshLink.title] = item;
  487. // 控件主索引链接
  488. for (int i = 0; i < propex.m_mainDataLinks.size(); i++)
  489. {
  490. const DataLink& dataLink = propex.m_mainDataLinks[i];
  491. // 添加索引Property
  492. item = m_manager->addProperty(
  493. VariantManager::tagDataLinkTypeId(),
  494. dataLink.title
  495. );
  496. // 数据链接值
  497. item->setValue(dataLink.toString());
  498. // 保存子项和名字的对应关系
  499. m_propertyToName.insert(item, dataLink.title);
  500. // 添加此主索引
  501. groupRoot->addSubProperty(item);
  502. // 保存本属性对应关系,用于后续查找和更新
  503. m_objectToNameToProperty[m_object][dataLink.title] = item;
  504. }
  505. // 在数据结构中保存本分类节点信息
  506. m_objectToGroups[m_object].push_back(groupRoot);
  507. // 在控件属性表中添加本属性分组根节点
  508. objectProperty->addSubProperty(groupRoot);
  509. }
  510. /// <summary>
  511. /// 构建控件扩展属性表中的分组部分
  512. /// </summary>
  513. /// <param name="objectProperty"></param>
  514. void ObjectControllerPrivate::buildPropertyGroups(QtProperty*& objectProperty)
  515. {
  516. // 取出对应的扩展属性
  517. const CONTROL_PROPERTY_EX& propex = m_pVcontrol->m_PropertyEx;
  518. // 循环添加控件扩展属性的每一个分组
  519. for (int i = 0; i < propex.m_groups.size(); i++)
  520. {
  521. const PROPERTY_EX_GROUP& group = propex.m_groups[i];
  522. // 建立分类根节点
  523. QtProperty* groupRoot = m_manager->addProperty(
  524. QtVariantPropertyManager::groupTypeId(),
  525. group.strTitle
  526. );
  527. // 循环将所有子项添加到属性表中
  528. for (int j = 0; j < group.subGroups.size(); j++)
  529. {
  530. this->buildPropertySubGroup(i, group.subGroups[j], groupRoot);
  531. }
  532. // 在数据结构中保存本分类节点信息
  533. m_objectToGroups[m_object].push_back(groupRoot);
  534. // 在控件属性表中添加本属性分组根节点
  535. objectProperty->addSubProperty(groupRoot);
  536. }
  537. }
  538. /// <summary>
  539. /// 更新扩展属性表
  540. /// </summary>
  541. void ObjectControllerPrivate::updateExtendProperties(QtProperty*& objectProperty)
  542. {
  543. Q_UNUSED(objectProperty);
  544. }
  545. /// <summary>
  546. /// 向界面属性表中增加属性内容(2022-1-25,增加了分组ID)
  547. /// Table 扩展属性项:列名、数据链接
  548. /// Pie 扩展属性项:分块名、分块颜色、数据链接
  549. /// Image 扩展属性项1:图层颜色、图层透明度、图层线宽、图层数据链接
  550. /// Image 扩展属性项2:文本颜色、文本横坐标、文本纵坐标、文本尺寸
  551. /// </summary>
  552. /// <param name="prop"></param>
  553. void ObjectControllerPrivate::buildPropertySubGroup(
  554. const int groupID,
  555. const PROPERTY_EX_SUBGROUP& subGroupInfo,
  556. QtProperty*& subGroupRoot
  557. )
  558. {
  559. // 创建子分组
  560. QtProperty* subGroup = m_manager->addProperty(
  561. QtVariantPropertyManager::groupTypeId(),
  562. subGroupInfo.strTitle
  563. );
  564. // 子分组属性项
  565. QtVariantProperty* item = nullptr;
  566. // --------- 数据链接部分
  567. // 循环添加所有数据链接
  568. for (int i = 0; i < subGroupInfo.dataLinks.size(); i++)
  569. {
  570. const DataLink& dataLink = subGroupInfo.dataLinks[i];
  571. // 数据链接项名
  572. item = m_manager->addProperty(
  573. VariantManager::tagDataLinkTypeId(),
  574. dataLink.title
  575. );
  576. // 数据链接值
  577. item->setValue(dataLink.toString());
  578. // 添加数据链接
  579. subGroup->addSubProperty(item);
  580. // 保存子项和名字的对应关系
  581. m_propertyToName.insert(item, dataLink.title);
  582. // 保存本属性对应关系,用于后续查找和更新
  583. m_objectToNameToProperty[m_object][dataLink.title] = item;
  584. }
  585. // --------- 杂项部分
  586. // 创建杂项子分组
  587. QtProperty* subMiscGroup = m_manager->addProperty(
  588. QtVariantPropertyManager::groupTypeId(),
  589. PROPERTY_EX_MISC
  590. );
  591. // 1.
  592. // 名称 (Table、Pie、Wave)
  593. if (!this->isVImageControl())
  594. {
  595. item = m_manager->addProperty(QVariant::String, subGroupInfo.strValueName);
  596. // 子项值
  597. item->setValue(subGroupInfo.strValue);
  598. // 添加子项
  599. subMiscGroup->addSubProperty(item);
  600. // 保存子项和名字的对应关系
  601. m_propertyToName.insert(item, subGroupInfo.strValueName);
  602. // 2021-12-24 保存本属性对应关系,用于后续查找和更新
  603. m_objectToNameToProperty[m_object][subGroupInfo.strValueName] = item;
  604. }
  605. // 2.
  606. // 颜色(Pie、Wave、Image)
  607. if (!this->isVTableControl() && !subGroupInfo.strColorName.isEmpty())
  608. {
  609. // 分块颜色项名
  610. item = m_manager->addProperty(QVariant::Color, subGroupInfo.strColorName);
  611. // 颜色数值
  612. item->setValue(subGroupInfo.color);
  613. // 添加颜色子项
  614. subMiscGroup->addSubProperty(item);
  615. // 保存子项和名字的对应关系
  616. m_propertyToName.insert(item, subGroupInfo.strColorName);
  617. // 2021-12-24 保存本属性对应关系,用于后续查找和更新
  618. m_objectToNameToProperty[m_object][subGroupInfo.strColorName] = item;
  619. }
  620. // 3.
  621. // 如果是Image控件,还需要加入其他杂项
  622. if (this->isVImageControl())
  623. {
  624. // 如果是HObject子分组
  625. if (groupID == GROUP_INDEX_HOBJECT)
  626. {
  627. // 线宽
  628. // 线宽项名
  629. item = m_manager->addProperty(QVariant::Int, subGroupInfo.strLineWidthName);
  630. // 线宽数值
  631. item->setValue(subGroupInfo.nLineWidth);
  632. // 添加线宽子项
  633. subMiscGroup->addSubProperty(item);
  634. // 保存子项和名字的对应关系
  635. m_propertyToName.insert(item, subGroupInfo.strLineWidthName);
  636. // 保存本属性对应关系,用于后续查找和更新
  637. m_objectToNameToProperty[m_object][subGroupInfo.strLineWidthName] = item;
  638. }
  639. // 如果是HTuple子分组
  640. else if (groupID == GROUP_INDEX_HTUPLE)
  641. {
  642. // 坐标
  643. // 坐标项名
  644. item = m_manager->addProperty(QVariant::Point, subGroupInfo.strPtName);
  645. // 坐标数值
  646. item->setValue(subGroupInfo.pt);
  647. // 添加坐标子项
  648. subMiscGroup->addSubProperty(item);
  649. // 保存子项和名字的对应关系
  650. m_propertyToName.insert(item, subGroupInfo.strPtName);
  651. // 保存本属性对应关系,用于后续查找和更新
  652. m_objectToNameToProperty[m_object][subGroupInfo.strPtName] = item;
  653. //// 坐标(数据链接)
  654. //// 数据链接项名
  655. //item = m_manager->addProperty(
  656. // VariantManager::tagDataLinkTypeId(),
  657. // subGroupInfo.dataLinkPoint.title
  658. //);
  659. //// 数据链接值
  660. //item->setValue("");
  661. //// 添加数据链接
  662. //subMiscGroup->addSubProperty(item);
  663. //// 保存子项和名字的对应关系
  664. //m_propertyToName.insert(item, subGroupInfo.dataLinkPoint.title);
  665. //// 保存本属性对应关系,用于后续查找和更新
  666. //m_objectToNameToProperty[m_object][subGroupInfo.dataLinkPoint.title] = item;
  667. // 尺寸
  668. // 尺寸项名
  669. item = m_manager->addProperty(QVariant::Int, subGroupInfo.strSize);
  670. // 尺寸数值
  671. item->setValue(subGroupInfo.nSize);
  672. // 添加尺寸子项
  673. subMiscGroup->addSubProperty(item);
  674. // 保存子项和名字的对应关系
  675. m_propertyToName.insert(item, subGroupInfo.strSize);
  676. // 保存本属性对应关系,用于后续查找和更新
  677. m_objectToNameToProperty[m_object][subGroupInfo.strSize] = item;
  678. }
  679. // 如果是 Display 子分组
  680. else if (groupID == GROUP_INDEX_DISPLAY)
  681. {
  682. }
  683. // 如果是 String 子分组
  684. else if (groupID == GROUP_INDEX_STRING)
  685. {
  686. // 坐标
  687. // 坐标项名
  688. item = m_manager->addProperty(QVariant::Point, subGroupInfo.strPtName);
  689. // 坐标数值
  690. item->setValue(subGroupInfo.pt);
  691. // 添加坐标子项
  692. subMiscGroup->addSubProperty(item);
  693. // 保存子项和名字的对应关系
  694. m_propertyToName.insert(item, subGroupInfo.strPtName);
  695. // 保存本属性对应关系,用于后续查找和更新
  696. m_objectToNameToProperty[m_object][subGroupInfo.strPtName] = item;
  697. //// 坐标(数据链接)
  698. //// 数据链接项名
  699. //item = m_manager->addProperty(
  700. // VariantManager::tagDataLinkTypeId(),
  701. // subGroupInfo.dataLinkPoint.title
  702. //);
  703. //// 数据链接值
  704. //item->setValue("");
  705. //// 添加数据链接
  706. //subMiscGroup->addSubProperty(item);
  707. //// 保存子项和名字的对应关系
  708. //m_propertyToName.insert(item, subGroupInfo.dataLinkPoint.title);
  709. //// 保存本属性对应关系,用于后续查找和更新
  710. //m_objectToNameToProperty[m_object][subGroupInfo.dataLinkPoint.title] = item;
  711. // 尺寸
  712. // 尺寸项名
  713. item = m_manager->addProperty(QVariant::Int, subGroupInfo.strSize);
  714. // 尺寸数值
  715. item->setValue(subGroupInfo.nSize);
  716. // 添加尺寸子项
  717. subMiscGroup->addSubProperty(item);
  718. // 保存子项和名字的对应关系
  719. m_propertyToName.insert(item, subGroupInfo.strSize);
  720. // 保存本属性对应关系,用于后续查找和更新
  721. m_objectToNameToProperty[m_object][subGroupInfo.strSize] = item;
  722. }
  723. // 如果是Save 子分组
  724. else if (groupID == GROUP_INDEX_SAVE)
  725. {
  726. // 1 启用存图(复选框)
  727. {
  728. item = m_manager->addProperty(QVariant::Bool, subGroupInfo.strSaveImage);
  729. item->setValue(subGroupInfo.bEnSaveImage);
  730. // 添加坐标子项
  731. subMiscGroup->addSubProperty(item);
  732. // 保存子项和名字的对应关系
  733. m_propertyToName.insert(item, subGroupInfo.strSaveImage);
  734. // 保存本属性对应关系,用于后续查找和更新
  735. m_objectToNameToProperty[m_object][subGroupInfo.strSaveImage] = item;
  736. }
  737. // 2 启用转储(复选框)
  738. {
  739. item = m_manager->addProperty(QVariant::Bool, subGroupInfo.strDumpWindow);
  740. item->setValue(subGroupInfo.bEnDumpWindow);
  741. // 添加坐标子项
  742. subMiscGroup->addSubProperty(item);
  743. // 保存子项和名字的对应关系
  744. m_propertyToName.insert(item, subGroupInfo.strDumpWindow);
  745. // 保存本属性对应关系,用于后续查找和更新
  746. m_objectToNameToProperty[m_object][subGroupInfo.strDumpWindow] = item;
  747. }
  748. // 3 启用应用状态(复选框)
  749. {
  750. item = m_manager->addProperty(QVariant::Bool, subGroupInfo.strExecuteState);
  751. item->setValue(subGroupInfo.bEnExecuteState);
  752. // 添加坐标子项
  753. subMiscGroup->addSubProperty(item);
  754. // 保存子项和名字的对应关系
  755. m_propertyToName.insert(item, subGroupInfo.strExecuteState);
  756. // 保存本属性对应关系,用于后续查找和更新
  757. m_objectToNameToProperty[m_object][subGroupInfo.strExecuteState] = item;
  758. }
  759. // 4 命名方式(下拉列表 1、序号模式,2、日期模式,3、链接模式 )
  760. {
  761. item = m_manager->addProperty(QtVariantPropertyManager::enumTypeId(), subGroupInfo.strSaveMode);
  762. QStringList enumNames;
  763. enumNames << "序号模式" << "日期模式" << "链接模式";
  764. item->setAttribute(QLatin1String("enumNames"), enumNames);
  765. item->setValue(subGroupInfo.nSaveMode);
  766. // 添加坐标子项
  767. subMiscGroup->addSubProperty(item);
  768. // 保存子项和名字的对应关系
  769. m_propertyToName.insert(item, subGroupInfo.strSaveMode);
  770. // 保存本属性对应关系,用于后续查找和更新
  771. m_objectToNameToProperty[m_object][subGroupInfo.strSaveMode] = item;
  772. }
  773. // 5 BufferSize
  774. {
  775. item = m_manager->addProperty(QVariant::Int, subGroupInfo.strBufferSize);
  776. item->setValue(subGroupInfo.nBufferSize);
  777. item->setAttribute(QLatin1String("minimum"), 10);
  778. item->setAttribute(QLatin1String("maximum"), 999);
  779. item->setAttribute(QLatin1String("singleStep"), 1);
  780. // 添加坐标子项
  781. subMiscGroup->addSubProperty(item);
  782. // 保存子项和名字的对应关系
  783. m_propertyToName.insert(item, subGroupInfo.strBufferSize);
  784. // 保存本属性对应关系,用于后续查找和更新
  785. m_objectToNameToProperty[m_object][subGroupInfo.strBufferSize] = item;
  786. }
  787. // 6 Free Time
  788. {
  789. item = m_manager->addProperty(QVariant::Int, subGroupInfo.strFreeTime);
  790. item->setValue(subGroupInfo.nFreeTime);
  791. item->setAttribute(QLatin1String("minimum"), 10);
  792. item->setAttribute(QLatin1String("maximum"), 500);
  793. item->setAttribute(QLatin1String("singleStep"), 1);
  794. // 添加坐标子项
  795. subMiscGroup->addSubProperty(item);
  796. // 保存子项和名字的对应关系
  797. m_propertyToName.insert(item, subGroupInfo.strFreeTime);
  798. // 保存本属性对应关系,用于后续查找和更新
  799. m_objectToNameToProperty[m_object][subGroupInfo.strFreeTime] = item;
  800. }
  801. // TODO: 此处,需要完成存储组的默认折叠
  802. }
  803. // 不应该执行到这里
  804. else
  805. {
  806. qDebug() << "[Error] ObjectControllerPrivate::buildPropertySubGroup - invalid groupID: " << groupID;
  807. }
  808. }
  809. // 4.
  810. // 如果是曲线控件,还需要加入其他杂项
  811. if (this->isVCustomPlot())
  812. {
  813. // 线宽
  814. // 线宽项名
  815. item = m_manager->addProperty(QVariant::Int, subGroupInfo.strLineWidthName);
  816. // 线宽数值
  817. item->setValue(subGroupInfo.nLineWidth);
  818. // 添加线宽子项
  819. subMiscGroup->addSubProperty(item);
  820. // 保存子项和名字的对应关系
  821. m_propertyToName.insert(item, subGroupInfo.strLineWidthName);
  822. // 保存本属性对应关系,用于后续查找和更新
  823. m_objectToNameToProperty[m_object][subGroupInfo.strLineWidthName] = item;
  824. }
  825. // 添加杂项分组
  826. subGroup->addSubProperty(subMiscGroup);
  827. // 添加子分组
  828. subGroupRoot->addSubProperty(subGroup);
  829. // 保存这个SubGroup的信息(用于删除使用)
  830. QtProperty* curGroup = m_objectToGroups[m_object][groupID];
  831. m_groupToSubGroups[curGroup].push_back(subGroup);
  832. // m_objectToSubGroups[m_object].push_back(subGroup);
  833. }
  834. void ObjectControllerPrivate::saveExpandedState()
  835. {
  836. }
  837. void ObjectControllerPrivate::restoreExpandedState()
  838. {
  839. }
  840. /// <summary>
  841. /// 属性表数据变动槽函数
  842. /// </summary>
  843. void ObjectControllerPrivate::slotValueChanged(QtProperty *property, const QVariant &value)
  844. {
  845. // qDebug() << "ObjectControllerPrivate::slotValueChanged - Property: " << property->propertyName() << " - Value: " << value;
  846. // 2022-2-12 如果更新的是geometry
  847. if (property->propertyName()=="形状")
  848. {
  849. this->changeGeometryProperty(value);
  850. }
  851. // 基础属性
  852. if (m_propertyToIndex.contains(property))
  853. {
  854. this->changeBasicProperties(property, value);
  855. }
  856. // 动态属性
  857. else
  858. {
  859. // 动态改变复杂控件的扩展属性
  860. this->changeExtendProperties(property, value);
  861. }
  862. }
  863. /// <summary>
  864. /// 更新基础属性
  865. /// </summary>
  866. /// <param name="property"></param>
  867. /// <param name="value"></param>
  868. void ObjectControllerPrivate::changeBasicProperties(QtProperty* property, const QVariant& value)
  869. {
  870. int idx = m_propertyToIndex.value(property);
  871. const QMetaObject* metaObject = m_object->metaObject();
  872. QMetaProperty metaProperty = metaObject->property(idx);
  873. metaProperty.write(m_object, value);
  874. updateBasicProperties(metaObject);
  875. //// 2022-2-14 修正,似乎不需要这么复杂,简化逻辑提高了效率
  876. //// updateBasicProperties(metaObject);
  877. //QtVariantProperty* subProperty = m_objectToIndexToProperty[m_object][idx];
  878. //subProperty->setValue(value);
  879. // 此处需要进行额外处理,如果改变的是扩展属性数量的关联Key,需要更新对应的扩展属性数量
  880. QString propertyName = metaProperty.name();
  881. // 如果改变了复杂控件扩展属性的数量
  882. if (propertyName == TABLE_COL_COUNT_NAME
  883. || propertyName == PIE_SLICE_COUNT_NAME
  884. || propertyName == CUSTOM_PLOT_COUNT_NAME
  885. || propertyName == IMAGE_OBJ_COUNT_NAME
  886. || propertyName == IMAGE_MSG_COUNT_NAME
  887. || propertyName == IMAGE_DISPLAY_COUNT_NAME
  888. || propertyName == IMAGE_STRING_COUNT_NAME
  889. )
  890. {
  891. // 调整对应的属性数量
  892. // 新的属性数量
  893. int newCount = value.toInt();
  894. // 动态更新属性数量
  895. this->updateExtendPropertiesCount(newCount, propertyName);
  896. }
  897. }
  898. /// <summary>
  899. /// 修改控件的扩展属性
  900. /// </summary>
  901. /// <param name="property"></param>
  902. /// <param name="value"></param>
  903. void ObjectControllerPrivate::changeExtendProperties(QtProperty* property, const QVariant& value)
  904. {
  905. // 找到属性对应的属性名字
  906. if (m_propertyToName.contains(property))
  907. {
  908. // 获取属性名字
  909. QString strValueTitle = m_propertyToName[property];
  910. // 调用虚函数更新对应的控件属性值
  911. m_pVcontrol->changeExProperties(strValueTitle, value);
  912. }
  913. }
  914. ///// <summary>
  915. ///// 增加新的属性项
  916. ///// </summary>
  917. ///// <param name="pTable"></param>
  918. ///// <param name="newCount"></param>
  919. //void ObjectControllerPrivate::appendExtendPropertiesCount(const int fixCount, const QString& propertyName)
  920. //{
  921. // //// 首先调用虚函数变更控件中扩展属性的数量
  922. // //m_pVcontrol->updateExPropertyCount(fixCount);
  923. //
  924. // //// 从对应的子属性组中获取最新的属性数据
  925. // //const QVector<PROPERTY_EX_SUBGROUP>& propsItems = m_pVcontrol->getPropertyEx().m_subGroups[groupID];
  926. //
  927. // // // 同步进行界面信息变更
  928. // //int nStart = m_pVcontrol->getPropertyExSubGroupCountByID(groupID) - fixCount;
  929. // //int nEnd = nStart + fixCount;
  930. // //for (int i = nStart; i < nEnd; i++)
  931. // //{
  932. // // this->addExtendPropertiesSubGroup(propsItems[i], m_objectToExRoots[m_object][groupID]);
  933. // //}
  934. //
  935. //}
  936. //
  937. //
  938. ///// <summary>
  939. ///// 减少新的属性项
  940. ///// </summary>
  941. ///// <param name="pTable"></param>
  942. ///// <param name="newCount"></param>
  943. //void ObjectControllerPrivate::removeExtendPropertiesCount(const int fixCount, const QString& propertyName)
  944. //{
  945. // //// 首先控件中减少数据结构信息(虚函数)
  946. // //m_pVcontrol->updateExPropertyCount(fixCount);
  947. //
  948. // // // 同步进行界面信息变更
  949. // // int nDelCount = -fixCount;
  950. //
  951. // // // 从后往前依次删除掉属性
  952. // // for (int i = 0; i < nDelCount; i++)
  953. // // {
  954. // // QtProperty* pDelSubGroup = m_objectToSubGroups[m_object].back();
  955. //
  956. // // // 删除子属性
  957. // // m_objectToExRoots[m_object]->removeSubProperty(pDelSubGroup);
  958. //
  959. // //m_objectToSubGroups[m_object].pop_back();
  960. // // }
  961. //}
  962. /// <summary>
  963. /// 动态调整属性项
  964. /// </summary>
  965. /// <param name="newCount"></param>
  966. /// <param name="propertyName"></param>
  967. void ObjectControllerPrivate::updateExtendPropertiesCount(const int newCount, const QString& propertyName)
  968. {
  969. // 需要调整的属性数量
  970. int nFixCount = newCount - m_pVcontrol->getExPropertyCountByName(propertyName);
  971. // GroupID
  972. int nGroupID = m_pVcontrol->getGroupIDByName(propertyName);
  973. // 检查有效性
  974. if (nGroupID < 0)
  975. {
  976. qDebug() << "[Error] ObjectControllerPrivate::updateExtendPropertiesCount - nGroupID in invalid: " << nGroupID;
  977. return;
  978. }
  979. // 2022-1-23 由于属性表中的0号分组是主索引链接分组,所以此处取到的nGroupID + 才是真实的属性表分组ID
  980. int nPropGroupID = nGroupID + 1;
  981. // 变更控件中扩展属性对应的数据结构数量(虚函数)
  982. m_pVcontrol->updateExPropertyCount(nFixCount, propertyName);
  983. // 需要增加
  984. if (nFixCount > 0)
  985. {
  986. // 获取最新的子分组数据
  987. // 从对应的子属性组中获取最新的属性数据
  988. const QVector<PROPERTY_EX_SUBGROUP>& subGroups = m_pVcontrol->m_PropertyEx.m_groups[nGroupID].subGroups;
  989. int nStart = m_pVcontrol->getExPropertyCountByID(nGroupID) - nFixCount;
  990. int nEnd = nStart + nFixCount;
  991. // 把新增加的subGroup数据结构添加到属性表中
  992. for (int i = nStart; i < nEnd; i++)
  993. {
  994. this->buildPropertySubGroup(nGroupID, subGroups[i], m_objectToGroups[m_object][nPropGroupID]);
  995. }
  996. }
  997. // 需要减少
  998. else
  999. {
  1000. // 从后往前依次删除掉属性
  1001. for (int i = 0; i < -nFixCount; i++)
  1002. {
  1003. // QtProperty* pDelSubGroup = m_objectToSubGroups[m_object].back();
  1004. // 从分组中找到对应的子分组
  1005. QtProperty* curGroup = m_objectToGroups[m_object][nGroupID];
  1006. QtProperty* pDelSubGroup = m_groupToSubGroups[curGroup].back();
  1007. // 删除子属性
  1008. m_objectToGroups[m_object][nPropGroupID]->removeSubProperty(pDelSubGroup);
  1009. m_groupToSubGroups[curGroup].pop_back();
  1010. }
  1011. }
  1012. // 基础属性表全部不展开
  1013. this->collapseAll();
  1014. // 只展开扩展属性表以及子属性表的部分
  1015. this->setExtendItemsExpandOnly();
  1016. }
  1017. /// <summary>
  1018. /// 仅展开扩展属性项
  1019. /// </summary>
  1020. void ObjectControllerPrivate::setExtendItemsExpandOnly()
  1021. {
  1022. // 2022-1-12 遍历所有的子属性项进行判断
  1023. for (int i = 0; i < m_objectToGroups[m_object].size(); i++)
  1024. {
  1025. QtProperty* prop = m_objectToGroups[m_object][i];
  1026. if (!prop || m_browser->items(prop).size() <= 0)
  1027. {
  1028. return;
  1029. }
  1030. // 枚举所有子项逐一进行展开
  1031. QtBrowserItem* pExRoot = m_browser->items(prop).at(0);
  1032. m_browser->setExpanded(pExRoot, true);
  1033. // Groups
  1034. QList<QtBrowserItem*> pGroups = pExRoot->children();
  1035. for (QtBrowserItem* group : pGroups)
  1036. {
  1037. m_browser->setExpanded(group, true);
  1038. //// subgroups
  1039. //QList<QtBrowserItem*> subGroups = group->children();
  1040. //for (QtBrowserItem* subGroup : subGroups)
  1041. //{
  1042. // m_browser->setExpanded(subGroup, true);
  1043. //}
  1044. }
  1045. }
  1046. }
  1047. ///// <summary>
  1048. ///// 2022-2-7为了解决反序列化时数据链接数值无法自动显示的问题,增加此函数
  1049. ///// </summary>
  1050. ///// <param name="dataLink"></param>
  1051. //void ObjectControllerPrivate::setDataLinkItem(QtVariantProperty*& item, const DataLink& dataLink)
  1052. //{
  1053. // item->setValue(dataLink.toString());
  1054. //
  1055. //
  1056. // //if (propex.m_refreshLink.value.size() <= 0)
  1057. // //{
  1058. // // item->setValue("");
  1059. // //}
  1060. // //else
  1061. // //{
  1062. // // item->setValue(propex.m_refreshLink.toString());
  1063. // //}
  1064. //}
  1065. //===================================================================
  1066. //
  1067. // ObjectController
  1068. //
  1069. //===================================================================
  1070. /// <summary>
  1071. ///
  1072. /// </summary>
  1073. /// <param name="parent"></param>
  1074. ObjectController::ObjectController(QWidget *parent)
  1075. : QWidget(parent)
  1076. {
  1077. d_ptr = new ObjectControllerPrivate;
  1078. d_ptr->q_ptr = this;
  1079. d_ptr->m_object = nullptr;
  1080. /*
  1081. QScrollArea *scroll = new QScrollArea(this);
  1082. scroll->setWidgetResizable(true);
  1083. d_ptr->m_browser = new QtGroupBoxPropertyBrowser(this);
  1084. QVBoxLayout *layout = new QVBoxLayout(this);
  1085. layout->setMargin(0);
  1086. layout->addWidget(scroll);
  1087. scroll->setWidget(d_ptr->m_browser);
  1088. */
  1089. // 生成属性浏览控件
  1090. QtTreePropertyBrowser *browser = new QtTreePropertyBrowser(this);
  1091. browser->setRootIsDecorated(false);
  1092. d_ptr->m_browser = browser;
  1093. QVBoxLayout *layout = new QVBoxLayout(this);
  1094. layout->setMargin(0);
  1095. // 添加新的属性表到界面中
  1096. layout->addWidget(d_ptr->m_browser);
  1097. d_ptr->m_readOnlyManager = new QtVariantPropertyManager(this);
  1098. // 2021-9-11 修改,此处生成 扩展的 VariantManager 对象
  1099. VariantManager* pVariantManager = new VariantManager(this);
  1100. d_ptr->m_manager = pVariantManager;
  1101. pVariantManager->setPropertyEditor(d_ptr->m_browser);
  1102. // d_ptr->m_manager = new QtVariantPropertyManager(this);
  1103. // 此处生成扩展的 VariantFactory 对象
  1104. QtVariantEditorFactory *factory = new VariantFactory(this);
  1105. d_ptr->m_browser->setFactoryForManager(d_ptr->m_manager, factory);
  1106. // 绑定数据更新消息
  1107. connect(d_ptr->m_manager, SIGNAL(valueChanged(QtProperty *, const QVariant &)),
  1108. this, SLOT(slotValueChanged(QtProperty *, const QVariant &)));
  1109. }
  1110. ObjectController::~ObjectController()
  1111. {
  1112. delete d_ptr;
  1113. }
  1114. /// <summary>
  1115. /// 设置对象属性
  1116. /// </summary>
  1117. /// <param name="object"></param>
  1118. void ObjectController::setObject(QObject *object)
  1119. {
  1120. // 根据控件类型分别进行不同的处理
  1121. // 根据控件类型的不同,分为设置基础控件属性和复杂控件属性
  1122. // Memo:基础控件属性的设置和复杂控件属性的设置还是有很大区别
  1123. // 基础控件可以根据metaObject来分类设置属性表,因为同一个metaObject类型的属性表项是完全一致的,直接更新即可
  1124. // 而复杂控件的属性表项是动态变化的,无法直接根据metaObject类型来成组设置,所以每次切换控件都需要清空删除后重新来过
  1125. // // QString name = object->objectName();
  1126. //如果设置的控件已经是当前控件则不处理
  1127. if (d_ptr->m_object == object)
  1128. {
  1129. return;
  1130. }
  1131. // 清空属性表
  1132. this->clearProperties();
  1133. // 将新的对象指针保存
  1134. d_ptr->m_object = object;
  1135. if (!d_ptr->m_object)
  1136. {
  1137. return;
  1138. }
  1139. // 2021-12-28 转换成VControlObject指针留着后面使用
  1140. d_ptr->m_pVcontrol = VControlObject::controlPtr(d_ptr->m_object);
  1141. // 2022-5-15,加一个检查,防止后续执行出现问题
  1142. if (d_ptr->m_pVcontrol == nullptr)
  1143. {
  1144. qDebug() << "[Error] ObjectController::setObject - Abandon, reason: m_pVcontrol is nullptr.";
  1145. return;
  1146. }
  1147. // 将简单控件的处理逻辑和复杂控件完全分开
  1148. if (this->isBasicControl())
  1149. {
  1150. // 添加基础控件的属性,设置对应属性表(新建或更新)
  1151. d_ptr->setBasicControlProperties(d_ptr->m_object->metaObject());
  1152. }
  1153. else
  1154. {
  1155. if (!d_ptr->m_pVcontrol)
  1156. {
  1157. return;
  1158. }
  1159. // 添加复杂控件的属性,设置对应属性表(新建或更新)
  1160. d_ptr->setComplexControlProperties(d_ptr->m_object->metaObject());
  1161. }
  1162. //// 还原属性结构中子属性的展开状态
  1163. //d_ptr->restoreExpandedState();
  1164. // 展开所有节点
  1165. // d_ptr->expandAll();
  1166. }
  1167. QObject *ObjectController::object() const
  1168. {
  1169. return d_ptr->m_object;
  1170. }
  1171. VControlObject* ObjectController::vobject() const
  1172. {
  1173. return d_ptr->m_pVcontrol;
  1174. }
  1175. /// <summary>
  1176. /// 清空属性表
  1177. /// </summary>
  1178. void ObjectController::clearProperties()
  1179. {
  1180. // 删除旧属性表中的内容
  1181. if (d_ptr->m_object)
  1182. {
  1183. //// 保存当前属性表中子属性的状态
  1184. //d_ptr->saveExpandedState();
  1185. // 枚举属性表中之前的所有属性进行删除
  1186. QListIterator<QtProperty*> it(d_ptr->m_topLevelProperties);
  1187. while (it.hasNext())
  1188. {
  1189. d_ptr->m_browser->removeProperty(it.next());
  1190. }
  1191. d_ptr->m_topLevelProperties.clear();
  1192. //// 2022-1-6增加,切换控件时需要清除相关的数据结构
  1193. //d_ptr->m_subGroups.clear();
  1194. // d_ptr->m_exPropertiesRoot = nullptr;
  1195. }
  1196. }
  1197. /// <summary>
  1198. /// 2021-12-25增加,删除对应属性表相关的数据结构
  1199. /// </summary>
  1200. /// <param name="object"></param>
  1201. void ObjectController::delObject(QObject* object)
  1202. {
  1203. d_ptr->m_object = object;
  1204. if (!d_ptr->m_object)
  1205. {
  1206. return;
  1207. }
  1208. // 清空对应的数据结构
  1209. d_ptr->m_objectToIndexToProperty.remove(object);
  1210. d_ptr->m_objectToProperty.remove(object);
  1211. d_ptr->m_objectToNameToProperty.remove(object);
  1212. // 清除当前分组中的所有子分组属性表
  1213. for (QtProperty* group : d_ptr->m_objectToGroups[object])
  1214. {
  1215. d_ptr->m_groupToSubGroups.remove(group);
  1216. }
  1217. d_ptr->m_objectToGroups.remove(object);
  1218. // 清空最终属性表
  1219. clearProperties();
  1220. d_ptr->m_object = nullptr;
  1221. }
  1222. /// <summary>
  1223. /// 2022-2-13 用于控件数值改变后向属性表同步
  1224. /// </summary>
  1225. /// <param name="pControl"></param>
  1226. /// <param name="value"></param>
  1227. void ObjectController::syncToObject(QObject* pControl, const OBJECT_SYNC_PROPERTY& syncInfo)
  1228. {
  1229. // 暂时未使用到pControl,因为ObjectController本身是绑定了控件指针的
  1230. // 同步到属性表
  1231. d_ptr->syncToPropertyTable(pControl, syncInfo);
  1232. }
  1233. /// <summary>
  1234. /// 是否是基础类型控件
  1235. /// </summary>
  1236. /// <returns></returns>
  1237. bool ObjectController::isBasicControl()
  1238. {
  1239. QString className = object()->metaObject()->className();
  1240. if (className != CLASS_NAME_TABLECONTROL
  1241. && className != CLASS_NAME_CUSTOMPLOT
  1242. && className != CLASS_NAME_PIECHART
  1243. && className != CLASS_NAME_IMAGECONTROL
  1244. )
  1245. {
  1246. return true;
  1247. }
  1248. return false;
  1249. }
  1250. //===================================================================
  1251. //
  1252. // 辅助函数
  1253. //
  1254. //===================================================================
  1255. int ObjectControllerPrivate::enumToInt(const QMetaEnum& metaEnum, int enumValue) const
  1256. {
  1257. QMap<int, int> valueMap; // dont show multiple enum values which have the same values
  1258. int pos = 0;
  1259. for (int i = 0; i < metaEnum.keyCount(); i++) {
  1260. int value = metaEnum.value(i);
  1261. if (!valueMap.contains(value)) {
  1262. if (value == enumValue) {
  1263. return pos;
  1264. }
  1265. valueMap[value] = pos++;
  1266. }
  1267. }
  1268. return -1;
  1269. }
  1270. int ObjectControllerPrivate::intToEnum(const QMetaEnum& metaEnum, int intValue) const
  1271. {
  1272. QMap<int, bool> valueMap; // dont show multiple enum values which have the same values
  1273. QList<int> values;
  1274. for (int i = 0; i < metaEnum.keyCount(); i++) {
  1275. int value = metaEnum.value(i);
  1276. if (!valueMap.contains(value)) {
  1277. valueMap[value] = true;
  1278. values.append(value);
  1279. }
  1280. }
  1281. if (intValue >= values.count()) {
  1282. return -1;
  1283. }
  1284. return values.at(intValue);
  1285. }
  1286. bool ObjectControllerPrivate::isSubValue(int value, int subValue) const
  1287. {
  1288. if (value == subValue) {
  1289. return true;
  1290. }
  1291. int i = 0;
  1292. while (subValue) {
  1293. if (!(value & (1 << i))) {
  1294. if (subValue & 1) {
  1295. return false;
  1296. }
  1297. }
  1298. i++;
  1299. subValue = subValue >> 1;
  1300. }
  1301. return true;
  1302. }
  1303. bool ObjectControllerPrivate::isPowerOf2(int value) const
  1304. {
  1305. while (value) {
  1306. if (value & 1) {
  1307. return value == 1;
  1308. }
  1309. value = value >> 1;
  1310. }
  1311. return false;
  1312. }
  1313. /// <summary>
  1314. /// 获取属性的中文名称
  1315. /// </summary>
  1316. /// <param name="enName"></param>
  1317. /// <returns></returns>
  1318. QString ObjectControllerPrivate::chName(const QString& enName)
  1319. {
  1320. // 中文属性名称
  1321. QString propertyName = propertyNamesMap.value(enName);
  1322. if (propertyName.isEmpty())
  1323. {
  1324. return enName;
  1325. }
  1326. return propertyName;
  1327. }
  1328. int ObjectControllerPrivate::flagToInt(const QMetaEnum& metaEnum, int flagValue) const
  1329. {
  1330. if (!flagValue) {
  1331. return 0;
  1332. }
  1333. int intValue = 0;
  1334. QMap<int, int> valueMap; // dont show multiple enum values which have the same values
  1335. int pos = 0;
  1336. for (int i = 0; i < metaEnum.keyCount(); i++) {
  1337. int value = metaEnum.value(i);
  1338. if (!valueMap.contains(value) && isPowerOf2(value)) {
  1339. if (isSubValue(flagValue, value)) {
  1340. intValue |= (1 << pos);
  1341. }
  1342. valueMap[value] = pos++;
  1343. }
  1344. }
  1345. return intValue;
  1346. }
  1347. int ObjectControllerPrivate::intToFlag(const QMetaEnum& metaEnum, int intValue) const
  1348. {
  1349. QMap<int, bool> valueMap; // dont show multiple enum values which have the same values
  1350. QList<int> values;
  1351. for (int i = 0; i < metaEnum.keyCount(); i++) {
  1352. int value = metaEnum.value(i);
  1353. if (!valueMap.contains(value) && isPowerOf2(value)) {
  1354. valueMap[value] = true;
  1355. values.append(value);
  1356. }
  1357. }
  1358. int flagValue = 0;
  1359. int temp = intValue;
  1360. int i = 0;
  1361. while (temp) {
  1362. if (i >= values.count()) {
  1363. return -1;
  1364. }
  1365. if (temp & 1) {
  1366. flagValue |= values.at(i);
  1367. }
  1368. i++;
  1369. temp = temp >> 1;
  1370. }
  1371. return flagValue;
  1372. }
  1373. void ObjectControllerPrivate::expandAll()
  1374. {
  1375. //打开所有节点
  1376. QtTreePropertyBrowser* browser = (QtTreePropertyBrowser*)m_browser;
  1377. browser->expandAll();
  1378. }
  1379. void ObjectControllerPrivate::collapseAll()
  1380. {
  1381. //折叠所有节点
  1382. QtTreePropertyBrowser* browser = (QtTreePropertyBrowser*)m_browser;
  1383. browser->collapseAll();
  1384. //展开父节点
  1385. QList<QtBrowserItem*> items = browser->topLevelItems();
  1386. for (QtBrowserItem* item : items)
  1387. {
  1388. browser->setExpanded(item, true);
  1389. }
  1390. }
  1391. /// <summary>
  1392. /// 当前控件是否是 Table
  1393. /// </summary>
  1394. /// <returns></returns>
  1395. bool ObjectControllerPrivate::isVTableControl()
  1396. {
  1397. QString className = m_object->metaObject()->className();
  1398. if (className == CLASS_NAME_TABLECONTROL)
  1399. {
  1400. return true;
  1401. }
  1402. return false;
  1403. }
  1404. /// <summary>
  1405. /// 当前控件是否是 Pie
  1406. /// </summary>
  1407. /// <returns></returns>
  1408. bool ObjectControllerPrivate::isVPieChart()
  1409. {
  1410. QString className = m_object->metaObject()->className();
  1411. if (className == CLASS_NAME_PIECHART)
  1412. {
  1413. return true;
  1414. }
  1415. return false;
  1416. }
  1417. /// <summary>
  1418. /// 当前控件是否是 Wave
  1419. /// </summary>
  1420. /// <returns></returns>
  1421. bool ObjectControllerPrivate::isVCustomPlot()
  1422. {
  1423. QString className = m_object->metaObject()->className();
  1424. if (className == CLASS_NAME_CUSTOMPLOT)
  1425. {
  1426. return true;
  1427. }
  1428. return false;
  1429. }
  1430. /// <summary>
  1431. /// 当前控件是否是 Image
  1432. /// </summary>
  1433. /// <returns></returns>
  1434. bool ObjectControllerPrivate::isVImageControl()
  1435. {
  1436. QString className = m_object->metaObject()->className();
  1437. if (className == CLASS_NAME_IMAGECONTROL)
  1438. {
  1439. return true;
  1440. }
  1441. return false;
  1442. }
  1443. #include "moc_objectcontroller.cpp"