diff --git a/doc/images/qmldesigner-run-settings.png b/doc/images/qmldesigner-run-settings.png index 3eff98e2901abde7f4545961f19f0a4980cdd155..0cd5d00d16e70ac54ac435ef20c13e75491ed57d 100644 Binary files a/doc/images/qmldesigner-run-settings.png and b/doc/images/qmldesigner-run-settings.png differ diff --git a/doc/images/qtcreator-build-dependencies.png b/doc/images/qtcreator-build-dependencies.png index de5b3ca59a9f53f704c3943583984eb9f63301d0..7f1284a50dcf3d9818c4d5a2c76dc1ee28c35d60 100644 Binary files a/doc/images/qtcreator-build-dependencies.png and b/doc/images/qtcreator-build-dependencies.png differ diff --git a/doc/images/qtcreator-code-style-settings-edit-cpp.png b/doc/images/qtcreator-code-style-settings-edit-cpp.png index 149ab65234331d2cb43db13940b1a5eae693c378..931211f53268d02a0adfe20592ed1bea831d04ef 100644 Binary files a/doc/images/qtcreator-code-style-settings-edit-cpp.png and b/doc/images/qtcreator-code-style-settings-edit-cpp.png differ diff --git a/doc/images/qtcreator-code-style-settings-edit-qtquick.png b/doc/images/qtcreator-code-style-settings-edit-qtquick.png index 4c32987cfa35599c282d550a1ef5b76a343acab6..563f09210518752884cb151cf0281d87852343d5 100644 Binary files a/doc/images/qtcreator-code-style-settings-edit-qtquick.png and b/doc/images/qtcreator-code-style-settings-edit-qtquick.png differ diff --git a/doc/images/qtcreator-editor-settings.png b/doc/images/qtcreator-editor-settings.png index 11c45b06bccc5491d60501b6411bb780599dece0..be9c7373ca60407ec48f8e769fcc0bfd7493fe8d 100644 Binary files a/doc/images/qtcreator-editor-settings.png and b/doc/images/qtcreator-editor-settings.png differ diff --git a/doc/images/qtcreator-qt4-qtversions-add.png b/doc/images/qtcreator-qt4-qtversions-add.png index 6c512d30f537aefbc1d1965cdec9e44cf2f56edf..ef59a4185c4e5564fe9a651994d8b70b64107da3 100644 Binary files a/doc/images/qtcreator-qt4-qtversions-add.png and b/doc/images/qtcreator-qt4-qtversions-add.png differ diff --git a/doc/images/qtcreator-qt4-qtversions-win-symbian.png b/doc/images/qtcreator-qt4-qtversions-win-symbian.png index 785e9e9b5df62119d7bb9881c97826e63626f143..5df8003eaf89fea6afd7d6e183a66e470daa462d 100644 Binary files a/doc/images/qtcreator-qt4-qtversions-win-symbian.png and b/doc/images/qtcreator-qt4-qtversions-win-symbian.png differ diff --git a/doc/images/qtcreator-session-manager.png b/doc/images/qtcreator-session-manager.png index 369a74ed37d64b714f8db0445939fefee3c4b7a7..65e057f64b1b2b60b72d67f34e79ae54b1c3483b 100644 Binary files a/doc/images/qtcreator-session-manager.png and b/doc/images/qtcreator-session-manager.png differ diff --git a/doc/images/qtcreator-toolchains.png b/doc/images/qtcreator-toolchains.png index 2455ecab494f16ae0eee9e5dfc4e7337f697df59..eee50fb6679a0d849ed7db8b663c9fd772c7bd7c 100644 Binary files a/doc/images/qtcreator-toolchains.png and b/doc/images/qtcreator-toolchains.png differ diff --git a/doc/images/qtcreator-welcome-session.png b/doc/images/qtcreator-welcome-session.png index b1418bccd879587d3aac4c8a2b3b2bd856a4ebf9..04e3419888307a3dd7b7e7da2f8915e76fb90389 100644 Binary files a/doc/images/qtcreator-welcome-session.png and b/doc/images/qtcreator-welcome-session.png differ diff --git a/doc/images/qtquick-debugging-settings.png b/doc/images/qtquick-debugging-settings.png index 67420059f2043bd12a20fab2835acf20f6f233d4..c789bfa5c408739cdbb58baecd183f2559afe03c 100644 Binary files a/doc/images/qtquick-debugging-settings.png and b/doc/images/qtquick-debugging-settings.png differ diff --git a/doc/src/debugger/qtquick-debugging.qdoc b/doc/src/debugger/qtquick-debugging.qdoc index bbe89d6a2995b9a84b6be7a3d665315a8b18958a..942aa6ce8f578e42abeae0e9f3b3f079919371a8 100644 --- a/doc/src/debugger/qtquick-debugging.qdoc +++ b/doc/src/debugger/qtquick-debugging.qdoc @@ -54,8 +54,9 @@ \list 1 - \o Select \gui Projects, and then select the \gui QML check box in the - \gui {Run Settings}, to enable QML debugging. + \o In \gui Projects mode \gui {Run Settings}, select the + \gui {Enable QML} check box in the \gui {Debugger Settings} to + enable QML debugging. \o For Qt 4.7, compile the QML Inspector debugging helper. For more information, see \l{Debugging Helpers for QML}. @@ -82,7 +83,8 @@ functions. Therefore, you must make sure that the port is properly protected by a firewall. - \o In the \gui {Run Settings}, select the \gui QML check box to enable + \o In the \gui {Run Settings}, \gui {Debugger Settings} section, select + the \gui {Enable QML} check box to enable QML debugging. \o Select \gui {Build > Rebuild Project} to clean and rebuild the @@ -98,7 +100,9 @@ \section1 Mixed C++/QML Debugging To debug both the C++ and QML parts of your application at the same time, - select the checkboxes for both languages in the \gui{Run Settings}. + select the \gui {Enable C++} and \gui {Enable QML} checkboxes for both + languages in the \gui {Debugger Settings} section in the project + \gui{Run Settings}. \image qtquick-debugging-settings.png diff --git a/doc/src/projects/creator-projects-settings-run-debug.qdocinc b/doc/src/projects/creator-projects-settings-run-debug.qdocinc new file mode 100644 index 0000000000000000000000000000000000000000..6e488a4af507b9e7122e99f74a0553714bbd3b45 --- /dev/null +++ b/doc/src/projects/creator-projects-settings-run-debug.qdocinc @@ -0,0 +1,19 @@ + \section2 Specifying Debugger Settings + + \image qtquick-debugging-settings.png "Debugger Settings" + + To select the languages to debug, select the \gui {Enable C++} and + \gui {Enable QML} check boxes. The \gui {Debug port} is the port to + communicate with the debugger. You can use any free port in the registered + or dynamic port range. + + \note Opening a socket at a well-known port presents a security risk. Anyone + on the Internet could connect to the application that you are debugging and + execute any JavaScript functions. Therefore, you must make sure that the + port is properly protected by a firewall. + + If you debug more than one application at a time, you might receive an error + message stating that the port is already in use. Specify a free port number + in \gui {Debug port} and try again. + + For more information about debugging, see \l{Debugging}. diff --git a/doc/src/qtquick/creator-projects-settings-run-qtquick.qdocinc b/doc/src/qtquick/creator-projects-settings-run-qtquick.qdocinc index 309f3303fa84c2a4f1d39f8fbd037a05390a66b6..76caa4527a777eeb2e726ceb3580e1cfed6b8f84 100644 --- a/doc/src/qtquick/creator-projects-settings-run-qtquick.qdocinc +++ b/doc/src/qtquick/creator-projects-settings-run-qtquick.qdocinc @@ -13,16 +13,6 @@ \o In the \gui {Main QML file}, select the file that \QQV will be started with. - \o In the \gui Debugger group, select the languages to debug: - \gui{C++} and \gui QML. \gui {Debug port} is the port to access - \QQV. You can use any free port in the registered port range. - For more information, see \l{Debugging Qt Quick Projects}. - \endlist - \note Opening a socket at a well-known port presents a security risk. Anyone - on the Internet could connect to the application that you are debugging and - execute any JavaScript functions. Therefore, you must make sure that the - port is properly protected by a firewall. - \image qmldesigner-run-settings.png "Run settings for Qt Quick UI projects" diff --git a/src/libs/utils/environment.cpp b/src/libs/utils/environment.cpp index 4390150f7321b883188b240500a85493cc4d8ad8..d6d0124d003fa1f385852e338c5c64e7c33acbf9 100644 --- a/src/libs/utils/environment.cpp +++ b/src/libs/utils/environment.cpp @@ -249,8 +249,11 @@ QString Environment::searchInPath(const QStringList &executables, if (exec.indexOf(slash) != -1) continue; foreach (const QString &p, path()) { - QString fp = p; - fp += slash; + QString fp = QDir::fromNativeSeparators(p); + // Avoid turing / into // on windows which triggers windows to check + // for network drives! + if (!fp.endsWith(slash)) + fp += slash; fp += exec; const QFileInfo fi(fp); if (fi.exists() && fi.isExecutable() && !fi.isDir()) diff --git a/src/plugins/coreplugin/images/splitbutton_closebottom.png b/src/plugins/coreplugin/images/splitbutton_closebottom.png index 5aa95802d6b05dc23ed21a25f5cc6f0b74edb37f..508f40f4f9011b59fb8ec3d0b1c22df2d30e0593 100644 Binary files a/src/plugins/coreplugin/images/splitbutton_closebottom.png and b/src/plugins/coreplugin/images/splitbutton_closebottom.png differ diff --git a/src/plugins/coreplugin/images/splitbutton_closeleft.png b/src/plugins/coreplugin/images/splitbutton_closeleft.png index 07e90c9ea1d035ed6419c11ab4523f41605c0809..2cff3f15f6847dfd63cc174b587dccc198675e52 100644 Binary files a/src/plugins/coreplugin/images/splitbutton_closeleft.png and b/src/plugins/coreplugin/images/splitbutton_closeleft.png differ diff --git a/src/plugins/coreplugin/images/splitbutton_closeright.png b/src/plugins/coreplugin/images/splitbutton_closeright.png index 8c9286e310c5d55d66381f902cb0a53d6fc09f99..96905815757fc3d5d8f2e1237d8c63480819a4f3 100644 Binary files a/src/plugins/coreplugin/images/splitbutton_closeright.png and b/src/plugins/coreplugin/images/splitbutton_closeright.png differ diff --git a/src/plugins/coreplugin/images/splitbutton_closetop.png b/src/plugins/coreplugin/images/splitbutton_closetop.png index 2c8f49db13f324423797ce8d2b157af1727d909c..1053ae107c343a692e915b282a4cd317e0bfbbc3 100644 Binary files a/src/plugins/coreplugin/images/splitbutton_closetop.png and b/src/plugins/coreplugin/images/splitbutton_closetop.png differ diff --git a/src/plugins/coreplugin/images/splitbutton_horizontal.png b/src/plugins/coreplugin/images/splitbutton_horizontal.png index 90730532f1ef7013a98722af36fc19c1f9ab05f1..e8a3e075c8d75221981965865616aebbc41d06bd 100644 Binary files a/src/plugins/coreplugin/images/splitbutton_horizontal.png and b/src/plugins/coreplugin/images/splitbutton_horizontal.png differ diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index ccf3e7a4c801c7ef809cb0a61a2fc1184dd15eaf..c7f1ffbffcf02fa2023fbde3b4c5af6bf8347c0c 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -1060,9 +1060,15 @@ void QmlEngine::expressionEvaluated(quint32 queryId, const QVariant &result) { if (d->queryIds.contains(queryId)) { d->queryIds.removeOne(queryId); - QtMessageLogItem *item = constructLogItemTree(result); + QtMessageLogItem *item = constructLogItemTree(qtMessageLogHandler()->root(), + result); if (item) qtMessageLogHandler()->appendItem(item); + } else { + qtMessageLogHandler()-> + appendItem(new QtMessageLogItem(qtMessageLogHandler()->root(), + QtMessageLogHandler::ErrorType, + _("Error evaluating expression."))); } } @@ -1133,7 +1139,8 @@ void QmlEngine::appendDebugOutput(QtMsgType type, const QString &message, //This case is not possible return; } - QtMessageLogItem *item = new QtMessageLogItem(itemType, message); + QtMessageLogItem *item = new QtMessageLogItem(qtMessageLogHandler()->root(), + itemType, message); item->file = info.file; item->line = info.line; qtMessageLogHandler()->appendItem(item); @@ -1175,6 +1182,7 @@ bool QmlEngine::evaluateScriptExpression(const QString& expression) qtMessageLogHandler()-> appendItem( new QtMessageLogItem( + qtMessageLogHandler()->root(), QtMessageLogHandler::ErrorType, _("Error evaluating expression."))); } @@ -1189,8 +1197,9 @@ bool QmlEngine::evaluateScriptExpression(const QString& expression) //Incase of invalid context, show Error message qtMessageLogHandler()-> appendItem(new QtMessageLogItem( + qtMessageLogHandler()->root(), QtMessageLogHandler::ErrorType, - _("Cannot evaluate without" + _("Cannot evaluate without " "a valid QML/JS Context.")), qtMessageLogHandler()->rowCount()); } @@ -1301,12 +1310,12 @@ bool QmlEngine::canEvaluateScript(const QString &script) } QtMessageLogItem *QmlEngine::constructLogItemTree( - const QVariant &result, const QString &key) + QtMessageLogItem *parent, const QVariant &result, const QString &key) { if (!result.isValid()) return 0; - QtMessageLogItem *item = new QtMessageLogItem(); + QtMessageLogItem *item = new QtMessageLogItem(parent); if (result.type() == QVariant::Map) { if (key.isEmpty()) item->text = _("Object"); @@ -1316,9 +1325,10 @@ QtMessageLogItem *QmlEngine::constructLogItemTree( QMapIterator<QString, QVariant> i(result.toMap()); while (i.hasNext()) { i.next(); - QtMessageLogItem *child = constructLogItemTree(i.value(), i.key()); + QtMessageLogItem *child = constructLogItemTree(item, + i.value(), i.key()); if (child) - item->insertChild(item->childCount(), child); + item->insertChild(child); } } else if (result.type() == QVariant::List) { if (key.isEmpty()) @@ -1327,10 +1337,10 @@ QtMessageLogItem *QmlEngine::constructLogItemTree( item->text = QString(_("[%1] : List")).arg(key); QVariantList resultList = result.toList(); for (int i = 0; i < resultList.count(); i++) { - QtMessageLogItem *child = constructLogItemTree(resultList.at(i), + QtMessageLogItem *child = constructLogItemTree(item, resultList.at(i), QString::number(i)); if (child) - item->insertChild(item->childCount(), child); + item->insertChild(child); } } else if (result.canConvert(QVariant::String)) { item->text = result.toString(); diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h index 71a7a6b2b7715edfd1a694943de77124d0969237..9a69094c9bd6c3015a579d215325ec096a9c9eb1 100644 --- a/src/plugins/debugger/qml/qmlengine.h +++ b/src/plugins/debugger/qml/qmlengine.h @@ -185,7 +185,8 @@ private: void updateEditor(Core::IEditor *editor, const QTextDocument *document); bool canEvaluateScript(const QString &script); - QtMessageLogItem *constructLogItemTree(const QVariant &result, + QtMessageLogItem *constructLogItemTree(QtMessageLogItem *parent, + const QVariant &result, const QString &key = QString()); bool adjustBreakpointLineAndColumn(const QString &filePath, quint32 *line, quint32 *column, bool *valid); diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp index 9067ec08c3334dfd7dbae4d4ffc608c0fbf7cfc6..01910e1bd5c287e964f099ad4dc7ab47deaf691d 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp @@ -128,8 +128,8 @@ public: //TODO:: remove this method void reformatRequest(QByteArray &request); - QtMessageLogItem *constructLogItemTree(const QmlV8ObjectData &objectData, - const QVariant &refsVal); + QtMessageLogItem *constructLogItemTree(QtMessageLogItem *parent, + const QmlV8ObjectData &objectData, const QVariant &refsVal); private: QByteArray packMessage(const QByteArray &type, const QByteArray &message = QByteArray()); QScriptValue initObject(); @@ -150,6 +150,8 @@ public: QHash<int, QString> evaluatingExpression; QHash<int, QByteArray> localsAndWatchers; + QList<int> updateLocalsAndWatchers; + QList<int> debuggerCommands; //Cache QStringList watchedExpressions; @@ -831,6 +833,7 @@ QmlV8ObjectData QmlV8DebuggerClientPrivate::extractData(const QVariant &data, objectData.properties = data.properties; } } else { + objectData.handle = dataMap.value(_(HANDLE)).toInt(); QString type = dataMap.value(_(TYPE)).toString(); if (type == _("undefined")) { @@ -876,6 +879,8 @@ void QmlV8DebuggerClientPrivate::clearCache() { watchedExpressions.clear(); currentFrameScopes.clear(); + evaluatingExpression.clear(); + updateLocalsAndWatchers.clear(); } QByteArray QmlV8DebuggerClientPrivate::packMessage(const QByteArray &type, const QByteArray &message) @@ -969,6 +974,7 @@ void QmlV8DebuggerClientPrivate::reformatRequest(QByteArray &request) } QtMessageLogItem *QmlV8DebuggerClientPrivate::constructLogItemTree( + QtMessageLogItem *parent, const QmlV8ObjectData &objectData, const QVariant &refsVal) { @@ -982,14 +988,14 @@ QtMessageLogItem *QmlV8DebuggerClientPrivate::constructLogItemTree( text = QString(_("%1: %2")).arg(QString::fromAscii(objectData.name)) .arg(objectData.value.toString()); - QtMessageLogItem *item = new QtMessageLogItem( - QtMessageLogHandler::UndefinedType, text); + QtMessageLogItem *item = new QtMessageLogItem(parent, + QtMessageLogHandler::UndefinedType, text); foreach (const QVariant &property, objectData.properties) { QtMessageLogItem *child = constructLogItemTree( - extractData(property, refsVal), refsVal); + item, extractData(property, refsVal), refsVal); if (child) - item->insertChild(item->childCount(), child); + item->insertChild(child); } return item; @@ -1161,6 +1167,7 @@ void QmlV8DebuggerClient::assignValueInDebugger(const WatchData * /*data*/, QString expression = QString(_("%1 = %2;")).arg(expr).arg(valueV.toString()); if (stackHandler->isContentsValid() && stackHandler->currentFrame().isUsable()) { d->evaluate(expression, false, false, stackHandler->currentIndex()); + d->updateLocalsAndWatchers.append(d->sequence); } else { d->engine->showMessage(QString(_("Cannot evaluate" "%1 in current stack frame")). @@ -1178,7 +1185,7 @@ void QmlV8DebuggerClient::executeDebuggerCommand(const QString &command) StackHandler *stackHandler = d->engine->stackHandler(); if (stackHandler->isContentsValid() && stackHandler->currentFrame().isUsable()) { d->evaluate(command, false, false, stackHandler->currentIndex()); - d->evaluatingExpression.insert(d->sequence, command); + d->debuggerCommands.append(d->sequence); } else { //Currently cannot evaluate if not in a javascript break d->engine->showMessage(QString(_("Cannot evaluate %1" @@ -1192,7 +1199,6 @@ void QmlV8DebuggerClient::synchronizeWatchers(const QStringList &watchers) SDEBUG(watchers); foreach (const QString &exp, watchers) { if (!d->watchedExpressions.contains(exp)) { - d->watchedExpressions << exp; StackHandler *stackHandler = d->engine->stackHandler(); if (stackHandler->isContentsValid() && stackHandler->currentFrame().isUsable()) { d->evaluate(exp, false, false, stackHandler->currentIndex()); @@ -1200,11 +1206,24 @@ void QmlV8DebuggerClient::synchronizeWatchers(const QStringList &watchers) } } } + d->watchedExpressions = watchers; } void QmlV8DebuggerClient::expandObject(const QByteArray &iname, quint64 objectId) { - d->localsAndWatchers.insert(objectId, iname); + if (objectId == 0) { + //We may have got the global object + const WatchData *watch = d->engine->watchHandler()->findItem(iname); + if (watch->value == QLatin1String("global")) { + StackHandler *stackHandler = d->engine->stackHandler(); + if (stackHandler->isContentsValid() && stackHandler->currentFrame().isUsable()) { + d->evaluate(watch->name, false, false, stackHandler->currentIndex()); + d->evaluatingExpression.insert(d->sequence, QLatin1String(iname)); + } + return; + } + } + d->localsAndWatchers.insertMulti(objectId, iname); d->lookup(QList<int>() << objectId); } @@ -1702,6 +1721,12 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const data.type = objectData.type; data.value = objectData.value.toString(); data.setHasChildren(objectData.properties.count()); + //Incase of global object, we do not get children + //Set children nevertheless and query later + if (data.value == QLatin1String("global")) { + data.setHasChildren(true); + data.id = 0; + } d->engine->watchHandler()->beginCycle(); d->engine->watchHandler()->insertData(data); d->engine->watchHandler()->endCycle(); @@ -1774,7 +1799,7 @@ void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &r locals << data; } else { handlesToLookup << handle; - d->localsAndWatchers.insert(handle, data.exp); + d->localsAndWatchers.insertMulti(handle, data.exp); } } @@ -1799,43 +1824,60 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, con // "running" : <is the VM running after sending this response> // "success" : true // } - if (!d->evaluatingExpression.contains(sequence)) { + if (d->updateLocalsAndWatchers.contains(sequence)) { + d->updateLocalsAndWatchers.removeOne(sequence); + //Update the locals + foreach (int index, d->currentFrameScopes) + d->scope(index); + //Also update "this" + QByteArray iname("local.this"); + const WatchData *parent = d->engine->watchHandler()->findItem(iname); + d->localsAndWatchers.insertMulti(parent->id, iname); + d->lookup(QList<int>() << parent->id); + + } else if (d->debuggerCommands.contains(sequence)) { + d->updateLocalsAndWatchers.removeOne(sequence); + QmlV8ObjectData body = d->extractData(bodyVal, refsVal); + QtMessageLogItem *item = d->constructLogItemTree(d->engine->qtMessageLogHandler()->root(), + body, refsVal); + if (item) + d->engine->qtMessageLogHandler()->appendItem(item); //Update the locals foreach (int index, d->currentFrameScopes) d->scope(index); } else { QmlV8ObjectData body = d->extractData(bodyVal, refsVal); - QString exp = d->evaluatingExpression.take(sequence); - if (d->watchedExpressions.contains(exp)) { - QByteArray iname = d->engine->watchHandler()->watcherName(exp.toLatin1()); - SDEBUG(QString(iname)); + if (d->evaluatingExpression.contains(sequence)) { + QString exp = d->evaluatingExpression.take(sequence); + QList<WatchData> watchDataList; WatchData data; - data.exp = exp.toLatin1(); - data.name = exp; - data.iname = iname; - data.id = body.handle; - if (success) { - data.type = body.type; - data.value = body.value.toString(); - data.hasChildren = body.properties.count(); + //Do we have request to evaluate a local? + if (exp.startsWith("local.")) { + const WatchData *watch = d->engine->watchHandler()->findItem(exp.toLatin1()); + watchDataList << createWatchDataList(watch, body.properties, refsVal); } else { - //Do not set type since it is unknown - data.setError(body.value.toString()); + QByteArray iname = d->engine->watchHandler()->watcherName(exp.toLatin1()); + SDEBUG(QString(iname)); + + data.exp = exp.toLatin1(); + data.name = exp; + data.iname = iname; + data.id = body.handle; + if (success) { + data.type = body.type; + data.value = body.value.toString(); + data.hasChildren = body.properties.count(); + } else { + //Do not set type since it is unknown + data.setError(body.value.toString()); + } + watchDataList << data << createWatchDataList(&data, body.properties, refsVal); } - //Insert the newly evaluated expression to the Watchers Window d->engine->watchHandler()->beginCycle(false); - d->engine->watchHandler()->insertData(data); + d->engine->watchHandler()->insertBulkData(watchDataList); d->engine->watchHandler()->endCycle(); - - } else { - QtMessageLogItem *item = d->constructLogItemTree(body, refsVal); - if (item) - d->engine->qtMessageLogHandler()->appendItem(item); - //Update the locals - foreach (int index, d->currentFrameScopes) - d->scope(index); } } } @@ -1911,35 +1953,9 @@ void QmlV8DebuggerClient::expandLocalsAndWatchers(const QVariant &bodyVal, const if (prepend.startsWith("local.") || prepend.startsWith("watch.")) { //Data for expanded local/watch - if (bodyObjectData.properties.count()) { - //Could be an object or function - const WatchData *parent = d->engine->watchHandler()->findItem(prepend); - foreach (const QVariant &property, bodyObjectData.properties) { - QmlV8ObjectData propertyData = d->extractData(property, refsVal); - WatchData data; - data.name = propertyData.name; - - //Check for v8 specific local data - if (data.name.startsWith(QLatin1Char('.')) || data.name.isEmpty()) - continue; - if (parent && parent->type == "object") { - if (parent->value == _("Array")) - data.exp = parent->exp + QByteArray("[") + - data.name.toLatin1() + QByteArray("]"); - else if (parent->value == _("Object")) - data.exp = parent->exp + QByteArray(".") + data.name.toLatin1(); - } else { - data.exp = data.name.toLatin1(); - } - - data.iname = prepend + '.' + data.name.toLatin1(); - data.id = propertyData.handle; - data.type = propertyData.type; - data.value = propertyData.value.toString(); - data.setHasChildren(propertyData.properties.count()); - watchDataList << data; - } - } + //Could be an object or function + const WatchData *parent = d->engine->watchHandler()->findItem(prepend); + watchDataList << createWatchDataList(parent, bodyObjectData.properties, refsVal); } else { //rest WatchData data; @@ -1962,6 +1978,41 @@ void QmlV8DebuggerClient::expandLocalsAndWatchers(const QVariant &bodyVal, const d->engine->watchHandler()->endCycle(); } +QList<WatchData> QmlV8DebuggerClient::createWatchDataList(const WatchData *parent, + const QVariantList &properties, + const QVariant &refsVal) +{ + QList<WatchData> watchDataList; + if (properties.count()) { + QTC_ASSERT(parent, return watchDataList); + foreach (const QVariant &property, properties) { + QmlV8ObjectData propertyData = d->extractData(property, refsVal); + WatchData data; + data.name = propertyData.name; + + //Check for v8 specific local data + if (data.name.startsWith(QLatin1Char('.')) || data.name.isEmpty()) + continue; + if (parent->type == "object") { + if (parent->value == _("Array")) + data.exp = parent->exp + '[' + data.name.toLatin1() + ']'; + else if (parent->value == _("Object")) + data.exp = parent->exp + '.' + data.name.toLatin1(); + } else { + data.exp = data.name.toLatin1(); + } + + data.iname = parent->iname + '.' + data.name.toLatin1(); + data.id = propertyData.handle; + data.type = propertyData.type; + data.value = propertyData.value.toString(); + data.setHasChildren(propertyData.properties.count()); + watchDataList << data; + } + } + return watchDataList; +} + void QmlV8DebuggerClient::highlightExceptionCode(int lineNumber, const QString &filePath, const QString &errorMessage) diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.h b/src/plugins/debugger/qml/qmlv8debuggerclient.h index 7a77b88d85308935b896d06d82bf330d81e730ad..1af42732b533fe3487b75bad3d91ffcaf720f72a 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.h +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.h @@ -116,6 +116,9 @@ private: void updateBreakpoints(const QVariant &bodyVal); void expandLocalsAndWatchers(const QVariant &bodyVal, const QVariant &refsVal); + QList<WatchData> createWatchDataList(const WatchData *parent, + const QVariantList &properties, + const QVariant &refsVal); void highlightExceptionCode(int lineNumber, const QString &filePath, const QString &errorMessage); diff --git a/src/plugins/debugger/qtmessageloghandler.cpp b/src/plugins/debugger/qtmessageloghandler.cpp index e8eae4038aec50f2cd716dd812e4fd7accb81127..3ca2d33bfa01b072c0202063d1906636b0c06fd8 100644 --- a/src/plugins/debugger/qtmessageloghandler.cpp +++ b/src/plugins/debugger/qtmessageloghandler.cpp @@ -31,6 +31,8 @@ **************************************************************************/ #include "qtmessageloghandler.h" +#include "debuggercore.h" +#include "debuggeractions.h" #include <utils/qtcassert.h> @@ -45,8 +47,8 @@ namespace Internal { // /////////////////////////////////////////////////////////////////////// -QtMessageLogItem::QtMessageLogItem(QtMessageLogHandler::ItemType itemType, - const QString &text, QtMessageLogItem *parent) +QtMessageLogItem::QtMessageLogItem(QtMessageLogItem *parent, + QtMessageLogHandler::ItemType itemType, const QString &text) : m_parentItem(parent), text(text), itemType(itemType), @@ -86,23 +88,35 @@ bool QtMessageLogItem::insertChildren(int position, int count) for (int row = 0; row < count; ++row) { QtMessageLogItem *item = new - QtMessageLogItem(QtMessageLogHandler::UndefinedType, QString(), - this); + QtMessageLogItem(this , QtMessageLogHandler::UndefinedType, + QString()); m_childItems.insert(position, item); } return true; } +void QtMessageLogItem::insertChild(QtMessageLogItem *item) +{ + if (!debuggerCore()->boolSetting(SortStructMembers)) { + m_childItems.insert(m_childItems.count(), item); + return; + } + + int i = 0; + for (; i < m_childItems.count(); i++) { + if (item->text < m_childItems[i]->text) { + break; + } + } + m_childItems.insert(i, item); +} + bool QtMessageLogItem::insertChild(int position, QtMessageLogItem *item) { if (position < 0 || position > m_childItems.size()) return false; - if (item->parent()) - item->parent()->detachChild(item->childNumber()); - - item->m_parentItem = this; m_childItems.insert(position, item); return true; @@ -143,7 +157,7 @@ bool QtMessageLogItem::detachChild(int position) QtMessageLogHandler::QtMessageLogHandler(QObject *parent) : QAbstractItemModel(parent), m_hasEditableRow(false), - m_rootItem(new QtMessageLogItem()), + m_rootItem(new QtMessageLogItem(0)), m_maxSizeOfFileName(0) { } @@ -157,8 +171,8 @@ void QtMessageLogHandler::clear() { beginResetModel(); reset(); - delete m_rootItem; - m_rootItem = new QtMessageLogItem(); + qDeleteAll(m_rootItem->m_childItems); + m_rootItem->m_childItems.clear(); endResetModel(); if (m_hasEditableRow) @@ -180,7 +194,7 @@ bool QtMessageLogHandler::appendItem(QtMessageLogItem *item, int position) bool QtMessageLogHandler::appendMessage(QtMessageLogHandler::ItemType itemType, const QString &message, int position) { - return appendItem(new QtMessageLogItem(itemType, message), position); + return appendItem(new QtMessageLogItem(m_rootItem, itemType, message), position); } void QtMessageLogHandler::setHasEditableRow(bool hasEditableRow) @@ -202,7 +216,7 @@ bool QtMessageLogHandler::hasEditableRow() const void QtMessageLogHandler::appendEditableRow() { int position = m_rootItem->childCount(); - if (appendItem(new QtMessageLogItem(QtMessageLogHandler::InputType), position)) + if (appendItem(new QtMessageLogItem(m_rootItem, QtMessageLogHandler::InputType), position)) emit selectEditableRow(index(position, 0), QItemSelectionModel::ClearAndSelect); } @@ -289,7 +303,8 @@ QModelIndex QtMessageLogHandler::parent(const QModelIndex &index) const return QModelIndex(); //can parentItem be 0? - QTC_ASSERT(parentItem, qDebug("Parent is Null!!")); + if (!parentItem) + return QModelIndex(); return createIndex(parentItem->childNumber(), 0, parentItem); } diff --git a/src/plugins/debugger/qtmessageloghandler.h b/src/plugins/debugger/qtmessageloghandler.h index 9031c8e94c31a44b8ed51a300ce23498eafa4a3b..6e84f67a18956fdbfd53a999306ab823d324db0d 100644 --- a/src/plugins/debugger/qtmessageloghandler.h +++ b/src/plugins/debugger/qtmessageloghandler.h @@ -78,6 +78,8 @@ public: int sizeOfFile(const QFont &font); int sizeOfLineNumber(const QFont &font); + QtMessageLogItem *root() const { return m_rootItem; } + public slots: void clear(); @@ -116,14 +118,15 @@ private: class QtMessageLogItem { public: - QtMessageLogItem(QtMessageLogHandler::ItemType type = QtMessageLogHandler::UndefinedType, - const QString &data = QString(), - QtMessageLogItem *parent = 0); + QtMessageLogItem(QtMessageLogItem *parent, + QtMessageLogHandler::ItemType type = QtMessageLogHandler::UndefinedType, + const QString &data = QString()); ~QtMessageLogItem(); QtMessageLogItem *child(int number); int childCount() const; bool insertChildren(int position, int count); + void insertChild(QtMessageLogItem *item); bool insertChild(int position, QtMessageLogItem *item); QtMessageLogItem *parent(); bool removeChildren(int position, int count); @@ -139,6 +142,9 @@ public: QtMessageLogHandler::ItemType itemType; QString file; int line; + +private: + friend class QtMessageLogHandler; }; } //Internal diff --git a/tests/manual/debugger/simple/simple_test_app.cpp b/tests/manual/debugger/simple/simple_test_app.cpp index 43a385f1c1aff4414a9de358820b72d85fbcb4c4..96f4b7564fde56e5497cb9e8d48b05b7406b8b97 100644 --- a/tests/manual/debugger/simple/simple_test_app.cpp +++ b/tests/manual/debugger/simple/simple_test_app.cpp @@ -2013,7 +2013,7 @@ namespace final { BREAK_HERE; // Expand settings. // Check settings "" QSettings. - // Check settings.[QObject] "" QSettings. + // Check settings.@1 "" QObject. // Check value "" QVariant (QString). // Continue. dummyStatement(&settings, &value); @@ -3577,7 +3577,7 @@ namespace qthread { // Expand this. // Check j 3 int. // CheckType this qthread::Thread. - // Check this.[QThread] "This is thread #3" qthread::Thread. + // Check this.@1 "This is thread #3" QThread. // Continue. dummyStatement(this); } @@ -3767,7 +3767,8 @@ namespace qvariant { // Check ha1.isParsed false bool. // Check ha1.protocol QAbstractSocket::UnknownNetworkLayerProtocol (-1) QAbstractSocket::NetworkLayerProtocol. // Check ha1.scopeId "" QString. - // Check var "127.0.0.1" QVariant (QHostAddress). + // CheckType var QVariant (QHostAddress). + // Check var.data "127.0.0.1" QHostAddress. // Continue. dummyStatement(&ha1); } @@ -3785,7 +3786,7 @@ namespace qvariant { //QString type = var.typeName(); var.setValue(my); BREAK_HERE; - // Expand my my.0 my.0.value my.1 my.1.value var var.0 var.0.value var.1 var.1.value. + // Expand my my.0 my.0.value my.1 my.1.value var var.data var.data.0 var.data.0.value var.data.1 var.data.1.value. // Check my <2 items> qvariant::MyType. // Check my.0 QMapNode<unsigned int, QStringList>. // Check my.0.key 1 unsigned int. @@ -3795,15 +3796,16 @@ namespace qvariant { // Check my.1.key 3 unsigned int. // Check my.1.value <1 items> QStringList. // Check my.1.value.0 "World" QString. - // Check var <2 items> QVariant (MyType). - // Check var.0 QMapNode<unsigned int, QStringList>. - // Check var.0.key 1 unsigned int. - // Check var.0.value <1 items> QStringList. + // CheckType var QVariant (QMap<unsigned int , QStringList>). + // Check var.data <2 items> QMap<unsigned int, QStringList>. + // Check var.data.0 QMapNode<unsigned int, QStringList>. + // Check var.data.0.key 1 unsigned int. + // Check var.data.0.value <1 items> QStringList. // Check var.0.value.0 "Hello" QString. - // Check var.1 QMapNode<unsigned int, QStringList>. - // Check var.1.key 3 unsigned int. - // Check var.1.value <1 items> QStringList. - // Check var.1.value.0 "World" QString. + // Check var.data.1 QMapNode<unsigned int, QStringList>. + // Check var.data.1.key 3 unsigned int. + // Check var.data.1.value <1 items> QStringList. + // Check var.data.1.value.0 "World" QString. // Continue. var.setValue(my); var.setValue(my); @@ -3817,15 +3819,16 @@ namespace qvariant { list << 1 << 2 << 3; QVariant variant = qVariantFromValue(list); BREAK_HERE; - // Expand list variant. + // Expand list variant variant.data. // Check list <3 items> QList<int>. // Check list.0 1 int. // Check list.1 2 int. // Check list.2 3 int. - // Check variant <3 items> QVariant (QList<int>). - // Check variant.0 1 int. - // Check variant.1 2 int. - // Check variant.2 3 int. + // CheckType variant QVariant (QList<int>). + // Check variant.data <3 items> QList<int>. + // Check variant.data.0 1 int. + // Check variant.data.1 2 int. + // Check variant.data.2 3 int. // Continue. list.clear(); list = qVariantValue<QList<int> >(variant); @@ -5095,7 +5098,6 @@ namespace qscript { s.setProperty("a", QScriptValue()); QScriptValue d = s.data(); BREAK_HERE; - // Check s <native> QScriptValue (JSCoreValue). // Check d (invalid) QScriptValue. // Check v 43 QVariant (int). // Check x 33 int. @@ -5693,17 +5695,17 @@ namespace bug5799 { typedef S1 Array[10]; Array a2; BREAK_HERE; - // Expand s2 s2.bug5700::S1 s4 s4.bug5799::S3 + // Expand s2 s2.@1 s4 s4.@1 // CheckType a1 bug5799::S1 [10]. // CheckType a2 bug5799::Array. // CheckType s2 bug5799::S2. - // CheckType s2.[bug5799::S1] bug5799::S1. - // Check s2.[bug5799::S1].m1 5 int. - // Check s2.[bug5799::S1].m2 32767 int. + // CheckType s2.@1 bug5799::S1. + // Check s2.@1.m1 5 int. + // CheckType s2.@1.m2 int. // CheckType s4 bug5799::S4. - // CheckType s4.[bug5799::S3] bug5799::S3. - // Check s4.[bug5799::S3].m1 5 int. - // Check s4.[bug5799::S3].m2 0 int. + // CheckType s4.@1 bug5799::S3. + // Check s4.@1.m1 5 int. + // CheckType s4.@1.m2 int. // Continue. dummyStatement(&s2, &s4, &a1, &a2); } @@ -5822,8 +5824,8 @@ namespace bug6857 { file.setObjectName("A file"); BREAK_HERE; // Expand file. - // Check file "A file" MyFile. - // Check file.[QFile] "/tmp/tt" QFile. + // Check file "A file" bug6857::MyFile. + // Check file.@1 "/tmp/tt" QFile. // Continue. dummyStatement(&file); } @@ -5846,7 +5848,7 @@ namespace bug6858 { QFile *pfile = &file; BREAK_HERE; // Check pfile "Another file" bug6858::MyFile. - // Check pfile.[QFile] "/tmp/tt" QFile. + // Check pfile.@1 "/tmp/tt" QFile. // Continue. dummyStatement(&file, pfile); } @@ -5969,15 +5971,15 @@ namespace gdb13393 { int sharedPtr = 1; #endif BREAK_HERE; - // Expand d ptr ptrConst ptrToPtr ref refConst s. + // Expand d ptr ptr.@1 ptrConst ptrToPtr ref refConst s. // CheckType d gdb13393::Derived. - // CheckType d.[gdb13393::Base] gdb13393::Derived. + // CheckType d.@1 gdb13393::Base. // Check d.b 2 int. // CheckType ptr gdb13393::Derived. - // CheckType ptr.[gdb12293::Base] gdb13393::Base. - // Check ptr.[a] 1 int. + // CheckType ptr.@1 gdb13393::Base. + // Check ptr.@1.a 1 int. // CheckType ptrConst gdb13393::Derived. - // CheckType ptrConst.[gdb13393::Base] gdb13393::Base. + // CheckType ptrConst.@1 gdb13393::Base. // Check ptrConst.b 2 int. // CheckType ptrToPtr gdb13393::Derived. // CheckType ptrToPtr.[vptr] . @@ -6032,7 +6034,10 @@ namespace gdb10586 { // CheckType v {...}. // CheckType n gdb10586::s. // Check v.a 2 int. - // Check s.x 1 int. + // Check v.b 3 int. + // Check v.x 1 int. + // Check n.x 10 int. + // Check n.y 20 int. // Continue. dummyStatement(&v, &n); }