objectcontroller_bak.cpp 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048
  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
  4. ** Contact: http://www.qt-project.org/legal
  5. **
  6. ** This file is part of the Qt Solutions component.
  7. **
  8. ** $QT_BEGIN_LICENSE:BSD$
  9. ** You may use this file under the terms of the BSD license as follows:
  10. **
  11. ** "Redistribution and use in source and binary forms, with or without
  12. ** modification, are permitted provided that the following conditions are
  13. ** met:
  14. ** * Redistributions of source code must retain the above copyright
  15. ** notice, this list of conditions and the following disclaimer.
  16. ** * Redistributions in binary form must reproduce the above copyright
  17. ** notice, this list of conditions and the following disclaimer in
  18. ** the documentation and/or other materials provided with the
  19. ** distribution.
  20. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
  21. ** of its contributors may be used to endorse or promote products derived
  22. ** from this software without specific prior written permission.
  23. **
  24. **
  25. ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  26. ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27. ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  28. ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  29. ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  30. ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  31. ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  32. ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  33. ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  34. ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  35. ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
  36. **
  37. ** $QT_END_LICENSE$
  38. **
  39. ****************************************************************************/
  40. #include <QMetaObject>
  41. #include <QMetaProperty>
  42. #include <QVBoxLayout>
  43. #include <QScrollArea>
  44. #include <QApplication>
  45. #include <QDebug>
  46. #include "objectcontroller.h"
  47. #include "qtvariantproperty.h"
  48. #include "qtgroupboxpropertybrowser.h"
  49. #include "qttreepropertybrowser.h"
  50. #include "qtpropertybrowser.h"
  51. #include "variantfactory.h"
  52. #include "variantmanager.h"
  53. #include "VTableControl.h"
  54. QMap<QString, QString> maps;
  55. class ObjectControllerPrivate
  56. {
  57. ObjectControllerPrivate()
  58. {
  59. maps.insert("tip", "文本");
  60. maps.insert("title", "标题");
  61. maps.insert("dataLink", "链接");
  62. maps.insert("textColor", "文本色");
  63. maps.insert("bgColor", "背景色");
  64. maps.insert("Red", "红");
  65. maps.insert("Green", "绿");
  66. maps.insert("Blue", "蓝");
  67. maps.insert("Alpha", "明度");
  68. maps.insert("font", "字体");
  69. maps.insert("enable", "启用");
  70. maps.insert("rowCount", "行数");
  71. maps.insert("colCount", "列数");
  72. }
  73. ObjectController* q_ptr;
  74. Q_DECLARE_PUBLIC(ObjectController)
  75. public:
  76. void expandAll();
  77. void collapseAll();
  78. void addClassProperties(const QMetaObject* metaObject);
  79. void addClassPropertiesParent(const QMetaObject* metaObject);
  80. void updateClassProperties(const QMetaObject* metaObject, bool recursive);
  81. void saveExpandedState();
  82. void restoreExpandedState();
  83. void slotValueChanged(QtProperty* property, const QVariant& value);
  84. int enumToInt(const QMetaEnum& metaEnum, int enumValue) const;
  85. int intToEnum(const QMetaEnum& metaEnum, int intValue) const;
  86. int flagToInt(const QMetaEnum& metaEnum, int flagValue) const;
  87. int intToFlag(const QMetaEnum& metaEnum, int intValue) const;
  88. bool isSubValue(int value, int subValue) const;
  89. bool isPowerOf2(int value) const;
  90. // 添加扩展属性
  91. void addTableProperties();
  92. // 移除扩展属性
  93. void removeTableProperites(int delCount);
  94. // 补充扩展属性
  95. void appendTableProperties(int nFixCount);
  96. // 具体的控件数值变更处理代码
  97. void updateTableProperties(VTableControl* pTable, QString propertyName, const QVariant& newValue);
  98. //// 2021-11-24,针对Table类型的控件生成对应的列信息属性表
  99. // QtVariantProperty* addTableProperties(QtProperty* pParent, const int colCount);
  100. // // 更新表格的属性
  101. // void updateTableProperties(QtProperty* pParent, const int colCount);
  102. QObject* m_object;
  103. QMap<const QMetaObject*, QtProperty*> m_classToProperty;
  104. QMap<QtProperty*, const QMetaObject*> m_propertyToClass;
  105. QMap<QtProperty*, int> m_propertyToIndex;
  106. QMap<const QMetaObject*, QMap<int, QtVariantProperty*> > m_classToIndexToProperty;
  107. QMap<QtProperty*, bool> m_propertyToExpanded;
  108. QList<QtProperty*> m_topLevelProperties;
  109. // 2021-11-27增加,保存扩展属性
  110. QList<QtProperty*> m_exProperties;
  111. QtProperty* m_groupEx;
  112. // 2021-9-11 修改 此处直接使用 QtTreePropertyBrowser 指针即可
  113. QtTreePropertyBrowser* m_browser;
  114. // 属性数据结构管理器
  115. QtVariantPropertyManager* m_manager;
  116. QtVariantPropertyManager* m_readOnlyManager;
  117. };
  118. int ObjectControllerPrivate::enumToInt(const QMetaEnum& metaEnum, int enumValue) const
  119. {
  120. QMap<int, int> valueMap; // dont show multiple enum values which have the same values
  121. int pos = 0;
  122. for (int i = 0; i < metaEnum.keyCount(); i++) {
  123. int value = metaEnum.value(i);
  124. if (!valueMap.contains(value)) {
  125. if (value == enumValue) {
  126. return pos;
  127. }
  128. valueMap[value] = pos++;
  129. }
  130. }
  131. return -1;
  132. }
  133. int ObjectControllerPrivate::intToEnum(const QMetaEnum& metaEnum, int intValue) const
  134. {
  135. QMap<int, bool> valueMap; // dont show multiple enum values which have the same values
  136. QList<int> values;
  137. for (int i = 0; i < metaEnum.keyCount(); i++) {
  138. int value = metaEnum.value(i);
  139. if (!valueMap.contains(value)) {
  140. valueMap[value] = true;
  141. values.append(value);
  142. }
  143. }
  144. if (intValue >= values.count()) {
  145. return -1;
  146. }
  147. return values.at(intValue);
  148. }
  149. bool ObjectControllerPrivate::isSubValue(int value, int subValue) const
  150. {
  151. if (value == subValue) {
  152. return true;
  153. }
  154. int i = 0;
  155. while (subValue) {
  156. if (!(value & (1 << i))) {
  157. if (subValue & 1) {
  158. return false;
  159. }
  160. }
  161. i++;
  162. subValue = subValue >> 1;
  163. }
  164. return true;
  165. }
  166. bool ObjectControllerPrivate::isPowerOf2(int value) const
  167. {
  168. while (value) {
  169. if (value & 1) {
  170. return value == 1;
  171. }
  172. value = value >> 1;
  173. }
  174. return false;
  175. }
  176. int ObjectControllerPrivate::flagToInt(const QMetaEnum& metaEnum, int flagValue) const
  177. {
  178. if (!flagValue) {
  179. return 0;
  180. }
  181. int intValue = 0;
  182. QMap<int, int> valueMap; // dont show multiple enum values which have the same values
  183. int pos = 0;
  184. for (int i = 0; i < metaEnum.keyCount(); i++) {
  185. int value = metaEnum.value(i);
  186. if (!valueMap.contains(value) && isPowerOf2(value)) {
  187. if (isSubValue(flagValue, value)) {
  188. intValue |= (1 << pos);
  189. }
  190. valueMap[value] = pos++;
  191. }
  192. }
  193. return intValue;
  194. }
  195. int ObjectControllerPrivate::intToFlag(const QMetaEnum& metaEnum, int intValue) const
  196. {
  197. QMap<int, bool> valueMap; // dont show multiple enum values which have the same values
  198. QList<int> values;
  199. for (int i = 0; i < metaEnum.keyCount(); i++) {
  200. int value = metaEnum.value(i);
  201. if (!valueMap.contains(value) && isPowerOf2(value)) {
  202. valueMap[value] = true;
  203. values.append(value);
  204. }
  205. }
  206. int flagValue = 0;
  207. int temp = intValue;
  208. int i = 0;
  209. while (temp) {
  210. if (i >= values.count()) {
  211. return -1;
  212. }
  213. if (temp & 1) {
  214. flagValue |= values.at(i);
  215. }
  216. i++;
  217. temp = temp >> 1;
  218. }
  219. return flagValue;
  220. }
  221. void ObjectControllerPrivate::expandAll()
  222. {
  223. //打开所有节点
  224. QtTreePropertyBrowser* browser = (QtTreePropertyBrowser*)m_browser;
  225. browser->expandAll();
  226. }
  227. void ObjectControllerPrivate::collapseAll()
  228. {
  229. //折叠所有节点
  230. QtTreePropertyBrowser* browser = (QtTreePropertyBrowser*)m_browser;
  231. browser->collapseAll();
  232. //展开父节点
  233. QList<QtBrowserItem*> items = browser->topLevelItems();
  234. foreach(QtBrowserItem * item, items)
  235. {
  236. browser->setExpanded(item, true);
  237. }
  238. }
  239. void ObjectControllerPrivate::addClassPropertiesParent(const QMetaObject* metaObject)
  240. {
  241. if (!metaObject) {
  242. return;
  243. }
  244. //存储需要过滤的属性,有时候大部分属性都用不上
  245. QStringList keyName;
  246. //keyName << "geometry" << "alignment";
  247. QtProperty* classProperty = m_classToProperty.value(metaObject);
  248. if (!classProperty) {
  249. QString className = QLatin1String(metaObject->className());
  250. classProperty = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), className);
  251. m_classToProperty[metaObject] = classProperty;
  252. m_propertyToClass[classProperty] = metaObject;
  253. for (int idx = metaObject->propertyOffset(); idx < metaObject->propertyCount(); idx++) {
  254. QMetaProperty metaProperty = metaObject->property(idx);
  255. int type = metaProperty.userType();
  256. QtVariantProperty* subProperty = 0;
  257. // //如果当前属性不在需要过滤的属性中则继续下一个属性判断
  258. // QString name = metaProperty.name();
  259. //if (!keyName.contains(name)) {
  260. // continue;
  261. //}
  262. if (!metaProperty.isReadable()) {
  263. subProperty = m_readOnlyManager->addProperty(QVariant::String, QLatin1String(metaProperty.name()));
  264. subProperty->setValue(QLatin1String("< Non Readable >"));
  265. }
  266. else if (metaProperty.isEnumType()) {
  267. if (metaProperty.isFlagType()) {
  268. subProperty = m_manager->addProperty(QtVariantPropertyManager::flagTypeId(), QLatin1String(metaProperty.name()));
  269. QMetaEnum metaEnum = metaProperty.enumerator();
  270. QMap<int, bool> valueMap;
  271. QStringList flagNames;
  272. for (int i = 0; i < metaEnum.keyCount(); i++) {
  273. int value = metaEnum.value(i);
  274. if (!valueMap.contains(value) && isPowerOf2(value)) {
  275. valueMap[value] = true;
  276. flagNames.append(QLatin1String(metaEnum.key(i)));
  277. }
  278. subProperty->setAttribute(QLatin1String("flagNames"), flagNames);
  279. subProperty->setValue(flagToInt(metaEnum, metaProperty.read(m_object).toInt()));
  280. }
  281. }
  282. else {
  283. subProperty = m_manager->addProperty(QtVariantPropertyManager::enumTypeId(), QLatin1String(metaProperty.name()));
  284. QMetaEnum metaEnum = metaProperty.enumerator();
  285. QMap<int, bool> valueMap; // dont show multiple enum values which have the same values
  286. QStringList enumNames;
  287. for (int i = 0; i < metaEnum.keyCount(); i++) {
  288. int value = metaEnum.value(i);
  289. if (!valueMap.contains(value)) {
  290. valueMap[value] = true;
  291. enumNames.append(QLatin1String(metaEnum.key(i)));
  292. }
  293. }
  294. subProperty->setAttribute(QLatin1String("enumNames"), enumNames);
  295. subProperty->setValue(enumToInt(metaEnum, metaProperty.read(m_object).toInt()));
  296. }
  297. }
  298. else if (m_manager->isPropertyTypeSupported(type)) {
  299. if (!metaProperty.isWritable()) {
  300. subProperty = m_readOnlyManager->addProperty(type, QLatin1String(metaProperty.name()) + QLatin1String(" (Non Writable)"));
  301. }
  302. if (!metaProperty.isDesignable()) {
  303. subProperty = m_readOnlyManager->addProperty(type, QLatin1String(metaProperty.name()) + QLatin1String(" (Non Designable)"));
  304. }
  305. else {
  306. subProperty = m_manager->addProperty(type, QLatin1String(metaProperty.name()));
  307. }
  308. subProperty->setValue(metaProperty.read(m_object));
  309. }
  310. else {
  311. subProperty = m_readOnlyManager->addProperty(QVariant::String, QLatin1String(metaProperty.name()));
  312. subProperty->setValue(QLatin1String("< Unknown Type >"));
  313. subProperty->setEnabled(false);
  314. }
  315. classProperty->addSubProperty(subProperty);
  316. m_propertyToIndex[subProperty] = idx;
  317. m_classToIndexToProperty[metaObject][idx] = subProperty;
  318. }
  319. }
  320. else {
  321. updateClassProperties(metaObject, false);
  322. }
  323. m_topLevelProperties.append(classProperty);
  324. m_browser->addProperty(classProperty);
  325. }
  326. void ObjectControllerPrivate::saveExpandedState()
  327. {
  328. }
  329. void ObjectControllerPrivate::restoreExpandedState()
  330. {
  331. }
  332. /////////////////// ObjectController
  333. ObjectController::ObjectController(QWidget* parent)
  334. : QWidget(parent)
  335. {
  336. d_ptr = new ObjectControllerPrivate;
  337. d_ptr->q_ptr = this;
  338. d_ptr->m_object = 0;
  339. /*
  340. QScrollArea *scroll = new QScrollArea(this);
  341. scroll->setWidgetResizable(true);
  342. d_ptr->m_browser = new QtGroupBoxPropertyBrowser(this);
  343. QVBoxLayout *layout = new QVBoxLayout(this);
  344. layout->setMargin(0);
  345. layout->addWidget(scroll);
  346. scroll->setWidget(d_ptr->m_browser);
  347. */
  348. // 生成属性浏览控件
  349. QtTreePropertyBrowser* browser = new QtTreePropertyBrowser(this);
  350. browser->setRootIsDecorated(false);
  351. d_ptr->m_browser = browser;
  352. QVBoxLayout* layout = new QVBoxLayout(this);
  353. layout->setMargin(0);
  354. // 添加新的属性表到界面中
  355. layout->addWidget(d_ptr->m_browser);
  356. d_ptr->m_readOnlyManager = new QtVariantPropertyManager(this);
  357. // 2021-9-11 修改,此处生成 扩展的 VariantManager 对象
  358. VariantManager* pVariantManager = new VariantManager(this);
  359. d_ptr->m_manager = pVariantManager;
  360. pVariantManager->setPropertyEditor(d_ptr->m_browser);
  361. // d_ptr->m_manager = new QtVariantPropertyManager(this);
  362. // 此处生成扩展的 VariantFactory 对象
  363. QtVariantEditorFactory* factory = new VariantFactory(this);
  364. d_ptr->m_browser->setFactoryForManager(d_ptr->m_manager, factory);
  365. // 绑定数据更新消息
  366. connect(d_ptr->m_manager, SIGNAL(valueChanged(QtProperty*, const QVariant&)),
  367. this, SLOT(slotValueChanged(QtProperty*, const QVariant&)));
  368. }
  369. ObjectController::~ObjectController()
  370. {
  371. delete d_ptr;
  372. }
  373. /// <summary>
  374. /// 核心函数,设置控件对象,加载对象的属性信息
  375. /// </summary>
  376. /// <param name="object"></param>
  377. void ObjectController::setObject(QObject* object)
  378. {
  379. //QString name = object->metaObject()->className();
  380. //VTableControl* pTableControl = (VTableControl*)object;
  381. //QVector<TABLE_PROPERTY_EX> pEx = pTableControl->getExProperties();
  382. //如果设置的控件已经是当前控件则不处理
  383. if (d_ptr->m_object == object)
  384. {
  385. return;
  386. }
  387. if (d_ptr->m_object)
  388. {
  389. // 保存当前属性表中子属性的状态
  390. d_ptr->saveExpandedState();
  391. // 枚举属性表中之前的所有属性进行删除
  392. QListIterator<QtProperty *> it(d_ptr->m_topLevelProperties);
  393. while (it.hasNext())
  394. {
  395. // 删除本节点下所有节点和子节点
  396. d_ptr->m_browser->removeProperty(it.next());
  397. }
  398. d_ptr->m_topLevelProperties.clear();
  399. }
  400. // 将新的对象指针保存
  401. d_ptr->m_object = object;
  402. if (!d_ptr->m_object)
  403. {
  404. return;
  405. }
  406. //加载父类的属性
  407. // QWidget
  408. // d_ptr->addClassPropertiesParent(d_ptr->m_object->metaObject()->superClass()->superClass());
  409. // 2021-9-21修改,此处只取子属性即可
  410. // d_ptr->addClassPropertiesParent(d_ptr->m_object->metaObject()->superClass());
  411. // 加载当前控件的属性
  412. d_ptr->addClassProperties(d_ptr->m_object->metaObject());
  413. // 根据不同的类型加载控件不同的扩展属性
  414. QString strControlClassName = d_ptr->m_object->metaObject()->className();
  415. // Table Control
  416. if (strControlClassName == CLASS_NAME_TABLECONTROL)
  417. {
  418. //VTableControl* pTable = qobject_cast<VTableControl*>(d_ptr->m_object);
  419. //d_ptr->addTablePropertiesEx(pTable, d_ptr->m_classToProperty.value(d_ptr->m_object->metaObject()));
  420. d_ptr->addTableProperties();
  421. }
  422. // 还原属性结构中子属性的展开状态
  423. d_ptr->restoreExpandedState();
  424. //展开所有节点
  425. d_ptr->expandAll();
  426. }
  427. QObject* ObjectController::object() const
  428. {
  429. return d_ptr->m_object;
  430. }
  431. /// <summary>
  432. /// 核心函数,解析metaObject,添加对应属性表
  433. /// </summary>
  434. /// <param name="metaObject"></param>
  435. void ObjectControllerPrivate::addClassProperties(const QMetaObject* metaObject)
  436. {
  437. if (!metaObject)
  438. {
  439. return;
  440. }
  441. // 根据类指针找到对应的属性表
  442. QtProperty* classProperty = m_classToProperty.value(metaObject);
  443. // 如果属性表有效
  444. if (!classProperty)
  445. {
  446. // 获取Object自身的名称作为属性表中的Top分组
  447. QString className = QLatin1String(metaObject->className());
  448. // 属性表中添加对应的Top分组
  449. classProperty = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), className);
  450. // 保存Top分组和Object指针的对应关系
  451. m_classToProperty[metaObject] = classProperty;
  452. // 保存Object指针和Top分组的对应关系
  453. m_propertyToClass[classProperty] = metaObject;
  454. // 枚举本Object的所有属性,从propertyOffset开始
  455. //// 保存控件多级属性的数量用于自动生成对应的属性设置信息
  456. //int nLinkCount = 0;
  457. for (int idx = metaObject->propertyOffset(); idx < metaObject->propertyCount(); idx++)
  458. {
  459. // 取出对应的属性
  460. QMetaProperty metaProperty = metaObject->property(idx);
  461. // 取出Type编号
  462. int type = metaProperty.userType();
  463. // 用来保存子属性
  464. QtVariantProperty* subProperty = 0;
  465. //将英文属性换成中文属性
  466. QString propertyName = metaProperty.name();
  467. // 从map对应表中获取对应的中文
  468. propertyName = maps.value(propertyName, propertyName);
  469. // 如果属性不可读,则直接设置为 Non Readable
  470. if (!metaProperty.isReadable())
  471. {
  472. subProperty = m_readOnlyManager->addProperty(QVariant::String, propertyName);
  473. subProperty->setValue(QLatin1String("< Non Readable >"));
  474. }
  475. // 是否是枚举类型
  476. else if (metaProperty.isEnumType())
  477. {
  478. // 是否是Flag类型
  479. if (metaProperty.isFlagType())
  480. {
  481. subProperty = m_manager->addProperty(QtVariantPropertyManager::flagTypeId(), propertyName);
  482. QMetaEnum metaEnum = metaProperty.enumerator();
  483. QMap<int, bool> valueMap;
  484. QStringList flagNames;
  485. for (int i = 0; i < metaEnum.keyCount(); i++) {
  486. int value = metaEnum.value(i);
  487. if (!valueMap.contains(value) && isPowerOf2(value)) {
  488. valueMap[value] = true;
  489. flagNames.append(QLatin1String(metaEnum.key(i)));
  490. }
  491. subProperty->setAttribute(QLatin1String("flagNames"), flagNames);
  492. subProperty->setValue(flagToInt(metaEnum, metaProperty.read(m_object).toInt()));
  493. }
  494. }
  495. // 否则按照枚举类型进行添加
  496. else
  497. {
  498. subProperty = m_manager->addProperty(QtVariantPropertyManager::enumTypeId(), propertyName);
  499. QMetaEnum metaEnum = metaProperty.enumerator();
  500. QMap<int, bool> valueMap; // dont show multiple enum values which have the same values
  501. QStringList enumNames;
  502. for (int i = 0; i < metaEnum.keyCount(); i++)
  503. {
  504. int value = metaEnum.value(i);
  505. if (!valueMap.contains(value))
  506. {
  507. valueMap[value] = true;
  508. //将枚举类型强制转为中文
  509. QString enumName = metaEnum.key(i);
  510. enumName = maps.value(enumName, enumName);
  511. enumNames.append(enumName);
  512. }
  513. }
  514. subProperty->setAttribute(QLatin1String("enumNames"), enumNames);
  515. subProperty->setValue(enumToInt(metaEnum, metaProperty.read(m_object).toInt()));
  516. }
  517. }
  518. // 是否是Manager所支持的属性
  519. else if (m_manager->isPropertyTypeSupported(type))
  520. {
  521. // 如果不可写,则以只读Manager添加
  522. if (!metaProperty.isWritable())
  523. {
  524. subProperty = m_readOnlyManager->addProperty(type, propertyName + QLatin1String(" (Non Writable)"));
  525. }
  526. // 如果不可设计,则以只读Manager添加
  527. else if (!metaProperty.isDesignable())
  528. {
  529. subProperty = m_readOnlyManager->addProperty(type, propertyName + QLatin1String(" (Non Designable)"));
  530. }
  531. //// 如果是表格类型,则单独进行表格类型的添加
  532. //else if (type == VariantManager::tagTableExInfoTypeId())
  533. //{
  534. // subProperty = this->addTableProperties(classProperty, nLinkCount);
  535. //}
  536. // 核心步骤:大部分属性都是通过此路径进行添加
  537. else if (type != VariantManager::tagTableExInfoTypeId())
  538. {
  539. subProperty = m_manager->addProperty(type, propertyName);
  540. }
  541. // 设置本属性的值
  542. // (对于表格等复杂属性来说,这个值是空的)
  543. QVariant objValue = metaProperty.read(m_object);
  544. subProperty->setValue(objValue);
  545. //// 保存Table的列信息用于生成对应的属性设置项
  546. //if (propertyName == "列数")
  547. //{
  548. // nLinkCount = objValue.toInt();
  549. //}
  550. }
  551. // 否则,则添加未知属性信息到表中,并且置为不可用
  552. else
  553. {
  554. subProperty = m_readOnlyManager->addProperty(QVariant::String, propertyName);
  555. subProperty->setValue(QLatin1String("< Unknown Type >"));
  556. subProperty->setEnabled(false);
  557. }
  558. // 在本属性组中添加本属性
  559. classProperty->addSubProperty(subProperty);
  560. // 保存属性及其对应的索引号
  561. m_propertyToIndex[subProperty] = idx;
  562. // 保存Object指针、索引号以及对应的属性关系
  563. m_classToIndexToProperty[metaObject][idx] = subProperty;
  564. }
  565. }
  566. else
  567. {
  568. // 否则不增加新属性,而是更新现有属性
  569. updateClassProperties(metaObject, false);
  570. }
  571. // 在属性表中的顶层属性表信息中添加本组属性
  572. //(由于控件的继承关系,属性表中会有多个顶层属性组)
  573. m_topLevelProperties.append(classProperty);
  574. // 向属性表中添加本组属性
  575. m_browser->addProperty(classProperty);
  576. }
  577. ///// <summary>
  578. ///// 2021-11-24,针对Table类型的控件生成对应的列信息属性表
  579. ///// </summary>
  580. ///// <param name="pParent"></param>
  581. ///// <param name="colCount"></param>
  582. //QtVariantProperty* ObjectControllerPrivate::addTableProperties(QtProperty* pParent, const int colCount)
  583. //{
  584. // QtVariantProperty* groupItemTop = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), ("表格"));
  585. //
  586. // if (colCount <= 0)
  587. // {
  588. // return groupItemTop;
  589. // }
  590. //
  591. // for (int i = 0; i < colCount; i++)
  592. // {
  593. // QtProperty* subGroupItem = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), QString("列") + QString::number(i+1));
  594. //
  595. // QtVariantProperty* item = m_manager->addProperty(QVariant::String, ("列名"));
  596. // subGroupItem->addSubProperty(item);
  597. // item->setValue(QString("列名") + QString::number(i + 1));
  598. //
  599. // item = m_manager->addProperty(VariantManager::tagDataLinkTypeId(), ("数据链接"));
  600. // subGroupItem->addSubProperty(item);
  601. // item->setValue("");
  602. //
  603. // groupItemTop->addSubProperty(subGroupItem);
  604. // }
  605. //
  606. // // m_topLevelProperties.append(groupItemTop);
  607. // // m_browser->addProperty(groupItemTop);
  608. //
  609. // return groupItemTop;
  610. //
  611. //
  612. //// QtVariantProperty* item = d_ptr->m_manager->addProperty(QVariant::Int, ("行数:"));
  613. //// item->setValue(2);
  614. //// groupItemTop->addSubProperty(item);
  615. //
  616. //// item = d_ptr->m_manager->addProperty(QVariant::Int, ("列数:"));
  617. //// item->setValue(6);
  618. //// groupItemTop->addSubProperty(item);
  619. //
  620. //
  621. //// QtProperty* groupItem2 = d_ptr->m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), ("列信息"));
  622. //
  623. //
  624. //// for (int i = 0; i < 3; i++)
  625. //// {
  626. //// QtProperty* subGroupItem = d_ptr->m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), QString("列名") + QString::number(i+1));
  627. ////
  628. //// item = d_ptr->m_manager->addProperty(QVariant::String, ("列名"));
  629. //// subGroupItem->addSubProperty(item);
  630. //// item->setValue(QString("列名") + QString::number(i + 1));
  631. //
  632. //// item = d_ptr->m_manager->addProperty(VariantManager::tagDataLinkTypeId(), ("数据链接"));
  633. //// subGroupItem->addSubProperty(item);
  634. //// item->setValue("");
  635. //
  636. //// groupItem2->addSubProperty(subGroupItem);
  637. //// }
  638. //
  639. //// groupItemTop->addSubProperty(groupItem2);
  640. //
  641. // //d_ptr->m_topLevelProperties.append(groupItemTop);
  642. // //d_ptr->m_browser->addProperty(groupItemTop);
  643. //}
  644. /// <summary>
  645. /// 添加Table的扩展属性
  646. /// </summary>
  647. /// <param name="pObject"></param>
  648. void ObjectControllerPrivate::addTableProperties()
  649. {
  650. const QMetaObject* metaObject = m_object->metaObject();
  651. //// 获取Table控件指针
  652. //VTableControl* pTable = qobject_cast<VTableControl*>(m_object);
  653. //// 取出对应的扩展属性
  654. //const QVector<TABLE_PROPERTY_EX>& props = pTable->getExProperties();
  655. //if (props.size() <= 0)
  656. //{
  657. // return;
  658. //}
  659. //int nExIndex = m_object->metaObject()->propertyCount();
  660. //// 根据类指针找到对应的属性表
  661. //QtProperty* classProperty = m_classToProperty.value(m_object->metaObject());
  662. //// 表格属性根节点
  663. //m_groupEx = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), ("表格"));
  664. //// 清空扩展属性表,准备保存新的扩展属性
  665. //m_exProperties.clear();
  666. //// 将子项添加到属性表中
  667. //for (int i = 0; i < props.size(); i++)
  668. //{
  669. // QtProperty* subGroupItem = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), QString("列") + QString::number(i + 1));
  670. // // 增加列名
  671. // QtVariantProperty* item = m_manager->addProperty(QVariant::String, ("列名"));
  672. // subGroupItem->addSubProperty(item);
  673. // item->setValue(props[i].m_strTitle);
  674. // // 保存属性及其对应的索引号
  675. // m_propertyToIndex[item] = nExIndex++;
  676. // // 保存Object指针、索引号以及对应的属性关系
  677. // m_classToIndexToProperty[metaObject][nExIndex] = item;
  678. // // 增加数据连接
  679. // item = m_manager->addProperty(VariantManager::tagDataLinkTypeId(), ("数据链接"));
  680. // subGroupItem->addSubProperty(item);
  681. // item->setValue("");
  682. // // 保存属性及其对应的索引号
  683. // m_propertyToIndex[item] = nExIndex++;
  684. // // 保存Object指针、索引号以及对应的属性关系
  685. // m_classToIndexToProperty[metaObject][nExIndex] = item;
  686. // // 本组中添加此属性
  687. // m_groupEx->addSubProperty(subGroupItem);
  688. // // 保存扩展属性信息
  689. // m_exProperties.push_back(subGroupItem);
  690. //}
  691. //// 在本属性组中添加本属性
  692. //classProperty->addSubProperty(m_groupEx);
  693. }
  694. /// <summary>
  695. /// 当属性表中有数值变更时,进行对应的处理
  696. /// </summary>
  697. /// <param name="property"></param>
  698. /// <param name="value"></param>
  699. void ObjectControllerPrivate::slotValueChanged(QtProperty* property, const QVariant& value)
  700. {
  701. qDebug() << "ObjectControllerPrivate::slotValueChanged - " << value.toString();
  702. if (!m_propertyToIndex.contains(property))
  703. {
  704. return;
  705. }
  706. int idx = m_propertyToIndex.value(property);
  707. const QMetaObject* metaObject = m_object->metaObject();
  708. QMetaProperty metaProperty = metaObject->property(idx);
  709. if (metaProperty.isEnumType())
  710. {
  711. if (metaProperty.isFlagType())
  712. {
  713. metaProperty.write(m_object, intToFlag(metaProperty.enumerator(), value.toInt()));
  714. }
  715. else
  716. {
  717. metaProperty.write(m_object, intToEnum(metaProperty.enumerator(), value.toInt()));
  718. }
  719. }
  720. else
  721. {
  722. metaProperty.write(m_object, value);
  723. }
  724. updateClassProperties(metaObject, true);
  725. // 继续处理扩展属性
  726. // 获取属性名称
  727. QString propertyName = metaProperty.name();
  728. QString className = metaObject->className();
  729. QVariant newValue = metaProperty.read(m_object);
  730. // 如果是Table控件相关属性变更
  731. if (className == CLASS_NAME_TABLECONTROL)
  732. {
  733. // 获取Table控件指针
  734. VTableControl* pTable = qobject_cast<VTableControl*>(m_object);
  735. //// 获取Table的扩展属性信息
  736. //QVector<TABLE_PROPERTY_EX>& props = pTable->getExProperties();
  737. this->updateTableProperties(pTable, propertyName, newValue);
  738. }
  739. }
  740. /// <summary>
  741. /// 移除扩展属性
  742. /// </summary>
  743. /// <param name="property"></param>
  744. /// <param name="delCount">需要删除的属性个数</param>
  745. void ObjectControllerPrivate::removeTableProperites(int delCount)
  746. {
  747. //// 获取Table控件指针
  748. //VTableControl* pTable = qobject_cast<VTableControl*>(m_object);
  749. //// 获取Table的扩展属性信息
  750. //QVector<TABLE_PROPERTY_EX>& props = pTable->getExProperties();
  751. //for (int i = 0; i < delCount; i++)
  752. //{
  753. // props.pop_back();
  754. // QtProperty* pDelProperty = m_exProperties.back();
  755. // // 递归删除此节点的数据及界面元素
  756. // m_browser->removePropertyEx(pDelProperty);
  757. // m_exProperties.pop_back();
  758. //}
  759. }
  760. /// <summary>
  761. /// 补充扩展属性
  762. /// </summary>
  763. /// <param name="nFixCount"></param>
  764. void ObjectControllerPrivate::appendTableProperties(int nFixCount)
  765. {
  766. //// 获取Table控件指针
  767. //VTableControl* pTable = qobject_cast<VTableControl*>(m_object);
  768. //// 获取Table的扩展属性信息
  769. //QVector<TABLE_PROPERTY_EX>& props = pTable->getExProperties();
  770. //// 将子项添加到属性表中
  771. //for (int i = 0; i < nFixCount; i++)
  772. //{
  773. // TABLE_PROPERTY_EX newProp;
  774. // newProp.m_strTitle = "列名" + QString::number(props.size() + 1);
  775. // props.push_back(newProp);
  776. // QtProperty* subGroupItem = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), QString("列") + QString::number(props.size() + 1));
  777. // QtVariantProperty* item = m_manager->addProperty(QVariant::String, ("列名"));
  778. // subGroupItem->addSubProperty(item);
  779. // item->setValue(newProp.m_strTitle);
  780. // item = m_manager->addProperty(VariantManager::tagDataLinkTypeId(), ("数据链接"));
  781. // subGroupItem->addSubProperty(item);
  782. // item->setValue("");
  783. // m_groupEx->addSubProperty(subGroupItem);
  784. // // 保存扩展属性信息
  785. // m_exProperties.push_back(subGroupItem);
  786. //}
  787. }
  788. /// <summary>
  789. /// 具体的控件数值变更处理代码
  790. /// </summary>
  791. /// <param name="propertyName"></param>
  792. /// <param name="newValue"></param>
  793. void ObjectControllerPrivate::updateTableProperties(VTableControl* pTable, QString propertyName, const QVariant& newValue)
  794. {
  795. //// 如果变更了列数,则需要动态调整属性表
  796. //if (propertyName == "colCount")
  797. //{
  798. // // 获取用户新输入的数量
  799. // int nNewCount = newValue.toInt();
  800. // int nFixCount = m_exProperties.size() - nNewCount;
  801. // // 如果新的数量小于旧的数量,则需要移除旧的属性项
  802. // if (nFixCount > 0)
  803. // {
  804. // // 临时屏蔽了删除代码,尚存在问题
  805. // // this->removeTableProperites(nFixCount);
  806. // return;
  807. // }
  808. // // 否则,增加新的属性项
  809. // this->appendTableProperties(qAbs(nFixCount));
  810. //}
  811. //// 如果变更了列名,则需要保存
  812. //else if (propertyName.indexOf("列名") >= 0)
  813. //{
  814. // int nColNameIndex = propertyName.remove("列名").toInt();
  815. // pTable->updateTableColName(nColNameIndex, newValue.toString());
  816. //}
  817. }
  818. /// <summary>
  819. /// 对已有属性表进行更新
  820. /// </summary>
  821. /// <param name="metaObject"></param>
  822. /// <param name="recursive"></param>
  823. void ObjectControllerPrivate::updateClassProperties(const QMetaObject* metaObject, bool recursive)
  824. {
  825. if (!metaObject)
  826. {
  827. return;
  828. }
  829. if (recursive)
  830. {
  831. updateClassProperties(metaObject->superClass(), recursive);
  832. }
  833. // 获取属性值的根节点
  834. QtProperty* classProperty = m_classToProperty.value(metaObject);
  835. if (!classProperty)
  836. {
  837. return;
  838. }
  839. // 保存控件多级属性的数量用于自动生成对应的属性设置信息
  840. // int nLinkCount = 0;
  841. // 遍历所有的属性执行更新
  842. for (int idx = metaObject->propertyOffset(); idx < metaObject->propertyCount(); idx++)
  843. {
  844. QMetaProperty metaProperty = metaObject->property(idx);
  845. //// 取出Type编号
  846. //int type = metaProperty.userType();
  847. if (metaProperty.isReadable())
  848. {
  849. if (m_classToIndexToProperty.contains(metaObject) && m_classToIndexToProperty[metaObject].contains(idx))
  850. {
  851. QtVariantProperty* subProperty = m_classToIndexToProperty[metaObject][idx];
  852. if (metaProperty.isEnumType())
  853. {
  854. if (metaProperty.isFlagType())
  855. {
  856. subProperty->setValue(flagToInt(metaProperty.enumerator(), metaProperty.read(m_object).toInt()));
  857. }
  858. else
  859. {
  860. subProperty->setValue(enumToInt(metaProperty.enumerator(), metaProperty.read(m_object).toInt()));
  861. }
  862. }
  863. // TODO: 需要在此处额外增加动态清除旧属性表,更新新属性表的内容
  864. // TODO: 此处更新时还需要清空DataLink表中的值,解决旧有的bug
  865. // // 如果是Table类型
  866. //else if (type == VariantManager::tagTableExInfoTypeId())
  867. //{
  868. // this->updateTableProperties(classProperty, nLinkCount);
  869. //}
  870. // 其他通用类型直接设置新的值
  871. else
  872. {
  873. subProperty->setValue(metaProperty.read(m_object));
  874. }
  875. //// 设置本属性的值
  876. //QVariant objValue = metaProperty.read(m_object);
  877. //// 保存Table的列信息用于生成对应的属性设置项
  878. //QString propertyName = metaProperty.name();
  879. //if (propertyName == "colCount")
  880. //{
  881. // nLinkCount = objValue.toInt();
  882. //}
  883. }
  884. }
  885. }
  886. }
  887. #include "moc_objectcontroller.cpp"