From a37ae8590026de2ef150e3da1b4b986022d6294a Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Tue, 6 Jul 2010 10:07:54 +0200 Subject: Doc: fixing img style --- doc/src/template/style/style.css | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/src/template/style/style.css b/doc/src/template/style/style.css index 299806b..184a832 100755 --- a/doc/src/template/style/style.css +++ b/doc/src/template/style/style.css @@ -18,6 +18,8 @@ fieldset, img { border: 0; + height:100%; + width:100% } address, caption, cite, code, dfn, em, strong, th, var, optgroup { @@ -756,6 +758,7 @@ pre { border: 1px solid #DDDDDD; + -moz-border-radius: 7px 7px 7px 7px; margin: 0 20px 10px 10px; padding: 20px 15px 20px 20px; overflow-x: auto; @@ -1023,6 +1026,7 @@ } h3.fn, span.fn { + -moz-border-radius:7px 7px 7px 7px; background-color: #F6F6F6; border-width: 1px; border-style: solid; @@ -1040,6 +1044,7 @@ border-width: 1px; border-style: solid; border-color: #E6E6E6; + -moz-border-radius: 7px 7px 7px 7px; width:100%; } @@ -1199,6 +1204,7 @@ vertical-align:top; width:100%; background-color:#F6F6F6; border:1px solid #E6E6E6; +-moz-border-radius: 7px 7px 7px 7px; font-size:12pt; padding-left:10px; margin-top:10px; @@ -1250,8 +1256,9 @@ pre.highlightedCode { } .navTop{ float:right; - padding-right:5px; - margin-top:15px; + display:block; + padding-right:15px; + /*margin-top:10px;*/ } .wrap .content .toc h3{ -- cgit v0.12 From 3b6c44f773d293f807784b775f352873c793e75a Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 6 Jul 2010 12:24:20 +0200 Subject: qdoc: Simplified code to enable fixing of QTBUG-6340. Also reworded some of the text for QTBUG-11575. Task-number: QTBUG-6340, QTBUG-11575 --- doc/src/declarative/extending.qdoc | 24 +- tools/qdoc3/htmlgenerator.cpp | 457 ++++++------------------------------- tools/qdoc3/htmlgenerator.h | 25 +- tools/qdoc3/tree.cpp | 17 +- 4 files changed, 97 insertions(+), 426 deletions(-) diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index 28d4ed4..2fd6fa8 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -423,22 +423,14 @@ signals with the \l {Connections} element. Additionally, if a property is added to a C++ class, all QML elements based on that C++ class will have a \e{value-changed} signal handler -for that property. The name of the signal handler is \e{onChanged}, with the first letter of the property name being upper -cased. - -\note If the NOTIFY signal for the added property is not simply -\c{Changed()}, then you will get two equivalent signal -handlers, one because of the signal, one because of the property. For -example, if the property \c{test_property} with NOTIFY signal -\c{testPropChanged()} is added to a C++ class, then QML elements based -on that C++ class will have two signal handlers: -\c{onTest_propertyChanged} because of the property, and -\c{onTestPropChanged} because of the NOTIFY signal. For clarity, we -suggest that for properties exposed to QML in this way, the name of -the NOTIFY signal should be just \c{Changed()}, so that -there will be just one signal handler in QML and one naming -convention used. +for that property. The name of the signal handler is +\e{onChanged}, with the first letter of the property +name being upper case. + +\note The QML signal handler will always be named +onChanged, regardless of the name used for the NOTIFY +signal in C++. We recommend using Changed() for the +NOTIFY signal in C++. See also \l {Extending types from QML}. diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 49ba5f6..89b1e98 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -1359,7 +1359,7 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, if (!s->inherited.isEmpty()) { out() << "
    \n"; - generateSectionInheritedList(*s, inner, marker, true); + generateSectionInheritedList(*s, inner, marker); out() << "
\n"; } } @@ -2636,44 +2636,6 @@ void HtmlGenerator::generateLegaleseList(const Node *relative, } } -/*void HtmlGenerator::generateSynopsis(const Node *node, - const Node *relative, - CodeMarker *marker, - CodeMarker::SynopsisStyle style) -{ - QString marked = marker->markedUpSynopsis(node, relative, style); - QRegExp templateTag("(<[^@>]*>)"); - if (marked.indexOf(templateTag) != -1) { - QString contents = protectEnc(marked.mid(templateTag.pos(1), - templateTag.cap(1).length())); - marked.replace(templateTag.pos(1), templateTag.cap(1).length(), - contents); - } - marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])"), - "\\1\\2"); - marked.replace("<@param>", ""); - marked.replace("", ""); - - if (style == CodeMarker::Summary) - marked.replace("@name>", "b>"); - - if (style == CodeMarker::SeparateList) { - QRegExp extraRegExp("<@extra>.*"); - extraRegExp.setMinimal(true); - marked.replace(extraRegExp, ""); - } - else { - marked.replace("<@extra>", "  "); - marked.replace("", ""); - } - - if (style != CodeMarker::Detailed) { - marked.replace("<@type>", ""); - marked.replace("", ""); - } - out() << highlightedCode(marked, marker, relative); -}*/ - #ifdef QDOC_QML void HtmlGenerator::generateQmlItem(const Node *node, const Node *relative, @@ -2703,6 +2665,17 @@ void HtmlGenerator::generateQmlItem(const Node *node, marked.replace("<@type>", ""); marked.replace("", ""); } + if (node->type() == Node::QmlProperty) { + const QmlPropertyNode* qpn = static_cast(node); + if (!summary && qpn->name() == "color" && qpn->dataType() == "color") { + if (relative && relative->name() == "GradientStop") { + qDebug() << "color : color"; + debugging_on = true; + qDebug() << " " << relative->name() << relative->type() << relative->subType(); + qDebug() << marked; + } + } + } out() << highlightedCode(marked, marker, relative); debugging_on = false; } @@ -2822,24 +2795,23 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m } } -#ifdef QDOC_NAME_ALIGNMENT void HtmlGenerator::generateSection(const NodeList& nl, const Node *relative, CodeMarker *marker, CodeMarker::SynopsisStyle style) { - bool name_alignment = true; + bool alignNames = true; if (!nl.isEmpty()) { bool twoColumn = false; if (style == CodeMarker::SeparateList) { - name_alignment = false; + alignNames = false; twoColumn = (nl.count() >= 16); } else if (nl.first()->type() == Node::Property) { twoColumn = (nl.count() >= 5); - name_alignment = false; + alignNames = false; } - if (name_alignment) { + if (alignNames) { out() << "\n"; } else { @@ -2857,7 +2829,7 @@ void HtmlGenerator::generateSection(const NodeList& nl, continue; } - if (name_alignment) { + if (alignNames) { out() << "\n"; else out() << "\n"; i++; ++m; } - if (name_alignment) + if (alignNames) out() << "
"; } else { @@ -2866,15 +2838,15 @@ void HtmlGenerator::generateSection(const NodeList& nl, out() << "
  • "; } - generateSynopsis(*m, relative, marker, style, name_alignment); - if (name_alignment) + generateSynopsis(*m, relative, marker, style, alignNames); + if (alignNames) out() << "
  • \n"; else { out() << "\n"; @@ -2889,18 +2861,18 @@ void HtmlGenerator::generateSectionList(const Section& section, CodeMarker *marker, CodeMarker::SynopsisStyle style) { - bool name_alignment = true; + bool alignNames = true; if (!section.members.isEmpty()) { bool twoColumn = false; if (style == CodeMarker::SeparateList) { - name_alignment = false; + alignNames = false; twoColumn = (section.members.count() >= 16); } else if (section.members.first()->type() == Node::Property) { twoColumn = (section.members.count() >= 5); - name_alignment = false; + alignNames = false; } - if (name_alignment) { + if (alignNames) { out() << "\n"; } else { @@ -2918,7 +2890,7 @@ void HtmlGenerator::generateSectionList(const Section& section, continue; } - if (name_alignment) { + if (alignNames) { out() << "\n"; else out() << "\n"; i++; ++m; } - if (name_alignment) + if (alignNames) out() << "
    "; } else { @@ -2927,15 +2899,15 @@ void HtmlGenerator::generateSectionList(const Section& section, out() << "
  • "; } - generateSynopsis(*m, relative, marker, style, name_alignment); - if (name_alignment) + generateSynopsis(*m, relative, marker, style, alignNames); + if (alignNames) out() << "
  • \n"; else { out() << "\n"; @@ -2946,22 +2918,18 @@ void HtmlGenerator::generateSectionList(const Section& section, if (style == CodeMarker::Summary && !section.inherited.isEmpty()) { out() << "
      \n"; - generateSectionInheritedList(section, relative, marker, name_alignment); + generateSectionInheritedList(section, relative, marker); out() << "
    \n"; } } void HtmlGenerator::generateSectionInheritedList(const Section& section, const Node *relative, - CodeMarker *marker, - bool nameAlignment) + CodeMarker *marker) { QList >::ConstIterator p = section.inherited.begin(); while (p != section.inherited.end()) { - if (nameAlignment) - out() << "
  • "; - else - out() << "
  • "; + out() << "
  • "; out() << (*p).second << " "; if ((*p).second == 1) { out() << section.singularMember; @@ -2981,7 +2949,7 @@ void HtmlGenerator::generateSynopsis(const Node *node, const Node *relative, CodeMarker *marker, CodeMarker::SynopsisStyle style, - bool nameAlignment) + bool alignNames) { QString marked = marker->markedUpSynopsis(node, relative, style); QRegExp templateTag("(<[^@>]*>)"); @@ -3014,14 +2982,13 @@ void HtmlGenerator::generateSynopsis(const Node *node, marked.replace("<@type>", ""); marked.replace("", ""); } - out() << highlightedCode(marked, marker, relative, style, nameAlignment); + out() << highlightedCode(marked, marker, relative, alignNames); } QString HtmlGenerator::highlightedCode(const QString& markedCode, - CodeMarker *marker, - const Node *relative, - CodeMarker::SynopsisStyle , - bool nameAlignment) + CodeMarker* marker, + const Node* relative, + bool alignNames) { QString src = markedCode; QString html; @@ -3031,20 +2998,24 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, const QChar charLangle = '<'; const QChar charAt = '@'; - // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*()" + static const QString typeTag("type"); + static const QString headerTag("headerfile"); + static const QString funcTag("func"); static const QString linkTag("link"); + + // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*()" bool done = false; - for (int i = 0, n = src.size(); i < n;) { + for (int i = 0, srcSize = src.size(); i < srcSize;) { if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') { - if (nameAlignment && !done) {// && (i != 0)) Why was this here? + if (alignNames && !done) {// && (i != 0)) Why was this here? html += ""; done = true; } i += 2; - if (parseArg(src, linkTag, &i, n, &arg, &par1)) { + if (parseArg(src, linkTag, &i, srcSize, &arg, &par1)) { html += ""; - QString link = linkForNode( - CodeMarker::nodeForString(par1.toString()), relative); + const Node* n = CodeMarker::nodeForString(par1.toString()); + QString link = linkForNode(n, relative); addLink(link, arg, &html); html += ""; } @@ -3064,16 +3035,14 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)()" src = html; html = QString(); - static const QString funcTag("func"); - for (int i = 0, n = src.size(); i < n;) { + for (int i = 0, srcSize = src.size(); i < srcSize;) { if (src.at(i) == charLangle && src.at(i + 1) == charAt) { i += 2; - if (parseArg(src, funcTag, &i, n, &arg, &par1)) { - QString link = linkForNode( - marker->resolveTarget(par1.toString(), - myTree, - relative), - relative); + if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { + const Node* n = marker->resolveTarget(par1.toString(), + myTree, + relative); + QString link = linkForNode(n, relative); addLink(link, arg, &html); par1 = QStringRef(); } @@ -3091,295 +3060,36 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, // replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)()" tags src = html; html = QString(); - static const QString typeTags[] = { "type", "headerfile", "func" }; - for (int i = 0, n = src.size(); i < n;) { - if (src.at(i) == charLangle && src.at(i + 1) == charAt) { + + for (int i=0, srcSize=src.size(); iresolveTarget(arg.toString(), myTree, relative); - QString link = linkForNode(n,relative); - addLink(link, arg, &html); - handled = true; - break; + if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) { + par1 = QStringRef(); + const Node* n = marker->resolveTarget(arg.toString(), myTree, relative); + if (HtmlGenerator::debugging_on) { + if (n) { + qDebug() << " " << n->name() << n->type() << n->subType(); + qDebug() << " " << relative->name() << relative->type() << relative->subType(); + } } + addLink(linkForNode(n,relative), arg, &html); + handled = true; } - if (!handled) { - html += charLangle; - html += charAt; - } - } - else { - html += src.at(i++); - } - } - - // replace all - // "<@comment>" -> ""; - // "<@preprocessor>" -> ""; - // "<@string>" -> ""; - // "<@char>" -> ""; - // "" -> "" - src = html; - html = QString(); - static const QString spanTags[] = { - "<@comment>", "", - "<@preprocessor>", "", - "<@string>", "", - "<@char>", "", - "", "", - "","", - "", "", - "", "" - // "<@char>", "", - // "", "", - // "<@func>", "", - // "", "", - // "<@id>", "", - // "", "", - // "<@keyword>", "", - // "", "", - // "<@number>", "", - // "", "", - // "<@op>", "", - // "", "", - // "<@param>", "", - // "", "", - // "<@string>", "", - // "", "", - }; - for (int i = 0, n = src.size(); i < n;) { - if (src.at(i) == charLangle) { - bool handled = false; - for (int k = 0; k != 8; ++k) { - const QString & tag = spanTags[2 * k]; - if (tag == QStringRef(&src, i, tag.length())) { - html += spanTags[2 * k + 1]; - i += tag.length(); - handled = true; - break; - } + else if (parseArg(src, headerTag, &i, srcSize, &arg, &par1)) { + par1 = QStringRef(); + const Node* n = marker->resolveTarget(arg.toString(), myTree, relative); + addLink(linkForNode(n,relative), arg, &html); + handled = true; } - if (!handled) { - ++i; - if (src.at(i) == charAt || - (src.at(i) == QLatin1Char('/') && src.at(i + 1) == charAt)) { - // drop 'our' unknown tags (the ones still containing '@') - while (i < n && src.at(i) != QLatin1Char('>')) - ++i; - ++i; - } - else { - // retain all others - html += charLangle; - } + else if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { + par1 = QStringRef(); + const Node* n = marker->resolveTarget(arg.toString(), myTree, relative); + addLink(linkForNode(n,relative), arg, &html); + handled = true; } - } - else { - html += src.at(i); - ++i; - } - } - - return html; -} -#else -void HtmlGenerator::generateSectionList(const Section& section, - const Node *relative, - CodeMarker *marker, - CodeMarker::SynopsisStyle style) -{ - if (!section.members.isEmpty()) { - bool twoColumn = false; - if (style == CodeMarker::SeparateList) { - twoColumn = (section.members.count() >= 16); - } - else if (section.members.first()->type() == Node::Property) { - twoColumn = (section.members.count() >= 5); - } - if (twoColumn) - out() << "\n"; - if (++numTableRows % 2 == 1) - out() << ""; - else - out() << ""; - -// << "\n
    "; - out() << "
      \n"; - - int i = 0; - NodeList::ConstIterator m = section.members.begin(); - while (m != section.members.end()) { - if ((*m)->access() == Node::Private) { - ++m; - continue; - } - - if (twoColumn && i == (int) (section.members.count() + 1) / 2) - out() << "
      \n"; - - out() << "
    • "; - if (style == CodeMarker::Accessors) - out() << ""; - generateSynopsis(*m, relative, marker, style); - if (style == CodeMarker::Accessors) - out() << ""; - out() << "
    • \n"; - i++; - ++m; - } - out() << "
    \n"; - if (twoColumn) - out() << "
    \n"; - } - - if (style == CodeMarker::Summary && !section.inherited.isEmpty()) { - out() << "
      \n"; - generateSectionInheritedList(section, relative, marker); - out() << "
    \n"; - } -} - -void HtmlGenerator::generateSectionInheritedList(const Section& section, - const Node *relative, - CodeMarker *marker) -{ - QList >::ConstIterator p = section.inherited.begin(); - while (p != section.inherited.end()) { - out() << "
  • "; - out() << (*p).second << " "; - if ((*p).second == 1) { - out() << section.singularMember; - } else { - out() << section.pluralMember; - } - out() << " inherited from " - << protectEnc(marker->plainFullName((*p).first, relative)) - << "
  • \n"; - ++p; - } -} - -void HtmlGenerator::generateSynopsis(const Node *node, - const Node *relative, - CodeMarker *marker, - CodeMarker::SynopsisStyle style) -{ - QString marked = marker->markedUpSynopsis(node, relative, style); - QRegExp templateTag("(<[^@>]*>)"); - if (marked.indexOf(templateTag) != -1) { - QString contents = protectEnc(marked.mid(templateTag.pos(1), - templateTag.cap(1).length())); - marked.replace(templateTag.pos(1), templateTag.cap(1).length(), - contents); - } - marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])"), "\\1\\2"); - marked.replace("<@param>", ""); - marked.replace("", ""); - - if (style == CodeMarker::Summary) - marked.replace("@name>", "b>"); - - if (style == CodeMarker::SeparateList) { - QRegExp extraRegExp("<@extra>.*"); - extraRegExp.setMinimal(true); - marked.replace(extraRegExp, ""); - } else { - marked.replace("<@extra>", ""); - marked.replace("", ""); - } - - if (style != CodeMarker::Detailed) { - marked.replace("<@type>", ""); - marked.replace("", ""); - } - out() << highlightedCode(marked, marker, relative); -} - -QString HtmlGenerator::highlightedCode(const QString& markedCode, - CodeMarker *marker, - const Node *relative) -{ - QString src = markedCode; - QString html; - QStringRef arg; - QStringRef par1; - - const QChar charLangle = '<'; - const QChar charAt = '@'; - - // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*()" - static const QString linkTag("link"); - for (int i = 0, n = src.size(); i < n;) { - if (src.at(i) == charLangle && src.at(i + 1) == charAt) { - i += 2; - if (parseArg(src, linkTag, &i, n, &arg, &par1)) { - const Node* node = CodeMarker::nodeForString(par1.toString()); - QString link = linkForNode(node, relative); - addLink(link, arg, &html); - } - else { - html += charLangle; - html += charAt; - } - } - else { - html += src.at(i++); - } - } - - if (slow) { - // is this block ever used at all? - // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)()" - src = html; - html = QString(); - static const QString funcTag("func"); - for (int i = 0, n = src.size(); i < n;) { - if (src.at(i) == charLangle && src.at(i + 1) == charAt) { - i += 2; - if (parseArg(src, funcTag, &i, n, &arg, &par1)) { - QString link = linkForNode( - marker->resolveTarget(par1.toString(), - myTree, - relative), - relative); - addLink(link, arg, &html); - par1 = QStringRef(); - } - else { - html += charLangle; - html += charAt; - } - } - else { - html += src.at(i++); - } - } - } - - // replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)()" tags - src = html; - html = QString(); - static const QString typeTags[] = { "type", "headerfile", "func" }; - for (int i = 0, n = src.size(); i < n;) { - if (src.at(i) == charLangle && src.at(i + 1) == charAt) { - i += 2; - bool handled = false; - for (int k = 0; k != 3; ++k) { - if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) { - par1 = QStringRef(); - QString link = linkForNode( - marker->resolveTarget(arg.toString(), myTree, relative), - relative); - addLink(link, arg, &html); - handled = true; - break; - } - } if (!handled) { html += charLangle; html += charAt; @@ -3407,22 +3117,6 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, "","", "", "", "", "" - // "<@char>", "", - // "", "", - // "<@func>", "", - // "", "", - // "<@id>", "", - // "", "", - // "<@keyword>", "", - // "", "", - // "<@number>", "", - // "", "", - // "<@op>", "", - // "", "", - // "<@param>", "", - // "", "", - // "<@string>", "", - // "", "", }; for (int i = 0, n = src.size(); i < n;) { if (src.at(i) == charLangle) { @@ -3459,7 +3153,6 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, return html; } -#endif void HtmlGenerator::generateLink(const Atom* atom, const Node* /* relative */, diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h index aad5021..80341de 100644 --- a/tools/qdoc3/htmlgenerator.h +++ b/tools/qdoc3/htmlgenerator.h @@ -46,8 +46,6 @@ #ifndef HTMLGENERATOR_H #define HTMLGENERATOR_H -#define QDOC_NAME_ALIGNMENT - #include #include #include @@ -198,7 +196,7 @@ class HtmlGenerator : public PageGenerator void generateQmlInstantiates(const QmlClassNode* qcn, CodeMarker* marker); void generateInstantiatedBy(const ClassNode* cn, CodeMarker* marker); #endif -#ifdef QDOC_NAME_ALIGNMENT + void generateSection(const NodeList& nl, const Node *relative, CodeMarker *marker, @@ -207,28 +205,15 @@ class HtmlGenerator : public PageGenerator const Node *relative, CodeMarker *marker, CodeMarker::SynopsisStyle style, - bool nameAlignment = false); - void generateSectionInheritedList(const Section& section, - const Node *relative, - CodeMarker *marker, - bool nameAlignment = false); - QString highlightedCode(const QString& markedCode, - CodeMarker *marker, - const Node *relative, - CodeMarker::SynopsisStyle style = CodeMarker::Accessors, - bool nameAlignment = false); -#else - void generateSynopsis(const Node *node, - const Node *relative, - CodeMarker *marker, - CodeMarker::SynopsisStyle style); + bool alignNames = false); void generateSectionInheritedList(const Section& section, const Node *relative, CodeMarker *marker); QString highlightedCode(const QString& markedCode, CodeMarker *marker, - const Node *relative); -#endif + const Node *relative, + bool alignNames = false); + void generateFullName(const Node *apparentNode, const Node *relative, CodeMarker *marker, diff --git a/tools/qdoc3/tree.cpp b/tools/qdoc3/tree.cpp index d3de46c..70b998f 100644 --- a/tools/qdoc3/tree.cpp +++ b/tools/qdoc3/tree.cpp @@ -134,15 +134,16 @@ Node *Tree::findNode(const QStringList &path, Node *relative, int findFlags) /*! */ -const Node *Tree::findNode(const QStringList &path, - const Node *relative, +const Node* Tree::findNode(const QStringList &path, + const Node* start, int findFlags) const { - if (!relative) - relative = root(); + const Node* current = start; + if (!current) + current = root(); do { - const Node *node = relative; + const Node *node = current; int i; for (i = 0; i < path.size(); ++i) { @@ -171,10 +172,10 @@ const Node *Tree::findNode(const QStringList &path, if (node && i == path.size() && (!(findFlags & NonFunction) || node->type() != Node::Function || ((FunctionNode *)node)->metaness() == FunctionNode::MacroWithoutParams)) - if (node->subType() != Node::QmlPropertyGroup) + if ((node != start) && (node->subType() != Node::QmlPropertyGroup)) return node; - relative = relative->parent(); - } while (relative); + current = current->parent(); + } while (current); return 0; } -- cgit v0.12 From 92b6ca830f279cfa9d37946f1fd72843b24e704b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 2 Jul 2010 17:38:10 +0200 Subject: fix bogus return value from qprocess::execute() Task-number: QTBUG-230, QTBUG-5866 Reviewed-by: joerg --- src/corelib/io/qprocess.cpp | 14 ++++++++++---- tests/auto/qprocess/tst_qprocess.cpp | 9 +++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 8eba2b0..4c21a40 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -2082,14 +2082,19 @@ QProcess::ExitStatus QProcess::exitStatus() const process. On Windows, arguments that contain spaces are wrapped in quotes. + + If the process cannot be started, -2 is returned. If the process + crashes, -1 is returned. Otherwise, the process' exit code is + returned. */ int QProcess::execute(const QString &program, const QStringList &arguments) { QProcess process; process.setReadChannelMode(ForwardedChannels); process.start(program, arguments); - process.waitForFinished(-1); - return process.exitCode(); + if (!process.waitForFinished(-1)) + return -2; + return process.exitStatus() == QProcess::NormalExit ? process.exitCode() : -1; } /*! @@ -2104,8 +2109,9 @@ int QProcess::execute(const QString &program) QProcess process; process.setReadChannelMode(ForwardedChannels); process.start(program); - process.waitForFinished(-1); - return process.exitCode(); + if (!process.waitForFinished(-1)) + return -2; + return process.exitStatus() == QProcess::NormalExit ? process.exitCode() : -1; } /*! diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp index 8dae9a0..8242d30 100644 --- a/tests/auto/qprocess/tst_qprocess.cpp +++ b/tests/auto/qprocess/tst_qprocess.cpp @@ -93,6 +93,7 @@ private slots: void getSetCheck(); void constructing(); void simpleStart(); + void execute(); void startDetached(); void crashTest(); void crashTest2(); @@ -284,6 +285,14 @@ void tst_QProcess::simpleStart() QCOMPARE(qVariantValue(spy.at(2).at(0)), QProcess::NotRunning); } //----------------------------------------------------------------------------- +void tst_QProcess::execute() +{ + QCOMPARE(QProcess::execute("testProcessNormal/testProcessNormal", + QStringList() << "arg1" << "arg2"), 0); + QCOMPARE(QProcess::execute("nonexistingexe"), -2); +} + +//----------------------------------------------------------------------------- void tst_QProcess::startDetached() { QProcess proc; -- cgit v0.12 From 4fe7291edcac2688f042a11ff5c23374c6c0375d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 6 Jul 2010 13:56:38 +0200 Subject: add setNativeArguments() and nativeArguments() this function enables starting subprocesses which need command lines which cannot be constructed via the portable list-based api. such cases would be programs which need quoting rules which diverge from the msvc runtime. Reviewed-by: joerg Task-number: QTBUG-7620 (and various others which boil down to that) --- src/corelib/io/qprocess.cpp | 44 ++++++++++++++++++ src/corelib/io/qprocess.h | 5 +++ src/corelib/io/qprocess_p.h | 3 ++ src/corelib/io/qprocess_symbian.cpp | 17 ++++--- src/corelib/io/qprocess_win.cpp | 5 +++ src/s60installs/bwins/QtCoreu.def | 2 + src/s60installs/eabi/QtCoreu.def | 2 + tests/auto/qprocess/testProcessSpacesArgs/main.cpp | 7 ++- tests/auto/qprocess/tst_qprocess.cpp | 52 ++++++++++++++++++++++ 9 files changed, 129 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 4c21a40..9bc4063 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1377,6 +1377,50 @@ void QProcess::setStandardOutputProcess(QProcess *destination) dto->stdinChannel.pipeFrom(dfrom); } +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + +/*! + \since 4.7 + + Returns the additional native command line arguments for the program. + + \note This function is available only on the Windows and Symbian + platforms. + + \sa setNativeArguments() +*/ +QString QProcess::nativeArguments() const +{ + Q_D(const QProcess); + return d->nativeArguments; +} + +/*! + \since 4.7 + \overload + + Sets additional native command line arguments for the program. + + On operating systems where the system API for passing command line + arguments to a subprocess natively uses a single string, one can + conceive command lines which cannot be passed via QProcess's portable + list-based API. In such cases this function must be used to set a + string which is \e appended to the string composed from the usual + argument list, with a delimiting space. + + \note This function is available only on the Windows and Symbian + platforms. + + \sa nativeArguments() +*/ +void QProcess::setNativeArguments(const QString &arguments) +{ + Q_D(QProcess); + d->nativeArguments = arguments; +} + +#endif + /*! If QProcess has been assigned a working directory, this function returns the working directory that the QProcess will enter before the program has diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h index f84b855..b07d742 100644 --- a/src/corelib/io/qprocess.h +++ b/src/corelib/io/qprocess.h @@ -148,6 +148,11 @@ public: void setStandardErrorFile(const QString &fileName, OpenMode mode = Truncate); void setStandardOutputProcess(QProcess *destination); +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + QString nativeArguments() const; + void setNativeArguments(const QString &arguments); +#endif + QString workingDirectory() const; void setWorkingDirectory(const QString &dir); diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 60b7b5a..8b7e3ff 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -181,6 +181,9 @@ public: QString program; QStringList arguments; +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + QString nativeArguments; +#endif QProcessEnvironment environment; QRingBuffer outputReadBuffer; diff --git a/src/corelib/io/qprocess_symbian.cpp b/src/corelib/io/qprocess_symbian.cpp index 92212fe..af657b2 100644 --- a/src/corelib/io/qprocess_symbian.cpp +++ b/src/corelib/io/qprocess_symbian.cpp @@ -219,7 +219,8 @@ static bool qt_rprocess_running(RProcess *proc) return false; } -static void qt_create_symbian_commandline(const QStringList &arguments, QString &commandLine) +static void qt_create_symbian_commandline( + const QStringList &arguments, const QString &nativeArguments, QString &commandLine) { for (int i = 0; i < arguments.size(); ++i) { QString tmp = arguments.at(i); @@ -243,12 +244,14 @@ static void qt_create_symbian_commandline(const QStringList &arguments, QString } } - // Chop the extra trailing space if any arguments were appended - if (arguments.size()) + if (!nativeArguments.isEmpty()) + commandLine += nativeArguments; + else if (!commandLine.isEmpty()) // Chop the extra trailing space if any arguments were appended commandLine.chop(1); } -static TInt qt_create_symbian_process(RProcess **proc, const QString &programName, const QStringList &arguments) +static TInt qt_create_symbian_process(RProcess **proc, + const QString &programName, const QStringList &arguments, const QString &nativeArguments) { RProcess *newProc = NULL; newProc = new RProcess(); @@ -257,7 +260,7 @@ static TInt qt_create_symbian_process(RProcess **proc, const QString &programNam return KErrNoMemory; QString commandLine; - qt_create_symbian_commandline(arguments, commandLine); + qt_create_symbian_commandline(arguments, nativeArguments, commandLine); TPtrC program_ptr(reinterpret_cast(programName.constData())); TPtrC cmdline_ptr(reinterpret_cast(commandLine.constData())); @@ -794,7 +797,7 @@ void QProcessPrivate::startProcess() q, SLOT(_q_processDied())); } - TInt err = qt_create_symbian_process(&symbianProcess, program, arguments); + TInt err = qt_create_symbian_process(&symbianProcess, program, arguments, nativeArguments); if (err == KErrNone) { pid = symbianProcess->Id().Id(); @@ -1030,7 +1033,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a RProcess *newProc = NULL; - TInt err = qt_create_symbian_process(&newProc, program, arguments); + TInt err = qt_create_symbian_process(&newProc, program, arguments, QString()); if (err == KErrNone) { if (pid) diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index cb25a58..702349f 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -366,6 +366,11 @@ void QProcessPrivate::startProcess() if (environment.d.constData()) envlist = qt_create_environment(environment.d.constData()->hash); #endif + if (!nativeArguments.isEmpty()) { + if (!args.isEmpty()) + args += QLatin1Char(' '); + args += nativeArguments; + } #if defined QPROCESS_DEBUG qDebug("Creating process"); diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def index 101c6a8..94be1bb 100644 --- a/src/s60installs/bwins/QtCoreu.def +++ b/src/s60installs/bwins/QtCoreu.def @@ -4482,4 +4482,6 @@ EXPORTS ?textDirection@QLocale@@QBE?AW4LayoutDirection@Qt@@XZ @ 4481 NONAME ; enum Qt::LayoutDirection QLocale::textDirection(void) const ?peek@QIODevicePrivate@@UAE_JPAD_J@Z @ 4482 NONAME ; long long QIODevicePrivate::peek(char *, long long) ?peek@QIODevicePrivate@@UAE?AVQByteArray@@_J@Z @ 4483 NONAME ; class QByteArray QIODevicePrivate::peek(long long) + ?nativeArguments@QProcess@@QBE?AVQString@@XZ @ 4484 NONAME ; class QString QProcess::nativeArguments(void) const + ?setNativeArguments@QProcess@@QAEXABVQString@@@Z @ 4485 NONAME ; void QProcess::setNativeArguments(class QString const &) diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index 7b9e777..46c4885 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -3709,4 +3709,6 @@ EXPORTS _ZNK7QString13isRightToLeftEv @ 3708 NONAME _ZN16QIODevicePrivate4peekEPcx @ 3709 NONAME _ZN16QIODevicePrivate4peekEx @ 3710 NONAME + _ZN8QProcess18setNativeArgumentsERK7QString @ 3711 NONAME + _ZNK8QProcess15nativeArgumentsEv @ 3712 NONAME diff --git a/tests/auto/qprocess/testProcessSpacesArgs/main.cpp b/tests/auto/qprocess/testProcessSpacesArgs/main.cpp index d842934..ae5d3ae 100644 --- a/tests/auto/qprocess/testProcessSpacesArgs/main.cpp +++ b/tests/auto/qprocess/testProcessSpacesArgs/main.cpp @@ -44,9 +44,14 @@ int main(int argc, char ** argv) { -#if defined(__SYMBIAN32__) +#if defined(__SYMBIAN32__) || defined(WINCE) || defined(_WIN32_WCE) +# if defined(__SYMBIAN32__) // Printing to stdout messes up the out.txt, so open a file and print there. FILE* file = fopen("c:\\logs\\qprocess_args_test.txt","w+"); +# else + // No pipes on this "OS" + FILE* file = fopen("\\temp\\qprocess_args_test.txt","w+"); +# endif for (int i = 0; i < argc; ++i) { if (i) fprintf(file, "|"); diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp index 8242d30..fd310f4 100644 --- a/tests/auto/qprocess/tst_qprocess.cpp +++ b/tests/auto/qprocess/tst_qprocess.cpp @@ -132,6 +132,9 @@ private slots: void waitForBytesWrittenInABytesWrittenSlot(); void spaceArgsTest_data(); void spaceArgsTest(); +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + void nativeArguments(); +#endif void exitCodeTest(); void setEnvironment_data(); void setEnvironment(); @@ -1630,6 +1633,55 @@ void tst_QProcess::spaceArgsTest() process = 0; } +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + +//----------------------------------------------------------------------------- +void tst_QProcess::nativeArguments() +{ + QProcess proc; + + // This doesn't actually need special quoting, so it is pointless to use + // native arguments here, but that's not the point of this test. + proc.setNativeArguments("hello kitty, \"*\"!"); + + proc.start(QString::fromLatin1("testProcessSpacesArgs/nospace"), QStringList()); + +#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) + QVERIFY(proc.waitForStarted(5000)); + QVERIFY(proc.waitForFinished(5000)); +#else + QVERIFY(proc.waitForStarted(10000)); + QVERIFY(proc.waitForFinished(10000)); +#endif + +#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE) + // Symbian test outputs to a file, so check that +# ifdef Q_OS_SYMBIAN + FILE* file = fopen("c:\\logs\\qprocess_args_test.txt","r"); +# else + FILE* file = fopen("\\temp\\qprocess_args_test.txt","r"); +# endif + char buf[256]; + fgets(buf, 256, file); + fclose(file); + QStringList actual = QString::fromLatin1(buf).split("|"); +#else + QStringList actual = QString::fromLatin1(proc.readAll()).split("|"); +#endif + QVERIFY(!actual.isEmpty()); + // not interested in the program name, it might be different. + actual.removeFirst(); + QStringList expected; +#if defined(Q_OS_WINCE) + expected << "hello" << "kitty," << "\"*\"!"; // Weird, weird ... +#else + expected << "hello" << "kitty," << "*!"; +#endif + QCOMPARE(actual, expected); +} + +#endif + //----------------------------------------------------------------------------- void tst_QProcess::exitCodeTest() { -- cgit v0.12 From fa9c62460791c9b9add365fc9543ec0392f50cee Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Mon, 5 Jul 2010 17:05:04 +0200 Subject: Adapt the TapAndHold recognizer to non-touch too The QTapAndHoldGestureRecognizer now can trigger also on mouse and GraphicsSceneMouse events and all of them will cause the gesture start event to be sent after the touch interval timed out. Reviewed-by: Denis --- src/gui/kernel/qstandardgestures.cpp | 63 +++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index 8a3e89e..62d8a53 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -45,6 +45,7 @@ #include "qevent.h" #include "qwidget.h" #include "qabstractscrollarea.h" +#include #include "qdebug.h" #ifndef QT_NO_GESTURES @@ -509,49 +510,65 @@ QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object, if (object == state && event->type() == QEvent::Timer) { q->killTimer(d->timerId); d->timerId = 0; - return QGestureRecognizer::Ignore | QGestureRecognizer::ConsumeEventHint; + return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint; } const QTouchEvent *ev = static_cast(event); - - QGestureRecognizer::Result result = QGestureRecognizer::CancelGesture; + const QMouseEvent *me = static_cast(event); + const QGraphicsSceneMouseEvent *gsme = static_cast(event); enum { TimerInterval = 2000 }; enum { TapRadius = 40 }; switch (event->type()) { + case QEvent::GraphicsSceneMousePress: + d->position = gsme->screenPos(); + q->setHotSpot(d->position); + if (d->timerId) + q->killTimer(d->timerId); + d->timerId = q->startTimer(TimerInterval); + return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout + case QEvent::MouseButtonPress: + d->position = me->globalPos(); + q->setHotSpot(d->position); + if (d->timerId) + q->killTimer(d->timerId); + d->timerId = q->startTimer(TimerInterval); + return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout case QEvent::TouchBegin: - d->position = ev->touchPoints().at(0).pos(); + d->position = ev->touchPoints().at(0).startScreenPos(); + q->setHotSpot(d->position); if (d->timerId) q->killTimer(d->timerId); d->timerId = q->startTimer(TimerInterval); - q->setHotSpot(ev->touchPoints().at(0).startScreenPos()); - result = QGestureRecognizer::TriggerGesture; - break; + return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout + case QEvent::GraphicsSceneMouseRelease: + case QEvent::MouseButtonRelease: case QEvent::TouchEnd: - if (d->timerId) - result = QGestureRecognizer::CancelGesture; - else - result = QGestureRecognizer::FinishGesture; - break; + return QGestureRecognizer::CancelGesture; // get out of the MayBeGesture state case QEvent::TouchUpdate: - if (q->state() != Qt::NoGesture && ev->touchPoints().size() == 1) { + if (d->timerId && ev->touchPoints().size() == 1) { QTouchEvent::TouchPoint p = ev->touchPoints().at(0); QPoint delta = p.pos().toPoint() - p.startPos().toPoint(); if (delta.manhattanLength() <= TapRadius) - result = QGestureRecognizer::TriggerGesture; + return QGestureRecognizer::MayBeGesture; } - break; - case QEvent::MouseButtonPress: - case QEvent::MouseMove: - case QEvent::MouseButtonRelease: - result = QGestureRecognizer::Ignore; - break; + return QGestureRecognizer::CancelGesture; + case QEvent::MouseMove: { + QPoint delta = me->globalPos() - d->position.toPoint(); + if (d->timerId && delta.manhattanLength() <= TapRadius) + return QGestureRecognizer::MayBeGesture; + return QGestureRecognizer::CancelGesture; + } + case QEvent::GraphicsSceneMouseMove: { + QPoint delta = gsme->screenPos() - d->position.toPoint(); + if (d->timerId && delta.manhattanLength() <= TapRadius) + return QGestureRecognizer::MayBeGesture; + return QGestureRecognizer::CancelGesture; + } default: - result = QGestureRecognizer::Ignore; - break; + return QGestureRecognizer::Ignore; } - return result; } void QTapAndHoldGestureRecognizer::reset(QGesture *state) -- cgit v0.12 From 2fa8b39c8a687550934e9668384f0bbe9f56f550 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 6 Jul 2010 19:08:45 +0200 Subject: fix autotest fixing QProcess::execute() revealed that this test has always been broken on windows. --- tests/auto/linguist/lrelease/tst_lrelease.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/auto/linguist/lrelease/tst_lrelease.cpp b/tests/auto/linguist/lrelease/tst_lrelease.cpp index fdb384e..3b2c2d2 100644 --- a/tests/auto/linguist/lrelease/tst_lrelease.cpp +++ b/tests/auto/linguist/lrelease/tst_lrelease.cpp @@ -171,7 +171,12 @@ void tst_lrelease::mixedcodecs() { QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/mixedcodecs-ts11.ts")); QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/mixedcodecs-ts20.ts")); +#ifdef Q_OS_WIN + QVERIFY(!QProcess::execute("fc /b testdata\\mixedcodecs-ts11.qm testdata\\mixedcodecs-ts20.qm")); +#else QVERIFY(!QProcess::execute("cmp testdata/mixedcodecs-ts11.qm testdata/mixedcodecs-ts20.qm")); +#endif + QTranslator translator; QVERIFY(translator.load("testdata/mixedcodecs-ts11.qm")); qApp->installTranslator(&translator); -- cgit v0.12