Changeset 846 for trunk/tools/qdoc3/node.cpp
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/tools/qdoc3/node.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 44 44 */ 45 45 46 #include <QtCore>47 46 #include "node.h" 47 #include "tree.h" 48 #include "codemarker.h" 49 #include <qdebug.h> 48 50 49 51 QT_BEGIN_NAMESPACE … … 86 88 87 89 /*! 90 Construct a node with the given \a type and having the 91 given \a parent and \a name. The new node is added to the 92 parent's child list. 88 93 */ 89 94 Node::Node(Type type, InnerNode *parent, const QString& name) 90 95 : typ(type), 91 96 acc(Public), 97 saf(UnspecifiedSafeness), 98 pageTyp(NoPageType), 92 99 sta(Commendable), 93 saf(UnspecifiedSafeness),94 100 par(parent), 95 101 rel(0), … … 98 104 if (par) 99 105 par->addChild(this); 100 } 101 102 /*! 106 //uuid = QUuid::createUuid(); 107 } 108 109 /*! 110 Returns the node's URL. 103 111 */ 104 112 QString Node::url() const … … 108 116 109 117 /*! 118 Sets the node's URL to \a url 110 119 */ 111 120 void Node::setUrl(const QString &url) … … 114 123 } 115 124 116 /*! 125 void Node::setPageType(const QString& t) 126 { 127 if ((t == "API") || (t == "api")) 128 pageTyp = ApiPage; 129 else if (t == "article") 130 pageTyp = ArticlePage; 131 else if (t == "example") 132 pageTyp = ExamplePage; 133 } 134 135 /*! 136 Sets the pointer to the node that this node relates to. 117 137 */ 118 138 void Node::setRelates(InnerNode *pseudoParent) … … 138 158 139 159 /*! 160 Returns a string representing the access specifier. 161 */ 162 QString Node::accessString() const 163 { 164 switch (acc) { 165 case Protected: 166 return "protected"; 167 case Private: 168 return "private"; 169 case Public: 170 default: 171 break; 172 } 173 return "public"; 174 } 175 176 /*! 177 Extract a class name from the type \a string and return it. 178 */ 179 QString Node::extractClassName(const QString &string) const 180 { 181 QString result; 182 for (int i=0; i<=string.size(); ++i) { 183 QChar ch; 184 if (i != string.size()) 185 ch = string.at(i); 186 187 QChar lower = ch.toLower(); 188 if ((lower >= QLatin1Char('a') && lower <= QLatin1Char('z')) || 189 ch.digitValue() >= 0 || 190 ch == QLatin1Char('_') || 191 ch == QLatin1Char(':')) { 192 result += ch; 193 } 194 else if (!result.isEmpty()) { 195 if (result != QLatin1String("const")) 196 return result; 197 result.clear(); 198 } 199 } 200 return result; 201 } 202 203 /*! 204 Returns a string representing the access specifier. 205 */ 206 QString RelatedClass::accessString() const 207 { 208 switch (access) { 209 case Node::Protected: 210 return "protected"; 211 case Node::Private: 212 return "private"; 213 case Node::Public: 214 default: 215 break; 216 } 217 return "public"; 218 } 219 220 /*! 140 221 */ 141 222 Node::Status Node::inheritedStatus() const … … 148 229 149 230 /*! 231 Returns the thread safeness value for whatever this node 232 represents. But if this node has a parent and the thread 233 safeness value of the parent is the same as the thread 234 safeness value of this node, what is returned is the 235 value \c{UnspecifiedSafeness}. Why? 150 236 */ 151 237 Node::ThreadSafeness Node::threadSafeness() const … … 157 243 158 244 /*! 245 If this node has a parent, the parent's thread safeness 246 value is returned. Otherwise, this node's thread safeness 247 value is returned. Why? 159 248 */ 160 249 Node::ThreadSafeness Node::inheritedThreadSafeness() const … … 166 255 167 256 /*! 257 Returns the sanitized file name without the path. 258 If the the file is an html file, the html suffix 259 is removed. Why? 168 260 */ 169 261 QString Node::fileBase() const … … 179 271 180 272 /*! 273 Returns this node's Universally Unique IDentifier. 274 If its UUID has not yet been created, it is created 275 first. 276 */ 277 QUuid Node::guid() const 278 { 279 if (uuid.isNull()) 280 uuid = QUuid::createUuid(); 281 return uuid; 282 } 283 284 /*! 285 Composes a string to be used as an href attribute in DITA 286 XML. It is composed of the file name and the UUID separated 287 by a '#'. If this node is a class node, the file name is 288 taken from this node; if this node is a function node, the 289 file name is taken from the parent node of this node. 290 */ 291 QString Node::ditaXmlHref() 292 { 293 QString href; 294 if ((type() == Function) || 295 (type() == Property) || 296 (type() == Variable)) { 297 href = parent()->fileBase(); 298 } 299 else { 300 href = fileBase(); 301 } 302 if (!href.endsWith(".xml")) 303 href += ".xml"; 304 return href + "#" + guid(); 305 } 306 307 /*! 181 308 \class InnerNode 182 309 */ 183 310 184 311 /*! 312 The inner node destructor deletes the children and removes 313 this node from its related nodes. 185 314 */ 186 315 InnerNode::~InnerNode() … … 191 320 192 321 /*! 322 Find the node in this node's children that has the 323 given \a name. If this node is a QML class node, be 324 sure to also look in the children of its property 325 group nodes. Return the matching node or 0. 193 326 */ 194 327 Node *InnerNode::findNode(const QString& name) 195 328 { 196 329 Node *node = childMap.value(name); 197 if (node )330 if (node && node->subType() != QmlPropertyGroup) 198 331 return node; 332 if ((type() == Fake) && (subType() == QmlClass)) { 333 for (int i=0; i<children.size(); ++i) { 334 Node* n = children.at(i); 335 if (n->subType() == QmlPropertyGroup) { 336 node = static_cast<InnerNode*>(n)->findNode(name); 337 if (node) 338 return node; 339 } 340 } 341 } 199 342 return primaryFunctionMap.value(name); 200 343 } 201 344 202 345 /*! 346 Same as the other findNode(), but if the node with the 347 specified \a name is not of the specified \a type, return 348 0. 203 349 */ 204 350 Node *InnerNode::findNode(const QString& name, Type type) … … 309 455 310 456 /*! 457 Mark all child nodes that have no documentation as having 458 private access and internal status. qdoc will then ignore 459 them for documentation purposes. 311 460 */ 312 461 void InnerNode::makeUndocumentedChildrenInternal() … … 382 531 /*! 383 532 */ 384 void InnerNode::removeFromRelated() 533 void InnerNode::removeFromRelated() 385 534 { 386 535 while (!related.isEmpty()) { … … 399 548 400 549 /*! 401 Returns true .550 Returns true because this is an inner node. 402 551 */ 403 552 bool InnerNode::isInnerNode() const … … 423 572 424 573 /*! 425 Find the function node in this node that has the given \a name. 574 Find the function node in this node that has the given \a name. 426 575 */ 427 576 const FunctionNode *InnerNode::findFunctionNode(const QString& name) const … … 453 602 454 603 /*! 604 Returnds the sequence number of the function node \a func 605 in the list of overloaded functions for a class, such that 606 all the functions have the same name as the \a func. 455 607 */ 456 608 int InnerNode::overloadNumber(const FunctionNode *func) const … … 466 618 467 619 /*! 620 Returns the number of member functions of a class such that 621 the functions are all named \a funcName. 468 622 */ 469 623 int InnerNode::numOverloads(const QString& funcName) const … … 478 632 479 633 /*! 634 Returns a node list containing all the member functions of 635 some class such that the functions overload the name \a funcName. 480 636 */ 481 637 NodeList InnerNode::overloads(const QString &funcName) const … … 491 647 492 648 /*! 649 Construct an inner node (i.e., not a leaf node) of the 650 given \a type and having the given \a parent and \a name. 493 651 */ 494 652 InnerNode::InnerNode(Type type, InnerNode *parent, const QString& name) 495 653 : Node(type, parent, name) 496 654 { 497 } 498 499 /*! 655 switch (type) { 656 case Class: 657 case Namespace: 658 setPageType(ApiPage); 659 break; 660 default: 661 break; 662 } 663 } 664 665 /*! 666 Appends an \a include file to the list of include files. 500 667 */ 501 668 void InnerNode::addInclude(const QString& include) … … 505 672 506 673 /*! 674 Sets the list of include files to \a includes. 507 675 */ 508 676 void InnerNode::setIncludes(const QStringList& includes) … … 548 716 549 717 /*! 718 Adds the \a child to this node's child list. 550 719 */ 551 720 void InnerNode::addChild(Node *child) … … 565 734 if (child->type() == Enum) 566 735 enumChildren.append(child); 567 736 childMap.insert(child->name(), child); 568 737 } 569 738 } … … 579 748 primaryFunctionMap.find(child->name()); 580 749 NodeList& secs = secondaryFunctionMap[child->name()]; 581 if ( *prim == child) {750 if (prim != primaryFunctionMap.end() && *prim == child) { 582 751 if (secs.isEmpty()) { 583 752 primaryFunctionMap.remove(child->name()); … … 591 760 } 592 761 QMap<QString, Node *>::Iterator ent = childMap.find( child->name() ); 593 if ( *ent == child)762 if (ent != childMap.end() && *ent == child) 594 763 childMap.erase( ent ); 595 764 } 596 765 else { 597 766 QMap<QString, Node *>::Iterator ent = childMap.find(child->name()); 598 if ( *ent == child)767 if (ent != childMap.end() && *ent == child) 599 768 childMap.erase(ent); 600 769 } … … 677 846 678 847 /*! 848 Constructs a leaf node named \a name of the specified 849 \a type. The new leaf node becomes a child of \a parent. 679 850 */ 680 851 LeafNode::LeafNode(Type type, InnerNode *parent, const QString& name) 681 852 : Node(type, parent, name) 682 853 { 854 switch (type) { 855 case Enum: 856 case Function: 857 case Typedef: 858 case Variable: 859 case QmlProperty: 860 case QmlSignal: 861 case QmlMethod: 862 setPageType(ApiPage); 863 break; 864 default: 865 break; 866 } 683 867 } 684 868 … … 688 872 689 873 /*! 874 Constructs a namespace node. 690 875 */ 691 876 NamespaceNode::NamespaceNode(InnerNode *parent, const QString& name) 692 877 : InnerNode(Namespace, parent, name) 693 878 { 879 setPageType(ApiPage); 694 880 } 695 881 696 882 /*! 697 883 \class ClassNode 698 */ 699 700 /*! 884 \brief This class represents a C++ class. 885 */ 886 887 /*! 888 Constructs a class node. A class node will generate an API page. 701 889 */ 702 890 ClassNode::ClassNode(InnerNode *parent, const QString& name) … … 704 892 { 705 893 hidden = false; 894 abstract = false; 895 setPageType(ApiPage); 706 896 } 707 897 … … 712 902 const QString &dataTypeWithTemplateArgs) 713 903 { 714 bas .append(RelatedClass(access, node, dataTypeWithTemplateArgs));715 node->der .append(RelatedClass(access, this));904 bases.append(RelatedClass(access, node, dataTypeWithTemplateArgs)); 905 node->derived.append(RelatedClass(access, this)); 716 906 } 717 907 … … 721 911 { 722 912 int i; 723 724 913 i = 0; 725 while (i < bas.size()) { 726 ClassNode *baseClass = bas.at(i).node; 727 if (baseClass->access() == Node::Private) { 728 bas.removeAt(i); 729 730 const QList<RelatedClass> &basesBases = baseClass->baseClasses(); 731 for (int j = basesBases.size() - 1; j >= 0; --j) 732 bas.insert(i, basesBases.at(j)); 914 while (i < bases.size()) { 915 ClassNode* bc = bases.at(i).node; 916 if (bc->access() == Node::Private) { 917 RelatedClass rc = bases.at(i); 918 bases.removeAt(i); 919 ignoredBases.append(rc); 920 const QList<RelatedClass> &bb = bc->baseClasses(); 921 for (int j = bb.size() - 1; j >= 0; --j) 922 bases.insert(i, bb.at(j)); 733 923 } 734 924 else { … … 738 928 739 929 i = 0; 740 while (i < der.size()) { 741 ClassNode *derivedClass = der.at(i).node; 742 if (derivedClass->access() == Node::Private) { 743 der.removeAt(i); 744 745 const QList<RelatedClass> &dersDers = 746 derivedClass->derivedClasses(); 747 for (int j = dersDers.size() - 1; j >= 0; --j) 748 der.insert(i, dersDers.at(j)); 930 while (i < derived.size()) { 931 ClassNode* dc = derived.at(i).node; 932 if (dc->access() == Node::Private) { 933 derived.removeAt(i); 934 const QList<RelatedClass> &dd = dc->derivedClasses(); 935 for (int j = dd.size() - 1; j >= 0; --j) 936 derived.insert(i, dd.at(j)); 749 937 } 750 938 else { … … 755 943 756 944 /*! 945 Search the child list to find the property node with the 946 specified \a name. 947 */ 948 const PropertyNode* ClassNode::findPropertyNode(const QString& name) const 949 { 950 const Node* n = findNode(name,Node::Property); 951 return (n ? static_cast<const PropertyNode*>(n) : 0); 952 } 953 954 /*! 757 955 \class FakeNode 758 956 */ … … 760 958 /*! 761 959 The type of a FakeNode is Fake, and it has a \a subtype, 762 which specifies the type of FakeNode. 960 which specifies the type of FakeNode. The page type for 961 the page index is set here. 763 962 */ 764 963 FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subtype) 765 964 : InnerNode(Fake, parent, name), sub(subtype) 766 965 { 966 switch (subtype) { 967 case Module: 968 case Page: 969 case Group: 970 setPageType(ArticlePage); 971 break; 972 case QmlClass: 973 case QmlBasicType: 974 setPageType(ApiPage); 975 break; 976 case Example: 977 setPageType(ExamplePage); 978 break; 979 default: 980 break; 981 } 982 } 983 984 /*! 985 Returns the fake node's title. This is used for the page title. 986 */ 987 QString FakeNode::title() const 988 { 989 return tle; 767 990 } 768 991 … … 817 1040 818 1041 /*! 1042 The constructor for the node representing an enum type 1043 has a \a parent class and an enum type \a name. 819 1044 */ 820 1045 EnumNode::EnumNode(InnerNode *parent, const QString& name) … … 824 1049 825 1050 /*! 1051 Add \a item to the enum type's item list. 826 1052 */ 827 1053 void EnumNode::addItem(const EnumItem& item) … … 832 1058 833 1059 /*! 1060 Returns the access level of the enumeration item named \a name. 1061 Apparently it is private if it has been omitted by qdoc's 1062 omitvalue command. Otherwise it is public. 834 1063 */ 835 1064 Node::Access EnumNode::itemAccess(const QString &name) const 836 1065 { 837 if (doc().omitEnumItemNames().contains(name)) {1066 if (doc().omitEnumItemNames().contains(name)) 838 1067 return Private; 839 } 840 else { 841 return Public; 842 } 1068 return Public; 843 1069 } 844 1070 … … 905 1131 /*! 906 1132 Assigning Parameter \a p to this Parameter copies the 907 strings across. 1133 strings across. 908 1134 */ 909 1135 Parameter& Parameter::operator=(const Parameter& p) … … 975 1201 976 1202 /*! 1203 Sets the \a virtualness of this function. If the \a virtualness 1204 is PureVirtual, and if the parent() is a ClassNode, set the parent's 1205 \e abstract flag to true. 1206 */ 1207 void FunctionNode::setVirtualness(Virtualness virtualness) 1208 { 1209 vir = virtualness; 1210 if ((virtualness == PureVirtual) && parent() && 1211 (parent()->type() == Node::Class)) 1212 parent()->setAbstract(true); 1213 } 1214 1215 /*! 977 1216 */ 978 1217 void FunctionNode::setOverload(bool overlode) … … 1064 1303 } 1065 1304 return names; 1305 } 1306 1307 /*! 1308 Returns a raw list of parameters. If \a names is true, the 1309 names are included. If \a values is true, the default values 1310 are included, if any are present. 1311 */ 1312 QString FunctionNode::rawParameters(bool names, bool values) const 1313 { 1314 QString raw; 1315 foreach (const Parameter ¶meter, parameters()) { 1316 raw += parameter.leftType() + parameter.rightType(); 1317 if (names) 1318 raw += parameter.name(); 1319 if (values) 1320 raw += parameter.defaultValue(); 1321 } 1322 return raw; 1066 1323 } 1067 1324 … … 1110 1367 void FunctionNode::debug() const 1111 1368 { 1112 qDebug() << "QML METHOD" << name() << "rt" << rt << "pp" << pp; 1369 qDebug("QML METHOD %s rt %s pp %s", 1370 qPrintable(name()), qPrintable(rt), qPrintable(pp.join(" "))); 1113 1371 } 1114 1372 1115 1373 /*! 1116 1374 \class PropertyNode 1117 */ 1118 1119 /*! 1375 1376 This class describes one instance of using the Q_PROPERTY macro. 1377 */ 1378 1379 /*! 1380 The constructor sets the \a parent and the \a name, but 1381 everything else is set to default values. 1120 1382 */ 1121 1383 PropertyNode::PropertyNode(InnerNode *parent, const QString& name) … … 1123 1385 sto(Trool_Default), 1124 1386 des(Trool_Default), 1387 scr(Trool_Default), 1388 wri(Trool_Default), 1389 usr(Trool_Default), 1390 cst(false), 1391 fnl(false), 1125 1392 overrides(0) 1126 1393 { 1127 } 1128 1129 /*! 1130 */ 1131 void PropertyNode::setOverriddenFrom(const PropertyNode *baseProperty) 1394 // nothing. 1395 } 1396 1397 /*! 1398 Sets this property's \e {overridden from} property to 1399 \a baseProperty, which indicates that this property 1400 overrides \a baseProperty. To begin with, all the values 1401 in this property are set to the corresponding values in 1402 \a baseProperty. 1403 1404 We probably should ensure that the constant and final 1405 attributes are not being overridden improperly. 1406 */ 1407 void PropertyNode::setOverriddenFrom(const PropertyNode* baseProperty) 1132 1408 { 1133 1409 for (int i = 0; i < NumFunctionRoles; ++i) { … … 1139 1415 if (des == Trool_Default) 1140 1416 des = baseProperty->des; 1417 if (scr == Trool_Default) 1418 scr = baseProperty->scr; 1419 if (wri == Trool_Default) 1420 wri = baseProperty->wri; 1421 if (usr == Trool_Default) 1422 usr = baseProperty->usr; 1141 1423 overrides = baseProperty; 1142 1424 } … … 1164 1446 } 1165 1447 1166 /*! 1448 /*! Converts the \a boolean value to an enum representation 1449 of the boolean type, which includes an enum value for the 1450 \e {default value} of the item, i.e. true, false, or default. 1167 1451 */ 1168 1452 PropertyNode::Trool PropertyNode::toTrool(bool boolean) … … 1172 1456 1173 1457 /*! 1458 Converts the enum \a troolean back to a boolean value. 1459 If \a troolean is neither the true enum value nor the 1460 false enum value, the boolean value returned is 1461 \a defaultValue. 1462 1463 Note that runtimeDesignabilityFunction() should be called 1464 first. If that function returns the name of a function, it 1465 means the function must be called at runtime to determine 1466 whether the property is Designable. 1174 1467 */ 1175 1468 bool PropertyNode::fromTrool(Trool troolean, bool defaultValue) … … 1206 1499 #ifdef QDOC_QML 1207 1500 bool QmlClassNode::qmlOnly = false; 1208 1209 /*! 1210 Constructor for the Qml class node. 1501 QMultiMap<QString,Node*> QmlClassNode::inheritedBy; 1502 1503 /*! 1504 Constructs a Qml class node (i.e. a Fake node with the 1505 subtype QmlClass. The new node has the given \a parent 1506 and \a name and is associated with the C++ class node 1507 specified by \a cn which may be null if the the Qml 1508 class node is not associated with a C++ class node. 1211 1509 */ 1212 1510 QmlClassNode::QmlClassNode(InnerNode *parent, … … 1215 1513 : FakeNode(parent, name, QmlClass), cnode(cn) 1216 1514 { 1217 setTitle((qmlOnly ? "" : "QML ") + name + " Element Reference"); 1515 if (name.startsWith(QLatin1String("QML:"))) 1516 setTitle((qmlOnly ? QLatin1String("") : QLatin1String("QML ")) + name.mid(4) + QLatin1String(" Element")); 1517 else 1518 setTitle((qmlOnly ? QLatin1String("") : QLatin1String("QML ")) + name + QLatin1String(" Element")); 1519 } 1520 1521 /*! 1522 I made this so I could print a debug message here. 1523 */ 1524 QmlClassNode::~QmlClassNode() 1525 { 1526 #ifdef DEBUG_MULTIPLE_QDOCCONF_FILES 1527 qDebug() << "Deleting QmlClassNode:" << name(); 1528 #endif 1529 } 1530 1531 /*! 1532 Clear the multimap so that subsequent runs don't try to use 1533 nodes from a previous run. 1534 */ 1535 void QmlClassNode::clear() 1536 { 1537 inheritedBy.clear(); 1218 1538 } 1219 1539 … … 1226 1546 QString QmlClassNode::fileBase() const 1227 1547 { 1228 #if 0 1548 #if 0 1229 1549 if (Node::fileBase() == "item") 1230 1550 qDebug() << "FILEBASE: qmlitem" << name(); … … 1235 1555 1236 1556 /*! 1557 Record the fact that QML class \a base is inherited by 1558 QML class \a sub. 1559 */ 1560 void QmlClassNode::addInheritedBy(const QString& base, Node* sub) 1561 { 1562 inheritedBy.insert(base,sub); 1563 #ifdef DEBUG_MULTIPLE_QDOCCONF_FILES 1564 qDebug() << "QmlClassNode::addInheritedBy(): insert" << base << sub->name() << inheritedBy.size(); 1565 #endif 1566 } 1567 1568 /*! 1569 Loads the list \a subs with the nodes of all the subclasses of \a base. 1570 */ 1571 void QmlClassNode::subclasses(const QString& base, NodeList& subs) 1572 { 1573 subs.clear(); 1574 if (inheritedBy.count(base) > 0) { 1575 subs = inheritedBy.values(base); 1576 #ifdef DEBUG_MULTIPLE_QDOCCONF_FILES 1577 qDebug() << "QmlClassNode::subclasses():" << inheritedBy.count(base) << base 1578 << "subs:" << subs.size() << "total size:" << inheritedBy.size(); 1579 #endif 1580 } 1581 } 1582 1583 /*! 1584 Constructs a Qml basic type node (i.e. a Fake node with 1585 the subtype QmlBasicType. The new node has the given 1586 \a parent and \a name. 1587 */ 1588 QmlBasicTypeNode::QmlBasicTypeNode(InnerNode *parent, 1589 const QString& name) 1590 : FakeNode(parent, name, QmlBasicType) 1591 { 1592 setTitle(name); 1593 } 1594 1595 /*! 1237 1596 Constructor for the Qml property group node. \a parent is 1238 always a QmlClassNode. 1597 always a QmlClassNode. 1239 1598 */ 1240 1599 QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent, … … 1261 1620 att(attached) 1262 1621 { 1263 // nothing.1622 setPageType(ApiPage); 1264 1623 } 1265 1624 … … 1286 1645 } 1287 1646 } 1647 1648 static QString valueType(const QString& n) 1649 { 1650 if (n == "QPoint") 1651 return "QDeclarativePointValueType"; 1652 if (n == "QPointF") 1653 return "QDeclarativePointFValueType"; 1654 if (n == "QSize") 1655 return "QDeclarativeSizeValueType"; 1656 if (n == "QSizeF") 1657 return "QDeclarativeSizeFValueType"; 1658 if (n == "QRect") 1659 return "QDeclarativeRectValueType"; 1660 if (n == "QRectF") 1661 return "QDeclarativeRectFValueType"; 1662 if (n == "QVector2D") 1663 return "QDeclarativeVector2DValueType"; 1664 if (n == "QVector3D") 1665 return "QDeclarativeVector3DValueType"; 1666 if (n == "QVector4D") 1667 return "QDeclarativeVector4DValueType"; 1668 if (n == "QQuaternion") 1669 return "QDeclarativeQuaternionValueType"; 1670 if (n == "QMatrix4x4") 1671 return "QDeclarativeMatrix4x4ValueType"; 1672 if (n == "QEasingCurve") 1673 return "QDeclarativeEasingValueType"; 1674 if (n == "QFont") 1675 return "QDeclarativeFontValueType"; 1676 return QString(); 1677 } 1678 1679 /*! 1680 Returns true if a QML property or attached property is 1681 read-only. The algorithm for figuring this out is long 1682 amd tedious and almost certainly will break. It currently 1683 doesn't work for qmlproperty bool PropertyChanges::explicit, 1684 because the tokenized gets confused on "explicit" . 1685 */ 1686 bool QmlPropertyNode::isWritable(const Tree* tree) const 1687 { 1688 Node* n = parent(); 1689 while (n && n->subType() != Node::QmlClass) 1690 n = n->parent(); 1691 if (n) { 1692 const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n); 1693 const ClassNode* cn = qcn->classNode(); 1694 if (cn) { 1695 QStringList dotSplit = name().split(QChar('.')); 1696 const PropertyNode* pn = cn->findPropertyNode(dotSplit[0]); 1697 if (pn) { 1698 if (dotSplit.size() > 1) { 1699 QStringList path(extractClassName(pn->qualifiedDataType())); 1700 const Node* nn = tree->findNode(path,Class); 1701 if (nn) { 1702 const ClassNode* cn = static_cast<const ClassNode*>(nn); 1703 pn = cn->findPropertyNode(dotSplit[1]); 1704 if (pn) { 1705 return pn->isWritable(); 1706 } 1707 else { 1708 const QList<RelatedClass>& bases = cn->baseClasses(); 1709 if (!bases.isEmpty()) { 1710 for (int i=0; i<bases.size(); ++i) { 1711 const ClassNode* cn = bases[i].node; 1712 pn = cn->findPropertyNode(dotSplit[1]); 1713 if (pn) { 1714 return pn->isWritable(); 1715 } 1716 } 1717 } 1718 const QList<RelatedClass>& ignoredBases = cn->ignoredBaseClasses(); 1719 if (!ignoredBases.isEmpty()) { 1720 for (int i=0; i<ignoredBases.size(); ++i) { 1721 const ClassNode* cn = ignoredBases[i].node; 1722 pn = cn->findPropertyNode(dotSplit[1]); 1723 if (pn) { 1724 return pn->isWritable(); 1725 } 1726 } 1727 } 1728 QString vt = valueType(cn->name()); 1729 if (!vt.isEmpty()) { 1730 QStringList path(vt); 1731 const Node* vtn = tree->findNode(path,Class); 1732 if (vtn) { 1733 const ClassNode* cn = static_cast<const ClassNode*>(vtn); 1734 pn = cn->findPropertyNode(dotSplit[1]); 1735 if (pn) { 1736 return pn->isWritable(); 1737 } 1738 } 1739 } 1740 } 1741 } 1742 } 1743 else { 1744 return pn->isWritable(); 1745 } 1746 } 1747 else { 1748 const QList<RelatedClass>& bases = cn->baseClasses(); 1749 if (!bases.isEmpty()) { 1750 for (int i=0; i<bases.size(); ++i) { 1751 const ClassNode* cn = bases[i].node; 1752 pn = cn->findPropertyNode(dotSplit[0]); 1753 if (pn) { 1754 return pn->isWritable(); 1755 } 1756 } 1757 } 1758 const QList<RelatedClass>& ignoredBases = cn->ignoredBaseClasses(); 1759 if (!ignoredBases.isEmpty()) { 1760 for (int i=0; i<ignoredBases.size(); ++i) { 1761 const ClassNode* cn = ignoredBases[i].node; 1762 pn = cn->findPropertyNode(dotSplit[0]); 1763 if (pn) { 1764 return pn->isWritable(); 1765 } 1766 } 1767 } 1768 if (isAttached()) { 1769 QString classNameAttached = cn->name() + "Attached"; 1770 QStringList path(classNameAttached); 1771 const Node* nn = tree->findNode(path,Class); 1772 const ClassNode* acn = static_cast<const ClassNode*>(nn); 1773 pn = acn->findPropertyNode(dotSplit[0]); 1774 if (pn) { 1775 return pn->isWritable(); 1776 } 1777 } 1778 } 1779 } 1780 } 1781 location().warning(tr("Can't determine read-only status of QML property %1; writable assumed.").arg(name())); 1782 return true; 1783 } 1784 1288 1785 #endif 1289 1786
Note:
See TracChangeset
for help on using the changeset viewer.