From a2a5536822ab101e8c0d066bd9039e5de732d8ad Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 18 Mar 2015 18:07:57 +0100 Subject: [PATCH 01/37] Fix timeline shaders for OpenGL ES In OpenGL ES you have to: * Specify the precision for most values in fragment shaders * Add a special declaration to use fwidth() * Make sure both values passed to max() are of the same type (this may be the case for some Desktop OpenGL implementations, too) Repeating the default precision (highp float) in vertex shaders is useless and might lead to type casting problems, so we drop it. Without this change, the timeline doesn't work on Windows with ANGLE. Change-Id: I69a1976eddb6f4dc6dfe5fe9f270839432088cbb Reviewed-by: Maurice Kalinowski Reviewed-by: Joerg Bornemann Reviewed-by: Kai Koehne --- src/libs/timeline/qml/notes.frag | 4 ++-- src/libs/timeline/qml/timelineitems.frag | 13 +++++++++---- src/libs/timeline/qml/timelineitems.vert | 8 ++++---- src/plugins/qmlprofiler/qml/bindingloops.frag | 2 +- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/libs/timeline/qml/notes.frag b/src/libs/timeline/qml/notes.frag index 472c0174db0..72ecfa93718 100644 --- a/src/libs/timeline/qml/notes.frag +++ b/src/libs/timeline/qml/notes.frag @@ -28,8 +28,8 @@ ** ****************************************************************************/ -vec4 orange = vec4(1.0, 165.0 / 255.0, 0.0, 1.0); -varying float d; +lowp vec4 orange = vec4(1.0, 165.0 / 255.0, 0.0, 1.0); +varying lowp float d; void main() { diff --git a/src/libs/timeline/qml/timelineitems.frag b/src/libs/timeline/qml/timelineitems.frag index 0ee0ad2aba6..5f44fbcf019 100644 --- a/src/libs/timeline/qml/timelineitems.frag +++ b/src/libs/timeline/qml/timelineitems.frag @@ -28,17 +28,22 @@ ** ****************************************************************************/ +#ifdef GL_OES_standard_derivatives +#extension GL_OES_standard_derivatives : enable +// else we probably have fwidth() in core +#endif + varying lowp vec3 edgeColor; varying lowp vec3 color; varying lowp vec2 barycentric; -vec4 zero = vec4(0.0); +lowp vec4 zero = vec4(0.0); void main() { - vec2 d = fwidth(barycentric) * 5.0; - vec4 edge_closeness = smoothstep(zero, vec4(d.x, d.y, d.x, d.y), + lowp vec2 d = fwidth(barycentric) * 5.0; + lowp vec4 edge_closeness = smoothstep(zero, vec4(d.x, d.y, d.x, d.y), vec4(barycentric.x, barycentric.y, 1.0 - barycentric.x, 1.0 - barycentric.y)); - float total = min(min(edge_closeness[0], edge_closeness[1]), + lowp float total = min(min(edge_closeness[0], edge_closeness[1]), min(edge_closeness[2], edge_closeness[3])); // square to make lines sharper total = total > 0.5 ? (1.0 - (1.0 - total) * (1.0 - total) * 2.0) : total * total * 2.0; diff --git a/src/libs/timeline/qml/timelineitems.vert b/src/libs/timeline/qml/timelineitems.vert index 58f28b558a9..cea5b49cd42 100644 --- a/src/libs/timeline/qml/timelineitems.vert +++ b/src/libs/timeline/qml/timelineitems.vert @@ -47,13 +47,13 @@ void main() gl_Position = matrix * vertexCoord; // Make very narrow events somewhat wider so that they don't collapse into 0 pixels - highp float scaledWidth = scale.x * rectSize.x; - highp float shift = sign(scaledWidth) * max(0, 3.0 - abs(scaledWidth)) * 0.0005; + float scaledWidth = scale.x * rectSize.x; + float shift = sign(scaledWidth) * max(0.0, 3.0 - abs(scaledWidth)) * 0.0005; gl_Position.x += shift; // Ditto for events with very small height - highp float scaledHeight = scale.y * rectSize.y; - gl_Position.y += float(rectSize.y > 0.0) * max(0, 3.0 - scaledHeight) * 0.003; + float scaledHeight = scale.y * rectSize.y; + gl_Position.y += float(rectSize.y > 0.0) * max(0.0, 3.0 - scaledHeight) * 0.003; barycentric = vec2(rectSize.x > 0.0 ? 1.0 : 0.0, rectSize.y > 0.0 ? 1.0 : 0.0); color = vertexColor.rgb; diff --git a/src/plugins/qmlprofiler/qml/bindingloops.frag b/src/plugins/qmlprofiler/qml/bindingloops.frag index 8f364adea43..135252ea9d7 100644 --- a/src/plugins/qmlprofiler/qml/bindingloops.frag +++ b/src/plugins/qmlprofiler/qml/bindingloops.frag @@ -28,7 +28,7 @@ ** ****************************************************************************/ -vec4 orange = vec4(1.0, 165.0 / 255.0, 0.0, 1.0); +lowp vec4 orange = vec4(1.0, 165.0 / 255.0, 0.0, 1.0); void main() { gl_FragColor = orange; From 89e418ef7060537659e2fe804050cbb5d3f1eb27 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 19 Mar 2015 14:54:16 +0100 Subject: [PATCH 02/37] Projects mode: Adapt kit selector width to kit names It now grows at least within a certain range Task-number: QTCREATORBUG-9566 Change-Id: Ie64a0c0c75ca7ac3a2e709bd27ba66a95b870634 Reviewed-by: Daniel Teske --- .../projectexplorer/targetselector.cpp | 22 ++++++++++++++----- src/plugins/projectexplorer/targetselector.h | 1 + 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/plugins/projectexplorer/targetselector.cpp b/src/plugins/projectexplorer/targetselector.cpp index a39c3f9df7a..7dcfd9b0564 100644 --- a/src/plugins/projectexplorer/targetselector.cpp +++ b/src/plugins/projectexplorer/targetselector.cpp @@ -41,6 +41,7 @@ static const int TARGET_HEIGHT = 43; static const int NAVBUTTON_WIDTH = 27; +static const int KITNAME_MARGINS = 6; namespace ProjectExplorer { namespace Internal { @@ -86,7 +87,8 @@ TargetSelector::TargetSelector(QWidget *parent) : m_currentTargetIndex(-1), m_currentHoveredTargetIndex(-1), m_startIndex(0), - m_menuShown(false) + m_menuShown(false), + m_targetWidthNeedsUpdate(true) { QFont f = font(); f.setPixelSize(10); @@ -129,6 +131,7 @@ void TargetSelector::insertTarget(int index, int subIndex, const QString &name) if (m_currentTargetIndex >= index) setCurrentIndex(m_currentTargetIndex + 1); + m_targetWidthNeedsUpdate = true; updateGeometry(); update(); } @@ -136,6 +139,8 @@ void TargetSelector::insertTarget(int index, int subIndex, const QString &name) void TargetSelector::renameTarget(int index, const QString &name) { m_targets[index].name = name; + m_targetWidthNeedsUpdate = true; + updateGeometry(); update(); } @@ -150,6 +155,7 @@ void TargetSelector::removeTarget(int index) // force a signal since the index has changed emit currentChanged(m_currentTargetIndex, m_targets.at(m_currentTargetIndex).currentSubIndex); } + m_targetWidthNeedsUpdate = true; updateGeometry(); update(); } @@ -212,10 +218,16 @@ void TargetSelector::setTargetMenu(QMenu *menu) int TargetSelector::targetWidth() const { static int width = -1; - if (width < 0) { + if (width < 0 || m_targetWidthNeedsUpdate) { + m_targetWidthNeedsUpdate = false; QFontMetrics fm = fontMetrics(); - width = qMax(fm.width(runButtonString()), fm.width(buildButtonString())); - width = qMax(149, width * 2 + 31); + width = 149; // minimum + // let it grow for the kit names ... + foreach (const Target &target, m_targets) + width = qMax(width, fm.width(target.name) + KITNAME_MARGINS + 2/*safety measure*/); + width = qMin(width, 299); // ... but not too much + int buttonWidth = qMax(fm.width(runButtonString()), fm.width(buildButtonString())); + width = qMax(width, buttonWidth * 2 + 31); // run & build button strings must be fully visible } return width; } @@ -416,7 +428,7 @@ void TargetSelector::paintEvent(QPaintEvent *event) QRect buttonRect(x, 1, targetWidth() , image.height()); Utils::StyleHelper::drawCornerImage(image, &p, buttonRect, 16, 0, 16, 0); const QString nameText = QFontMetrics(font()).elidedText(target.name, Qt::ElideRight, - targetWidth() - 6); + targetWidth() - KITNAME_MARGINS); p.drawText(x + (targetWidth()- fm.width(nameText))/2 + 1, 7 + fm.ascent(), nameText); diff --git a/src/plugins/projectexplorer/targetselector.h b/src/plugins/projectexplorer/targetselector.h index e1f12943c0e..433b4a0cfe8 100644 --- a/src/plugins/projectexplorer/targetselector.h +++ b/src/plugins/projectexplorer/targetselector.h @@ -116,6 +116,7 @@ private: int m_currentHoveredTargetIndex; int m_startIndex; bool m_menuShown; + mutable bool m_targetWidthNeedsUpdate; }; } // namespace Internal From 3594d68979137753bcfeb37ae0a962661ffd5284 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 19 Mar 2015 17:10:10 +0100 Subject: [PATCH 03/37] Raise main window when opening output panes with focus request. Also do that if the output pane doesn't want the focus. The user still wants to see the output pane even if the main window is not the current window. Change-Id: I341543be53082adec4fade4ffa859ca7c74d3dae Task-number: QTCREATORBUG-13088 Reviewed-by: Daniel Teske --- src/plugins/coreplugin/outputpanemanager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/coreplugin/outputpanemanager.cpp b/src/plugins/coreplugin/outputpanemanager.cpp index e77fa29dd80..fa2672713ec 100644 --- a/src/plugins/coreplugin/outputpanemanager.cpp +++ b/src/plugins/coreplugin/outputpanemanager.cpp @@ -494,8 +494,9 @@ void OutputPaneManager::showPage(int idx, int flags) ensurePageVisible(idx); IOutputPane *out = m_panes.at(idx); out->visibilityChanged(true); - if (flags & IOutputPane::WithFocus && out->canFocus()) { - out->setFocus(); + if (flags & IOutputPane::WithFocus) { + if (out->canFocus()) + out->setFocus(); ICore::raiseWindow(m_outputWidgetPane); } From 3fd6e9e77c5cdf8e57f52ef7c61d41d866f3113e Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 18 Mar 2015 17:23:35 +0100 Subject: [PATCH 04/37] Debugger: Replace uses of one of the depracted WatchHandler members Change-Id: I1761b75c0c2605e2d3157f318f26da5158cc6395 Reviewed-by: Christian Stenger --- .../debugger/qml/qmlinspectoragent.cpp | 28 +++++++--------- src/plugins/debugger/qml/qmlinspectoragent.h | 4 +-- .../debugger/qml/qmlv8debuggerclient.cpp | 32 +++++++------------ .../debugger/qml/qmlv8debuggerclient.h | 6 ++-- src/plugins/debugger/watchhandler.cpp | 6 ---- src/plugins/debugger/watchhandler.h | 1 - 6 files changed, 27 insertions(+), 50 deletions(-) diff --git a/src/plugins/debugger/qml/qmlinspectoragent.cpp b/src/plugins/debugger/qml/qmlinspectoragent.cpp index 7e2aecc4697..4b1f557e107 100644 --- a/src/plugins/debugger/qml/qmlinspectoragent.cpp +++ b/src/plugins/debugger/qml/qmlinspectoragent.cpp @@ -661,12 +661,11 @@ void QmlInspectorAgent::insertObjectInTree(const ObjectReference &object) const int parentId = parentIdForIname(m_debugIdToIname.value(objectDebugId)); QElapsedTimer timeElapsed; - QList watchData; bool printTime = qmlInspectorLog().isDebugEnabled(); if (printTime) timeElapsed.start(); - watchData.append(buildWatchData(object, m_debugIdToIname.value(parentId), true)); + addWatchData(object, m_debugIdToIname.value(parentId), true); qCDebug(qmlInspectorLog) << __FUNCTION__ << "Time: Build Watch Data took " << timeElapsed.elapsed() << " ms"; if (printTime) @@ -675,10 +674,8 @@ void QmlInspectorAgent::insertObjectInTree(const ObjectReference &object) qCDebug(qmlInspectorLog) << __FUNCTION__ << "Time: Build Debug Id Hash took " << timeElapsed.elapsed() << " ms"; - WatchHandler *watchHandler = m_debuggerEngine->watchHandler(); if (printTime) timeElapsed.start(); - watchHandler->insertDataList(watchData); qCDebug(qmlInspectorLog) << __FUNCTION__ << "Time: Insertion took " << timeElapsed.elapsed() << " ms"; @@ -689,7 +686,7 @@ void QmlInspectorAgent::insertObjectInTree(const ObjectReference &object) // select item in view QByteArray iname = m_debugIdToIname.value(m_objectToSelect); qCDebug(qmlInspectorLog) << " selecting" << iname << "in tree"; - watchHandler->setCurrentItem(iname); + m_debuggerEngine->watchHandler()->setCurrentItem(iname); m_objectToSelect = -1; } } @@ -738,14 +735,12 @@ static QByteArray buildIName(const QByteArray &parentIname, const QString &name) return parentIname + "." + name.toLatin1(); } -QList QmlInspectorAgent::buildWatchData(const ObjectReference &obj, - const QByteArray &parentIname, - bool append) +void QmlInspectorAgent::addWatchData(const ObjectReference &obj, + const QByteArray &parentIname, + bool append) { qCDebug(qmlInspectorLog) << '(' << obj << parentIname << ')'; - QList list; - int objDebugId = obj.debugId(); QByteArray objIname = buildIName(parentIname, objDebugId); @@ -756,7 +751,7 @@ QList QmlInspectorAgent::buildWatchData(const ObjectReference &obj, name = obj.className(); if (name.isEmpty()) - return list; + return; // object objWatch.id = objDebugId; @@ -768,7 +763,7 @@ QList QmlInspectorAgent::buildWatchData(const ObjectReference &obj, objWatch.setHasChildren(true); objWatch.setAllUnneeded(); - list.append(objWatch); + m_debuggerEngine->watchHandler()->insertData(objWatch); addObjectWatch(objWatch.id); if (m_debugIdToIname.contains(objDebugId)) { // The data needs to be removed since we now know the parent and @@ -784,7 +779,7 @@ QList QmlInspectorAgent::buildWatchData(const ObjectReference &obj, // we don't know the children yet. Not adding the 'properties' // element makes sure we're queried on expansion. if (obj.needsMoreData()) - return list; + return; } // properties @@ -799,7 +794,7 @@ QList QmlInspectorAgent::buildWatchData(const ObjectReference &obj, propertiesWatch.setHasChildren(true); propertiesWatch.setAllUnneeded(); - list.append(propertiesWatch); + m_debuggerEngine->watchHandler()->insertData(propertiesWatch); foreach (const PropertyReference &property, obj.properties()) { const QString propertyName = property.name(); @@ -814,14 +809,13 @@ QList QmlInspectorAgent::buildWatchData(const ObjectReference &obj, propertyWatch.value = property.value().toString(); propertyWatch.setAllUnneeded(); propertyWatch.setHasChildren(false); - list.append(propertyWatch); + m_debuggerEngine->watchHandler()->insertData(propertyWatch); } } // recurse foreach (const ObjectReference &child, obj.children()) - list.append(buildWatchData(child, objIname, append)); - return list; + addWatchData(child, objIname, append); } void QmlInspectorAgent::log(QmlInspectorAgent::LogDirection direction, diff --git a/src/plugins/debugger/qml/qmlinspectoragent.h b/src/plugins/debugger/qml/qmlinspectoragent.h index 3c01307f150..b888161ae1f 100644 --- a/src/plugins/debugger/qml/qmlinspectoragent.h +++ b/src/plugins/debugger/qml/qmlinspectoragent.h @@ -113,8 +113,8 @@ private: void insertObjectInTree(const QmlDebug::ObjectReference &result); void buildDebugIdHashRecursive(const QmlDebug::ObjectReference &ref); - QList buildWatchData(const QmlDebug::ObjectReference &obj, - const QByteArray &parentIname, bool append); + void addWatchData(const QmlDebug::ObjectReference &obj, + const QByteArray &parentIname, bool append); enum LogDirection { LogSend, diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp index f2e5fd250e7..da87ce05f1c 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp @@ -1553,7 +1553,6 @@ void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &r QmlV8ObjectData objectData = extractData(bodyMap.value(_("object")), refsVal); QList handlesToLookup; - QList locals; foreach (const QVariant &property, objectData.properties) { QmlV8ObjectData localData = extractData(property, refsVal); WatchData data; @@ -1571,7 +1570,7 @@ void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &r data.type = localData.type; data.value = localData.value.toString(); data.setHasChildren(localData.properties.count()); - locals << data; + d->engine->watchHandler()->insertData(data); } else { handlesToLookup << handle; d->localsAndWatchers.insertMulti(handle, data.exp); @@ -1580,9 +1579,6 @@ void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &r if (!handlesToLookup.isEmpty()) d->lookup(handlesToLookup); - - if (!locals.isEmpty()) - d->engine->watchHandler()->insertDataList(locals); } QmlJS::ConsoleItem *constructLogItemTree(QmlJS::ConsoleItem *parent, @@ -1662,12 +1658,11 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, QmlV8ObjectData body = extractData(bodyVal, refsVal); if (d->evaluatingExpression.contains(sequence)) { QString exp = d->evaluatingExpression.take(sequence); - QList watchDataList; WatchData data; //Do we have request to evaluate a local? if (exp.startsWith(QLatin1String("local."))) { const WatchData *watch = watchHandler->findData(exp.toLatin1()); - watchDataList << createWatchDataList(watch, body.properties, refsVal); + createWatchDataList(watch, body.properties, refsVal); } else { QByteArray iname = watchHandler->watcherName(exp.toLatin1()); SDEBUG(QString(iname)); @@ -1684,10 +1679,10 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, //Do not set type since it is unknown data.setError(body.value.toString()); } - watchDataList << data << createWatchDataList(&data, body.properties, refsVal); + watchHandler->insertData(data); + createWatchDataList(&data, body.properties, refsVal); } //Insert the newly evaluated expression to the Watchers Window - watchHandler->insertDataList(watchDataList); } } } @@ -1704,7 +1699,6 @@ void QmlV8DebuggerClient::expandLocalsAndWatchers(const QVariant &bodyVal, const // } const QVariantMap body = bodyVal.toMap(); - QList watchDataList; QStringList handlesList = body.keys(); WatchHandler *watchHandler = d->engine->watchHandler(); foreach (const QString &handle, handlesList) { @@ -1713,10 +1707,10 @@ void QmlV8DebuggerClient::expandLocalsAndWatchers(const QVariant &bodyVal, const QByteArray prepend = d->localsAndWatchers.take(handle.toInt()); if (prepend.startsWith("local.") || prepend.startsWith("watch.")) { - //Data for expanded local/watch - //Could be an object or function + // Data for expanded local/watch. + // Could be an object or function. const WatchData *parent = watchHandler->findData(prepend); - watchDataList << createWatchDataList(parent, bodyObjectData.properties, refsVal); + createWatchDataList(parent, bodyObjectData.properties, refsVal); } else { //rest WatchData data; @@ -1730,20 +1724,17 @@ void QmlV8DebuggerClient::expandLocalsAndWatchers(const QVariant &bodyVal, const data.setHasChildren(bodyObjectData.properties.count()); - watchDataList << data; + d->engine->watchHandler()->insertData(data); } } - - watchHandler->insertDataList(watchDataList); } -QList QmlV8DebuggerClient::createWatchDataList(const WatchData *parent, +void QmlV8DebuggerClient::createWatchDataList(const WatchData *parent, const QVariantList &properties, const QVariant &refsVal) { - QList watchDataList; if (properties.count()) { - QTC_ASSERT(parent, return watchDataList); + QTC_ASSERT(parent, return); foreach (const QVariant &property, properties) { QmlV8ObjectData propertyData = extractData(property, refsVal); WatchData data; @@ -1766,10 +1757,9 @@ QList QmlV8DebuggerClient::createWatchDataList(const WatchData *paren data.type = propertyData.type; data.value = propertyData.value.toString(); data.setHasChildren(propertyData.properties.count()); - watchDataList << data; + d->engine->watchHandler()->insertData(data); } } - return watchDataList; } void QmlV8DebuggerClient::highlightExceptionCode(int lineNumber, diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.h b/src/plugins/debugger/qml/qmlv8debuggerclient.h index 524084a11f9..08df8d243ff 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.h +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.h @@ -111,9 +111,9 @@ private: void updateEvaluationResult(int sequence, bool success, const QVariant &bodyVal, const QVariant &refsVal); void expandLocalsAndWatchers(const QVariant &bodyVal, const QVariant &refsVal); - QList createWatchDataList(const WatchData *parent, - const QVariantList &properties, - const QVariant &refsVal); + void 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/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 107d59fc05a..f42a96b7462 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -1253,12 +1253,6 @@ void WatchHandler::insertData(const WatchData &data) m_model->insertDataItem(data); } -void WatchHandler::insertDataList(const QList &list) -{ - for (int i = 0, n = list.size(); i != n; ++i) - m_model->insertDataItem(list.at(i)); -} - void WatchHandler::removeAllData(bool includeInspectData) { m_model->reinitialize(includeInspectData); diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index e99e449319d..c9d4dc6418e 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -239,7 +239,6 @@ public: void appendFormatRequests(DebuggerCommand *cmd); void insertData(const WatchData &data); // DEPRECATED - void insertDataList(const QList &list); // DEPRECATED void insertItem(WatchItem *item); // Takes ownership. void removeItemByIName(const QByteArray &iname); void removeAllData(bool includeInspectData = false); From 15f1ca9028c82864341fb13bd14f0934db6cc0f8 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 19 Mar 2015 10:04:58 +0100 Subject: [PATCH 05/37] Debugger: Remove some only MI related code Change-Id: I18d247efe2bcf0815e7867148b62fdecdd9af7be Reviewed-by: Christian Stenger --- src/plugins/debugger/watchdata.cpp | 15 +++------------ src/plugins/debugger/watchdata.h | 19 +------------------ 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp index d010768c4fa..5e6d3e951b2 100644 --- a/src/plugins/debugger/watchdata.cpp +++ b/src/plugins/debugger/watchdata.cpp @@ -260,7 +260,6 @@ void WatchData::setType(const QByteArray &str, bool guessChildrenFromType) else changed = false; } - setTypeUnneeded(); if (guessChildrenFromType) { switch (guessChildren(type)) { case HasChildren: @@ -320,7 +319,7 @@ QString WatchData::toString() const if (isValueNeeded()) str << "value=,"; - if (isValueKnown() && !value.isEmpty()) + if (!value.isEmpty()) str << "value=\"" << value << doubleQuoteComma; if (elided) @@ -333,15 +332,9 @@ QString WatchData::toString() const if (!dumperFlags.isEmpty()) str << "dumperFlags=\"" << dumperFlags << doubleQuoteComma; - if (isTypeNeeded()) - str << "type=,"; - if (isTypeKnown() && !type.isEmpty()) - str << "type=\"" << type << doubleQuoteComma; + str << "type=\"" << type << doubleQuoteComma; - if (isHasChildrenNeeded()) - str << "hasChildren=,"; - if (isHasChildrenKnown()) - str << "hasChildren=\"" << (hasChildren ? "true" : "false") << doubleQuoteComma; + str << "hasChildren=\"" << (hasChildren ? "true" : "false") << doubleQuoteComma; if (isChildrenNeeded()) str << "children=,"; @@ -511,8 +504,6 @@ void WatchData::updateType(const GdbMi &item) { if (item.isValid()) setType(item.data()); - else if (type.isEmpty()) - setTypeNeeded(); } void WatchData::updateDisplayedType(const GdbMi &item) diff --git a/src/plugins/debugger/watchdata.h b/src/plugins/debugger/watchdata.h index b00de932205..1423127b8e7 100644 --- a/src/plugins/debugger/watchdata.h +++ b/src/plugins/debugger/watchdata.h @@ -48,19 +48,15 @@ public: enum State { - Complete = 0, HasChildrenNeeded = 1, ValueNeeded = 2, - TypeNeeded = 4, ChildrenNeeded = 8, NeededMask = ValueNeeded - | TypeNeeded | ChildrenNeeded | HasChildrenNeeded, InitialState = ValueNeeded - | TypeNeeded | ChildrenNeeded | HasChildrenNeeded }; @@ -69,27 +65,14 @@ public: void setAllNeeded() { state = NeededMask; } void setAllUnneeded() { state = State(0); } - bool isTypeNeeded() const { return state & TypeNeeded; } - bool isTypeKnown() const { return !(state & TypeNeeded); } - void setTypeNeeded() { state = State(state | TypeNeeded); } - void setTypeUnneeded() { state = State(state & ~TypeNeeded); } - bool isValueNeeded() const { return state & ValueNeeded; } - bool isValueKnown() const { return !(state & ValueNeeded); } void setValueNeeded() { state = State(state | ValueNeeded); } void setValueUnneeded() { state = State(state & ~ValueNeeded); } bool isChildrenNeeded() const { return state & ChildrenNeeded; } - bool isChildrenKnown() const { return !(state & ChildrenNeeded); } void setChildrenNeeded() { state = State(state | ChildrenNeeded); } void setChildrenUnneeded() { state = State(state & ~ChildrenNeeded); } - - bool isHasChildrenNeeded() const { return state & HasChildrenNeeded; } - bool isHasChildrenKnown() const { return !(state & HasChildrenNeeded); } - void setHasChildrenNeeded() { state = State(state | HasChildrenNeeded); } - void setHasChildrenUnneeded() { state = State(state & ~HasChildrenNeeded); } - void setHasChildren(bool c) { hasChildren = c; setHasChildrenUnneeded(); - if (!c) setChildrenUnneeded(); } + void setHasChildren(bool c) { hasChildren = c; if (!c) setChildrenUnneeded(); } bool isLocal() const { return iname.startsWith("local."); } bool isWatcher() const { return iname.startsWith("watch."); } From b08e5a9bc3dd04e6630f43c459753731e87eda1a Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 19 Mar 2015 10:30:50 +0100 Subject: [PATCH 06/37] Debugger: Reduce QML engine <-> watch handler interaction Change-Id: Ia00f0747f40b18e99da2a7824d3e490291ab0b23 Reviewed-by: Christian Stenger --- .../debugger/qml/qmlinspectoragent.cpp | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/plugins/debugger/qml/qmlinspectoragent.cpp b/src/plugins/debugger/qml/qmlinspectoragent.cpp index 4b1f557e107..778e691c79d 100644 --- a/src/plugins/debugger/qml/qmlinspectoragent.cpp +++ b/src/plugins/debugger/qml/qmlinspectoragent.cpp @@ -784,33 +784,28 @@ void QmlInspectorAgent::addWatchData(const ObjectReference &obj, // properties if (append && obj.properties().count()) { - WatchData propertiesWatch; - propertiesWatch.id = objDebugId; - propertiesWatch.exp = ""; - propertiesWatch.name = tr("Properties"); - propertiesWatch.iname = objIname + ".[properties]"; - propertiesWatch.type = ""; - propertiesWatch.value = _("list"); - propertiesWatch.setHasChildren(true); - propertiesWatch.setAllUnneeded(); - - m_debuggerEngine->watchHandler()->insertData(propertiesWatch); + QByteArray iname = objIname + ".[properties]"; + auto propertiesWatch = new WatchItem(iname, tr("Properties")); + propertiesWatch->d.id = objDebugId; + propertiesWatch->d.value = _("list"); + propertiesWatch->d.setHasChildren(true); + propertiesWatch->d.setAllUnneeded(); foreach (const PropertyReference &property, obj.properties()) { const QString propertyName = property.name(); if (propertyName.isEmpty()) continue; - WatchData propertyWatch; - propertyWatch.id = objDebugId; - propertyWatch.exp = propertyName.toLatin1(); - propertyWatch.name = propertyName; - propertyWatch.iname = buildIName(propertiesWatch.iname, propertyName); - propertyWatch.type = property.valueTypeName().toLatin1(); - propertyWatch.value = property.value().toString(); - propertyWatch.setAllUnneeded(); - propertyWatch.setHasChildren(false); - m_debuggerEngine->watchHandler()->insertData(propertyWatch); + auto propertyWatch = new WatchItem(buildIName(iname, propertyName), propertyName); + propertyWatch->d.id = objDebugId; + propertyWatch->d.exp = propertyName.toLatin1(); + propertyWatch->d.type = property.valueTypeName().toLatin1(); + propertyWatch->d.value = property.value().toString(); + propertyWatch->d.setAllUnneeded(); + propertyWatch->d.setHasChildren(false); + propertiesWatch->appendChild(propertyWatch); } + + m_debuggerEngine->watchHandler()->insertItem(propertiesWatch); } // recurse From b3f88df41df29f8a20e7ddf6fd8b83100a75740d Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 19 Mar 2015 12:42:53 +0100 Subject: [PATCH 07/37] Debugger: Remove most remaining occurrences of WatchData ... in WatchHandler and DebuggerEngine interface. Adjust using code. Change-Id: I6371f3e96ba46a783e23a5767cdde24a10d3fce7 Reviewed-by: Christian Stenger Reviewed-by: hjk --- share/qtcreator/debugger/creatortypes.py | 2 +- src/libs/utils/treemodel.cpp | 11 + src/libs/utils/treemodel.h | 1 + src/plugins/debugger/cdb/cdbengine.cpp | 41 +- src/plugins/debugger/cdb/cdbengine.h | 4 +- src/plugins/debugger/debuggerengine.cpp | 6 +- src/plugins/debugger/debuggerengine.h | 5 +- .../debugger/debuggertooltipmanager.cpp | 4 +- src/plugins/debugger/gdb/gdbengine.cpp | 18 +- src/plugins/debugger/gdb/gdbengine.h | 5 +- src/plugins/debugger/lldb/lldbengine.cpp | 10 +- src/plugins/debugger/lldb/lldbengine.h | 5 +- src/plugins/debugger/pdb/pdbengine.cpp | 10 +- src/plugins/debugger/pdb/pdbengine.h | 4 +- .../debugger/qml/baseqmldebuggerclient.h | 1 + src/plugins/debugger/qml/qmlcppengine.cpp | 20 +- src/plugins/debugger/qml/qmlcppengine.h | 4 +- src/plugins/debugger/qml/qmlengine.cpp | 42 +- src/plugins/debugger/qml/qmlengine.h | 5 +- .../debugger/qml/qmlinspectoragent.cpp | 82 ++- src/plugins/debugger/qml/qmlinspectoragent.h | 2 +- .../debugger/qml/qmlv8debuggerclient.cpp | 126 +++-- .../debugger/qml/qmlv8debuggerclient.h | 2 +- .../debugger/qml/qscriptdebuggerclient.cpp | 34 +- src/plugins/debugger/watchdata.cpp | 14 +- src/plugins/debugger/watchdata.h | 5 +- src/plugins/debugger/watchhandler.cpp | 487 ++++++++---------- src/plugins/debugger/watchhandler.h | 86 ++-- 28 files changed, 468 insertions(+), 568 deletions(-) diff --git a/share/qtcreator/debugger/creatortypes.py b/share/qtcreator/debugger/creatortypes.py index 677fe4a5b81..3e9fdf6110b 100644 --- a/share/qtcreator/debugger/creatortypes.py +++ b/share/qtcreator/debugger/creatortypes.py @@ -67,7 +67,7 @@ def qdump__Debugger__Internal__WatchData(d, value): d.putPlainChildren(value) def qdump__Debugger__Internal__WatchItem(d, value): - d.putByteArrayValue(value["d"]["iname"]) + d.putByteArrayValue(value["iname"]) d.putPlainChildren(value) def qdump__Debugger__Internal__BreakpointModelId(d, value): diff --git a/src/libs/utils/treemodel.cpp b/src/libs/utils/treemodel.cpp index 249c5e875e2..dda0d6f2e6c 100644 --- a/src/libs/utils/treemodel.cpp +++ b/src/libs/utils/treemodel.cpp @@ -725,6 +725,17 @@ void TreeItem::removeChildren() } } +void TreeItem::sortChildren(const std::function &cmp) +{ + if (m_model) { + m_model->layoutAboutToBeChanged(); + std::sort(m_children.begin(), m_children.end(), cmp); + m_model->layoutChanged(); + } else { + std::sort(m_children.begin(), m_children.end(), cmp); + } +} + void TreeItem::update() { if (m_model) { diff --git a/src/libs/utils/treemodel.h b/src/libs/utils/treemodel.h index 23d2f1bea06..03d79170798 100644 --- a/src/libs/utils/treemodel.h +++ b/src/libs/utils/treemodel.h @@ -88,6 +88,7 @@ public: void appendChild(TreeItem *item); void insertChild(int pos, TreeItem *item); void removeChildren(); + void sortChildren(const std::function &cmp); void update(); void updateColumn(int column); void expand(); diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 657972e8994..a4535f10ef6 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -974,46 +974,47 @@ static inline bool isWatchIName(const QByteArray &iname) return iname.startsWith("watch"); } -void CdbEngine::updateWatchData(const WatchData &dataIn) +void CdbEngine::updateWatchItem(WatchItem *item) { if (debug || debugLocals || debugWatches) qDebug("CdbEngine::updateWatchData() %dms accessible=%d %s: %s", elapsedLogTime(), m_accessible, stateName(state()), - qPrintable(dataIn.toString())); + qPrintable(item->toString())); if (!m_accessible) // Add watch data while running? return; // New watch item? - if (dataIn.isWatcher() && dataIn.isValueNeeded()) { + if (item->isWatcher() && item->isValueNeeded()) { QByteArray args; ByteArrayInputStream str(args); - str << dataIn.iname << " \"" << dataIn.exp << '"'; + WatchData data = *item; // Don't pass pointers to async functions. + str << data.iname << " \"" << data.exp << '"'; postExtensionCommand("addwatch", args, 0, - [this, dataIn](const CdbResponse &r) { handleAddWatch(r, dataIn); }); + [this, data](const CdbResponse &r) { handleAddWatch(r, data); }); return; } - if (!dataIn.hasChildren && !dataIn.isValueNeeded()) { - WatchData data = dataIn; - data.setAllUnneeded(); - watchHandler()->insertData(data); - return; + if (item->wantsChildren || item->isValueNeeded()) { + updateLocalVariable(item->iname); + } else { + item->setAllUnneeded(); + item->update(); } - updateLocalVariable(dataIn.iname); } -void CdbEngine::handleAddWatch(const CdbResponse &response, WatchData item) +void CdbEngine::handleAddWatch(const CdbResponse &response, WatchData data) { if (debugWatches) - qDebug() << "handleAddWatch ok=" << response.success << item.iname; + qDebug() << "handleAddWatch ok=" << response.success << data.iname; if (response.success) { - updateLocalVariable(item.iname); + updateLocalVariable(data.iname); } else { - item.setError(tr("Unable to add expression")); - watchHandler()->insertData(item); + auto item = new WatchItem(data); + item->setError(tr("Unable to add expression")); + watchHandler()->insertItem(item); showMessage(QString::fromLatin1("Unable to add watch item \"%1\"/\"%2\": %3"). - arg(QString::fromLatin1(item.iname), QString::fromLatin1(item.exp), + arg(QString::fromLatin1(data.iname), QString::fromLatin1(data.exp), QString::fromLocal8Bit(response.errorMessage)), LogError); } } @@ -1269,7 +1270,7 @@ static inline bool isAsciiWord(const QString &s) return true; } -void CdbEngine::assignValueInDebugger(const WatchData *w, const QString &expr, const QVariant &value) +void CdbEngine::assignValueInDebugger(WatchItem *w, const QString &expr, const QVariant &value) { if (debug) qDebug() << "CdbEngine::assignValueInDebugger" << w->iname << expr << value; @@ -1871,13 +1872,13 @@ void CdbEngine::handleLocals(const CdbResponse &response, bool newFrame) QSet toDelete; if (newFrame) { foreach (WatchItem *item, handler->model()->treeLevelItems(2)) - toDelete.insert(item->d.iname); + toDelete.insert(item->iname); } foreach (const GdbMi &child, all.children()) { WatchItem *item = new WatchItem(child); handler->insertItem(item); - toDelete.remove(item->d.iname); + toDelete.remove(item->iname); } handler->purgeOutdatedItems(toDelete); diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index 76ecd6a472c..e57b2ca1ab6 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -89,7 +89,7 @@ public: virtual void shutdownEngine(); virtual void abortDebugger(); virtual void detachDebugger(); - virtual void updateWatchData(const WatchData &data); + virtual void updateWatchItem(WatchItem *item); virtual bool hasCapability(unsigned cap) const; virtual void watchPoint(const QPoint &); virtual void setRegisterValue(const QByteArray &name, const QString &value); @@ -106,7 +106,7 @@ public: virtual void executeRunToLine(const ContextData &data); virtual void executeRunToFunction(const QString &functionName); virtual void executeJumpToLine(const ContextData &data); - virtual void assignValueInDebugger(const WatchData *w, const QString &expr, const QVariant &value); + virtual void assignValueInDebugger(WatchItem *w, const QString &expr, const QVariant &value); virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); virtual void activateFrame(int index); diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index c2a826b3902..8c7989bd72c 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -1439,10 +1439,6 @@ bool DebuggerEngine::setToolTipExpression(const DebuggerToolTipContext &) return false; } -void DebuggerEngine::updateWatchData(const WatchData &) -{ -} - void DebuggerEngine::watchDataSelected(const QByteArray &) { } @@ -1635,7 +1631,7 @@ void DebuggerEngine::changeBreakpoint(Breakpoint bp) QTC_CHECK(false); } -void DebuggerEngine::assignValueInDebugger(const WatchData *, +void DebuggerEngine::assignValueInDebugger(WatchItem *, const QString &, const QVariant &) { } diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 2ff08231cc9..fb11e6553bf 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -62,6 +62,7 @@ class DebuggerPluginPrivate; class DisassemblerAgent; class MemoryAgent; class WatchData; +class WatchItem; class BreakHandler; class ModulesHandler; class RegisterHandler; @@ -139,7 +140,7 @@ public: virtual bool setToolTipExpression(const Internal::DebuggerToolTipContext &); - virtual void updateWatchData(const Internal::WatchData &data); + virtual void updateWatchItem(WatchItem *) {} virtual void watchDataSelected(const QByteArray &iname); virtual void startDebugger(DebuggerRunControl *runControl); @@ -198,7 +199,7 @@ public: virtual bool acceptsDebuggerCommands() const { return true; } virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); - virtual void assignValueInDebugger(const Internal::WatchData *data, + virtual void assignValueInDebugger(WatchItem *item, const QString &expr, const QVariant &value); virtual void selectThread(Internal::ThreadId threadId) = 0; diff --git a/src/plugins/debugger/debuggertooltipmanager.cpp b/src/plugins/debugger/debuggertooltipmanager.cpp index fc1bd3626b5..a91c7409079 100644 --- a/src/plugins/debugger/debuggertooltipmanager.cpp +++ b/src/plugins/debugger/debuggertooltipmanager.cpp @@ -218,9 +218,9 @@ ToolTipWatchItem::ToolTipWatchItem(WatchItem *item) name = item->displayName(); value = item->displayValue(); type = item->displayType(); - iname = item->d.iname; + iname = item->iname; valueColor = item->valueColor(); - expandable = item->d.hasChildren; + expandable = item->hasChildren(); expression = item->expression(); foreach (TreeItem *child, item->children()) appendChild(new ToolTipWatchItem(static_cast(child))); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index d4ecc5fd908..f8e6d602774 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3724,11 +3724,11 @@ void GdbEngine::reloadLocals() updateLocals(); } -void GdbEngine::updateWatchData(const WatchData &data) +void GdbEngine::updateWatchItem(WatchItem *item) { UpdateParameters params; params.tryPartial = m_pendingBreakpointRequests == 0; - params.varList = data.iname; + params.varList = item->iname; updateLocalsPython(params); } @@ -3759,14 +3759,14 @@ void GdbEngine::updateLocals() updateLocalsPython(UpdateParameters()); } -void GdbEngine::assignValueInDebugger(const WatchData *data, +void GdbEngine::assignValueInDebugger(WatchItem *item, const QString &expression, const QVariant &value) { DebuggerCommand cmd("assignValue"); - cmd.arg("type", data->type.toHex()); + cmd.arg("type", item->type.toHex()); cmd.arg("expr", expression.toLatin1().toHex()); cmd.arg("value", value.toString().toLatin1().toHex()); - cmd.arg("simpleType", isIntOrFloatType(data->type)); + cmd.arg("simpleType", isIntOrFloatType(item->type)); cmd.callback = CB(handleVarAssign); runCommand(cmd); } @@ -4805,17 +4805,17 @@ void GdbEngine::handleStackFramePython(const DebuggerResponse &response, bool pa QSet toDelete; if (!partial) { foreach (WatchItem *item, handler->model()->treeLevelItems(2)) - toDelete.insert(item->d.iname); + toDelete.insert(item->iname); } foreach (const GdbMi &child, data.children()) { WatchItem *item = new WatchItem(child); - const TypeInfo ti = m_typeInfoCache.value(item->d.type); + const TypeInfo ti = m_typeInfoCache.value(item->type); if (ti.size) - item->d.size = ti.size; + item->size = ti.size; handler->insertItem(item); - toDelete.remove(item->d.iname); + toDelete.remove(item->iname); } handler->purgeOutdatedItems(toDelete); diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index bfa310770a8..e71455c3939 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -59,7 +59,6 @@ class MemoryAgentCookie; class BreakpointParameters; class BreakpointResponse; -class WatchData; class DisassemblerAgentCookie; class DisassemblerLines; @@ -384,7 +383,7 @@ protected: // Watch specific stuff // virtual bool setToolTipExpression(const DebuggerToolTipContext &); - virtual void assignValueInDebugger(const WatchData *data, + virtual void assignValueInDebugger(WatchItem *item, const QString &expr, const QVariant &value); virtual void fetchMemory(MemoryAgent *agent, QObject *token, @@ -398,8 +397,8 @@ protected: virtual void watchPoint(const QPoint &); void handleWatchPoint(const DebuggerResponse &response); - void updateWatchData(const WatchData &data); void rebuildWatchModel(); + void updateWatchItem(WatchItem *item); void showToolTip(); void handleVarAssign(const DebuggerResponse &response); diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 863d13968f2..1be58dd442b 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -844,19 +844,17 @@ void LldbEngine::reloadFullStack() // ////////////////////////////////////////////////////////////////////// -void LldbEngine::assignValueInDebugger(const Internal::WatchData *data, +void LldbEngine::assignValueInDebugger(WatchItem *, const QString &expression, const QVariant &value) { - Q_UNUSED(data); DebuggerCommand cmd("assignValue"); cmd.arg("exp", expression.toLatin1().toHex()); cmd.arg("value", value.toString().toLatin1().toHex()); runCommand(cmd); } -void LldbEngine::updateWatchData(const WatchData &data) +void LldbEngine::updateWatchItem(WatchItem *) { - Q_UNUSED(data); updateLocals(); } @@ -1001,12 +999,12 @@ void LldbEngine::refreshLocals(const GdbMi &vars) QSet toDelete; foreach (WatchItem *item, handler->model()->treeLevelItems(2)) - toDelete.insert(item->d.iname); + toDelete.insert(item->iname); foreach (const GdbMi &child, vars.children()) { WatchItem *item = new WatchItem(child); handler->insertItem(item); - toDelete.remove(item->d.iname); + toDelete.remove(item->iname); } handler->purgeOutdatedItems(toDelete); diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index 31c404e4249..280f7ba78c5 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -105,8 +105,7 @@ private: void removeBreakpoint(Breakpoint bp); void changeBreakpoint(Breakpoint bp); - void assignValueInDebugger(const WatchData *data, - const QString &expr, const QVariant &value); + void assignValueInDebugger(WatchItem *item, const QString &expr, const QVariant &value); void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); void loadSymbols(const QString &moduleName); @@ -122,7 +121,7 @@ private: bool supportsThreads() const { return true; } bool isSynchronous() const { return true; } - void updateWatchData(const WatchData &data); + void updateWatchItem(WatchItem *item); void setRegisterValue(const QByteArray &name, const QString &value); void fetchMemory(Internal::MemoryAgent *, QObject *, quint64 addr, quint64 length); diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp index c4bb9acd689..88d3bb7abf3 100644 --- a/src/plugins/debugger/pdb/pdbengine.cpp +++ b/src/plugins/debugger/pdb/pdbengine.cpp @@ -382,7 +382,7 @@ bool PdbEngine::setToolTipExpression(const DebuggerToolTipContext &ctx) return true; } -void PdbEngine::assignValueInDebugger(const WatchData *, const QString &expression, const QVariant &value) +void PdbEngine::assignValueInDebugger(WatchItem *, const QString &expression, const QVariant &value) { //DebuggerCommand cmd("assignValue"); //cmd.arg("expression", expression); @@ -393,9 +393,9 @@ void PdbEngine::assignValueInDebugger(const WatchData *, const QString &expressi updateLocals(); } -void PdbEngine::updateWatchData(const WatchData &data) +void PdbEngine::updateWatchItem(WatchItem *item) { - Q_UNUSED(data); + Q_UNUSED(item); updateAll(); } @@ -573,12 +573,12 @@ void PdbEngine::refreshLocals(const GdbMi &vars) QSet toDelete; foreach (WatchItem *item, handler->model()->treeLevelItems(2)) - toDelete.insert(item->d.iname); + toDelete.insert(item->iname); foreach (const GdbMi &child, vars.children()) { WatchItem *item = new WatchItem(child); handler->insertItem(item); - toDelete.remove(item->d.iname); + toDelete.remove(item->iname); } handler->purgeOutdatedItems(toDelete); diff --git a/src/plugins/debugger/pdb/pdbengine.h b/src/plugins/debugger/pdb/pdbengine.h index 9d190d31e8f..751ebbc943d 100644 --- a/src/plugins/debugger/pdb/pdbengine.h +++ b/src/plugins/debugger/pdb/pdbengine.h @@ -82,7 +82,7 @@ private: void insertBreakpoint(Breakpoint bp); void removeBreakpoint(Breakpoint bp); - void assignValueInDebugger(const WatchData *data, + void assignValueInDebugger(WatchItem *item, const QString &expr, const QVariant &value); void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); @@ -96,7 +96,7 @@ private: bool supportsThreads() const { return true; } bool isSynchronous() const { return true; } - void updateWatchData(const WatchData &data); + void updateWatchItem(WatchItem *item); QString mainPythonFile() const; void runCommand(const DebuggerCommand &cmd); diff --git a/src/plugins/debugger/qml/baseqmldebuggerclient.h b/src/plugins/debugger/qml/baseqmldebuggerclient.h index 409a3dc9c5b..47435fbf996 100644 --- a/src/plugins/debugger/qml/baseqmldebuggerclient.h +++ b/src/plugins/debugger/qml/baseqmldebuggerclient.h @@ -38,6 +38,7 @@ namespace Debugger { namespace Internal { class WatchData; +class WatchItem; class BreakHandler; class BreakpointModelId; class QmlEngine; diff --git a/src/plugins/debugger/qml/qmlcppengine.cpp b/src/plugins/debugger/qml/qmlcppengine.cpp index dab64a71a49..222fc097e64 100644 --- a/src/plugins/debugger/qml/qmlcppengine.cpp +++ b/src/plugins/debugger/qml/qmlcppengine.cpp @@ -112,18 +112,18 @@ bool QmlCppEngine::setToolTipExpression(const DebuggerToolTipContext &ctx) return success; } -void QmlCppEngine::updateWatchData(const WatchData &data) +void QmlCppEngine::updateWatchItem(WatchItem *item) { - if (data.isInspect()) - m_qmlEngine->updateWatchData(data); + if (item->isInspect()) + m_qmlEngine->updateWatchItem(item); else - m_activeEngine->updateWatchData(data); + m_activeEngine->updateWatchItem(item); } void QmlCppEngine::watchDataSelected(const QByteArray &iname) { - const WatchData *wd = watchHandler()->findData(iname); - if (wd && wd->isInspect()) + const WatchItem *item = watchHandler()->findItem(iname); + if (item && item->isInspect()) m_qmlEngine->watchDataSelected(iname); } @@ -264,13 +264,13 @@ void QmlCppEngine::selectThread(ThreadId threadId) m_activeEngine->selectThread(threadId); } -void QmlCppEngine::assignValueInDebugger(const WatchData *data, +void QmlCppEngine::assignValueInDebugger(WatchItem *item, const QString &expr, const QVariant &value) { - if (data->isInspect()) - m_qmlEngine->assignValueInDebugger(data, expr, value); + if (item->isInspect()) + m_qmlEngine->assignValueInDebugger(item, expr, value); else - m_activeEngine->assignValueInDebugger(data, expr, value); + m_activeEngine->assignValueInDebugger(item, expr, value); } void QmlCppEngine::notifyInferiorIll() diff --git a/src/plugins/debugger/qml/qmlcppengine.h b/src/plugins/debugger/qml/qmlcppengine.h index 6960cde7fce..3ea2b14ff34 100644 --- a/src/plugins/debugger/qml/qmlcppengine.h +++ b/src/plugins/debugger/qml/qmlcppengine.h @@ -48,7 +48,7 @@ public: bool canDisplayTooltip() const; bool setToolTipExpression(const DebuggerToolTipContext &); - void updateWatchData(const WatchData &data); + void updateWatchItem(WatchItem *item); void watchDataSelected(const QByteArray &iname); void watchPoint(const QPoint &); @@ -79,7 +79,7 @@ public: bool acceptsBreakpoint(Breakpoint bp) const; void selectThread(ThreadId threadId); - void assignValueInDebugger(const WatchData *data, + void assignValueInDebugger(WatchItem *item, const QString &expr, const QVariant &value); DebuggerEngine *cppEngine() { return m_cppEngine; } diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index 6f6e7d2ccd6..eb32ddfe114 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -988,45 +988,41 @@ bool QmlEngine::setToolTipExpression(const DebuggerToolTipContext &context) // ////////////////////////////////////////////////////////////////////// -void QmlEngine::assignValueInDebugger(const WatchData *data, +void QmlEngine::assignValueInDebugger(WatchItem *item, const QString &expression, const QVariant &valueV) { if (!expression.isEmpty()) { - if (data->isInspect() && m_inspectorAdapter.agent()) - m_inspectorAdapter.agent()->assignValue(data, expression, valueV); + if (item->isInspect() && m_inspectorAdapter.agent()) + m_inspectorAdapter.agent()->assignValue(item, expression, valueV); else if (m_adapter.activeDebuggerClient()) - m_adapter.activeDebuggerClient()->assignValueInDebugger(data, expression, valueV); + m_adapter.activeDebuggerClient()->assignValueInDebugger(item, expression, valueV); } } -void QmlEngine::updateWatchData(const WatchData &data) +void QmlEngine::updateWatchItem(WatchItem *item) { // qDebug() << "UPDATE WATCH DATA" << data.toString(); //showStatusMessage(tr("Stopped."), 5000); - if (data.isInspect()) { - m_inspectorAdapter.agent()->updateWatchData(data); + if (item->isInspect()) { + m_inspectorAdapter.agent()->updateWatchData(*item); } else { - if (!data.name.isEmpty() && m_adapter.activeDebuggerClient()) { - if (data.isValueNeeded()) - m_adapter.activeDebuggerClient()->updateWatchData(data); - if (data.isChildrenNeeded() - && watchHandler()->isExpandedIName(data.iname)) { - m_adapter.activeDebuggerClient()->expandObject(data.iname, data.id); + if (!item->name.isEmpty() && m_adapter.activeDebuggerClient()) { + if (item->isValueNeeded()) + m_adapter.activeDebuggerClient()->updateWatchData(*item); + if (item->isChildrenNeeded() && watchHandler()->isExpandedIName(item->iname)) { + m_adapter.activeDebuggerClient()->expandObject(item->iname, item->id); } } synchronizeWatchers(); } - - if (!data.isSomethingNeeded()) - watchHandler()->insertData(data); } void QmlEngine::watchDataSelected(const QByteArray &iname) { - const WatchData *wd = watchHandler()->findData(iname); - if (wd && wd->isInspect()) - m_inspectorAdapter.agent()->watchDataSelected(wd); + const WatchItem *item = watchHandler()->findItem(iname); + if (item && item->isInspect()) + m_inspectorAdapter.agent()->watchDataSelected(item->id); } void QmlEngine::synchronizeWatchers() @@ -1153,11 +1149,11 @@ void QmlEngine::updateCurrentContext() context = stackHandler()->currentFrame().function; } else { QModelIndex currentIndex = inspectorTreeView()->currentIndex(); - const WatchData *currentData = watchHandler()->watchData(currentIndex); + const WatchData *currentData = watchHandler()->watchItem(currentIndex); if (!currentData) return; - const WatchData *parentData = watchHandler()->watchData(currentIndex.parent()); - const WatchData *grandParentData = watchHandler()->watchData( + const WatchData *parentData = watchHandler()->watchItem(currentIndex.parent()); + const WatchData *grandParentData = watchHandler()->watchItem( currentIndex.parent().parent()); if (currentData->id != parentData->id) context = currentData->name; @@ -1217,7 +1213,7 @@ bool QmlEngine::evaluateScript(const QString &expression) if (state() != InferiorStopOk) { QModelIndex currentIndex = inspectorTreeView()->currentIndex(); QmlInspectorAgent *agent = m_inspectorAdapter.agent(); - quint32 queryId = agent->queryExpressionResult(watchHandler()->watchData(currentIndex)->id, + quint32 queryId = agent->queryExpressionResult(watchHandler()->watchItem(currentIndex)->id, expression); if (queryId) { queryIds << queryId; diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h index 60fd23dd2cf..621947dfe48 100644 --- a/src/plugins/debugger/qml/qmlengine.h +++ b/src/plugins/debugger/qml/qmlengine.h @@ -145,10 +145,9 @@ private: void changeBreakpoint(Breakpoint bp); bool acceptsBreakpoint(Breakpoint bp) const; - void assignValueInDebugger(const WatchData *data, + void assignValueInDebugger(WatchItem *item, const QString &expr, const QVariant &value); - void loadSymbols(const QString &moduleName); void loadAllSymbols(); void requestModuleSymbols(const QString &moduleName); @@ -158,7 +157,7 @@ private: void reloadFullStack() {} bool supportsThreads() const { return false; } - void updateWatchData(const WatchData &data); + void updateWatchItem(WatchItem *item); void watchDataSelected(const QByteArray &iname); void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); bool evaluateScript(const QString &expression); diff --git a/src/plugins/debugger/qml/qmlinspectoragent.cpp b/src/plugins/debugger/qml/qmlinspectoragent.cpp index 778e691c79d..ece99ccb761 100644 --- a/src/plugins/debugger/qml/qmlinspectoragent.cpp +++ b/src/plugins/debugger/qml/qmlinspectoragent.cpp @@ -125,13 +125,13 @@ void QmlInspectorAgent::updateWatchData(const WatchData &data) } } -void QmlInspectorAgent::watchDataSelected(const WatchData *data) +void QmlInspectorAgent::watchDataSelected(quint64 id) { - qCDebug(qmlInspectorLog) << __FUNCTION__ << '(' << data->id << ')'; + qCDebug(qmlInspectorLog) << __FUNCTION__ << '(' << id << ')'; - if (data->id) { - QTC_ASSERT(m_debugIdLocations.keys().contains(data->id), return); - emit jumpToObjectDefinition(m_debugIdLocations.value(data->id), data->id); + if (id) { + QTC_ASSERT(m_debugIdLocations.keys().contains(id), return); + emit jumpToObjectDefinition(m_debugIdLocations.value(id), id); } } @@ -154,7 +154,7 @@ bool QmlInspectorAgent::selectObjectInTree(int debugId) using namespace QmlDebug::Constants; if (m_engineClient->objectName() == QLatin1String(QDECLARATIVE_ENGINE)) { // reset current Selection - QByteArray root = m_debuggerEngine->watchHandler()->watchData(QModelIndex())->iname; + QByteArray root = m_debuggerEngine->watchHandler()->watchItem(QModelIndex())->iname; m_debuggerEngine->watchHandler()->setCurrentItem(root); } else { fetchObject(debugId); @@ -256,8 +256,8 @@ ObjectReference QmlInspectorAgent::objectForName( const WatchHandler *watchHandler = m_debuggerEngine->watchHandler(); while (iter.hasNext()) { iter.next(); - const WatchData *wd = watchHandler->findData(iter.value()); - if (wd && wd->name == objectId) + const WatchItem *item = watchHandler->findItem(iter.value()); + if (item && item->name == objectId) return ObjectReference(iter.key()); } } @@ -313,13 +313,11 @@ QHash QmlInspectorAgent::rootObjectIds() const { QHash rIds; const WatchHandler *watchHandler = m_debuggerEngine->watchHandler(); - foreach (const QByteArray &in, m_debugIdToIname) { - const WatchData *data = watchHandler->findData(in); - if (!data) - continue; - int debugId = data->id; - QString className = QLatin1String(data->type); - rIds.insert(debugId, className); + foreach (const QByteArray &iname, m_debugIdToIname) { + if (const WatchItem *item = watchHandler->findItem(iname)) { + int debugId = item->id; + rIds.insert(debugId, QLatin1String(item->type)); + } } return rIds; } @@ -415,10 +413,10 @@ QString QmlInspectorAgent::displayName(int objectDebugId) const return QString(); if (m_debugIdToIname.contains(objectDebugId)) { - const WatchData *data = m_debuggerEngine->watchHandler()->findData( + const WatchItem *item = m_debuggerEngine->watchHandler()->findItem( m_debugIdToIname.value(objectDebugId)); - QTC_ASSERT(data, return QString()); - return data->name; + QTC_ASSERT(item, return QString()); + return item->name; } return QString(); } @@ -505,14 +503,12 @@ void QmlInspectorAgent::onValueChanged(int debugId, const QByteArray &propertyNa const QByteArray iname = m_debugIdToIname.value(debugId) + ".[properties]." + propertyName; WatchHandler *watchHandler = m_debuggerEngine->watchHandler(); - const WatchData *data = watchHandler->findData(iname); qCDebug(qmlInspectorLog) << __FUNCTION__ << '(' << debugId << ')' << iname << value.toString(); - if (data) { - WatchData d(*data); - d.value = value.toString(); - watchHandler->insertData(d); + if (WatchItem *item = watchHandler->findItem(iname)) { + item->value = value.toString(); + item->update(); } } @@ -745,7 +741,6 @@ void QmlInspectorAgent::addWatchData(const ObjectReference &obj, QByteArray objIname = buildIName(parentIname, objDebugId); if (append) { - WatchData objWatch; QString name = obj.idString(); if (name.isEmpty()) name = obj.className(); @@ -754,17 +749,16 @@ void QmlInspectorAgent::addWatchData(const ObjectReference &obj, return; // object - objWatch.id = objDebugId; - objWatch.exp = name.toLatin1(); - objWatch.name = name; - objWatch.iname = objIname; - objWatch.type = obj.className().toLatin1(); - objWatch.value = _("object"); - objWatch.setHasChildren(true); - objWatch.setAllUnneeded(); + auto objWatch = new WatchItem(objIname, name); + objWatch->id = objDebugId; + objWatch->exp = name.toLatin1(); + objWatch->type = obj.className().toLatin1(); + objWatch->value = _("object"); + objWatch->wantsChildren = true; + objWatch->setAllUnneeded(); - m_debuggerEngine->watchHandler()->insertData(objWatch); - addObjectWatch(objWatch.id); + m_debuggerEngine->watchHandler()->insertItem(objWatch); + addObjectWatch(objWatch->id); if (m_debugIdToIname.contains(objDebugId)) { // The data needs to be removed since we now know the parent and // hence we can insert the data in the correct position @@ -786,22 +780,22 @@ void QmlInspectorAgent::addWatchData(const ObjectReference &obj, if (append && obj.properties().count()) { QByteArray iname = objIname + ".[properties]"; auto propertiesWatch = new WatchItem(iname, tr("Properties")); - propertiesWatch->d.id = objDebugId; - propertiesWatch->d.value = _("list"); - propertiesWatch->d.setHasChildren(true); - propertiesWatch->d.setAllUnneeded(); + propertiesWatch->id = objDebugId; + propertiesWatch->value = _("list"); + propertiesWatch->wantsChildren = true; + propertiesWatch->setAllUnneeded(); foreach (const PropertyReference &property, obj.properties()) { const QString propertyName = property.name(); if (propertyName.isEmpty()) continue; auto propertyWatch = new WatchItem(buildIName(iname, propertyName), propertyName); - propertyWatch->d.id = objDebugId; - propertyWatch->d.exp = propertyName.toLatin1(); - propertyWatch->d.type = property.valueTypeName().toLatin1(); - propertyWatch->d.value = property.value().toString(); - propertyWatch->d.setAllUnneeded(); - propertyWatch->d.setHasChildren(false); + propertyWatch->id = objDebugId; + propertyWatch->exp = propertyName.toLatin1(); + propertyWatch->type = property.valueTypeName().toLatin1(); + propertyWatch->value = property.value().toString(); + propertyWatch->wantsChildren = false; + propertyWatch->setAllUnneeded(); propertiesWatch->appendChild(propertyWatch); } diff --git a/src/plugins/debugger/qml/qmlinspectoragent.h b/src/plugins/debugger/qml/qmlinspectoragent.h index b888161ae1f..4719ed2782a 100644 --- a/src/plugins/debugger/qml/qmlinspectoragent.h +++ b/src/plugins/debugger/qml/qmlinspectoragent.h @@ -57,7 +57,7 @@ public: void assignValue(const WatchData *data, const QString &expression, const QVariant &valueV); void updateWatchData(const WatchData &data); - void watchDataSelected(const WatchData *data); + void watchDataSelected(quint64 id); bool selectObjectInTree(int debugId); quint32 setBindingForObject(int objectDebugId, diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp index da87ce05f1c..65b02fbfe47 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp @@ -253,7 +253,7 @@ void QmlV8DebuggerClientPrivate::evaluate(const QString expr, bool global, QScriptValue ctxtList = parser.call(QScriptValue(), QScriptValueList() << _(ARRAY )); while (rowCount) { QModelIndex index = watchModel->index(--rowCount, 0); - const WatchData *data = watchHandler->watchData(index); + const WatchData *data = watchHandler->watchItem(index); QScriptValue ctxt = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT))); ctxt.setProperty(_(NAME), QScriptValue(data->name)); ctxt.setProperty(_(HANDLE), QScriptValue(int(data->id))); @@ -969,7 +969,7 @@ void QmlV8DebuggerClient::expandObject(const QByteArray &iname, quint64 objectId { if (objectId == 0) { //We may have got the global object - const WatchData *watch = d->engine->watchHandler()->findData(iname); + const WatchItem *watch = d->engine->watchHandler()->findItem(iname); if (watch->value == QLatin1String("global")) { StackHandler *stackHandler = d->engine->stackHandler(); if (stackHandler->isContentsValid() && stackHandler->currentFrame().isUsable()) { @@ -1469,10 +1469,9 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const QHash handlesToLookup; // Store handles of all expanded watch data foreach (const QByteArray &iname, expandedInames) { - const WatchData *wd = watchHandler->findData(iname); - if (!wd || !wd->isLocal()) - continue; - handlesToLookup.insert(wd->id, iname); + const WatchItem *item = watchHandler->findItem(iname); + if (item && item->isLocal()) + handlesToLookup.insert(item->id, iname); } watchHandler->removeAllData(); if (frameIndex < 0) @@ -1483,22 +1482,19 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const //Set "this" variable { - WatchData data; - data.exp = QByteArray("this"); - data.name = QLatin1String(data.exp); - data.iname = QByteArray("local.") + data.exp; + auto item = new WatchItem("local.this", QLatin1String("this")); QmlV8ObjectData objectData = extractData(currentFrame.value(_("receiver")), refsVal); - data.id = objectData.handle; - data.type = objectData.type; - data.value = objectData.value.toString(); - data.setHasChildren(objectData.properties.count()); + item->id = objectData.handle; + item->type = objectData.type; + item->value = objectData.value.toString(); + item->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; + if (item->value == QLatin1String("global")) { + item->setHasChildren(true); + item->id = 0; } - watchHandler->insertData(data); + watchHandler->insertItem(item); } const QVariantList currentFrameScopes = currentFrame.value(_("scopes")).toList(); @@ -1555,25 +1551,25 @@ void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &r QList handlesToLookup; foreach (const QVariant &property, objectData.properties) { QmlV8ObjectData localData = extractData(property, refsVal); - WatchData data; - data.exp = localData.name; + auto item = new WatchItem; + item->exp = localData.name; //Check for v8 specific local data - if (data.exp.startsWith('.') || data.exp.isEmpty()) + if (item->exp.startsWith('.') || item->exp.isEmpty()) continue; - data.name = QLatin1String(data.exp); - data.iname = QByteArray("local.") + data.exp; + item->name = QLatin1String(item->exp); + item->iname = QByteArray("local.") + item->exp; int handle = localData.handle; if (localData.value.isValid()) { - data.id = handle; - data.type = localData.type; - data.value = localData.value.toString(); - data.setHasChildren(localData.properties.count()); - d->engine->watchHandler()->insertData(data); + item->id = handle; + item->type = localData.type; + item->value = localData.value.toString(); + item->setHasChildren(localData.properties.count()); + d->engine->watchHandler()->insertItem(item); } else { handlesToLookup << handle; - d->localsAndWatchers.insertMulti(handle, data.exp); + d->localsAndWatchers.insertMulti(handle, item->exp); } } @@ -1636,7 +1632,7 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, d->scope(index); //Also update "this" QByteArray iname("local.this"); - const WatchData *parent = watchHandler->findData(iname); + const WatchItem *parent = watchHandler->findItem(iname); d->localsAndWatchers.insertMulti(parent->id, iname); d->lookup(QList() << parent->id); @@ -1658,29 +1654,27 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, QmlV8ObjectData body = extractData(bodyVal, refsVal); if (d->evaluatingExpression.contains(sequence)) { QString exp = d->evaluatingExpression.take(sequence); - WatchData data; //Do we have request to evaluate a local? if (exp.startsWith(QLatin1String("local."))) { - const WatchData *watch = watchHandler->findData(exp.toLatin1()); - createWatchDataList(watch, body.properties, refsVal); + const WatchItem *item = watchHandler->findItem(exp.toLatin1()); + createWatchDataList(item, body.properties, refsVal); } else { QByteArray iname = watchHandler->watcherName(exp.toLatin1()); SDEBUG(QString(iname)); - data.exp = exp.toLatin1(); - data.name = exp; - data.iname = iname; - data.id = body.handle; + auto item = new WatchItem(iname, exp); + item->exp = exp.toLatin1(); + item->id = body.handle; if (success) { - data.type = body.type; - data.value = body.value.toString(); - data.hasChildren = body.properties.count(); + item->type = body.type; + item->value = body.value.toString(); + item->wantsChildren = body.properties.count(); } else { //Do not set type since it is unknown - data.setError(body.value.toString()); + item->setError(body.value.toString()); } - watchHandler->insertData(data); - createWatchDataList(&data, body.properties, refsVal); + watchHandler->insertItem(item); + createWatchDataList(item, body.properties, refsVal); } //Insert the newly evaluated expression to the Watchers Window } @@ -1709,27 +1703,27 @@ void QmlV8DebuggerClient::expandLocalsAndWatchers(const QVariant &bodyVal, const if (prepend.startsWith("local.") || prepend.startsWith("watch.")) { // Data for expanded local/watch. // Could be an object or function. - const WatchData *parent = watchHandler->findData(prepend); + const WatchItem *parent = watchHandler->findItem(prepend); createWatchDataList(parent, bodyObjectData.properties, refsVal); } else { //rest - WatchData data; - data.exp = prepend; - data.name = QLatin1String(data.exp); - data.iname = QByteArray("local.") + data.exp; - data.id = handle.toInt(); + auto item = new WatchItem; + item->exp = prepend; + item->name = QLatin1String(item->exp); + item->iname = QByteArray("local.") + item->exp; + item->id = handle.toInt(); - data.type = bodyObjectData.type; - data.value = bodyObjectData.value.toString(); + item->type = bodyObjectData.type; + item->value = bodyObjectData.value.toString(); - data.setHasChildren(bodyObjectData.properties.count()); + item->setHasChildren(bodyObjectData.properties.count()); - d->engine->watchHandler()->insertData(data); + d->engine->watchHandler()->insertItem(item); } } } -void QmlV8DebuggerClient::createWatchDataList(const WatchData *parent, +void QmlV8DebuggerClient::createWatchDataList(const WatchItem *parent, const QVariantList &properties, const QVariant &refsVal) { @@ -1737,27 +1731,27 @@ void QmlV8DebuggerClient::createWatchDataList(const WatchData *parent, QTC_ASSERT(parent, return); foreach (const QVariant &property, properties) { QmlV8ObjectData propertyData = extractData(property, refsVal); - WatchData data; - data.name = QString::fromUtf8(propertyData.name); + auto item = new WatchItem; + item->name = QString::fromUtf8(propertyData.name); //Check for v8 specific local data - if (data.name.startsWith(QLatin1Char('.')) || data.name.isEmpty()) + if (item->name.startsWith(QLatin1Char('.')) || item->name.isEmpty()) continue; if (parent->type == "object") { if (parent->value == _("Array")) - data.exp = parent->exp + '[' + data.name.toLatin1() + ']'; + item->exp = parent->exp + '[' + item->name.toLatin1() + ']'; else if (parent->value == _("Object")) - data.exp = parent->exp + '.' + data.name.toLatin1(); + item->exp = parent->exp + '.' + item->name.toLatin1(); } else { - data.exp = data.name.toLatin1(); + item->exp = item->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()); - d->engine->watchHandler()->insertData(data); + item->iname = parent->iname + '.' + item->name.toLatin1(); + item->id = propertyData.handle; + item->type = propertyData.type; + item->value = propertyData.value.toString(); + item->setHasChildren(propertyData.properties.count()); + d->engine->watchHandler()->insertItem(item); } } } diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.h b/src/plugins/debugger/qml/qmlv8debuggerclient.h index 08df8d243ff..ae78443e77a 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.h +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.h @@ -111,7 +111,7 @@ private: void updateEvaluationResult(int sequence, bool success, const QVariant &bodyVal, const QVariant &refsVal); void expandLocalsAndWatchers(const QVariant &bodyVal, const QVariant &refsVal); - void createWatchDataList(const WatchData *parent, + void createWatchDataList(const WatchItem *parent, const QVariantList &properties, const QVariant &refsVal); diff --git a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp index 923a1bcb890..fd9b246557e 100644 --- a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp +++ b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp @@ -482,16 +482,18 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) d->logReceiveMessage(QLatin1String(command) + QLatin1Char(' ') + QLatin1String(iname) + QLatin1Char(' ') + data.value); - data.iname = iname; + + auto item = new WatchItem(data); + item->iname = iname; if (iname.startsWith("watch.")) { - watchHandler->insertData(data); + watchHandler->insertItem(item); } else if (iname == "console") { - d->engine->showMessage(data.value, ConsoleOutput); + d->engine->showMessage(item->value, ConsoleOutput); } else if (iname.startsWith("local.")) { - data.name = data.name.left(data.name.indexOf(QLatin1Char(' '))); - watchHandler->insertData(data); + item->name = item->name.left(item->name.indexOf(QLatin1Char(' '))); + watchHandler->insertItem(item); } else { - qWarning() << "QmlEngine: Unexcpected result: " << iname << data.value; + qWarning() << "QmlEngine: Unexcpected result: " << iname << item->value; } } else if (command == "EXPANDED") { QList result; @@ -504,7 +506,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) foreach (WatchData data, result) { data.iname = iname + '.' + data.exp; - watchHandler->insertData(data); + watchHandler->insertItem(new WatchItem(data)); if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) { needPing = true; @@ -552,9 +554,10 @@ void QScriptDebuggerClient::insertLocalsAndWatches(QList &locals, return; bool needPing = false; - foreach (WatchData data, watches) { - data.iname = watchHandler->watcherName(data.exp); - watchHandler->insertData(data); + foreach (const WatchData &data, watches) { + auto item = new WatchItem(data); + item->iname = watchHandler->watcherName(data.exp); + watchHandler->insertItem(item); if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) { needPing = true; @@ -562,11 +565,12 @@ void QScriptDebuggerClient::insertLocalsAndWatches(QList &locals, } } - foreach (WatchData data, locals) { - if (data.name == QLatin1String("")) - data.name = tr("No Local Variables"); - data.iname = "local." + data.exp; - watchHandler->insertData(data); + foreach (const WatchData &data, locals) { + auto item = new WatchItem(data); + if (item->name == QLatin1String("")) + item->name = tr("No Local Variables"); + item->iname = "local." + item->exp; + watchHandler->insertItem(item); if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) { needPing = true; diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp index 5e6d3e951b2..ef120265109 100644 --- a/src/plugins/debugger/watchdata.cpp +++ b/src/plugins/debugger/watchdata.cpp @@ -128,7 +128,7 @@ WatchData::WatchData() : bitpos(0), bitsize(0), elided(0), - hasChildren(false), + wantsChildren(false), valueEnabled(true), valueEditable(true), error(false), @@ -150,7 +150,7 @@ bool WatchData::isEqual(const WatchData &other) const && address == other.address && size == other.size && elided == other.elided - && hasChildren == other.hasChildren + && wantsChildren == other.wantsChildren && valueEnabled == other.valueEnabled && valueEditable == other.valueEditable && error == other.error; @@ -177,7 +177,7 @@ void WatchData::setError(const QString &msg) { setAllUnneeded(); value = msg; - setHasChildren(false); + wantsChildren = false; valueEnabled = false; valueEditable = false; error = true; @@ -188,7 +188,7 @@ void WatchData::setValue(const QString &value0) value = value0; if (value == QLatin1String("{...}")) { value.clear(); - hasChildren = true; // at least one... + wantsChildren = true; // at least one... } // strip off quoted characters for chars. if (value.endsWith(QLatin1Char('\'')) && type.endsWith("char")) { @@ -334,7 +334,7 @@ QString WatchData::toString() const str << "type=\"" << type << doubleQuoteComma; - str << "hasChildren=\"" << (hasChildren ? "true" : "false") << doubleQuoteComma; + str << "wantsChildren=\"" << (wantsChildren ? "true" : "false") << doubleQuoteComma; if (isChildrenNeeded()) str << "children=,"; @@ -604,10 +604,6 @@ void parseChildrenData(const WatchData &data0, const GdbMi &item, mi = item["editformat"]; data.editformat = mi.toInt(); - mi = item["typeformats"]; - if (mi.isValid()) - data.typeFormats = QString::fromUtf8(mi.data()); - mi = item["valueelided"]; if (mi.isValid()) data.elided = mi.toInt(); diff --git a/src/plugins/debugger/watchdata.h b/src/plugins/debugger/watchdata.h index 1423127b8e7..7191e58637a 100644 --- a/src/plugins/debugger/watchdata.h +++ b/src/plugins/debugger/watchdata.h @@ -72,7 +72,7 @@ public: bool isChildrenNeeded() const { return state & ChildrenNeeded; } void setChildrenNeeded() { state = State(state | ChildrenNeeded); } void setChildrenUnneeded() { state = State(state & ~ChildrenNeeded); } - void setHasChildren(bool c) { hasChildren = c; if (!c) setChildrenUnneeded(); } + void setHasChildren(bool c) { wantsChildren = c; if (!c) setChildrenUnneeded(); } bool isLocal() const { return iname.startsWith("local."); } bool isWatcher() const { return iname.startsWith("watch."); } @@ -113,7 +113,6 @@ public: QString value; // Displayed value QByteArray editvalue; // Displayed value qint32 editformat; // Format of displayed value - QString typeFormats; // Selection of formats of displayed value QByteArray type; // Type for further processing QString displayedType;// Displayed type (optional) quint64 address; // Displayed address of the actual object @@ -122,7 +121,7 @@ public: uint bitpos; // Position within bit fields uint bitsize; // Size in case of bit fields int elided; // Full size if value was cut off, -1 if cut on unknown size, 0 otherwise - bool hasChildren; + bool wantsChildren; bool valueEnabled; // Value will be enabled or not bool valueEditable; // Value will be editable bool error; diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index f42a96b7462..ed2a051d086 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -110,8 +110,6 @@ static QByteArray stripForFormat(const QByteArray &ba) class SeparatedView : public QTabWidget { - Q_OBJECT - public: SeparatedView() : QTabWidget(Internal::mainWindow()) { @@ -199,26 +197,27 @@ public: explicit WatchModel(WatchHandler *handler); static QString nameForFormat(int format); - TypeFormatList typeFormatList(const WatchData &value) const; QVariant data(const QModelIndex &idx, int role) const; bool setData(const QModelIndex &idx, const QVariant &value, int role); - void insertDataItem(const WatchData &data); void reinsertAllData(); void reinsertAllDataHelper(WatchItem *item, QList *data); QString displayForAutoTest(const QByteArray &iname) const; void reinitialize(bool includeInspectData = false); - friend QDebug operator<<(QDebug d, const WatchModel &m); + WatchItem *findItem(const QByteArray &iname) const; + void insertItem(WatchItem *item); + void reexpandItems(); - void showInEditorHelper(QString *contents, WatchItem *item, int level); void setCurrentItem(const QByteArray &iname); + void showEditValue(const WatchData &data); QString removeNamespaces(QString str) const; DebuggerEngine *engine() const; bool contentIsValid() const; +public: WatchHandler *m_handler; // Not owned. WatchItem *root() const { return static_cast(rootItem()); } @@ -228,21 +227,13 @@ public: WatchItem *m_returnRoot; // Not owned. WatchItem *m_tooltipRoot; // Not owned. + SeparatedView m_separatedView; + QSet m_expandedINames; QTimer m_requestUpdateTimer; - TypeFormatList builtinTypeFormatList(const WatchData &data) const; - QStringList dumperTypeFormatList(const WatchData &data) const; DumperTypeFormats m_reportedTypeFormats; - - WatchItem *createItem(const QByteArray &iname); - WatchItem *findItem(const QByteArray &iname) const; - friend class WatchItem; - typedef QHash ValueCache; - ValueCache m_valueCache; - - void insertItem(WatchItem *item); - void reexpandItems(); + QHash m_valueCache; }; WatchModel::WatchModel(WatchHandler *handler) @@ -293,31 +284,21 @@ WatchItem *WatchModel::findItem(const QByteArray &iname) const WatchItem *WatchItem::findItem(const QByteArray &iname) { - if (d.iname == iname) + if (this->iname == iname) return this; foreach (TreeItem *child, children()) { auto witem = static_cast(child); - if (witem->d.iname == iname) + if (witem->iname == iname) return witem; - if (witem->d.isAncestorOf(iname)) + if (witem->isAncestorOf(iname)) return witem->findItem(iname); } return 0; } -void WatchModel::reinsertAllData() -{ - QList list; - foreach (TreeItem *child, rootItem()->children()) - reinsertAllDataHelper(static_cast(child), &list); - reinitialize(true); - for (int i = 0, n = list.size(); i != n; ++i) - insertDataItem(list.at(i)); -} - void WatchModel::reinsertAllDataHelper(WatchItem *item, QList *data) { - data->append(item->d); + data->append(*item); // Slices intentionally. data->back().setAllUnneeded(); foreach (TreeItem *child, item->children()) reinsertAllDataHelper(static_cast(child), data); @@ -498,64 +479,63 @@ static QString translate(const QString &str) QString WatchItem::formattedValue() const { - if (d.type == "bool") { - if (d.value == QLatin1String("0")) + if (type == "bool") { + if (value == QLatin1String("0")) return QLatin1String("false"); - if (d.value == QLatin1String("1")) + if (value == QLatin1String("1")) return QLatin1String("true"); - return d.value; + return value; } const int format = itemFormat(); // Append quoted, printable character also for decimal. - if (d.type.endsWith("char") || d.type.endsWith("QChar")) { + if (type.endsWith("char") || type.endsWith("QChar")) { bool ok; - const int code = d.value.toInt(&ok); - return ok ? reformatCharacter(code, format) : d.value; + const int code = value.toInt(&ok); + return ok ? reformatCharacter(code, format) : value; } if (format == HexadecimalIntegerFormat || format == DecimalIntegerFormat || format == OctalIntegerFormat || format == BinaryIntegerFormat) { - bool isSigned = d.value.startsWith(QLatin1Char('-')); - quint64 raw = isSigned ? quint64(d.value.toLongLong()) : d.value.toULongLong(); - return reformatInteger(raw, format, d.size, isSigned); + bool isSigned = value.startsWith(QLatin1Char('-')); + quint64 raw = isSigned ? quint64(value.toLongLong()) : value.toULongLong(); + return reformatInteger(raw, format, size, isSigned); } if (format == ScientificFloatFormat) { - double dd = d.value.toDouble(); + double dd = value.toDouble(); return QString::number(dd, 'e'); } if (format == CompactFloatFormat) { - double dd = d.value.toDouble(); + double dd = value.toDouble(); return QString::number(dd, 'g'); } - if (d.type == "va_list") - return d.value; + if (type == "va_list") + return value; - if (!isPointerType(d.type) && !d.isVTablePointer()) { + if (!isPointerType(type) && !isVTablePointer()) { bool ok = false; - qulonglong integer = d.value.toULongLong(&ok, 0); + qulonglong integer = value.toULongLong(&ok, 0); if (ok) { const int format = itemFormat(); - return reformatInteger(integer, format, d.size, false); + return reformatInteger(integer, format, size, false); } } - if (d.elided) { - QString v = d.value; + if (elided) { + QString v = value; v.chop(1); v = translate(v); - QString len = d.elided > 0 ? QString::number(d.elided) - : QLatin1String("unknown length"); + QString len = elided > 0 ? QString::number(elided) : QLatin1String("unknown length"); return v + QLatin1String("\"... (") + len + QLatin1Char(')'); } - return translate(d.value); + return translate(value); } // Get a pointer address from pointer values reported by the debugger. @@ -573,14 +553,14 @@ static inline quint64 pointerValue(QString data) // Return the type used for editing int WatchItem::editType() const { - if (d.type == "bool") + if (type == "bool") return QVariant::Bool; - if (isIntType(d.type)) - return d.type.contains('u') ? QVariant::ULongLong : QVariant::LongLong; - if (isFloatType(d.type)) + if (isIntType(type)) + return type.contains('u') ? QVariant::ULongLong : QVariant::LongLong; + if (isFloatType(type)) return QVariant::Double; // Check for pointers using hex values (0xAD00 "Hallo") - if (isPointerType(d.type) && d.value.startsWith(QLatin1String("0x"))) + if (isPointerType(type) && value.startsWith(QLatin1String("0x"))) return QVariant::ULongLong; return QVariant::String; } @@ -590,21 +570,21 @@ QVariant WatchItem::editValue() const { switch (editType()) { case QVariant::Bool: - return d.value != QLatin1String("0") && d.value != QLatin1String("false"); + return value != QLatin1String("0") && value != QLatin1String("false"); case QVariant::ULongLong: - if (isPointerType(d.type)) // Fix pointer values (0xAD00 "Hallo" -> 0xAD00) - return QVariant(pointerValue(d.value)); - return QVariant(d.value.toULongLong()); + if (isPointerType(type)) // Fix pointer values (0xAD00 "Hallo" -> 0xAD00) + return QVariant(pointerValue(value)); + return QVariant(value.toULongLong()); case QVariant::LongLong: - return QVariant(d.value.toLongLong()); + return QVariant(value.toLongLong()); case QVariant::Double: - return QVariant(d.value.toDouble()); + return QVariant(value.toDouble()); default: break; } // Some string value: '0x434 "Hallo"': // Remove quotes and replace newlines, which will cause line edit troubles. - QString stringValue = d.value; + QString stringValue = value; if (stringValue.endsWith(QLatin1Char('"'))) { const int leadingDoubleQuote = stringValue.indexOf(QLatin1Char('"')); if (leadingDoubleQuote != stringValue.size() - 1) { @@ -618,11 +598,11 @@ QVariant WatchItem::editValue() const bool WatchItem::canFetchMore() const { - if (!d.hasChildren) + if (!wantsChildren) return false; if (!watchModel()) return false; - if (!watchModel()->contentIsValid() && !d.isInspect()) + if (!watchModel()->contentIsValid() && !isInspect()) return false; return !fetchTriggered; } @@ -632,11 +612,11 @@ void WatchItem::fetchMore() if (fetchTriggered) return; - watchModel()->m_expandedINames.insert(d.iname); + watchModel()->m_expandedINames.insert(iname); fetchTriggered = true; if (children().isEmpty()) { - d.setChildrenNeeded(); - watchModel()->engine()->updateWatchData(d); + setChildrenNeeded(); + watchModel()->engine()->updateWatchItem(this); } } @@ -654,10 +634,10 @@ static QString truncateValue(QString v) int WatchItem::itemFormat() const { - const int individualFormat = theIndividualFormats.value(d.iname, AutomaticFormat); + const int individualFormat = theIndividualFormats.value(iname, AutomaticFormat); if (individualFormat != AutomaticFormat) return individualFormat; - return theTypeFormats.value(stripForFormat(d.type), AutomaticFormat); + return theTypeFormats.value(stripForFormat(type), AutomaticFormat); } bool WatchModel::contentIsValid() const @@ -671,17 +651,17 @@ bool WatchModel::contentIsValid() const QString WatchItem::expression() const { - if (!d.exp.isEmpty()) - return QString::fromLatin1(d.exp); - if (d.address && !d.type.isEmpty()) { + if (!exp.isEmpty()) + return QString::fromLatin1(exp); + if (address && !type.isEmpty()) { return QString::fromLatin1("*(%1*)%2"). - arg(QLatin1String(d.type), QLatin1String(d.hexAddress())); + arg(QLatin1String(type), QLatin1String(hexAddress())); } if (const WatchItem *p = parentItem()) { - if (!p->d.exp.isEmpty()) - return QString::fromLatin1("(%1).%2").arg(QString::fromLatin1(p->d.exp), d.name); + if (!p->exp.isEmpty()) + return QString::fromLatin1("(%1).%2").arg(QString::fromLatin1(p->exp), name); } - return d.name; + return name; } QString WatchItem::displayName() const @@ -689,12 +669,12 @@ QString WatchItem::displayName() const QString result; if (!parentItem()) return result; - if (d.iname.startsWith("return")) + if (iname.startsWith("return")) result = WatchModel::tr("returned value"); - else if (d.name == QLatin1String("*")) - result = QLatin1Char('*') + parentItem()->d.name; + else if (name == QLatin1String("*")) + result = QLatin1Char('*') + parentItem()->name; else - result = watchModel()->removeNamespaces(d.name); + result = watchModel()->removeNamespaces(name); // Simplyfy names that refer to base classes. if (result.startsWith(QLatin1Char('['))) { @@ -709,20 +689,20 @@ QString WatchItem::displayName() const QString WatchItem::displayValue() const { QString result = watchModel()->removeNamespaces(truncateValue(formattedValue())); - if (result.isEmpty() && d.address) - result += QString::fromLatin1("@0x" + QByteArray::number(d.address, 16)); -// if (d.origaddr) -// result += QString::fromLatin1(" (0x" + QByteArray::number(d.origaddr, 16) + ')'); + if (result.isEmpty() && address) + result += QString::fromLatin1("@0x" + QByteArray::number(address, 16)); +// if (origaddr) +// result += QString::fromLatin1(" (0x" + QByteArray::number(origaddr, 16) + ')'); return result; } QString WatchItem::displayType() const { - QString result = d.displayedType.isEmpty() - ? niceTypeHelper(d.type) - : d.displayedType; - if (d.bitsize) - result += QString::fromLatin1(":%1").arg(d.bitsize); + QString result = displayedType.isEmpty() + ? niceTypeHelper(type) + : displayedType; + if (bitsize) + result += QString::fromLatin1(":%1").arg(bitsize); result.remove(QLatin1Char('\'')); result = watchModel()->removeNamespaces(result); return result; @@ -733,13 +713,13 @@ QColor WatchItem::valueColor() const static const QColor red(200, 0, 0); static const QColor gray(140, 140, 140); if (watchModel()) { - if (!d.valueEnabled) + if (!valueEnabled) return gray; - if (!watchModel()->contentIsValid() && !d.isInspect()) + if (!watchModel()->contentIsValid() && !isInspect()) return gray; - if (d.value.isEmpty()) // This might still show 0x... + if (value.isEmpty()) // This might still show 0x... return gray; - if (d.value != watchModel()->m_valueCache.value(d.iname)) + if (value != watchModel()->m_valueCache.value(iname)) return red; } return QColor(); @@ -752,10 +732,10 @@ QVariant WatchItem::data(int column, int role) const return QVariant(editType()); case LocalsNameRole: - return QVariant(d.name); + return QVariant(name); case LocalsIntegerBaseRole: - if (isPointerType(d.type)) // Pointers using 0x-convention + if (isPointerType(type)) // Pointers using 0x-convention return QVariant(16); return QVariant(formatToIntegerBase(itemFormat())); @@ -767,9 +747,9 @@ QVariant WatchItem::data(int column, int role) const return editValue(); case 2: // FIXME:: To be tested: Can debuggers handle those? - if (!d.displayedType.isEmpty()) - return d.displayedType; - return QString::fromUtf8(d.type); + if (!displayedType.isEmpty()) + return displayedType; + return QString::fromUtf8(type); } } @@ -786,7 +766,7 @@ QVariant WatchItem::data(int column, int role) const case Qt::ToolTipRole: return boolSetting(UseToolTipsInLocalsView) - ? d.toToolTip() : QVariant(); + ? toToolTip() : QVariant(); case Qt::ForegroundRole: if (column == 1) @@ -796,51 +776,51 @@ QVariant WatchItem::data(int column, int role) const return expression(); case LocalsRawExpressionRole: - return d.exp; + return exp; case LocalsINameRole: - return d.iname; + return iname; case LocalsExpandedRole: - return watchModel()->m_expandedINames.contains(d.iname); + return watchModel()->m_expandedINames.contains(iname); case LocalsTypeFormatListRole: - return QVariant::fromValue(watchModel()->typeFormatList(d)); + return QVariant::fromValue(typeFormatList()); case LocalsTypeRole: return watchModel()->removeNamespaces(displayType()); case LocalsRawTypeRole: - return QString::fromLatin1(d.type); + return QString::fromLatin1(type); case LocalsTypeFormatRole: - return theTypeFormats.value(stripForFormat(d.type), AutomaticFormat); + return theTypeFormats.value(stripForFormat(type), AutomaticFormat); case LocalsIndividualFormatRole: - return theIndividualFormats.value(d.iname, AutomaticFormat); + return theIndividualFormats.value(iname, AutomaticFormat); case LocalsRawValueRole: - return d.value; + return value; case LocalsObjectAddressRole: - return d.address; + return address; case LocalsPointerAddressRole: - return d.origaddr; + return origaddr; case LocalsIsWatchpointAtObjectAddressRole: { BreakpointParameters bp(WatchpointAtAddress); - bp.address = d.address; + bp.address = address; return watchModel()->engine()->breakHandler()->findWatchpoint(bp) != 0; } case LocalsSizeRole: - return QVariant(d.size); + return QVariant(size); case LocalsIsWatchpointAtPointerAddressRole: - if (isPointerType(d.type)) { + if (isPointerType(type)) { BreakpointParameters bp(WatchpointAtAddress); - bp.address = pointerValue(d.value); + bp.address = pointerValue(value); return watchModel()->engine()->breakHandler()->findWatchpoint(bp) != 0; } return false; @@ -871,7 +851,6 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role WatchItem *item = static_cast(itemFromIndex(idx)); QTC_ASSERT(item, return false); - const WatchData &data = item->d; switch (role) { case Qt::EditRole: @@ -881,35 +860,35 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role break; } case 1: // Change value - engine()->assignValueInDebugger(&data, item->expression(), value); + engine()->assignValueInDebugger(item, item->expression(), value); break; case 2: // TODO: Implement change type. - engine()->assignValueInDebugger(&data, item->expression(), value); + engine()->assignValueInDebugger(item, item->expression(), value); break; } case LocalsExpandedRole: if (value.toBool()) { // Should already have been triggered by fetchMore() - //QTC_CHECK(m_expandedINames.contains(data.iname)); - m_expandedINames.insert(data.iname); + //QTC_CHECK(m_expandedINames.contains(item->iname)); + m_expandedINames.insert(item->iname); } else { - m_expandedINames.remove(data.iname); + m_expandedINames.remove(item->iname); } emit columnAdjustmentRequested(); break; case LocalsTypeFormatRole: - m_handler->setFormat(data.type, value.toInt()); - engine()->updateWatchData(data); + m_handler->setFormat(item->type, value.toInt()); + engine()->updateWatchItem(item); break; case LocalsIndividualFormatRole: { const int format = value.toInt(); if (format == AutomaticFormat) - theIndividualFormats.remove(data.iname); + theIndividualFormats.remove(item->iname); else - theIndividualFormats[data.iname] = format; - engine()->updateWatchData(data); + theIndividualFormats[item->iname] = format; + engine()->updateWatchItem(item); break; } } @@ -931,29 +910,29 @@ Qt::ItemFlags WatchItem::flags(int column) const const Qt::ItemFlags notEditable = Qt::ItemIsSelectable | Qt::ItemIsEnabled; const Qt::ItemFlags editable = notEditable | Qt::ItemIsEditable; - if (d.isWatcher()) { + if (isWatcher()) { if (state != InferiorStopOk && state != DebuggerNotReady && state != DebuggerFinished && !engine->hasCapability(AddWatcherWhileRunningCapability)) return Qt::ItemFlags(); - if (column == 0 && d.iname.count('.') == 1) + if (column == 0 && iname.count('.') == 1) return editable; // Watcher names are editable. - if (!d.name.isEmpty()) { + if (!name.isEmpty()) { // FIXME: Forcing types is not implemented yet. //if (idx.column() == 2) // return editable; // Watcher types can be set by force. - if (column == 1 && d.valueEditable) + if (column == 1 && valueEditable) return editable; // Watcher values are sometimes editable. } - } else if (d.isLocal()) { + } else if (isLocal()) { if (state != InferiorStopOk && !engine->hasCapability(AddWatcherWhileRunningCapability)) return Qt::ItemFlags(); - if (column == 1 && d.valueEditable) + if (column == 1 && valueEditable) return editable; // Locals values are sometimes editable. - } else if (d.isInspect()) { - if (column == 1 && d.valueEditable) + } else if (isInspect()) { + if (column == 1 && valueEditable) return editable; // Inspector values are sometimes editable. } return notEditable; @@ -991,26 +970,26 @@ QString WatchModel::nameForFormat(int format) return QString(); } -TypeFormatList WatchModel::typeFormatList(const WatchData &data) const +TypeFormatList WatchItem::typeFormatList() const { TypeFormatList formats; // Types supported by dumpers: // Hack: Compensate for namespaces. - QString type = QLatin1String(stripForFormat(data.type)); - int pos = type.indexOf(QLatin1String("::Q")); - if (pos >= 0 && type.count(QLatin1Char(':')) == 2) - type.remove(0, pos + 2); - pos = type.indexOf(QLatin1Char('<')); + QString t = QLatin1String(stripForFormat(type)); + int pos = t.indexOf(QLatin1String("::Q")); + if (pos >= 0 && t.count(QLatin1Char(':')) == 2) + t.remove(0, pos + 2); + pos = t.indexOf(QLatin1Char('<')); if (pos >= 0) - type.truncate(pos); - type.replace(QLatin1Char(':'), QLatin1Char('_')); - QStringList reported = m_reportedTypeFormats.value(type); + t.truncate(pos); + t.replace(QLatin1Char(':'), QLatin1Char('_')); + QStringList reported = watchModel()->m_reportedTypeFormats.value(t); for (int i = 0, n = reported.size(); i != n; ++i) formats.append(TypeFormatItem(reported.at(i), i)); // Fixed artificial string and pointer types. - if (data.origaddr || isPointerType(data.type)) { + if (origaddr || isPointerType(type)) { formats.append(RawFormat); formats.append(Latin1StringFormat); formats.append(SeparateLatin1StringFormat); @@ -1023,7 +1002,7 @@ TypeFormatList WatchModel::typeFormatList(const WatchData &data) const formats.append(Array100Format); formats.append(Array1000Format); formats.append(Array10000Format); - } else if (data.type.contains("char[") || data.type.contains("char [")) { + } else if (type.contains("char[") || type.contains("char [")) { formats.append(RawFormat); formats.append(Latin1StringFormat); formats.append(SeparateLatin1StringFormat); @@ -1036,14 +1015,14 @@ TypeFormatList WatchModel::typeFormatList(const WatchData &data) const // Fixed artificial floating point types. bool ok = false; - data.value.toDouble(&ok); + value.toDouble(&ok); if (ok) { formats.append(CompactFloatFormat); formats.append(ScientificFloatFormat); } // Fixed artificial integral types. - QString v = data.value; + QString v = value; if (v.startsWith(QLatin1Char('-'))) v = v.mid(1); v.toULongLong(&ok, 10); @@ -1093,25 +1072,11 @@ static bool watchDataLessThan(const QByteArray &iname1, int sortId1, return qstrcmp(iname1.constData() + cmpPos1, iname2.constData() + cmpPos2) < 0; } -// Sort key for watch data consisting of iname and numerical sort id. -struct WatchDataSortKey -{ - explicit WatchDataSortKey(const WatchData &wd) - : iname(wd.iname), sortId(wd.sortId) {} - QByteArray iname; - int sortId; -}; - -inline bool operator<(const WatchDataSortKey &k1, const WatchDataSortKey &k2) -{ - return watchDataLessThan(k1.iname, k1.sortId, k2.iname, k2.sortId); -} - bool watchItemSorter(const TreeItem *item1, const TreeItem *item2) { const WatchItem *it1 = static_cast(item1); const WatchItem *it2 = static_cast(item2); - return watchDataLessThan(it1->d.iname, it1->d.sortId, it2->d.iname, it2->d.sortId); + return watchDataLessThan(it1->iname, it1->sortId, it2->iname, it2->sortId); } static int findInsertPosition(const QVector &list, const WatchItem *item) @@ -1121,27 +1086,38 @@ static int findInsertPosition(const QVector &list, const WatchItem * return it - list.begin(); } -int WatchItem::requestedFormat() const +void WatchModel::reinsertAllData() { - int format = theIndividualFormats.value(d.iname, AutomaticFormat); - if (format == AutomaticFormat) - format = theTypeFormats.value(stripForFormat(d.type), AutomaticFormat); - return format; + QList list; + foreach (TreeItem *child, rootItem()->children()) + reinsertAllDataHelper(static_cast(child), &list); + + reinitialize(true); + + for (int i = 0, n = list.size(); i != n; ++i) { + const WatchData &data = list.at(i); + QTC_ASSERT(!data.iname.isEmpty(), qDebug() << data.toString(); return); + // Add new entry. + WatchItem *parent = findItem(parentName(data.iname)); + QTC_ASSERT(parent, return); + WatchItem *newItem = new WatchItem(data); + newItem->sortChildren(&watchItemSorter); + const int row = findInsertPosition(parent->children(), newItem); + parent->insertChild(row, newItem); + if (m_expandedINames.contains(parent->iname)) { + emit inameIsExpanded(parent->iname); + emit itemIsExpanded(indexFromItem(parent)); + } + showEditValue(data); + } } -void WatchItem::showInEditorHelper(QString *contents, int depth) const +int WatchItem::requestedFormat() const { - const QChar tab = QLatin1Char('\t'); - const QChar nl = QLatin1Char('\n'); - contents->append(QString(depth, tab)); - contents->append(d.name); - contents->append(tab); - contents->append(d.value); - contents->append(tab); - contents->append(QString::fromLatin1(d.type)); - contents->append(nl); - foreach (const TreeItem *child, children()) - static_cast(child)->showInEditorHelper(contents, depth + 1); + int format = theIndividualFormats.value(iname, AutomaticFormat); + if (format == AutomaticFormat) + format = theTypeFormats.value(stripForFormat(type), AutomaticFormat); + return format; } void WatchModel::setCurrentItem(const QByteArray &iname) @@ -1165,15 +1141,13 @@ WatchHandler::WatchHandler(DebuggerEngine *engine) m_contentsValid = false; m_contentsValid = true; // FIXME m_resetLocationScheduled = false; - m_separatedView = new SeparatedView; } WatchHandler::~WatchHandler() { - delete m_separatedView; - m_separatedView = 0; // Do it manually to prevent calling back in model destructors // after m_cache is destroyed. + m_model->disconnect(); delete m_model; m_model = 0; } @@ -1185,7 +1159,7 @@ void WatchHandler::cleanup() saveWatchers(); m_model->reinitialize(); emit m_model->updateFinished(); - m_separatedView->hide(); + m_model->m_separatedView.hide(); } void WatchHandler::insertItem(WatchItem *item) @@ -1195,44 +1169,19 @@ void WatchHandler::insertItem(WatchItem *item) void WatchModel::insertItem(WatchItem *item) { - WatchItem *existing = findItem(item->d.iname); + WatchItem *existing = findItem(item->iname); if (existing) removeItem(existing); - WatchItem *parent = findItem(parentName(item->d.iname)); + //item->walkTree([item](TreeItem *sub) { sub->sortChildren(&watchItemSorter); }); + item->sortChildren(&watchItemSorter); + + WatchItem *parent = findItem(parentName(item->iname)); QTC_ASSERT(parent, return); const int row = findInsertPosition(parent->children(), item); parent->insertChild(row, item); } -void WatchModel::insertDataItem(const WatchData &data) -{ - QTC_ASSERT(!data.iname.isEmpty(), qDebug() << data.toString(); return); - - if (WatchItem *item = findItem(data.iname)) { - // Remove old children. - item->fetchTriggered = false; - item->removeChildren(); - - // Overwrite old entry. - item->d = data; - item->update(); - } else { - // Add new entry. - WatchItem *parent = findItem(parentName(data.iname)); - QTC_ASSERT(parent, return); - WatchItem *newItem = new WatchItem; - newItem->d = data; - const int row = findInsertPosition(parent->children(), newItem); - parent->insertChild(row, newItem); - if (m_expandedINames.contains(parent->d.iname)) { - emit inameIsExpanded(parent->d.iname); - emit itemIsExpanded(indexFromItem(parent)); - } - } - m_handler->showEditValue(data); -} - void WatchModel::reexpandItems() { foreach (const QByteArray &iname, m_expandedINames) { @@ -1248,11 +1197,6 @@ void WatchModel::reexpandItems() } } -void WatchHandler::insertData(const WatchData &data) -{ - m_model->insertDataItem(data); -} - void WatchHandler::removeAllData(bool includeInspectData) { m_model->reinitialize(includeInspectData); @@ -1265,7 +1209,7 @@ void WatchHandler::resetValueCache() TreeItem *root = m_model->rootItem(); root->walkTree([this, root](TreeItem *item) { auto watchItem = static_cast(item); - m_model->m_valueCache[watchItem->d.iname] = watchItem->d.value; + m_model->m_valueCache[watchItem->iname] = watchItem->value; }); } @@ -1307,8 +1251,8 @@ void WatchHandler::removeItemByIName(const QByteArray &iname) WatchItem *item = m_model->findItem(iname); if (!item) return; - if (item->d.isWatcher()) { - theWatcherNames.remove(item->d.exp); + if (item->isWatcher()) { + theWatcherNames.remove(item->exp); saveWatchers(); } m_model->removeItem(item); @@ -1330,19 +1274,18 @@ void WatchHandler::watchExpression(const QString &exp0, const QString &name) theWatcherNames[exp] = theWatcherCount++; - WatchData data; - data.exp = exp; - data.name = name.isEmpty() ? exp0 : name; - data.iname = watcherName(exp); + auto item = new WatchItem; + item->exp = exp; + item->name = name.isEmpty() ? exp0 : name; + item->iname = watcherName(exp); saveWatchers(); if (m_engine->state() == DebuggerNotReady) { - data.setAllUnneeded(); - data.setValue(QString(QLatin1Char(' '))); - data.setHasChildren(false); - m_model->insertDataItem(data); + item->setAllUnneeded(); + item->setValue(QString(QLatin1Char(' '))); + m_model->insertItem(item); } else { - m_engine->updateWatchData(data); + m_engine->updateWatchItem(item); } updateWatchersWindow(); } @@ -1371,12 +1314,12 @@ static void swapEndian(char *d, int nchar) } } -void WatchHandler::showEditValue(const WatchData &data) +void WatchModel::showEditValue(const WatchData &data) { const QByteArray key = data.address ? data.hexAddress() : data.iname; switch (data.editformat) { case StopDisplay: - m_separatedView->removeObject(data.iname); + m_separatedView.removeObject(data.iname); break; case DisplayImageData: case DisplayImageFile: { // QImage @@ -1414,7 +1357,7 @@ void WatchHandler::showEditValue(const WatchData &data) tr("%1 Object at %2").arg(QLatin1String(data.type), QLatin1String(data.hexAddress())) : tr("%1 Object at Unknown Address").arg(QLatin1String(data.type)); - ImageViewer *v = m_separatedView->prepareObject(key, title); + ImageViewer *v = m_separatedView.prepareObject(key, title); v->setProperty(INameProperty, data.iname); v->setImage(im); break; @@ -1430,7 +1373,7 @@ void WatchHandler::showEditValue(const WatchData &data) str = QString::fromLatin1(ba.constData(), ba.size()); else if (data.editformat == DisplayUtf8String) str = QString::fromUtf8(ba.constData(), ba.size()); - QTextEdit *t = m_separatedView->prepareObject(key, data.name); + QTextEdit *t = m_separatedView.prepareObject(key, data.name); t->setProperty(INameProperty, data.iname); t->setText(str); break; @@ -1557,37 +1500,29 @@ WatchModelBase *WatchHandler::model() const return m_model; } -const WatchData *WatchHandler::watchData(const QModelIndex &idx) const +const WatchItem *WatchHandler::watchItem(const QModelIndex &idx) const { - TreeItem *item = m_model->itemFromIndex(idx); - return item ? &static_cast(item)->d : 0; + return static_cast(m_model->itemFromIndex(idx)); } void WatchHandler::fetchMore(const QByteArray &iname) const { - WatchItem *item = m_model->findItem(iname); - if (item) + if (WatchItem *item = m_model->findItem(iname)) item->fetchMore(); } -const WatchData *WatchHandler::findData(const QByteArray &iname) const -{ - const WatchItem *item = m_model->findItem(iname); - return item ? &item->d : 0; -} - WatchItem *WatchHandler::findItem(const QByteArray &iname) const { return m_model->findItem(iname); } -const WatchData *WatchHandler::findCppLocalVariable(const QString &name) const +const WatchItem *WatchHandler::findCppLocalVariable(const QString &name) const { // Can this be found as a local variable? const QByteArray localsPrefix("local."); QByteArray iname = localsPrefix + name.toLatin1(); - if (const WatchData *wd = findData(iname)) - return wd; + if (const WatchItem *item = findItem(iname)) + return item; // // Nope, try a 'local.this.m_foo'. // iname.insert(localsPrefix.size(), "this."); // if (const WatchData *wd = findData(iname)) @@ -1615,9 +1550,9 @@ int WatchHandler::format(const QByteArray &iname) const { int result = AutomaticFormat; if (const WatchItem *item = m_model->findItem(iname)) { - result = theIndividualFormats.value(item->d.iname, AutomaticFormat); + result = theIndividualFormats.value(item->iname, AutomaticFormat); if (result == AutomaticFormat) - result = theTypeFormats.value(stripForFormat(item->d.type), AutomaticFormat); + result = theTypeFormats.value(stripForFormat(item->type), AutomaticFormat); } return result; } @@ -1716,10 +1651,21 @@ void WatchHandler::addTypeFormats(const QByteArray &type, const QStringList &for m_model->m_reportedTypeFormats.insert(QLatin1String(stripForFormat(type)), formats); } +static void showInEditorHelper(const WatchItem *item, QTextStream &ts, int depth) +{ + const QChar tab = QLatin1Char('\t'); + const QChar nl = QLatin1Char('\n'); + ts << QString(depth, tab) << item->name << tab << item->value << tab + << item->type << nl; + foreach (const TreeItem *child, item->children()) + showInEditorHelper(static_cast(child), ts, depth + 1); +} + QString WatchHandler::editorContents() { QString contents; - m_model->root()->showInEditorHelper(&contents, 0); + QTextStream ts(&contents); + showInEditorHelper(m_model->root(), ts, 0); return contents; } @@ -1733,22 +1679,6 @@ DumperTypeFormats WatchHandler::typeFormats() const return m_model->m_reportedTypeFormats; } -void WatchHandler::editTypeFormats(bool includeLocals, const QByteArray &iname) -{ - Q_UNUSED(includeLocals); - TypeFormatsDialog dlg(0); - - //QHashIterator it(m_reportedTypeFormats); - QList l = m_model->m_reportedTypeFormats.keys(); - Utils::sort(l); - foreach (const QString &ba, l) { - int f = iname.isEmpty() ? AutomaticFormat : format(iname); - dlg.addTypeFormats(ba, m_model->m_reportedTypeFormats.value(ba), f); - } - if (dlg.exec()) - setTypeFormats(dlg.typeFormats()); -} - void WatchHandler::scheduleResetLocation() { m_contentsValid = false; @@ -1828,30 +1758,30 @@ WatchItem::WatchItem() WatchItem::WatchItem(const QByteArray &i, const QString &n) { fetchTriggered = false; - d.iname = i; - d.name = n; + iname = i; + name = n; } WatchItem::WatchItem(const WatchData &data) - : d(data), fetchTriggered(false) + : WatchData(data), fetchTriggered(false) { } WatchItem::WatchItem(const GdbMi &data) : fetchTriggered(false) { - d.iname = data["iname"].data(); + iname = data["iname"].data(); GdbMi wname = data["wname"]; if (wname.isValid()) // Happens (only) for watched expressions. - d.name = QString::fromUtf8(QByteArray::fromHex(wname.data())); + name = QString::fromUtf8(QByteArray::fromHex(wname.data())); else - d.name = QString::fromLatin1(data["name"].data()); + name = QString::fromLatin1(data["name"].data()); parseWatchData(data); if (wname.isValid()) - d.exp = d.name.toUtf8(); + exp = name.toUtf8(); } WatchItem *WatchItem::parentItem() const @@ -1872,8 +1802,9 @@ WatchModel *WatchItem::watchModel() void WatchItem::parseWatchData(const GdbMi &input) { auto itemHandler = [this](const WatchData &data) { - d = data; + WatchData::operator=(data); }; + auto childHandler = [this](const WatchData &innerData, const GdbMi &innerInput) { WatchItem *item = new WatchItem(innerData); item->parseWatchData(innerInput); @@ -1889,10 +1820,8 @@ void WatchItem::parseWatchData(const GdbMi &input) decodeArrayData(itemAdder, childTemplate, encodedData, encoding); }; - parseChildrenData(d, input, itemHandler, childHandler, arrayDecoder); + parseChildrenData(*this, input, itemHandler, childHandler, arrayDecoder); } } // namespace Internal } // namespace Debugger - -#include "watchhandler.moc" diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index c9d4dc6418e..318c9bc6a2d 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -35,17 +35,34 @@ #include -#include #include namespace Debugger { namespace Internal { class DebuggerCommand; -class SeparatedView; +class DebuggerEngine; class WatchModel; -class WatchItem : public Utils::TreeItem +class TypeFormatItem +{ +public: + TypeFormatItem() : format(-1) {} + TypeFormatItem(const QString &display, int format); + + QString display; + int format; +}; + +class TypeFormatList : public QVector +{ +public: + using QVector::append; + void append(int format); + TypeFormatItem find(int format) const; +}; + +class WatchItem : public Utils::TreeItem, public WatchData { public: WatchItem(); @@ -53,14 +70,6 @@ public: explicit WatchItem(const WatchData &data); explicit WatchItem(const GdbMi &data); - WatchItem *parentItem() const; - const WatchModel *watchModel() const; - WatchModel *watchModel(); - - QVariant data(int column, int role) const; - Qt::ItemFlags flags(int column) const; - - bool canFetchMore() const; void fetchMore(); QString displayName() const; @@ -76,12 +85,19 @@ public: QColor valueColor() const; int requestedFormat() const; - void showInEditorHelper(QString *contents, int depth) const; WatchItem *findItem(const QByteArray &iname); - void parseWatchData(const GdbMi &input); -public: - WatchData d; +private: + WatchItem *parentItem() const; + const WatchModel *watchModel() const; + WatchModel *watchModel(); + TypeFormatList typeFormatList() const; + + bool canFetchMore() const; + QVariant data(int column, int role) const; + Qt::ItemFlags flags(int column) const; + + void parseWatchData(const GdbMi &input); bool fetchTriggered; }; @@ -125,35 +141,6 @@ enum DisplayFormat ScientificFloatFormat, }; - -class TypeFormatItem -{ -public: - TypeFormatItem() : format(-1) {} - TypeFormatItem(const QString &display, int format); - - QString display; - int format; -}; - -class TypeFormatList : public QVector -{ -public: - using QVector::append; - void append(int format); - TypeFormatItem find(int format) const; -}; - -} // namespace Internal -} // namespace Debugger - -Q_DECLARE_METATYPE(Debugger::Internal::TypeFormatList) - -namespace Debugger { -namespace Internal { - -class DebuggerEngine; - class UpdateParameters { public: @@ -196,13 +183,10 @@ public: void watchVariable(const QString &exp); Q_SLOT void clearWatches(); - void showEditValue(const WatchData &data); - - const WatchData *watchData(const QModelIndex &) const; + const WatchItem *watchItem(const QModelIndex &) const; void fetchMore(const QByteArray &iname) const; - const WatchData *findData(const QByteArray &iname) const; WatchItem *findItem(const QByteArray &iname) const; - const WatchData *findCppLocalVariable(const QString &name) const; + const WatchItem *findCppLocalVariable(const QString &name) const; bool hasItem(const QByteArray &iname) const; void loadSessionData(); @@ -229,7 +213,6 @@ public: QByteArray watcherName(const QByteArray &exp); QString editorContents(); - void editTypeFormats(bool includeLocals, const QByteArray &iname); void scheduleResetLocation(); void resetLocation(); @@ -238,7 +221,6 @@ public: void updateWatchersWindow(); void appendFormatRequests(DebuggerCommand *cmd); - void insertData(const WatchData &data); // DEPRECATED void insertItem(WatchItem *item); // Takes ownership. void removeItemByIName(const QByteArray &iname); void removeAllData(bool includeInspectData = false); @@ -259,7 +241,6 @@ private: WatchModel *m_model; // Owned. DebuggerEngine *m_engine; // Not owned. - SeparatedView *m_separatedView; // Owned. bool m_contentsValid; bool m_resetLocationScheduled; @@ -269,5 +250,6 @@ private: } // namespace Debugger Q_DECLARE_METATYPE(Debugger::Internal::UpdateParameters) +Q_DECLARE_METATYPE(Debugger::Internal::TypeFormatList) #endif // DEBUGGER_WATCHHANDLER_H From 789547487b7b94525f1b2caaf383687a3796cf3a Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 19 Mar 2015 14:04:53 +0100 Subject: [PATCH 08/37] Doc: managing chunks in the diff editor Change-Id: I408faf99e71d6e368f719af8796ea0d238258d84 Reviewed-by: Jarek Kobus --- doc/src/editors/creator-diff-editor.qdoc | 8 ++++++++ doc/src/editors/creator-editors.qdoc | 3 +++ 2 files changed, 11 insertions(+) diff --git a/doc/src/editors/creator-diff-editor.qdoc b/doc/src/editors/creator-diff-editor.qdoc index 8485d5461e3..a920a3a4a83 100644 --- a/doc/src/editors/creator-diff-editor.qdoc +++ b/doc/src/editors/creator-diff-editor.qdoc @@ -51,6 +51,10 @@ indicates lines that contain added text (painted a darker green) in the right pane. + To revert the changes, right-click added text and then select + \uicontrol {Revert Chunk} in the context menu. To apply the changes, select + removed text and then select \uicontrol {Apply Chunk}. + To view the differences in a unified view where changed rows are placed below each other, select \inlineimage qtcreator-switchto-unified-diffeditor.png @@ -99,4 +103,8 @@ If the files change outside \QC, select \inlineimage qtcreator-regenerate-index.png (\uicontrol {Reload Editor}) to compare them again and to show the results. + + To send a chunk of changes to a \l{Pasting and Fetching Code Snippets} + {code pasting service}, select \uicontrol {Send Chunk to CodePaster} in the + context menu. */ diff --git a/doc/src/editors/creator-editors.qdoc b/doc/src/editors/creator-editors.qdoc index 8d150f31a01..0113072e5dc 100644 --- a/doc/src/editors/creator-editors.qdoc +++ b/doc/src/editors/creator-editors.qdoc @@ -1029,6 +1029,9 @@ To paste any content that you copied to the clipboard, select \uicontrol Tools > \uicontrol {Code Pasting} > \uicontrol {Paste Snippet}. + To paste content from the \l{Comparing Files}{diff editor}, right-click a + chunk and select \uicontrol {Send Chunk to CodePaster} in the context menu. + To fetch a snippet of code from the server, select \uicontrol{Tools} > \uicontrol{Code Pasting} > \uicontrol{Fetch Snippet} or press \key{Alt+C,Alt+F}. Select the snippet to fetch from the list. From 51ee57aad080f90f93df803e8984f7e207246f48 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Fri, 20 Mar 2015 11:29:01 +0100 Subject: [PATCH 09/37] Debugger: Fix compile with MSVC2010 Change-Id: Ic75a4d6d7fc5cfd27f2a42b59b83366bb1822a39 Reviewed-by: hjk --- src/plugins/debugger/watchhandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index ed2a051d086..128005f711a 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -1802,7 +1802,7 @@ WatchModel *WatchItem::watchModel() void WatchItem::parseWatchData(const GdbMi &input) { auto itemHandler = [this](const WatchData &data) { - WatchData::operator=(data); + static_cast(this)->operator=(data); // FIXME with 3.5 }; auto childHandler = [this](const WatchData &innerData, const GdbMi &innerInput) { From d26a49d43cca4d9c5bcb23664db7efae73afa21c Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 19 Mar 2015 14:03:36 +0100 Subject: [PATCH 10/37] Debugger: Convert some connections to Qt 5 style Change-Id: I7f879f373ce460459318302a13fa83814c69310d Reviewed-by: Christian Stenger --- src/plugins/debugger/cdb/cdbengine.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index a4535f10ef6..5522b7794b9 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -480,12 +480,12 @@ bool CdbEngine::startConsole(const DebuggerStartParameters &sp, QString *errorMe qDebug("startConsole %s", qPrintable(sp.executable)); m_consoleStub.reset(new ConsoleProcess); m_consoleStub->setMode(ConsoleProcess::Suspend); - connect(m_consoleStub.data(), SIGNAL(processError(QString)), - SLOT(consoleStubError(QString))); - connect(m_consoleStub.data(), SIGNAL(processStarted()), - SLOT(consoleStubProcessStarted())); - connect(m_consoleStub.data(), SIGNAL(stubStopped()), - SLOT(consoleStubExited())); + connect(m_consoleStub.data(), &ConsoleProcess::processError, + this, &CdbEngine::consoleStubError); + connect(m_consoleStub.data(), &ConsoleProcess::processStarted, + this, &CdbEngine::consoleStubProcessStarted); + connect(m_consoleStub.data(), &ConsoleProcess::stubStopped, + this, &CdbEngine::consoleStubExited); m_consoleStub->setWorkingDirectory(sp.workingDirectory); if (sp.environment.size()) m_consoleStub->setEnvironment(sp.environment); @@ -1166,8 +1166,8 @@ void CdbEngine::doInterruptInferior(SpecialStopMode sm) m_signalOperation = startParameters().device->signalOperation(); m_specialStopMode = sm; QTC_ASSERT(m_signalOperation, notifyInferiorStopFailed(); return;); - connect(m_signalOperation.data(), SIGNAL(finished(QString)), - SLOT(handleDoInterruptInferior(QString))); + connect(m_signalOperation.data(), &DeviceProcessSignalOperation::finished, + this, &CdbEngine::handleDoInterruptInferior); m_signalOperation->setDebuggerCommand(startParameters().debuggerCommand); m_signalOperation->interruptProcess(inferiorPid()); From a1ec5cd0960825336b07b1c06bc52b5779186465 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 20 Mar 2015 11:45:08 +0100 Subject: [PATCH 11/37] Debugger: Fix recent crash on ramp down Change-Id: Iaa9c0b16c3f09b72d7a755a2d66c8ac1bf021283 Reviewed-by: Christian Stenger --- src/plugins/debugger/watchhandler.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 128005f711a..687d26ef3a9 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -227,7 +227,7 @@ public: WatchItem *m_returnRoot; // Not owned. WatchItem *m_tooltipRoot; // Not owned. - SeparatedView m_separatedView; + SeparatedView *m_separatedView; // Not owned. QSet m_expandedINames; QTimer m_requestUpdateTimer; @@ -237,7 +237,7 @@ public: }; WatchModel::WatchModel(WatchHandler *handler) - : m_handler(handler) + : m_handler(handler), m_separatedView(new SeparatedView) { setObjectName(QLatin1String("WatchModel")); @@ -1147,7 +1147,6 @@ WatchHandler::~WatchHandler() { // Do it manually to prevent calling back in model destructors // after m_cache is destroyed. - m_model->disconnect(); delete m_model; m_model = 0; } @@ -1159,7 +1158,7 @@ void WatchHandler::cleanup() saveWatchers(); m_model->reinitialize(); emit m_model->updateFinished(); - m_model->m_separatedView.hide(); + m_model->m_separatedView->hide(); } void WatchHandler::insertItem(WatchItem *item) @@ -1319,7 +1318,7 @@ void WatchModel::showEditValue(const WatchData &data) const QByteArray key = data.address ? data.hexAddress() : data.iname; switch (data.editformat) { case StopDisplay: - m_separatedView.removeObject(data.iname); + m_separatedView->removeObject(data.iname); break; case DisplayImageData: case DisplayImageFile: { // QImage @@ -1357,7 +1356,7 @@ void WatchModel::showEditValue(const WatchData &data) tr("%1 Object at %2").arg(QLatin1String(data.type), QLatin1String(data.hexAddress())) : tr("%1 Object at Unknown Address").arg(QLatin1String(data.type)); - ImageViewer *v = m_separatedView.prepareObject(key, title); + ImageViewer *v = m_separatedView->prepareObject(key, title); v->setProperty(INameProperty, data.iname); v->setImage(im); break; @@ -1373,7 +1372,7 @@ void WatchModel::showEditValue(const WatchData &data) str = QString::fromLatin1(ba.constData(), ba.size()); else if (data.editformat == DisplayUtf8String) str = QString::fromUtf8(ba.constData(), ba.size()); - QTextEdit *t = m_separatedView.prepareObject(key, data.name); + QTextEdit *t = m_separatedView->prepareObject(key, data.name); t->setProperty(INameProperty, data.iname); t->setText(str); break; From 59172f9ab423be9aa8ca51ad960f1c95d09d8eb8 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 19 Mar 2015 14:21:20 +0100 Subject: [PATCH 12/37] Debugger: Inline GdbEngine::rebuildWatchModel ... into its only caller, remove duplicated and unused code. Change-Id: Ibdd84eeda34e4f7b4b307dc619c9f31399d7ec5f Reviewed-by: Christian Stenger --- src/plugins/debugger/gdb/gdbengine.cpp | 33 +++++++------------------- src/plugins/debugger/gdb/gdbengine.h | 1 - 2 files changed, 9 insertions(+), 25 deletions(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index f8e6d602774..fa6810d8400 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3732,19 +3732,6 @@ void GdbEngine::updateWatchItem(WatchItem *item) updateLocalsPython(params); } -void GdbEngine::rebuildWatchModel() -{ - static int count = 0; - ++count; - PENDING_DEBUG("REBUILDING MODEL" << count); - if (boolSetting(LogTimeStamps)) - showMessage(LogWindow::logTimeStamp(), LogMiscInput); - showMessage(_("").arg(count), LogMiscInput); - showStatusMessage(tr("Finished retrieving data"), 400); - - DebuggerToolTipManager::updateEngine(this); -} - void GdbEngine::handleVarAssign(const DebuggerResponse &) { // Everything might have changed, force re-evaluation. @@ -4711,7 +4698,6 @@ void addGdbOptionPages(QList *opts) void GdbEngine::updateLocalsPython(const UpdateParameters ¶ms) { - //m_pendingWatchRequests = 0; m_pendingBreakpointRequests = 0; DebuggerCommand cmd("showData"); @@ -4820,17 +4806,16 @@ void GdbEngine::handleStackFramePython(const DebuggerResponse &response, bool pa handler->purgeOutdatedItems(toDelete); - //PENDING_DEBUG("AFTER handleStackFrame()"); - // FIXME: This should only be used when updateLocals() was - // triggered by expanding an item in the view. - //if (m_pendingWatchRequests <= 0) { - //PENDING_DEBUG("\n\n .... AND TRIGGERS MODEL UPDATE\n"); - rebuildWatchModel(); - //} - if (!partial) { + static int count = 0; + showMessage(_("") + .arg(++count).arg(LogWindow::logTimeStamp()), LogMiscInput); + showStatusMessage(tr("Finished retrieving data"), 400); + + DebuggerToolTipManager::updateEngine(this); + + if (!partial) emit stackFrameCompleted(); - DebuggerToolTipManager::updateEngine(this); - } + } else { showMessage(_("DUMPER FAILED: " + response.toString())); } diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index e71455c3939..dff3c80d3ef 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -397,7 +397,6 @@ protected: virtual void watchPoint(const QPoint &); void handleWatchPoint(const DebuggerResponse &response); - void rebuildWatchModel(); void updateWatchItem(WatchItem *item); void showToolTip(); From d9135665f0217a5d4e2ffb574d808005b7d2ae2e Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Thu, 19 Mar 2015 22:35:39 +0200 Subject: [PATCH 13/37] Debugger: Fix removal of expression that ends with whitespace * Start a debugging session * Add an evaluated expression "(char*)foo " * Delete the expression * Press F10 * It reappears Change-Id: I5c54ca6ab2f4be6c613880a2747e4aff653d15be Reviewed-by: Christian Stenger --- src/plugins/debugger/debuggerplugin.cpp | 1 + src/plugins/debugger/watchhandler.cpp | 4 ++-- src/plugins/debugger/watchwindow.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index aff64de8f8d..cf4a40de9a6 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -919,6 +919,7 @@ public slots: exp = removeObviousSideEffects(exp); else exp = fixCppExpression(exp); + exp = exp.trimmed(); if (exp.isEmpty()) return; currentEngine()->watchHandler()->watchVariable(exp); diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 687d26ef3a9..015f6a2ea74 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -856,7 +856,7 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role case Qt::EditRole: switch (idx.column()) { case 0: { - m_handler->watchExpression(value.toString()); + m_handler->watchExpression(value.toString().trimmed()); break; } case 1: // Change value @@ -1491,7 +1491,7 @@ void WatchHandler::loadSessionData() QVariant value = sessionValue("Watchers"); m_model->m_watchRoot->removeChildren(); foreach (const QString &exp, value.toStringList()) - watchExpression(exp); + watchExpression(exp.trimmed()); } WatchModelBase *WatchHandler::model() const diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index 6ff501c61e3..c82a3fa5b93 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -1108,7 +1108,7 @@ void WatchTreeView::inputNewExpression() "\">documentation.")); dlg.setHistoryCompleter(QLatin1String("WatchItems")); if (dlg.exec() == QDialog::Accepted) { - QString exp = dlg.text(); + const QString exp = dlg.text().trimmed(); if (!exp.isEmpty()) watchExpression(exp, exp); } From 4b0731624f83ce7d78f98e49885932558deeeff6 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 20 Mar 2015 12:10:35 +0100 Subject: [PATCH 14/37] Debugger: Inline DebuggerPluginPrivate::{isDockVisible,mainWindow} Change-Id: I1494d5ed0635768095ff78b61341b2339e885b3f Reviewed-by: hjk --- src/plugins/debugger/debuggerplugin.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index cf4a40de9a6..c9d2d71a4bd 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -727,14 +727,6 @@ public: void enableReverseDebuggingTriggered(const QVariant &value); void showStatusMessage(const QString &msg, int timeout = -1); - DebuggerMainWindow *mainWindow() const { return m_mainWindow; } - - bool isDockVisible(const QString &objectName) const - { - QDockWidget *dock = mainWindow()->findChild(objectName); - return dock && dock->toggleViewAction()->isChecked(); - } - void runControlStarted(DebuggerEngine *engine); void runControlFinished(DebuggerEngine *engine); void remoteCommand(const QStringList &options); @@ -1823,7 +1815,7 @@ void DebuggerPluginPrivate::connectEngine(DebuggerEngine *engine) engine->watchHandler()->resetWatchers(); - mainWindow()->setEngineDebugLanguages(engine->startParameters().languages); + m_mainWindow->setEngineDebugLanguages(engine->startParameters().languages); } static void changeFontSize(QWidget *widget, qreal size) @@ -2049,7 +2041,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) m_detachAction->setEnabled(detachable); if (stopped) - QApplication::alert(mainWindow(), 3000); + QApplication::alert(m_mainWindow, 3000); const bool canReverse = engine->hasCapability(ReverseSteppingCapability) && boolSetting(EnableReverseDebugging); @@ -3197,12 +3189,13 @@ void synchronizeBreakpoints() QWidget *mainWindow() { - return dd->mainWindow(); + return dd->m_mainWindow; } bool isDockVisible(const QString &objectName) { - return dd->isDockVisible(objectName); + QDockWidget *dock = dd->m_mainWindow->findChild(objectName); + return dock && dock->toggleViewAction()->isChecked(); } void openMemoryEditor() From fb6d7ce91b5c469300d53415e2f0dfa22742e1a3 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 20 Mar 2015 14:17:44 +0100 Subject: [PATCH 15/37] Remove some duplicate includes Change-Id: If7bae084cd34c6fb0fe77f9227d9848517c0e691 Reviewed-by: Tobias Hunger --- src/plugins/analyzerbase/analyzerutils.cpp | 1 - src/plugins/android/androidsettingswidget.cpp | 2 -- src/plugins/clangcodemodel/constants.h | 1 - src/plugins/coreplugin/iversioncontrol.cpp | 2 -- src/plugins/coreplugin/vcsmanager.cpp | 1 - src/plugins/cppeditor/cppeditor.cpp | 1 - src/plugins/cpptools/cppcompletionassist.cpp | 1 - src/plugins/cpptools/cpppointerdeclarationformatter_test.cpp | 1 - src/plugins/debugger/registerwindow.cpp | 1 - src/plugins/diffeditor/diffeditor.cpp | 1 - src/plugins/diffeditor/diffeditormanager.cpp | 1 - src/plugins/diffeditor/unifieddiffeditorwidget.cpp | 1 - src/plugins/git/gitplugin.cpp | 1 - src/plugins/ios/iosdsymbuildstep.cpp | 1 - src/plugins/projectexplorer/devicesupport/devicemanager.cpp | 1 - src/plugins/projectexplorer/session.cpp | 1 - 16 files changed, 18 deletions(-) diff --git a/src/plugins/analyzerbase/analyzerutils.cpp b/src/plugins/analyzerbase/analyzerutils.cpp index 3d4e71747d4..5d8986eacc0 100644 --- a/src/plugins/analyzerbase/analyzerutils.cpp +++ b/src/plugins/analyzerbase/analyzerutils.cpp @@ -41,7 +41,6 @@ #include #include -#include #include diff --git a/src/plugins/android/androidsettingswidget.cpp b/src/plugins/android/androidsettingswidget.cpp index 9274f937825..f8748be2294 100644 --- a/src/plugins/android/androidsettingswidget.cpp +++ b/src/plugins/android/androidsettingswidget.cpp @@ -45,8 +45,6 @@ #include #include -#include - #include #include #include diff --git a/src/plugins/clangcodemodel/constants.h b/src/plugins/clangcodemodel/constants.h index 30387c647b0..f67f93f5f6f 100644 --- a/src/plugins/clangcodemodel/constants.h +++ b/src/plugins/clangcodemodel/constants.h @@ -31,7 +31,6 @@ #ifndef CONSTANTS_H #define CONSTANTS_H -#include #include namespace ClangCodeModel { diff --git a/src/plugins/coreplugin/iversioncontrol.cpp b/src/plugins/coreplugin/iversioncontrol.cpp index 57f18ade22e..f9cbf4a90d1 100644 --- a/src/plugins/coreplugin/iversioncontrol.cpp +++ b/src/plugins/coreplugin/iversioncontrol.cpp @@ -127,8 +127,6 @@ QString IVersionControl::TopicCache::topic(const QString &topLevel) #if defined(WITH_TESTS) -#include "vcsmanager.h" - #include namespace Core { diff --git a/src/plugins/coreplugin/vcsmanager.cpp b/src/plugins/coreplugin/vcsmanager.cpp index 65182b46d97..f4ec9e84735 100644 --- a/src/plugins/coreplugin/vcsmanager.cpp +++ b/src/plugins/coreplugin/vcsmanager.cpp @@ -491,7 +491,6 @@ void VcsManager::handleConfigurationChanges() #include #include "coreplugin.h" -#include "iversioncontrol.h" #include diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index c88e4213586..460d8b7c3a0 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -48,7 +48,6 @@ #include #include -#include #include #include #include diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp index 58d09432677..bb482038ec4 100644 --- a/src/plugins/cpptools/cppcompletionassist.cpp +++ b/src/plugins/cpptools/cppcompletionassist.cpp @@ -33,7 +33,6 @@ #include "builtineditordocumentparser.h" #include "cppdoxygen.h" #include "cppmodelmanager.h" -#include "cppmodelmanager.h" #include "cpptoolsconstants.h" #include "cpptoolsreuse.h" #include "editordocumenthandle.h" diff --git a/src/plugins/cpptools/cpppointerdeclarationformatter_test.cpp b/src/plugins/cpptools/cpppointerdeclarationformatter_test.cpp index 09a3c7cc85d..27c540fae92 100644 --- a/src/plugins/cpptools/cpppointerdeclarationformatter_test.cpp +++ b/src/plugins/cpptools/cpppointerdeclarationformatter_test.cpp @@ -30,7 +30,6 @@ #include "cpppointerdeclarationformatter.h" #include "cpptoolsplugin.h" -#include "cpptoolsplugin.h" #include "cpptoolstestcase.h" #include diff --git a/src/plugins/debugger/registerwindow.cpp b/src/plugins/debugger/registerwindow.cpp index 818301a4ea3..f96e5785a3d 100644 --- a/src/plugins/debugger/registerwindow.cpp +++ b/src/plugins/debugger/registerwindow.cpp @@ -37,7 +37,6 @@ #include "debuggerengine.h" #include "registerhandler.h" #include "watchdelegatewidgets.h" -#include "memoryagent.h" #include #include diff --git a/src/plugins/diffeditor/diffeditor.cpp b/src/plugins/diffeditor/diffeditor.cpp index bd514fd9133..f1d3c86640f 100644 --- a/src/plugins/diffeditor/diffeditor.cpp +++ b/src/plugins/diffeditor/diffeditor.cpp @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include diff --git a/src/plugins/diffeditor/diffeditormanager.cpp b/src/plugins/diffeditor/diffeditormanager.cpp index d5944418199..242b19bcd4f 100644 --- a/src/plugins/diffeditor/diffeditormanager.cpp +++ b/src/plugins/diffeditor/diffeditormanager.cpp @@ -30,7 +30,6 @@ #include "diffeditormanager.h" #include "diffeditor.h" -#include "diffeditordocument.h" #include "diffeditorconstants.h" #include "diffeditordocument.h" #include diff --git a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp index 22ef037c3d1..e94f21b2380 100644 --- a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp +++ b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp @@ -45,7 +45,6 @@ #include #include -#include #include #include #include diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 3f5d39a2a45..3e2f1b8c283 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -61,7 +61,6 @@ #include #include #include -#include #include #include diff --git a/src/plugins/ios/iosdsymbuildstep.cpp b/src/plugins/ios/iosdsymbuildstep.cpp index 1eb5874ed04..2b08097d9b6 100644 --- a/src/plugins/ios/iosdsymbuildstep.cpp +++ b/src/plugins/ios/iosdsymbuildstep.cpp @@ -48,7 +48,6 @@ #include #include #include -#include using namespace Core; using namespace ProjectExplorer; diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp index 14b300f3f1c..e76faef254f 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp index 7b0716ffc24..a4feac93632 100644 --- a/src/plugins/projectexplorer/session.cpp +++ b/src/plugins/projectexplorer/session.cpp @@ -48,7 +48,6 @@ #include #include -#include #include #include From 2c8e0c34e7187978a8a0aa7e66dbdadef6b8bb9e Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 20 Mar 2015 16:47:13 +0100 Subject: [PATCH 16/37] Doc: using diff editor for Subversion by default Change-Id: I0f814e9f8be8f91072be8c0fb0c38ccef7a5ce2d Reviewed-by: Orgad Shaneh --- doc/src/howto/creator-vcs.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/howto/creator-vcs.qdoc b/doc/src/howto/creator-vcs.qdoc index 6c050c52a4d..affc2d2703d 100644 --- a/doc/src/howto/creator-vcs.qdoc +++ b/doc/src/howto/creator-vcs.qdoc @@ -202,7 +202,7 @@ \image qtcreator-vcs-diff.png - With Git, the diff is displayed side-by-side in a \l{Comparing Files} + With Git and Subversion, the diff is displayed side-by-side in a \l{Comparing Files} {diff editor} by default. To use the inline diff view instead, select the \uicontrol {Switch to Text Diff Editor} option from the toolbar. In the inline diff view, you can use context menu commands to apply, revert, stage, and From dba12a1eab8846174d55e794c1f24d3dcb4d40ef Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 20 Mar 2015 13:18:36 +0100 Subject: [PATCH 17/37] Debugger: More interface streamlining This makes WatchModel practically a WatchHandlerPrivate. Change-Id: Iaf3435711012af5e233a7dfc0dc0caf9c8c3ab24 Reviewed-by: Christian Stenger --- src/plugins/debugger/watchhandler.cpp | 114 +++++++++++--------------- src/plugins/debugger/watchhandler.h | 13 --- 2 files changed, 46 insertions(+), 81 deletions(-) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 015f6a2ea74..a3177c30e99 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -102,6 +102,11 @@ static QByteArray stripForFormat(const QByteArray &ba) return res; } +static void saveWatchers() +{ + setSessionValue("Watchers", WatchHandler::watchedExpressions()); +} + /////////////////////////////////////////////////////////////////////// // // SeparatedView @@ -194,7 +199,7 @@ public: class WatchModel : public WatchModelBase { public: - explicit WatchModel(WatchHandler *handler); + WatchModel(WatchHandler *handler, DebuggerEngine *engine); static QString nameForFormat(int format); @@ -210,15 +215,17 @@ public: void insertItem(WatchItem *item); void reexpandItems(); - void setCurrentItem(const QByteArray &iname); void showEditValue(const WatchData &data); + void setFormat(const QByteArray &type, int format); QString removeNamespaces(QString str) const; - DebuggerEngine *engine() const; - bool contentIsValid() const; public: WatchHandler *m_handler; // Not owned. + DebuggerEngine *m_engine; // Not owned. + + bool m_contentsValid; + bool m_resetLocationScheduled; WatchItem *root() const { return static_cast(rootItem()); } WatchItem *m_localsRoot; // Not owned. @@ -236,11 +243,15 @@ public: QHash m_valueCache; }; -WatchModel::WatchModel(WatchHandler *handler) - : m_handler(handler), m_separatedView(new SeparatedView) +WatchModel::WatchModel(WatchHandler *handler, DebuggerEngine *engine) + : m_handler(handler), m_engine(engine), m_separatedView(new SeparatedView) { setObjectName(QLatin1String("WatchModel")); + m_contentsValid = false; + m_contentsValid = true; // FIXME + m_resetLocationScheduled = false; + setHeader(QStringList() << tr("Name") << tr("Value") << tr("Type")); auto root = new WatchItem; root->appendChild(m_localsRoot = new WatchItem("local", tr("Locals"))); @@ -272,11 +283,6 @@ void WatchModel::reinitialize(bool includeInspectData) m_inspectorRoot->removeChildren(); } -DebuggerEngine *WatchModel::engine() const -{ - return m_handler->m_engine; -} - WatchItem *WatchModel::findItem(const QByteArray &iname) const { return root()->findItem(iname); @@ -327,7 +333,7 @@ QString WatchModel::removeNamespaces(QString str) const if (!boolSetting(ShowStdNamespace)) str.remove(QLatin1String("std::")); if (!boolSetting(ShowQtNamespace)) { - const QString qtNamespace = QString::fromLatin1(engine()->qtNamespace()); + const QString qtNamespace = QString::fromLatin1(m_engine->qtNamespace()); if (!qtNamespace.isEmpty()) str.remove(qtNamespace); } @@ -602,7 +608,7 @@ bool WatchItem::canFetchMore() const return false; if (!watchModel()) return false; - if (!watchModel()->contentIsValid() && !isInspect()) + if (!watchModel()->m_contentsValid && !isInspect()) return false; return !fetchTriggered; } @@ -616,7 +622,7 @@ void WatchItem::fetchMore() fetchTriggered = true; if (children().isEmpty()) { setChildrenNeeded(); - watchModel()->engine()->updateWatchItem(this); + watchModel()->m_engine->updateWatchItem(this); } } @@ -640,15 +646,6 @@ int WatchItem::itemFormat() const return theTypeFormats.value(stripForFormat(type), AutomaticFormat); } -bool WatchModel::contentIsValid() const -{ - // FIXME: - // inspector doesn't follow normal beginCycle()/endCycle() - //if (m_type == InspectWatch) - // return true; - return m_handler->m_contentsValid; -} - QString WatchItem::expression() const { if (!exp.isEmpty()) @@ -715,7 +712,7 @@ QColor WatchItem::valueColor() const if (watchModel()) { if (!valueEnabled) return gray; - if (!watchModel()->contentIsValid() && !isInspect()) + if (!watchModel()->m_contentsValid && !isInspect()) return gray; if (value.isEmpty()) // This might still show 0x... return gray; @@ -811,7 +808,7 @@ QVariant WatchItem::data(int column, int role) const case LocalsIsWatchpointAtObjectAddressRole: { BreakpointParameters bp(WatchpointAtAddress); bp.address = address; - return watchModel()->engine()->breakHandler()->findWatchpoint(bp) != 0; + return watchModel()->m_engine->breakHandler()->findWatchpoint(bp) != 0; } case LocalsSizeRole: @@ -821,7 +818,7 @@ QVariant WatchItem::data(int column, int role) const if (isPointerType(type)) { BreakpointParameters bp(WatchpointAtAddress); bp.address = pointerValue(value); - return watchModel()->engine()->breakHandler()->findWatchpoint(bp) != 0; + return watchModel()->m_engine->breakHandler()->findWatchpoint(bp) != 0; } return false; @@ -860,10 +857,10 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role break; } case 1: // Change value - engine()->assignValueInDebugger(item, item->expression(), value); + m_engine->assignValueInDebugger(item, item->expression(), value); break; case 2: // TODO: Implement change type. - engine()->assignValueInDebugger(item, item->expression(), value); + m_engine->assignValueInDebugger(item, item->expression(), value); break; } case LocalsExpandedRole: @@ -878,8 +875,8 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role break; case LocalsTypeFormatRole: - m_handler->setFormat(item->type, value.toInt()); - engine()->updateWatchItem(item); + setFormat(item->type, value.toInt()); + m_engine->updateWatchItem(item); break; case LocalsIndividualFormatRole: { @@ -888,7 +885,7 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role theIndividualFormats.remove(item->iname); else theIndividualFormats[item->iname] = format; - engine()->updateWatchItem(item); + m_engine->updateWatchItem(item); break; } } @@ -900,7 +897,7 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role Qt::ItemFlags WatchItem::flags(int column) const { QTC_ASSERT(model(), return Qt::ItemFlags()); - DebuggerEngine *engine = watchModel()->engine(); + DebuggerEngine *engine = watchModel()->m_engine; QTC_ASSERT(engine, return Qt::ItemFlags()); const DebuggerState state = engine->state(); @@ -1120,14 +1117,6 @@ int WatchItem::requestedFormat() const return format; } -void WatchModel::setCurrentItem(const QByteArray &iname) -{ - if (WatchItem *item = findItem(iname)) { - QModelIndex idx = indexFromItem(item); - emit currentIndexRequested(idx); - } -} - /////////////////////////////////////////////////////////////////////// // // WatchHandler @@ -1136,11 +1125,7 @@ void WatchModel::setCurrentItem(const QByteArray &iname) WatchHandler::WatchHandler(DebuggerEngine *engine) { - m_engine = engine; - m_model = new WatchModel(this); - m_contentsValid = false; - m_contentsValid = true; // FIXME - m_resetLocationScheduled = false; + m_model = new WatchModel(this, engine); } WatchHandler::~WatchHandler() @@ -1220,13 +1205,13 @@ void WatchHandler::resetWatchers() void WatchHandler::notifyUpdateStarted() { m_model->m_requestUpdateTimer.start(80); - m_contentsValid = false; + m_model->m_contentsValid = false; updateWatchersWindow(); } void WatchHandler::notifyUpdateFinished() { - m_contentsValid = true; + m_model->m_contentsValid = true; updateWatchersWindow(); m_model->m_requestUpdateTimer.stop(); emit m_model->updateFinished(); @@ -1241,7 +1226,7 @@ void WatchHandler::purgeOutdatedItems(const QSet &inames) m_model->layoutChanged(); m_model->reexpandItems(); - m_contentsValid = true; + m_model->m_contentsValid = true; updateWatchersWindow(); } @@ -1279,12 +1264,12 @@ void WatchHandler::watchExpression(const QString &exp0, const QString &name) item->iname = watcherName(exp); saveWatchers(); - if (m_engine->state() == DebuggerNotReady) { + if (m_model->m_engine->state() == DebuggerNotReady) { item->setAllUnneeded(); item->setValue(QString(QLatin1Char(' '))); m_model->insertItem(item); } else { - m_engine->updateWatchItem(item); + m_model->m_engine->updateWatchItem(item); } updateWatchersWindow(); } @@ -1426,12 +1411,7 @@ QStringList WatchHandler::watchedExpressions() return watcherNames; } -void WatchHandler::saveWatchers() -{ - setSessionValue("Watchers", watchedExpressions()); -} - -void WatchHandler::loadFormats() +static void loadFormats() { QVariant value = sessionValue("DefaultFormats"); QMapIterator it(value.toMap()); @@ -1450,7 +1430,7 @@ void WatchHandler::loadFormats() } } -void WatchHandler::saveFormats() +static void saveFormats() { QMap formats; QHashIterator it(theTypeFormats); @@ -1529,12 +1509,7 @@ const WatchItem *WatchHandler::findCppLocalVariable(const QString &name) const return 0; } -bool WatchHandler::hasItem(const QByteArray &iname) const -{ - return m_model->findItem(iname); -} - -void WatchHandler::setFormat(const QByteArray &type0, int format) +void WatchModel::setFormat(const QByteArray &type0, int format) { const QByteArray type = stripForFormat(type0); if (format == AutomaticFormat) @@ -1542,7 +1517,7 @@ void WatchHandler::setFormat(const QByteArray &type0, int format) else theTypeFormats[type] = format; saveFormats(); - m_model->reinsertAllData(); + reinsertAllData(); } int WatchHandler::format(const QByteArray &iname) const @@ -1680,18 +1655,21 @@ DumperTypeFormats WatchHandler::typeFormats() const void WatchHandler::scheduleResetLocation() { - m_contentsValid = false; - m_resetLocationScheduled = true; + m_model->m_contentsValid = false; + m_model->m_resetLocationScheduled = true; } void WatchHandler::resetLocation() { - m_resetLocationScheduled = false; + m_model->m_resetLocationScheduled = false; } void WatchHandler::setCurrentItem(const QByteArray &iname) { - m_model->setCurrentItem(iname); + if (WatchItem *item = m_model->findItem(iname)) { + QModelIndex idx = m_model->indexFromItem(item); + emit m_model->currentIndexRequested(idx); + } } QHash WatchHandler::watcherNames() diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index 318c9bc6a2d..971cacda05b 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -187,7 +187,6 @@ public: void fetchMore(const QByteArray &iname) const; WatchItem *findItem(const QByteArray &iname) const; const WatchItem *findCppLocalVariable(const QString &name) const; - bool hasItem(const QByteArray &iname) const; void loadSessionData(); void saveSessionData(); @@ -231,19 +230,7 @@ public: void purgeOutdatedItems(const QSet &inames); private: - friend class WatchModel; - - void saveWatchers(); - static void loadFormats(); - static void saveFormats(); - - void setFormat(const QByteArray &type, int format); - WatchModel *m_model; // Owned. - DebuggerEngine *m_engine; // Not owned. - - bool m_contentsValid; - bool m_resetLocationScheduled; }; } // namespace Internal From 4f4de6372193630ef49bacb94cd07fb1f65f5c31 Mon Sep 17 00:00:00 2001 From: Thorben Kroeger Date: Sun, 22 Mar 2015 11:33:10 +0100 Subject: [PATCH 18/37] FakeVim: implement C-u in insert mode In insert mode: input: "aaa bbb ccc|" keys: C-u result: "" Change-Id: I1813369c401aaee1a634c363ca5f4c252062613c Reviewed-by: hjk --- src/plugins/fakevim/fakevimhandler.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 710270cfe3a..d8dcc3578e4 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -4914,6 +4914,15 @@ void FakeVimHandler::Private::handleInsertMode(const Input &input) const int beginPos = position(); Range range(beginPos, endPos, RangeCharMode); removeText(range); + } else if (input.isControl('u')) { + const int blockNumber = m_cursor.blockNumber(); + const int endPos = position(); + moveToStartOfLine(); + if (blockNumber != m_cursor.blockNumber()) + moveToEndOfLine(); + const int beginPos = position(); + Range range(beginPos, endPos, RangeCharMode); + removeText(range); } else if (input.isKey(Key_Insert)) { g.mode = ReplaceMode; } else if (input.isKey(Key_Left)) { From 0023eafc4c81830bb593ef0dc843a319fa7d0a43 Mon Sep 17 00:00:00 2001 From: Thorben Kroeger Date: Sun, 22 Mar 2015 11:04:41 +0100 Subject: [PATCH 19/37] FakeVim: fix yank register The yank register "0 is only used when using y{motion} commands. This fixes the following: In normal mode: input: |aaa bbb ccc keys: yiw w diw "0P result: aaa aaa ccc Change-Id: I7fb8a62aed29b753ff8b129b5a8aa5f8e965026e Reviewed-by: hjk --- src/plugins/fakevim/fakevimhandler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index d8dcc3578e4..be62edb62e6 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -6935,9 +6935,6 @@ void FakeVimHandler::Private::yankText(const Range &range, int reg) // If register is not specified or " ... if (m_register == '"') { - // copy to yank register 0 too - setRegister('0', text, range.rangemode); - // with delete and change commands set register 1 (if text contains more lines) or // small delete register - if (g.submode == DeleteSubMode || g.submode == ChangeSubMode) { @@ -6945,6 +6942,9 @@ void FakeVimHandler::Private::yankText(const Range &range, int reg) setRegister('1', text, range.rangemode); else setRegister('-', text, range.rangemode); + } else { + // copy to yank register 0 too + setRegister('0', text, range.rangemode); } } else { // Always copy to " register too. From 0f8b5ef43633c41f54fdbc45e6f6847b2d581783 Mon Sep 17 00:00:00 2001 From: Thorben Kroeger Date: Sun, 22 Mar 2015 11:12:08 +0100 Subject: [PATCH 20/37] FakeVim: fix black hole register This fixes the following: In normal mode: input: |aaa bbb ccc keys: yiw w "_diw P result: aaa aaa ccc Change-Id: If66d80660c1bef5be1466883db30a87254065f00 Reviewed-by: hjk --- src/plugins/fakevim/fakevimhandler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index be62edb62e6..3956a3454fa 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -4566,7 +4566,7 @@ bool FakeVimHandler::Private::handleRegisterSubMode(const Input &input) bool handled = false; QChar reg = input.asChar(); - if (QString::fromLatin1("*+.%#:-\"").contains(reg) || reg.isLetterOrNumber()) { + if (QString::fromLatin1("*+.%#:-\"_").contains(reg) || reg.isLetterOrNumber()) { m_register = reg.unicode(); handled = true; } @@ -6946,8 +6946,8 @@ void FakeVimHandler::Private::yankText(const Range &range, int reg) // copy to yank register 0 too setRegister('0', text, range.rangemode); } - } else { - // Always copy to " register too. + } else if (m_register != '_') { + // Always copy to " register too (except black hole register). setRegister('"', text, range.rangemode); } From 5ffb70ab7588151dfa57195f4a52f2da7e9bb8f2 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 19 Mar 2015 07:24:16 +0100 Subject: [PATCH 21/37] Cdbext: Use max string size for QByteArray dumper. Change-Id: I19327d45a7a45433b68359d4143e96017f271b4d Reviewed-by: Christian Stenger --- src/libs/qtcreatorcdbext/symbolgroupvalue.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp index 44e6aaf8ed9..55666678aae 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp @@ -1731,7 +1731,8 @@ static inline bool dumpQByteArray(const SymbolGroupValue &v, std::wostream &str, char *memory; unsigned fullSize; unsigned size; - if (!readQt5StringData(dV, qtInfo, false, 0, 10240, &fullSize, &size, &memory)) + const unsigned &maxStringSize = ExtensionContext::instance().parameters().maxStringLength; + if (!readQt5StringData(dV, qtInfo, false, 0, maxStringSize, &fullSize, &size, &memory)) return false; if (size) { // Emulate CDB's behavior of replacing unprintable characters From 0b6b5631b76011a3858979b1d10a91c00ebdebfd Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 19 Mar 2015 07:35:18 +0100 Subject: [PATCH 22/37] Tests: Dumper: Fix QByteArray dumper test for cdb. Change-Id: Ic5cdf0092d720bc13c1609b6e489e48712645f8b Reviewed-by: Christian Stenger --- tests/auto/debugger/tst_dumpers.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 22710817cd9..6117c31b28f 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -1257,8 +1257,11 @@ void tst_Dumpers::dumper() << QLatin1String("-c") << QLatin1String("g") << QLatin1String("debug\\doit.exe"); + cmds = "!qtcreatorcdbext.setparameter maxStringLength=100"; if (data.bigArray) - cmds = "!qtcreatorcdbext.setparameter maxArraySize=10000\n"; + cmds += " maxArraySize=10000"; + cmds += "\n"; + cmds += "!qtcreatorcdbext.locals -t -D -e " + expanded + " -v -c 0\n" "q\n"; } else if (m_debuggerEngine == LldbEngine) { @@ -1544,8 +1547,10 @@ void tst_Dumpers::dumper_data() + Check("ba1.13", "[13]", "2", "char") + CheckType("ba2", "@QByteArray") - + Check("s", '"' + QByteArray(100, 'x') + '"', "@QString") - + Check("ss", '"' + QByteArray(100, 'c') + '"', "std::string") + + Check("s", '"' + QByteArray(100, 'x') + '"', "@QString") % NoCdbEngine + + Check("s", '"' + QByteArray(100, 'x') + "..." + '"', "@QString") % CdbEngine + + Check("ss", '"' + QByteArray(100, 'c') + '"', "std::string") % NoCdbEngine + + Check("ss", '"' + QByteArray(100, 'c') + "..." + '"', "std::string") % CdbEngine + Check("buf1", "\"" + QByteArray(1, (char)0xee) + "\"", "@QByteArray") + Check("buf2", "\"" + QByteArray(1, (char)0xee) + "\"", "@QByteArray") From a4bb572a3bf32f50327d672e3ee4e1407b5b1494 Mon Sep 17 00:00:00 2001 From: Thorben Kroeger Date: Thu, 19 Mar 2015 20:00:15 +0100 Subject: [PATCH 23/37] Theming: theme compile output pane Change-Id: Ic364457884765ea755d0dc6e3e35296d5bd36359 Reviewed-by: Orgad Shaneh --- share/qtcreator/themes/dark.creatortheme | 4 ++++ share/qtcreator/themes/default.creatortheme | 4 ++++ src/libs/utils/theme/theme.h | 6 ++++++ .../projectexplorer/compileoutputwindow.cpp | 17 +++++++---------- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/share/qtcreator/themes/dark.creatortheme b/share/qtcreator/themes/dark.creatortheme index 21f057f88e2..3d972cbb243 100644 --- a/share/qtcreator/themes/dark.creatortheme +++ b/share/qtcreator/themes/dark.creatortheme @@ -87,6 +87,10 @@ OutputPaneToggleButtonTextColorChecked=text OutputPaneToggleButtonTextColorUnchecked=text QtOutputFormatter_LinkTextColor=ff0000ff +CompileOutput_ErrorOutput=ffff6c6c +CompileOutput_MessageOutput=ff008787 +CompileOutput_ErrorMessageOutput=ffff6c6c + Welcome_BackgroundColorNormal=normalBackground Welcome_Button_BorderColorNormal=0 Welcome_Button_BorderColorPressed=0 diff --git a/share/qtcreator/themes/default.creatortheme b/share/qtcreator/themes/default.creatortheme index 2f17c1b9095..6927484ce5b 100644 --- a/share/qtcreator/themes/default.creatortheme +++ b/share/qtcreator/themes/default.creatortheme @@ -81,6 +81,10 @@ OutputPaneToggleButtonTextColorChecked=ffffffff OutputPaneToggleButtonTextColorUnchecked=ff000000 QtOutputFormatter_LinkTextColor=ff0000aa +CompileOutput_ErrorOutput=ffaa0000 +CompileOutput_MessageOutput=ff0000aa +CompileOutput_ErrorMessageOutput=ffaa0000 + Welcome_BackgroundColorNormal=ffffffff Welcome_Button_BorderColorNormal=ff737373 Welcome_Button_BorderColorPressed=ff333333 diff --git a/src/libs/utils/theme/theme.h b/src/libs/utils/theme/theme.h index 4f63f28c963..167052e1152 100644 --- a/src/libs/utils/theme/theme.h +++ b/src/libs/utils/theme/theme.h @@ -133,6 +133,12 @@ public: QtOutputFormatter_LinkTextColor, + /* Compile Output Pane */ + + CompileOutput_ErrorOutput, + CompileOutput_MessageOutput, + CompileOutput_ErrorMessageOutput, + /* Welcome Plugin */ Welcome_TextColorNormal, diff --git a/src/plugins/projectexplorer/compileoutputwindow.cpp b/src/plugins/projectexplorer/compileoutputwindow.cpp index 707bc15fb47..1ddf2d8d5cf 100644 --- a/src/plugins/projectexplorer/compileoutputwindow.cpp +++ b/src/plugins/projectexplorer/compileoutputwindow.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -184,30 +185,26 @@ QList CompileOutputWindow::toolBarWidgets() const return QList() << m_cancelBuildButton; } -static QColor mix_colors(const QColor &a, const QColor &b) -{ - return QColor((a.red() + 2 * b.red()) / 3, (a.green() + 2 * b.green()) / 3, - (a.blue() + 2* b.blue()) / 3, (a.alpha() + 2 * b.alpha()) / 3); -} - void CompileOutputWindow::appendText(const QString &text, BuildStep::OutputFormat format) { + using Utils::Theme; QPalette p = m_outputWindow->palette(); + Theme *theme = Utils::creatorTheme(); QTextCharFormat textFormat; switch (format) { case BuildStep::NormalOutput: - textFormat.setForeground(p.color(QPalette::Text)); + textFormat.setForeground(theme->color(Theme::TextColorNormal)); textFormat.setFontWeight(QFont::Normal); break; case BuildStep::ErrorOutput: - textFormat.setForeground(mix_colors(p.color(QPalette::Text), QColor(Qt::red))); + textFormat.setForeground(theme->color(Theme::CompileOutput_ErrorOutput)); textFormat.setFontWeight(QFont::Normal); break; case BuildStep::MessageOutput: - textFormat.setForeground(mix_colors(p.color(QPalette::Text), QColor(Qt::blue))); + textFormat.setForeground(theme->color(Theme::CompileOutput_MessageOutput)); break; case BuildStep::ErrorMessageOutput: - textFormat.setForeground(mix_colors(p.color(QPalette::Text), QColor(Qt::red))); + textFormat.setForeground(theme->color(Theme::CompileOutput_ErrorMessageOutput)); textFormat.setFontWeight(QFont::Bold); break; From ce04aeb2dcd878f1f7c08b4c58b8904fa020d5fd Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 23 Feb 2015 11:31:03 +0100 Subject: [PATCH 24/37] QmlProfiler: Don't hide/show trace view when loading and saving This was a workaround to compensate for the fact that windows in window containers don't follow the stacking order and thus the state widget wasn't shown. With QQuickWidget we don't need to do this anymore. Change-Id: I2c1e57d891bee6284ef9f033b8747df4b153271b Task-number: QTCREATORBUG-11833 Reviewed-by: Joerg Bornemann --- .../qmlprofiler/qmlprofilertraceview.cpp | 23 +------------------ .../qmlprofiler/qmlprofilertraceview.h | 4 +--- .../qmlprofiler/qmlprofilerviewmanager.cpp | 3 +-- 3 files changed, 3 insertions(+), 27 deletions(-) diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp index 4e65b3f2d51..94d71028bcc 100644 --- a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp @@ -76,7 +76,6 @@ public: QmlProfilerTraceViewPrivate(QmlProfilerTraceView *qq) : q(qq) {} QmlProfilerTraceView *q; - QmlProfilerStateManager *m_profilerState; QmlProfilerTool *m_profilerTool; QmlProfilerViewManager *m_viewContainer; @@ -90,7 +89,7 @@ public: Timeline::TimelineZoomControl *m_zoomControl; }; -QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, QmlProfilerTool *profilerTool, QmlProfilerViewManager *container, QmlProfilerModelManager *modelManager, QmlProfilerStateManager *profilerState) +QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, QmlProfilerTool *profilerTool, QmlProfilerViewManager *container, QmlProfilerModelManager *modelManager) : QWidget(parent), d(new QmlProfilerTraceViewPrivate(this)) { setObjectName(QLatin1String("QML Profiler")); @@ -141,9 +140,6 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, QmlProfilerTool *pro // Connect this last so that it's executed after the models have updated their data. connect(modelManager->qmlModel(), SIGNAL(changed()), d->m_modelProxy, SIGNAL(stateChanged())); - connect(d->m_modelManager, SIGNAL(stateChanged()), this, SLOT(profilerDataModelStateChanged())); - - d->m_profilerState = profilerState; // Minimum height: 5 rows of 20 pixels + scrollbar of 50 pixels + 20 pixels margin setMinimumHeight(170); @@ -308,23 +304,6 @@ void QmlProfilerTraceView::showContextMenu(QPoint position) } //////////////////////////////////////////////////////////////// -// Profiler State -void QmlProfilerTraceView::profilerDataModelStateChanged() -{ - switch (d->m_modelManager->state()) { - case QmlProfilerDataState::Empty: break; - case QmlProfilerDataState::ClearingData: - d->m_mainView->hide(); - break; - case QmlProfilerDataState::AcquiringData: break; - case QmlProfilerDataState::ProcessingData: break; - case QmlProfilerDataState::Done: - d->m_mainView->show(); - break; - default: - break; - } -} } // namespace Internal } // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.h b/src/plugins/qmlprofiler/qmlprofilertraceview.h index 41a5bbc2cc1..b70de78e947 100644 --- a/src/plugins/qmlprofiler/qmlprofilertraceview.h +++ b/src/plugins/qmlprofiler/qmlprofilertraceview.h @@ -51,8 +51,7 @@ class QmlProfilerTraceView : public QWidget public: explicit QmlProfilerTraceView(QWidget *parent, QmlProfilerTool *profilerTool, QmlProfilerViewManager *container, - QmlProfilerModelManager *modelManager, - QmlProfilerStateManager *profilerState); + QmlProfilerModelManager *modelManager); ~QmlProfilerTraceView(); bool hasValidSelection() const; @@ -68,7 +67,6 @@ public slots: private slots: void updateCursorPosition(); - void profilerDataModelStateChanged(); protected: virtual void contextMenuEvent(QContextMenuEvent *event); diff --git a/src/plugins/qmlprofiler/qmlprofilerviewmanager.cpp b/src/plugins/qmlprofiler/qmlprofilerviewmanager.cpp index 234e81e97f6..d5100209ed3 100644 --- a/src/plugins/qmlprofiler/qmlprofilerviewmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerviewmanager.cpp @@ -95,8 +95,7 @@ void QmlProfilerViewManager::createViews() d->traceView = new QmlProfilerTraceView(mw, d->profilerTool, this, - d->profilerModelManager, - d->profilerState); + d->profilerModelManager); d->traceView->setWindowTitle(tr("Timeline")); connect(d->traceView, SIGNAL(gotoSourceLocation(QString,int,int)), this, SIGNAL(gotoSourceLocation(QString,int,int))); From d216f61ae13159c0fa84f29de449f7b4b51c708f Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 23 Mar 2015 11:09:12 +0100 Subject: [PATCH 25/37] Git: Remove wrong comment Change-Id: Iba84d32c807c99b99bceb4b61e5dd45c59f4512a Reviewed-by: Tobias Hunger --- src/plugins/git/clonewizardpage.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/git/clonewizardpage.h b/src/plugins/git/clonewizardpage.h index 7c5c9ae4c23..2decbf68e5c 100644 --- a/src/plugins/git/clonewizardpage.h +++ b/src/plugins/git/clonewizardpage.h @@ -41,7 +41,6 @@ namespace Git { struct CloneWizardPagePrivate; -// Used by gitorious as well. class CloneWizardPage : public VcsBase::BaseCheckoutWizardPage { Q_OBJECT From ec161a4aa6a038319109502735884ef6653daf81 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Sun, 22 Mar 2015 11:50:01 +0200 Subject: [PATCH 26/37] Fire ProjectExplorerPlugin::runControlFinished signal. runControlFinished was never fired, let's fire it the same way as we fire runControlStarted signal. Change-Id: I551b9b534c428d97a90b28847383c5ed1dc6c718 Reviewed-by: Daniel Teske --- src/plugins/projectexplorer/projectexplorer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 5d6ebf31bc1..67b5420a005 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -565,6 +565,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er connect(dd->m_outputPane, &AppOutputPane::runControlStarted, this, &ProjectExplorerPlugin::runControlStarted); + connect(dd->m_outputPane, &AppOutputPane::runControlFinished, + this, &ProjectExplorerPlugin::runControlFinished); connect(dd->m_outputPane, &AppOutputPane::runControlFinished, dd, &ProjectExplorerPluginPrivate::handleRunControlFinished); From 669d9ede547e3fd970cea34888dc7979d3341744 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Sun, 22 Mar 2015 11:44:50 +0200 Subject: [PATCH 27/37] Clenaup handleRunControlFinished. handleRunControlFinished was already handled in ProjectExplorerPlugin::initialize and it just emit updateRunActions signal. There is no need to call a function just to emit a signal as long as "connect" can do it for us. Change-Id: I58e759eb9101b65e6faa117f5157c63f69b18ea9 Reviewed-by: Daniel Teske --- src/plugins/projectexplorer/projectexplorer.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 67b5420a005..5f429755ad3 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -288,7 +288,6 @@ public: void updateWelcomePage(); - void handleRunControlFinished(); void runConfigurationConfigurationFinished(); public: @@ -568,7 +567,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er connect(dd->m_outputPane, &AppOutputPane::runControlFinished, this, &ProjectExplorerPlugin::runControlFinished); connect(dd->m_outputPane, &AppOutputPane::runControlFinished, - dd, &ProjectExplorerPluginPrivate::handleRunControlFinished); + this, &ProjectExplorerPlugin::updateRunActions); addAutoReleasedObject(new AllProjectsFilter); addAutoReleasedObject(new CurrentProjectFilter); @@ -1966,11 +1965,6 @@ void ProjectExplorerPlugin::startRunControl(RunControl *runControl, RunMode runM dd->startRunControl(runControl, runMode); } -void ProjectExplorerPluginPrivate::handleRunControlFinished() -{ - emit m_instance->updateRunActions(); -} - void ProjectExplorerPluginPrivate::startRunControl(RunControl *runControl, RunMode runMode) { m_outputPane->createNewOutputWindow(runControl); @@ -1980,8 +1974,6 @@ void ProjectExplorerPluginPrivate::startRunControl(RunControl *runControl, RunMo || ((runMode == DebugRunMode || runMode == DebugRunModeWithBreakOnMain) && m_projectExplorerSettings.showDebugOutput); m_outputPane->setBehaviorOnOutput(runControl, popup ? AppOutputPane::Popup : AppOutputPane::Flash); - QObject::connect(runControl, &RunControl::finished, - this, &ProjectExplorerPluginPrivate::handleRunControlFinished); runControl->start(); emit m_instance->updateRunActions(); } From 7481bff2b4a2e7391deac3dfdde0f33241a2e370 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Tue, 17 Mar 2015 11:39:48 +0200 Subject: [PATCH 28/37] Don't allow to run static libs. Static libs can't be run on Android and on iOS, so we need to filter them out. Change-Id: I90b778ffaa5e7d6267cc0e8d753be56bf93007a7 Reviewed-by: Daniel Teske --- src/plugins/ios/iosrunfactories.cpp | 2 +- .../qmakeandroidrunfactories.cpp | 2 +- .../librarydetailscontroller.cpp | 2 +- src/plugins/qmakeprojectmanager/qmakenodes.cpp | 15 ++++++++++----- src/plugins/qmakeprojectmanager/qmakenodes.h | 3 ++- src/plugins/qmakeprojectmanager/qmakeproject.cpp | 3 ++- src/shared/proparser/profileevaluator.cpp | 6 +++--- src/shared/proparser/profileevaluator.h | 3 ++- 8 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/plugins/ios/iosrunfactories.cpp b/src/plugins/ios/iosrunfactories.cpp index f351fd56aad..f2671539050 100644 --- a/src/plugins/ios/iosrunfactories.cpp +++ b/src/plugins/ios/iosrunfactories.cpp @@ -101,7 +101,7 @@ QList IosRunConfigurationFactory::availableCreationIds(Target *parent, QList nodes = project->allProFiles(QList() << ApplicationTemplate - << LibraryTemplate + << SharedLibraryTemplate << AuxTemplate); if (mode == AutoCreate) nodes = QmakeProject::nodesWithQtcRunnable(nodes); diff --git a/src/plugins/qmakeandroidsupport/qmakeandroidrunfactories.cpp b/src/plugins/qmakeandroidsupport/qmakeandroidrunfactories.cpp index dbf112f7a07..8de0fa3ed5d 100644 --- a/src/plugins/qmakeandroidsupport/qmakeandroidrunfactories.cpp +++ b/src/plugins/qmakeandroidsupport/qmakeandroidrunfactories.cpp @@ -92,7 +92,7 @@ QList QmakeAndroidRunConfigurationFactory::availableCreationIds(Target QmakeProject *project = static_cast(parent->project()); QList nodes = project->allProFiles(QList() << ApplicationTemplate - << LibraryTemplate); + << SharedLibraryTemplate); if (mode == AutoCreate) nodes = QmakeProject::nodesWithQtcRunnable(nodes); diff --git a/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp b/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp index fd8761b47e8..9770c70ee4a 100644 --- a/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp +++ b/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp @@ -1048,7 +1048,7 @@ void InternalLibraryDetailsController::updateProFile() QList proFiles = findQt4ProFiles(rootProject); foreach (QmakeProFileNode *proFileNode, proFiles) { const QString proFilePath = proFileNode->path().toString(); - if (proFileNode->projectType() == LibraryTemplate) { + if (proFileNode->projectType() == SharedLibraryTemplate) { const QStringList configVar = proFileNode->variableValue(ConfigVar); if (!configVar.contains(QLatin1String("plugin"))) { const QString relProFilePath = rootDir.relativeFilePath(proFilePath); diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp index 9a10b03850b..6a18db58247 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -917,7 +917,8 @@ QList QmakePriFileNode::supportedActions(Node *node) const switch (proFileNode->projectType()) { case ApplicationTemplate: - case LibraryTemplate: + case StaticLibraryTemplate: + case SharedLibraryTemplate: case AuxTemplate: { // TODO: Some of the file types don't make much sense for aux // projects (e.g. cpp). It'd be nice if the "add" action could @@ -1495,8 +1496,10 @@ static QmakeProjectType proFileTemplateTypeToProjectType(ProFileEvaluator::Templ case ProFileEvaluator::TT_Unknown: case ProFileEvaluator::TT_Application: return ApplicationTemplate; - case ProFileEvaluator::TT_Library: - return LibraryTemplate; + case ProFileEvaluator::TT_StaticLibrary: + return StaticLibraryTemplate; + case ProFileEvaluator::TT_SharedLibrary: + return SharedLibraryTemplate; case ProFileEvaluator::TT_Script: return ScriptTemplate; case ProFileEvaluator::TT_Aux: @@ -1639,7 +1642,7 @@ FolderNode::AddNewInformation QmakeProFileNode::addNewInformation(const QStringL bool QmakeProFileNode::showInSimpleTree(QmakeProjectType projectType) const { - return (projectType == ApplicationTemplate || projectType == LibraryTemplate); + return (projectType == ApplicationTemplate || projectType == SharedLibraryTemplate || projectType == StaticLibraryTemplate); } bool QmakeProFileNode::isDebugAndRelease() const @@ -2512,7 +2515,9 @@ void QmakeProFileNode::updateUiFiles(const QString &buildDir) m_uiFiles.clear(); // Only those two project types can have ui files for us - if (m_projectType == ApplicationTemplate || m_projectType == LibraryTemplate) { + if (m_projectType == ApplicationTemplate || + m_projectType == SharedLibraryTemplate || + m_projectType == StaticLibraryTemplate) { // Find all ui files FindUiFileNodesVisitor uiFilesVisitor; this->accept(&uiFilesVisitor); diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h index 2a005c4a351..59344ed5611 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.h +++ b/src/plugins/qmakeprojectmanager/qmakenodes.h @@ -72,7 +72,8 @@ class QmakeProject; enum QmakeProjectType { InvalidProject = 0, ApplicationTemplate, - LibraryTemplate, + StaticLibraryTemplate, + SharedLibraryTemplate, ScriptTemplate, AuxTemplate, SubDirsTemplate diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 92d279d671d..aaab37486b7 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -1492,7 +1492,8 @@ void QmakeProject::collectData(const QmakeProFileNode *node, DeploymentData &dep if (!installsList.targetPath.isEmpty()) collectApplicationData(node, deploymentData); break; - case LibraryTemplate: + case SharedLibraryTemplate: + case StaticLibraryTemplate: collectLibraryData(node, deploymentData); break; case SubDirsTemplate: diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index af823daf84a..36bb033afa4 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -175,7 +175,7 @@ ProFileEvaluator::TemplateType ProFileEvaluator::templateType() const if (!t.compare(QLatin1String("app"), Qt::CaseInsensitive)) return TT_Application; if (!t.compare(QLatin1String("lib"), Qt::CaseInsensitive)) - return TT_Library; + return d->isActiveConfig(QStringLiteral("staticlib")) ? TT_StaticLibrary : TT_SharedLibrary; if (!t.compare(QLatin1String("script"), Qt::CaseInsensitive)) return TT_Script; if (!t.compare(QLatin1String("aux"), Qt::CaseInsensitive)) @@ -220,8 +220,8 @@ bool ProFileEvaluator::accept(ProFile *pro, QMakeEvaluator::LoadFlags flags) case TT_Application: cxxflags += d->values(ProKey("QMAKE_CXXFLAGS_APP")); break; - case TT_Library: - if (d->isActiveConfig(QStringLiteral("dll"))) { + case TT_SharedLibrary: + { bool plugin = d->isActiveConfig(QStringLiteral("plugin")); if (!plugin || !d->isActiveConfig(QStringLiteral("plugin_no_share_shlib_cflags"))) cxxflags += d->values(ProKey("QMAKE_CXXFLAGS_SHLIB")); diff --git a/src/shared/proparser/profileevaluator.h b/src/shared/proparser/profileevaluator.h index 5ededbc1764..7249eef1afe 100644 --- a/src/shared/proparser/profileevaluator.h +++ b/src/shared/proparser/profileevaluator.h @@ -58,7 +58,8 @@ public: enum TemplateType { TT_Unknown = 0, TT_Application, - TT_Library, + TT_StaticLibrary, + TT_SharedLibrary, TT_Script, TT_Aux, TT_Subdirs From 69f8463fddb295c927294b88b9f2252e48d2fac1 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Mon, 23 Mar 2015 11:53:07 +0100 Subject: [PATCH 29/37] Make compile with MSVC 2012 That compiler doesn't have variadic templates so std::tie takes at most 5 parameters. Change-Id: I9c8b56a3847be54a9cc4a5a356835efd8772ffa7 Reviewed-by: Friedemann Kleint Reviewed-by: Daniel Teske --- src/plugins/qmakeprojectmanager/qmakestep.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/qmakestep.h b/src/plugins/qmakeprojectmanager/qmakestep.h index 85891a7fff9..0f3fb7be4ba 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.h +++ b/src/plugins/qmakeprojectmanager/qmakestep.h @@ -114,8 +114,10 @@ public: inline bool operator ==(const QMakeStepConfig &a, const QMakeStepConfig &b) { - return std::tie(a.archConfig, a.osType, a.linkQmlDebuggingQQ1, a.linkQmlDebuggingQQ2, a.useQtQuickCompiler, a.separateDebugInfo) - == std::tie(b.archConfig, b.osType, b.linkQmlDebuggingQQ1, b.linkQmlDebuggingQQ2, b.useQtQuickCompiler, b.separateDebugInfo); + return std::tie(a.archConfig, a.osType, a.linkQmlDebuggingQQ1, a.linkQmlDebuggingQQ2) + == std::tie(b.archConfig, b.osType, b.linkQmlDebuggingQQ1, b.linkQmlDebuggingQQ2) + && std::tie(a.useQtQuickCompiler, a.separateDebugInfo) + == std::tie(b.useQtQuickCompiler, b.separateDebugInfo); } inline bool operator !=(const QMakeStepConfig &a, const QMakeStepConfig &b) { From 11f6cc7c3f27558f196bcf134ee02bb73e9a9f85 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 23 Mar 2015 11:26:25 +0100 Subject: [PATCH 30/37] Doc: Replace links to gitorious Gitorious is closing down, so set links to qt.io sites. Change-Id: If8c2576f1015066266b8a308f42e902020ab188c Reviewed-by: Leena Miettinen --- doc/src/howto/qtcreator-faq.qdoc | 2 +- doc/src/overview/creator-acknowledgements.qdoc | 2 +- doc/src/qtquick/qtquick-exporting-qml.qdoc | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/src/howto/qtcreator-faq.qdoc b/doc/src/howto/qtcreator-faq.qdoc index 9ac5727c625..bf658da173e 100644 --- a/doc/src/howto/qtcreator-faq.qdoc +++ b/doc/src/howto/qtcreator-faq.qdoc @@ -290,7 +290,7 @@ If it is a scheduled feature, you can see this in the task tracker. If a feature already has been implemented, it is mentioned in the - \l{http://qt.gitorious.org/qt-creator/qt-creator/trees/master/dist}{changes file} + \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/dist}{changes file} for the upcoming release. \b {Why does \QC not use tabs for editors?} diff --git a/doc/src/overview/creator-acknowledgements.qdoc b/doc/src/overview/creator-acknowledgements.qdoc index 1b9d9e08f88..f000b6473ba 100644 --- a/doc/src/overview/creator-acknowledgements.qdoc +++ b/doc/src/overview/creator-acknowledgements.qdoc @@ -90,7 +90,7 @@ here: \list \li QtCreator/src/libs/3rdparty - \li \l{http://qt.gitorious.org/qt-creator/qt-creator/trees/master/src/libs/3rdparty} + \li \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty} \endlist \li \b{ANGLE (Windows)} diff --git a/doc/src/qtquick/qtquick-exporting-qml.qdoc b/doc/src/qtquick/qtquick-exporting-qml.qdoc index b233941c1d3..5172e2a9502 100644 --- a/doc/src/qtquick/qtquick-exporting-qml.qdoc +++ b/doc/src/qtquick/qtquick-exporting-qml.qdoc @@ -115,8 +115,8 @@ \list 1 \li Download the export script, \e{Export QML.jx}, from - \l{http://qt.gitorious.org/qt-labs/photoshop-qmlexporter/trees/master} - {Gitorious}. + \l{https://code.qt.io/cgit/qt-labs/photoshop-qmlexporter.git/} + {code.qt.io}. \note Read the README.txt file in the repository for latest information about the script. @@ -173,8 +173,8 @@ {Tutorial: Installing Python for GIMP 2.6 (Windows)}. \li Download the export script, \e qmlexporter.py, from - \l{http://qt.gitorious.org/qt-labs/gimp-qmlexporter/trees/master} - {Gitorious}. + \l{https://code.qt.io/cgit/qt-labs/gimp-qmlexporter.git/} + {code.qt.io}. \note Read the INSTALL.txt in the repository for latest information about the script. From 93011385404314fb4a8402660743ba445e91e031 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 23 Mar 2015 11:03:37 +0100 Subject: [PATCH 31/37] SettingsDialog: Unknown settings pages aren't a fatal condition. Whenever you remove a plugin with a settings page you will eventually run into this. We can silently ignore it. Change-Id: I887d7e7d21e1e2f68375b60456160f9998f9c650 Reviewed-by: Friedemann Kleint Reviewed-by: Eike Ziller --- src/plugins/coreplugin/dialogs/settingsdialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/src/plugins/coreplugin/dialogs/settingsdialog.cpp index cd3483776aa..fefce66e3b7 100644 --- a/src/plugins/coreplugin/dialogs/settingsdialog.cpp +++ b/src/plugins/coreplugin/dialogs/settingsdialog.cpp @@ -397,8 +397,8 @@ void SettingsDialog::showPage(const Id pageId) } } - QTC_ASSERT(!initialPageId.isValid() || initialPageIndex != -1, - qDebug("Unknown page: %s", initialPageId.name().constData())); + if (initialPageId.isValid() && initialPageIndex == -1) + return; // Unknown settings page, probably due to missing plugin. if (initialCategoryIndex != -1) { const QModelIndex modelIndex = m_proxyModel->mapFromSource(m_model->index(initialCategoryIndex)); From b727c15a534ce337e8cfcd49a0b091aee5462bf3 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Mon, 23 Mar 2015 14:44:37 +0100 Subject: [PATCH 32/37] ProjectMode: Alwyas show at least one target Even though that target is not usseable at that width, this looks better. Change-Id: If985808bcde6c0a836e4d6085536d0a1d9023c4d Task-number: QTCREATORBUG-14182 Reviewed-by: Eike Ziller --- src/plugins/projectexplorer/targetselector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/targetselector.cpp b/src/plugins/projectexplorer/targetselector.cpp index 7dcfd9b0564..6ad1576d2fa 100644 --- a/src/plugins/projectexplorer/targetselector.cpp +++ b/src/plugins/projectexplorer/targetselector.cpp @@ -239,7 +239,7 @@ QSize TargetSelector::sizeHint() const int TargetSelector::maxVisibleTargets() const { - return (width() - ((NAVBUTTON_WIDTH + 1) * 2 + 3))/(targetWidth() + 1); + return qMax((width() - ((NAVBUTTON_WIDTH + 1) * 2 + 3))/(targetWidth() + 1), 1); } void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetIndex, int *targetSubIndex) From 48ac7c186b0228f13bbd8a0f00ab39300765dc4a Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 20 Mar 2015 16:03:59 +0100 Subject: [PATCH 33/37] Debugger: Re-organize passing of display formats The current setup (dumper->gui: list of descriptions, gui->dumper: index in list) is fragile and not easily i18n'able. Go with an enum based approach now. Change-Id: Ie78c596065a8b2ba87ad725274da29d4be3a6da4 Reviewed-by: Christian Stenger --- share/qtcreator/debugger/dumper.py | 148 +++++++++++++---------- share/qtcreator/debugger/gdbbridge.py | 31 +---- share/qtcreator/debugger/lldbbridge.py | 11 +- share/qtcreator/debugger/qttypes.py | 59 ++++----- share/qtcreator/debugger/stdtypes.py | 5 +- src/plugins/debugger/cdb/cdbengine.cpp | 14 ++- src/plugins/debugger/debuggerdialogs.cpp | 13 +- src/plugins/debugger/debuggerdialogs.h | 7 +- src/plugins/debugger/watchhandler.cpp | 87 +++++-------- src/plugins/debugger/watchhandler.h | 102 +++++++--------- src/plugins/debugger/watchwindow.cpp | 20 ++- 11 files changed, 221 insertions(+), 276 deletions(-) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 6fa45a43c74..52e475e27f8 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -67,9 +67,15 @@ StartRemoteProcess, \ # Known special formats. Keep in sync with DisplayFormat in watchhandler.h -KnownDumperFormatBase, \ +AutomaticFormat, \ +RawFormat, \ +SimpleFormat, \ +EnhancedFormat, \ +SeparateFormat, \ Latin1StringFormat, \ +SeparateLatin1StringFormat, \ Utf8StringFormat, \ +SeparateUtf8StringFormat, \ Local8BitStringFormat, \ Utf16StringFormat, \ Ucs4StringFormat, \ @@ -77,9 +83,11 @@ Array10Format, \ Array100Format, \ Array1000Format, \ Array10000Format, \ -SeparateLatin1StringFormat, \ -SeparateUtf8StringFormat \ - = range(100, 112) +ArrayPlotFormat, \ +CompactMapFormat, \ +DirectQListStorageFormat, \ +IndirectQListStorageFormat, \ + = range(0, 20) # Breakpoints. Keep synchronized with BreakpointType in breakpoint.h UnknownType, \ @@ -171,10 +179,10 @@ if hasSubprocess and hasPlot: def arrayForms(): global hasPlot - return "Normal,Plot" if hasPlot else "Normal" + return [ArrayPlotFormat] if hasPlot else [] def mapForms(): - return "Normal,Compact" + return [CompactMapFormat] class ReportItem: @@ -583,12 +591,13 @@ class DumperBase: elided, shown = self.computeLimit(size, limit) return elided, self.readMemory(data, shown) - def putStdStringHelper(self, data, size, charSize, format = None): + def putStdStringHelper(self, data, size, charSize, displayFormat = AutomaticFormat): bytelen = size * charSize elided, shown = self.computeLimit(bytelen, self.displayStringLimit) mem = self.readMemory(data, shown) if charSize == 1: - if format == 1 or format == 2: + if displayFormat == Latin1StringFormat \ + or displayFormat == SeparateLatin1StringFormat: encodingType = Hex2EncodedLatin1 else: encodingType = Hex2EncodedUtf8 @@ -603,9 +612,11 @@ class DumperBase: self.putNumChild(0) self.putValue(mem, encodingType, elided=elided) - if format == 1 or format == 3: + if displayFormat == Latin1StringFormat \ + or displayFormat == Utf8StringFormat: self.putDisplay(StopDisplay) - elif format == 2 or format == 4: + elif displayFormat == SeparateLatin1StringFormat \ + or displayFormat == SeparateUtf8StringFormat: self.putField("editformat", displayType) elided, shown = self.computeLimit(bytelen, 100000) self.putField("editvalue", self.readMemory(data, shown)) @@ -801,9 +812,8 @@ class DumperBase: self.putFields(value, dumpBase) def isMapCompact(self, keyType, valueType): - format = self.currentItemFormat() - if format == 2: - return True # Compact. + if self.currentItemFormat() == CompactMapFormat: + return True return self.isSimpleType(keyType) and self.isSimpleType(valueType) @@ -920,13 +930,13 @@ class DumperBase: except: p = None - itemFormat = self.currentItemFormat() + displayFormat = self.currentItemFormat() n = int(arrayType.sizeof / ts) - if p and self.tryPutSimpleFormattedPointer(p, str(arrayType), itemFormat, arrayType.sizeof): + if p and self.tryPutSimpleFormattedPointer(p, str(arrayType), displayFormat, arrayType.sizeof): self.putNumChild(n) pass - elif itemFormat is None: + elif displayFormat is None: innerTypeName = str(innerType.unqualified()) blob = self.readMemory(self.addressOf(value), arrayType.sizeof) if innerTypeName == "char": @@ -969,6 +979,31 @@ class DumperBase: pass return str(addr) + def tryPutPrettyItem(self, typeName, value): + if self.useFancy and self.currentItemFormat() != RawFormat: + self.putType(typeName) + + nsStrippedType = self.stripNamespaceFromType(typeName)\ + .replace("::", "__") + + # The following block is only needed for D. + if nsStrippedType.startswith("_A"): + # DMD v2.058 encodes string[] as _Array_uns long long. + # With spaces. + if nsStrippedType.startswith("_Array_"): + qdump_Array(self, value) + return True + if nsStrippedType.startswith("_AArray_"): + qdump_AArray(self, value) + return True + + dumper = self.qqDumpers.get(nsStrippedType) + if not dumper is None: + dumper(self, value) + return True + + return False + def tryPutArrayContents(self, base, n, innerType): enc = self.simpleEncoding(innerType) if not enc: @@ -991,8 +1026,8 @@ class DumperBase: data = self.readMemory(base, shown) self.putValue(data, Hex2EncodedLatin1, elided=elided) - def putDisplay(self, format, value = None, cmd = None): - self.put('editformat="%s",' % format) + def putDisplay(self, editFormat, value = None, cmd = None): + self.put('editformat="%s",' % editFormat) if cmd is None: if not value is None: self.put('editvalue="%s",' % value) @@ -1000,8 +1035,8 @@ class DumperBase: self.put('editvalue="%s|%s",' % (cmd, value)) # This is shared by pointer and array formatting. - def tryPutSimpleFormattedPointer(self, value, typeName, itemFormat, limit): - if itemFormat == None and typeName == "char": + def tryPutSimpleFormattedPointer(self, value, typeName, displayFormat, limit): + if displayFormat == AutomaticFormat and typeName == "char": # Use Latin1 as default for char *. self.putType(typeName) (elided, data) = self.encodeCArray(value, 1, limit) @@ -1009,56 +1044,49 @@ class DumperBase: self.putDisplay(StopDisplay) return True - if itemFormat == Latin1StringFormat: - # Explicitly requested Latin1 formatting. + if displayFormat == Latin1StringFormat: self.putType(typeName) (elided, data) = self.encodeCArray(value, 1, limit) self.putValue(data, Hex2EncodedLatin1, elided=elided) self.putDisplay(StopDisplay) return True - if itemFormat == SeparateLatin1StringFormat: - # Explicitly requested Latin1 formatting in separate window. + if displayFormat == SeparateLatin1StringFormat: self.putType(typeName) (elided, data) = self.encodeCArray(value, 1, limit) self.putValue(data, Hex2EncodedLatin1, elided=elided) self.putDisplay(DisplayLatin1String, data) return True - if itemFormat == Utf8StringFormat: - # Explicitly requested UTF-8 formatting. + if displayFormat == Utf8StringFormat: self.putType(typeName) (elided, data) = self.encodeCArray(value, 1, limit) self.putValue(data, Hex2EncodedUtf8, elided=elided) self.putDisplay(StopDisplay) return True - if itemFormat == SeparateUtf8StringFormat: - # Explicitly requested UTF-8 formatting in separate window. + if displayFormat == SeparateUtf8StringFormat: self.putType(typeName) (elided, data) = self.encodeCArray(value, 1, limit) self.putValue(data, Hex2EncodedUtf8, elided=elided) self.putDisplay(DisplayUtf8String, data) return True - if itemFormat == Local8BitStringFormat: - # Explicitly requested local 8 bit formatting. + if displayFormat == Local8BitStringFormat: self.putType(typeName) (elided, data) = self.encodeCArray(value, 1, limit) self.putValue(data, Hex2EncodedLocal8Bit, elided=elided) self.putDisplay(StopDisplay) return True - if itemFormat == Utf16StringFormat: - # Explicitly requested UTF-16 formatting. + if displayFormat == Utf16StringFormat: self.putType(typeName) (elided, data) = self.encodeCArray(value, 2, limit) self.putValue(data, Hex4EncodedLittleEndian, elided=elided) self.putDisplay(StopDisplay) return True - if itemFormat == Ucs4StringFormat: - # Explicitly requested UCS-4 formatting. + if displayFormat == Ucs4StringFormat: self.putType(typeName) (elided, data) = self.encodeCArray(value, 4, limit) self.putValue(data, Hex8EncodedLittleEndian, elided=elided) @@ -1091,16 +1119,16 @@ class DumperBase: self.putNumChild(0) return - format = self.currentItemFormat(value.type) + displayFormat = self.currentItemFormat(value.type) if innerTypeName == "void": - #warn("VOID POINTER: %s" % format) + #warn("VOID POINTER: %s" % displayFormat) self.putType(typeName) self.putValue(str(value)) self.putNumChild(0) return - if format == 0: + if displayFormat == RawFormat: # Explicitly requested bald pointer. self.putType(typeName) self.putValue(self.hexencode(str(value)), Hex2EncodedUtf8WithoutQuotes) @@ -1112,16 +1140,15 @@ class DumperBase: return limit = self.displayStringLimit - if format == DisplayLatin1String or format == DisplayUtf8String: + if displayFormat == SeparateLatin1StringFormat \ + or displayFormat == SeparateUtf8StringFormat: limit = 1000000 - if self.tryPutSimpleFormattedPointer(value, typeName, format, limit): + if self.tryPutSimpleFormattedPointer(value, typeName, displayFormat, limit): self.putNumChild(0) return - if not format is None \ - and format >= Array10Format and format <= Array1000Format: - # Explicitly requested formatting as array of n items. - n = (10, 100, 1000, 10000)[format - Array10Format] + if Array10Format <= displayFormat and displayFormat <= Array1000Format: + n = (10, 100, 1000, 10000)[displayFormat - Array10Format] self.putType(typeName) self.putItemCount(n) self.putArrayData(value, n, innerType) @@ -1141,9 +1168,7 @@ class DumperBase: #warn("AUTODEREF: %s" % self.autoDerefPointers) #warn("INAME: %s" % self.currentIName) if self.autoDerefPointers or self.currentIName.endswith('.this'): - ## Generic pointer type with format None - #warn("GENERIC AUTODEREF POINTER: %s AT %s TO %s" - # % (type, value.address, innerTypeName)) + # Generic pointer type with AutomaticFormat. # Never dereference char types. if innerTypeName != "char" \ and innerTypeName != "signed char" \ @@ -1491,13 +1516,13 @@ class DumperBase: return typeName == "QStringList" and self.qtVersion() >= 0x050000 def currentItemFormat(self, type = None): - format = self.formats.get(self.currentIName) - if format is None: + displayFormat = self.formats.get(self.currentIName, AutomaticFormat) + if displayFormat == AutomaticFormat: if type is None: type = self.currentType.value needle = self.stripForFormat(str(type)) - format = self.typeformats.get(needle) - return format + displayFormat = self.typeformats.get(needle, AutomaticFormat) + return displayFormat def putArrayData(self, base, n, innerType = None, childNumChild = None, maxNumChild = 10000): @@ -1511,19 +1536,19 @@ class DumperBase: i = toInteger(i) self.putSubItem(i, (base + i).dereference()) - def putArrayItem(self, name, addr, n, typeName, plotFormat = 2): + def putArrayItem(self, name, addr, n, typeName): with SubItem(self, name): self.putEmptyValue() self.putType("%s [%d]" % (typeName, n)) self.putArrayData(addr, n, self.lookupType(typeName)) self.putAddress(addr) - def putPlotData(self, base, n, typeobj, plotFormat = 2): + def putPlotData(self, base, n, typeobj): if self.isExpanded(): self.putArrayData(base, n, typeobj) if hasPlot: if self.isSimpleType(typeobj): - show = self.currentItemFormat() == plotFormat + show = self.currentItemFormat() == ArrayPlotFormat iname = self.currentIName data = [] if show: @@ -1688,15 +1713,13 @@ class DumperBase: if funcname.startswith("qdump__"): typename = funcname[7:] self.qqDumpers[typename] = function - self.qqFormats[typename] = self.qqFormats.get(typename, "") + self.qqFormats[typename] = self.qqFormats.get(typename, []) elif funcname.startswith("qform__"): typename = funcname[7:] - formats = "" try: - formats = function() + self.qqFormats[typename] = function() except: - pass - self.qqFormats[typename] = formats + self.qqFormats[typename] = [] elif funcname.startswith("qedit__"): typename = funcname[7:] try: @@ -1721,15 +1744,14 @@ class DumperBase: msg = "dumpers=[" for key, value in self.qqFormats.items(): - if key in self.qqEditable: - msg += '{type="%s",formats="%s",editable="true"},' % (key, value) - else: - msg += '{type="%s",formats="%s"},' % (key, value) + editable = ',editable="true"' if key in self.qqEditable else '' + formats = (',formats=\"%s\"' % str(value)[1:-1]) if len(value) else '' + msg += '{type="%s"%s%s},' % (key, editable, formats) msg += ']' self.reportDumpers(msg) def reportDumpers(self, msg): - raise NotImplementedError # Pure + raise NotImplementedError def reloadDumpers(self, args): for mod in self.dumpermodules: diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index 089c4ae4610..f22bd37b1d2 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -1075,35 +1075,8 @@ class Dumper(DumperBase): self.putItem(self.expensiveDowncast(value), False) return - format = self.currentItemFormat(typeName) - - if self.useFancy and (format is None or format >= 1): - self.putType(typeName) - - nsStrippedType = self.stripNamespaceFromType(typeName)\ - .replace("::", "__") - - # The following block is only needed for D. - if nsStrippedType.startswith("_A"): - # DMD v2.058 encodes string[] as _Array_uns long long. - # With spaces. - if nsStrippedType.startswith("_Array_"): - qdump_Array(self, value) - return - if nsStrippedType.startswith("_AArray_"): - qdump_AArray(self, value) - return - - #warn(" STRIPPED: %s" % nsStrippedType) - #warn(" DUMPERS: %s" % self.qqDumpers) - #warn(" DUMPERS: %s" % (nsStrippedType in self.qqDumpers)) - dumper = self.qqDumpers.get(nsStrippedType, None) - if not dumper is None: - if tryDynamic: - dumper(self, self.expensiveDowncast(value)) - else: - dumper(self, value) - return + if self.tryPutPrettyItem(typeName, value): + return # D arrays, gdc compiled. if typeName.endswith("[]"): diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 4d814223880..fdf70468a8f 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -1063,15 +1063,8 @@ class Dumper(DumperBase): #warn("VALUE: %s" % value) #warn("FANCY: %s" % self.useFancy) - if self.useFancy: - stripped = self.stripNamespaceFromType(typeName).replace("::", "__") - #warn("STRIPPED: %s" % stripped) - #warn("DUMPABLE: %s" % (stripped in self.qqDumpers)) - if stripped in self.qqDumpers: - self.putType(typeName) - self.context = value - self.qqDumpers[stripped](self, value) - return + if self.tryPutPrettyItem(typeName, value): + return # Normal value #numchild = 1 if value.MightHaveChildren() else 0 diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index cff457ae44c..f640786ceff 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -53,24 +53,25 @@ def qdump__QAtomicPointer(d, value): d.putSubItem("_q_value", q.dereference()) def qform__QByteArray(): - return "Latin1 String,Latin1 String in Separate Window,UTF-8 String,UTF-8 String in Separate Window" + return [Latin1StringFormat, SeparateLatin1StringFormat, + Utf8StringFormat, SeparateUtf8StringFormat ] def qdump__QByteArray(d, value): data, size, alloc = d.byteArrayData(value) d.putNumChild(size) elided, p = d.encodeByteArrayHelper(d.extractPointer(value), d.displayStringLimit) - format = d.currentItemFormat() - if format == 1 or format is None: + displayFormat = d.currentItemFormat() + if displayFormat == AutomaticFormat or displayFormat == Latin1StringFormat: d.putDisplay(StopDisplay) d.putValue(p, Hex2EncodedLatin1, elided=elided) - elif format == 2: + elif displayFormat == SeparateLatin1StringFormat: d.putValue(p, Hex2EncodedLatin1, elided=elided) d.putField("editformat", DisplayLatin1String) d.putField("editvalue", d.encodeByteArray(value, limit=100000)) - elif format == 3: + elif displayFormat == Utf8StringFormat: d.putDisplay(StopDisplay) d.putValue(p, Hex2EncodedUtf8, elided=elided) - elif format == 4: + elif displayFormat == SeparateUtf8StringFormat: d.putValue(p, Hex2EncodedUtf8, elided=elided) d.putField("editformat", DisplayUtf8String) d.putField("editvalue", d.encodeByteArray(value, limit=100000)) @@ -92,14 +93,14 @@ def qdump__QChar(d, value): def qform__QAbstractItemModel(): - return "Normal,Enhanced" + return [SimpleFormat, EnhancedFormat] def qdump__QAbstractItemModel(d, value): - format = d.currentItemFormat() - if format == 1: + displayFormat = d.currentItemFormat() + if displayFormat == SimpleFormat: d.putPlainChildren(value) return - #format == 2: + #displayFormat == EnhancedFormat: # Create a default-constructed QModelIndex on the stack. try: ri = d.makeValue(d.qtNamespace() + "QModelIndex", "-1, -1, 0, 0") @@ -134,11 +135,11 @@ def qdump__QAbstractItemModel(d, value): #gdb.execute("call free($ri)") def qform__QModelIndex(): - return "Normal,Enhanced" + return [SimpleFormat, EnhancedFormat] def qdump__QModelIndex(d, value): - format = d.currentItemFormat() - if format == 1: + displayFormat = d.currentItemFormat() + if displayFormat == SimpleFormat: d.putPlainChildren(value) return r = value["r"] @@ -768,7 +769,7 @@ def qdump__QIPv6Address(d, value): d.putPlainChildren(c) def qform__QList(): - return "Assume Direct Storage,Assume Indirect Storage" + return [DirectQListStorageFormat, IndirectQListStorageFormat] def qdump__QList(d, value): base = d.extractPointer(value) @@ -794,10 +795,10 @@ def qdump__QList(d, value): # but this data is available neither in the compiled binary nor # in the frontend. # So as first approximation only do the 'isLarge' check: - format = d.currentItemFormat() - if format == 1: + displayFormat = d.currentItemFormat() + if displayFormat == DirectQListStorageFormat: isInternal = True - elif format == 2: + elif displayFormat == IndirectQListStorageFormat: isInternal = False else: isInternal = innerSize <= stepSize and d.isMovableType(innerType) @@ -818,7 +819,7 @@ def qdump__QList(d, value): d.putSubItem(i, x) def qform__QImage(): - return "Normal,Displayed" + return [SimpleFormat, SeparateFormat] def qdump__QImage(d, value): # This relies on current QImage layout: @@ -861,10 +862,10 @@ def qdump__QImage(d, value): d.putNumChild(0) d.putType("void *") - format = d.currentItemFormat() - if format == 1: + displayFormat = d.currentItemFormat() + if displayFormat == SimpleFormat: d.putDisplay(StopDisplay) - elif format == 2: + elif displayFormat == SeparateFormat: # This is critical for performance. Writing to an external # file using the following is faster when using GDB. # file = tempfile.mkstemp(prefix="gdbpy_") @@ -1751,16 +1752,16 @@ def qedit__QString(d, value, data): d.setValues(base, "short", [ord(c) for c in data]) def qform__QString(): - return "Inline,Separate Window" + return [SimpleFormat, SeparateFormat] def qdump__QString(d, value): d.putStringValue(value) data, size, alloc = d.stringData(value) d.putNumChild(size) - format = d.currentItemFormat() - if format == 1: + displayFormat = d.currentItemFormat() + if displayFormat == SimpleFormat: d.putDisplay(StopDisplay) - elif format == 2: + elif displayFormat == SeparateFormat: d.putField("editformat", DisplayUtf16String) d.putField("editvalue", d.encodeString(value, limit=100000)) if d.isExpanded(): @@ -1847,7 +1848,7 @@ def qdump__QTextDocument(d, value): def qform__QUrl(): - return "Inline,Separate Window" + return [SimpleFormat, SeparateFormat] def qdump__QUrl(d, value): if d.qtVersion() < 0x050000: @@ -1911,10 +1912,10 @@ def qdump__QUrl(d, value): url += path d.putValue(url, Hex4EncodedLittleEndian) - format = d.currentItemFormat() - if format == 1: + displayFormat = d.currentItemFormat() + if displayFormat == SimpleFormat: d.putDisplay(StopDisplay) - elif format == 2: + elif displayFormat == SeparateFormat: d.putField("editformat", DisplayUtf16String) d.putField("editvalue", url) diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py index 88e60f52281..54a6cc34d71 100644 --- a/share/qtcreator/debugger/stdtypes.py +++ b/share/qtcreator/debugger/stdtypes.py @@ -398,7 +398,8 @@ def qdump__std____debug__stack(d, value): qdump__std__stack(d, value) def qform__std__string(): - return "Latin1 String,Latin1 String in Separate Window,UTF-8 String,UTF-8 String in Separate Window" + return [Latin1StringFormat, SeparateLatin1StringFormat, + Utf8StringFormat, SeparateUtf8StringFormat ] def qdump__std__string(d, value): qdump__std__stringHelper1(d, value, 1, d.currentItemFormat()) @@ -787,7 +788,7 @@ def qdump__string(d, value): qdump__std__string(d, value) def qform__std__wstring(): - return "Inline String,String in Separate Window" + return [SimpleFormat, SeparateFormat] def qdump__std__wstring(d, value): charSize = d.lookupType('wchar_t').sizeof diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 5522b7794b9..c9c49200846 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -576,17 +576,21 @@ void CdbEngine::setupEngine() STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineSetupFailed") notifyEngineSetupFailed(); } - const QString normalFormat = tr("Normal"); - const QStringList stringFormats = QStringList() - << normalFormat << tr("Separate Window"); + + DisplayFormats stringFormats; + stringFormats.append(SimpleFormat); + stringFormats.append(SeparateFormat); + WatchHandler *wh = watchHandler(); wh->addTypeFormats("QString", stringFormats); wh->addTypeFormats("QString *", stringFormats); wh->addTypeFormats("QByteArray", stringFormats); wh->addTypeFormats("QByteArray *", stringFormats); wh->addTypeFormats("std__basic_string", stringFormats); // Python dumper naming convention for std::[w]string - const QStringList imageFormats = QStringList() - << normalFormat << tr("Image"); + + DisplayFormats imageFormats; + imageFormats.append(SimpleFormat); + imageFormats.append(EnhancedFormat); wh->addTypeFormats("QImage", imageFormats); wh->addTypeFormats("QImage *", imageFormats); } diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp index 7b724bad3d0..066323c193d 100644 --- a/src/plugins/debugger/debuggerdialogs.cpp +++ b/src/plugins/debugger/debuggerdialogs.cpp @@ -807,7 +807,7 @@ public: } void addTypeFormats(const QString &type, - const QStringList &typeFormats, int current) + const DisplayFormats &typeFormats, int current) { const int row = m_layout->rowCount(); int column = 0; @@ -815,7 +815,8 @@ public: m_layout->addWidget(new QLabel(type), row, column++); for (int i = -1; i != typeFormats.size(); ++i) { QRadioButton *choice = new QRadioButton(this); - choice->setText(i == -1 ? TypeFormatsDialog::tr("Reset") : typeFormats.at(i)); + choice->setText(i == -1 ? TypeFormatsDialog::tr("Reset") + : WatchHandler::nameForFormat(typeFormats.at(i))); m_layout->addWidget(choice, row, column++); if (i == current) choice->setChecked(true); @@ -868,7 +869,6 @@ private: // /////////////////////////////////////////////////////////////////////// - TypeFormatsDialog::TypeFormatsDialog(QWidget *parent) : QDialog(parent), m_ui(new TypeFormatsDialogUi(this)) { @@ -888,7 +888,7 @@ TypeFormatsDialog::~TypeFormatsDialog() } void TypeFormatsDialog::addTypeFormats(const QString &type0, - const QStringList &typeFormats, int current) + const DisplayFormats &typeFormats, int current) { QString type = type0; type.replace(QLatin1String("__"), QLatin1String("::")); @@ -900,10 +900,5 @@ void TypeFormatsDialog::addTypeFormats(const QString &type0, m_ui->pages[pos]->addTypeFormats(type, typeFormats, current); } -DumperTypeFormats TypeFormatsDialog::typeFormats() const -{ - return DumperTypeFormats(); -} - } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h index eee9ee11c4a..9b0ddc4673b 100644 --- a/src/plugins/debugger/debuggerdialogs.h +++ b/src/plugins/debugger/debuggerdialogs.h @@ -31,6 +31,8 @@ #ifndef DEBUGGER_DIALOGS_H #define DEBUGGER_DIALOGS_H +#include "watchhandler.h" + #include #include @@ -162,8 +164,6 @@ private: QDialogButtonBox *m_box; }; -typedef QHash DumperTypeFormats; - class StartRemoteEngineDialog : public QDialog { Q_OBJECT @@ -191,9 +191,8 @@ public: explicit TypeFormatsDialog(QWidget *parent); ~TypeFormatsDialog(); - void addTypeFormats(const QString &type, const QStringList &formats, + void addTypeFormats(const QString &type, const DisplayFormats &formats, int currentFormat); - DumperTypeFormats typeFormats() const; private: TypeFormatsDialogUi *m_ui; diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index a3177c30e99..cfcc0466c0f 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -40,6 +40,7 @@ #include "simplifytype.h" #include "imageviewer.h" #include "watchutils.h" +#include "cdb/cdbengine.h" // Remove after string freeze #include @@ -239,7 +240,7 @@ public: QSet m_expandedINames; QTimer m_requestUpdateTimer; - DumperTypeFormats m_reportedTypeFormats; + QHash m_reportedTypeFormats; // Type name -> Dumper Formats QHash m_valueCache; }; @@ -943,22 +944,31 @@ static inline QString msgArrayFormat(int n) QString WatchModel::nameForFormat(int format) { switch (format) { + case AutomaticFormat: return QLatin1String(""); + case RawFormat: return tr("Raw Data"); + case SimpleFormat: return CdbEngine::tr("Normal"); // FIXME: String + case EnhancedFormat: return QLatin1String("Enhanced"); // FIXME: String + case SeparateFormat: return CdbEngine::tr("Separate Window"); // FIXME: String + case Latin1StringFormat: return tr("Latin1 String"); + case SeparateLatin1StringFormat: return tr("Latin1 String in Separate Window"); case Utf8StringFormat: return tr("UTF-8 String"); + case SeparateUtf8StringFormat: return tr("UTF-8 String in Separate Window"); case Local8BitStringFormat: return tr("Local 8-Bit String"); case Utf16StringFormat: return tr("UTF-16 String"); case Ucs4StringFormat: return tr("UCS-4 String"); + case Array10Format: return msgArrayFormat(10); case Array100Format: return msgArrayFormat(100); case Array1000Format: return msgArrayFormat(1000); case Array10000Format: return msgArrayFormat(10000); - case SeparateLatin1StringFormat: return tr("Latin1 String in Separate Window"); - case SeparateUtf8StringFormat: return tr("UTF-8 String in Separate Window"); + case DecimalIntegerFormat: return tr("Decimal Integer"); case HexadecimalIntegerFormat: return tr("Hexadecimal Integer"); case BinaryIntegerFormat: return tr("Binary Integer"); case OctalIntegerFormat: return tr("Octal Integer"); + case CompactFloatFormat: return tr("Compact Float"); case ScientificFloatFormat: return tr("Scientific Float"); } @@ -967,9 +977,9 @@ QString WatchModel::nameForFormat(int format) return QString(); } -TypeFormatList WatchItem::typeFormatList() const +DisplayFormats WatchItem::typeFormatList() const { - TypeFormatList formats; + DisplayFormats formats; // Types supported by dumpers: // Hack: Compensate for namespaces. @@ -981,9 +991,7 @@ TypeFormatList WatchItem::typeFormatList() const if (pos >= 0) t.truncate(pos); t.replace(QLatin1Char(':'), QLatin1Char('_')); - QStringList reported = watchModel()->m_reportedTypeFormats.value(t); - for (int i = 0, n = reported.size(); i != n; ++i) - formats.append(TypeFormatItem(reported.at(i), i)); + formats << watchModel()->m_reportedTypeFormats.value(t); // Fixed artificial string and pointer types. if (origaddr || isPointerType(type)) { @@ -1531,6 +1539,11 @@ int WatchHandler::format(const QByteArray &iname) const return result; } +QString WatchHandler::nameForFormat(int format) +{ + return WatchModel::nameForFormat(format); +} + QByteArray WatchHandler::typeFormatRequests() const { QByteArray ba; @@ -1539,7 +1552,7 @@ QByteArray WatchHandler::typeFormatRequests() const while (it.hasNext()) { it.next(); const int format = it.value(); - if (format >= RawFormat && format < ArtificialFormatBase) { + if (format != AutomaticFormat) { ba.append(it.key().toHex()); ba.append('='); ba.append(QByteArray::number(format)); @@ -1559,7 +1572,7 @@ QByteArray WatchHandler::individualFormatRequests() const while (it.hasNext()) { it.next(); const int format = it.value(); - if (format >= RawFormat && format < ArtificialFormatBase) { + if (format != AutomaticFormat) { ba.append(it.key()); ba.append('='); ba.append(QByteArray::number(it.value())); @@ -1588,7 +1601,7 @@ void WatchHandler::appendFormatRequests(DebuggerCommand *cmd) while (it.hasNext()) { it.next(); const int format = it.value(); - if (format >= RawFormat && format < ArtificialFormatBase) + if (format != AutomaticFormat) cmd->arg(it.key(), format); } cmd->endGroup(); @@ -1598,7 +1611,7 @@ void WatchHandler::appendFormatRequests(DebuggerCommand *cmd) while (it2.hasNext()) { it2.next(); const int format = it2.value(); - if (format >= RawFormat && format < ArtificialFormatBase) + if (format != AutomaticFormat) cmd->arg(it2.key(), format); } cmd->endGroup(); @@ -1607,20 +1620,18 @@ void WatchHandler::appendFormatRequests(DebuggerCommand *cmd) void WatchHandler::addDumpers(const GdbMi &dumpers) { foreach (const GdbMi &dumper, dumpers.children()) { - QStringList formats(tr("Raw structure")); - foreach (const QByteArray &format, dumper["formats"].data().split(',')) { - if (format == "Normal") - formats.append(tr("Normal")); - else if (format == "Displayed") - formats.append(tr("Displayed")); - else if (!format.isEmpty()) - formats.append(QString::fromLatin1(format)); + DisplayFormats formats; + formats.append(RawFormat); + QByteArray reportedFormats = dumper["formats"].data(); + foreach (const QByteArray &format, reportedFormats.split(',')) { + if (int f = format.toInt()) + formats.append(DisplayFormat(f)); } addTypeFormats(dumper["type"].data(), formats); } } -void WatchHandler::addTypeFormats(const QByteArray &type, const QStringList &formats) +void WatchHandler::addTypeFormats(const QByteArray &type, const DisplayFormats &formats) { m_model->m_reportedTypeFormats.insert(QLatin1String(stripForFormat(type)), formats); } @@ -1643,16 +1654,6 @@ QString WatchHandler::editorContents() return contents; } -void WatchHandler::setTypeFormats(const DumperTypeFormats &typeFormats) -{ - m_model->m_reportedTypeFormats = typeFormats; -} - -DumperTypeFormats WatchHandler::typeFormats() const -{ - return m_model->m_reportedTypeFormats; -} - void WatchHandler::scheduleResetLocation() { m_model->m_contentsValid = false; @@ -1698,30 +1699,6 @@ QSet WatchHandler::expandedINames() const return m_model->m_expandedINames; } - -//////////////////////////////////////////////////////////////////// -// -// TypeFormatItem/List -// -//////////////////////////////////////////////////////////////////// - -TypeFormatItem::TypeFormatItem(const QString &display, int format) - : display(display), format(format) -{} - -void TypeFormatList::append(int format) -{ - append(TypeFormatItem(WatchModel::nameForFormat(format), format)); -} - -TypeFormatItem TypeFormatList::find(int format) const -{ - for (int i = 0; i != size(); ++i) - if (at(i).format == format) - return at(i); - return TypeFormatItem(); -} - //////////////////////////////////////////////////////////////////// // // WatchItem diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index 971cacda05b..c505853d6da 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -44,23 +44,48 @@ class DebuggerCommand; class DebuggerEngine; class WatchModel; -class TypeFormatItem +// Special formats. Keep in sync with dumper.py. +enum DisplayFormat { -public: - TypeFormatItem() : format(-1) {} - TypeFormatItem(const QString &display, int format); + AutomaticFormat, // Based on type for individuals, dumper default for types. + RawFormat, - QString display; - int format; + SimpleFormat, // Typical simple format (e.g. for QModelIndex row/column) + EnhancedFormat, // Enhanced format (e.g. for QModelIndex with resolved display) + SeparateFormat, // Display in separate Window + + Latin1StringFormat, + SeparateLatin1StringFormat, + Utf8StringFormat, + SeparateUtf8StringFormat, + Local8BitStringFormat, + Utf16StringFormat, + Ucs4StringFormat, + + Array10Format, + Array100Format, + Array1000Format, + Array10000Format, + ArrayPlotFormat, + + CompactMapFormat, + DirectQListStorageFormat, + IndirectQListStorageFormat, + + // Not used in *.py. + BoolTextFormat, + BoolIntegerFormat, + + DecimalIntegerFormat, + HexadecimalIntegerFormat, + BinaryIntegerFormat, + OctalIntegerFormat, + + CompactFloatFormat, + ScientificFloatFormat, }; -class TypeFormatList : public QVector -{ -public: - using QVector::append; - void append(int format); - TypeFormatItem find(int format) const; -}; +typedef QVector DisplayFormats; class WatchItem : public Utils::TreeItem, public WatchData { @@ -91,7 +116,7 @@ private: WatchItem *parentItem() const; const WatchModel *watchModel() const; WatchModel *watchModel(); - TypeFormatList typeFormatList() const; + DisplayFormats typeFormatList() const; bool canFetchMore() const; QVariant data(int column, int role) const; @@ -101,46 +126,6 @@ private: bool fetchTriggered; }; -// Special formats. Keep in sync with dumper.py. -enum DisplayFormat -{ - AutomaticFormat = -1, // Based on type for individuals, dumper default for types. - RawFormat = 0, - - // Values between 1 and 99 refer to dumper provided custom formats. - - // Values between 100 and 199 refer to well-known formats handled in dumpers. - KnownDumperFormatBase = 100, - Latin1StringFormat, - Utf8StringFormat, - Local8BitStringFormat, - Utf16StringFormat, - Ucs4StringFormat, - - Array10Format, - Array100Format, - Array1000Format, - Array10000Format, - - SeparateLatin1StringFormat, - SeparateUtf8StringFormat, - - - // Values above 200 refer to format solely handled in the WatchHandler code - ArtificialFormatBase = 200, - - BoolTextFormat, - BoolIntegerFormat, - - DecimalIntegerFormat, - HexadecimalIntegerFormat, - BinaryIntegerFormat, - OctalIntegerFormat, - - CompactFloatFormat, - ScientificFloatFormat, -}; - class UpdateParameters { public: @@ -150,8 +135,6 @@ public: QByteArray varList; }; -typedef QHash DumperTypeFormats; // Type name -> Dumper Formats - class WatchModelBase : public Utils::TreeModel { Q_OBJECT @@ -201,11 +184,10 @@ public: QByteArray individualFormatRequests() const; int format(const QByteArray &iname) const; + static QString nameForFormat(int format); void addDumpers(const GdbMi &dumpers); - void addTypeFormats(const QByteArray &type, const QStringList &formats); - void setTypeFormats(const DumperTypeFormats &typeFormats); - DumperTypeFormats typeFormats() const; + void addTypeFormats(const QByteArray &type, const DisplayFormats &formats); void setUnprintableBase(int base); static int unprintableBase(); @@ -237,6 +219,6 @@ private: } // namespace Debugger Q_DECLARE_METATYPE(Debugger::Internal::UpdateParameters) -Q_DECLARE_METATYPE(Debugger::Internal::TypeFormatList) +Q_DECLARE_METATYPE(Debugger::Internal::DisplayFormats) #endif // DEBUGGER_WATCHHANDLER_H diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index c82a3fa5b93..c8f145fb29a 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -554,12 +554,10 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi) const QModelIndex mi2 = mi.sibling(mi.row(), 2); const QString type = mi2.data().toString(); - const TypeFormatList alternativeFormats = - mi.data(LocalsTypeFormatListRole).value(); - int typeFormat = - mi.data(LocalsTypeFormatRole).toInt(); - const int individualFormat = - mi.data(LocalsIndividualFormatRole).toInt(); + const DisplayFormats alternativeFormats = + mi.data(LocalsTypeFormatListRole).value(); + const int typeFormat = mi.data(LocalsTypeFormatRole).toInt(); + const int individualFormat = mi.data(LocalsIndividualFormatRole).toInt(); const int unprintableBase = WatchHandler::unprintableBase(); QAction *showUnprintableUnicode = 0; @@ -595,7 +593,7 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi) dummy->setEnabled(false); QString msg = (individualFormat == AutomaticFormat && typeFormat != AutomaticFormat) ? tr("Use Format for Type (Currently %1)") - .arg(alternativeFormats.find(typeFormat).display) + .arg(WatchHandler::nameForFormat(typeFormat)) : tr("Use Display Format Based on Type") + QLatin1Char(' '); QAction *clearIndividualFormatAction = formatMenu->addAction(spacer + msg); @@ -608,8 +606,8 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi) }); for (int i = 0; i != alternativeFormats.size(); ++i) { - const QString display = spacer + alternativeFormats.at(i).display; - const int format = alternativeFormats.at(i).format; + const int format = alternativeFormats.at(i); + const QString display = spacer + WatchHandler::nameForFormat(format); QAction *act = new QAction(display, formatMenu); act->setCheckable(true); act->setChecked(format == individualFormat); @@ -633,9 +631,9 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi) }); for (int i = 0; i != alternativeFormats.size(); ++i) { - const QString display = spacer + alternativeFormats.at(i).display; + const int format = alternativeFormats.at(i); + const QString display = spacer + WatchHandler::nameForFormat(format); QAction *act = new QAction(display, formatMenu); - const int format = alternativeFormats.at(i).format; act->setCheckable(true); act->setChecked(format == typeFormat); formatMenu->addAction(act); From c1fd41c5b02b709da315ba052a5069a046a4c834 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 20 Mar 2015 14:44:02 +0100 Subject: [PATCH 34/37] Debugger: Replace empty tooltips by a "No valid expression" message Task-number: QTCREATORBUG-13774 Change-Id: I2c14a50c1457ca4f24843df2691fda83a790931b Reviewed-by: Christian Stenger Reviewed-by: Orgad Shaneh --- .../debugger/debuggertooltipmanager.cpp | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/plugins/debugger/debuggertooltipmanager.cpp b/src/plugins/debugger/debuggertooltipmanager.cpp index a91c7409079..07028a144d0 100644 --- a/src/plugins/debugger/debuggertooltipmanager.cpp +++ b/src/plugins/debugger/debuggertooltipmanager.cpp @@ -831,8 +831,9 @@ void DebuggerToolTipHolder::setState(DebuggerTooltipState newState) bool ok = (state == New && newState == PendingUnshown) || (state == PendingUnshown && newState == PendingShown) || (state == PendingShown && newState == Acquired) - || (state == Acquired && (newState == Released)) - || (state == Released && (newState == Acquired)); + || (state == Acquired && newState == Released) + || (state == Acquired && newState == Acquired) + || (state == Released && newState == Acquired); // FIXME: These happen when a tooltip is re-used in findOrCreate. ok = ok @@ -856,9 +857,22 @@ void DebuggerToolTipHolder::destroy() void DebuggerToolTipHolder::releaseEngine() { + DEBUG("RELEASE ENGINE: STATE " << state); if (state == Released) return; - DEBUG("RELEASE ENGINE: STATE " << state); + + if (state == PendingShown) { + // This happens after hovering over something that looks roughly like + // a valid expression but can't be resolved by the debugger backend. + // (Out of scope items, keywords, ...) + ToolTip::show(context.mousePosition, + DebuggerToolTipManager::tr("No valid expression"), + Internal::mainWindow()); + QTC_ASSERT(widget, return); + widget->deleteLater(); + return; + } + setState(Released); QTC_ASSERT(widget, return); From c097867f3cc0c04e40a96a86dd41848c4a21eb13 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 23 Mar 2015 13:17:56 +0100 Subject: [PATCH 35/37] Debugger: Prevent endless recursion on output of broken dumpers That fixes a recent regression. If a dumper announces to have children, but doesn't produce any we re-tried for ever. This is reproducible e.g. by putting an 'return' before any 'if d.isExpanded():' stanza in a dumper and triggering that dumper. Keep track of expanded items, and only ask for children once per location change. Change-Id: I349fdc7380444eb3ac9fa2fae098a3f3e7658195 Reviewed-by: Christian Stenger --- src/plugins/debugger/watchhandler.cpp | 26 ++++++++++++-------------- src/plugins/debugger/watchhandler.h | 3 +-- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index cfcc0466c0f..8b67ee91d4f 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -238,6 +238,7 @@ public: SeparatedView *m_separatedView; // Not owned. QSet m_expandedINames; + QSet m_fetchTriggered; QTimer m_requestUpdateTimer; QHash m_reportedTypeFormats; // Type name -> Dumper Formats @@ -607,23 +608,25 @@ bool WatchItem::canFetchMore() const { if (!wantsChildren) return false; - if (!watchModel()) + const WatchModel *model = watchModel(); + if (!model) return false; - if (!watchModel()->m_contentsValid && !isInspect()) + if (!model->m_contentsValid && !isInspect()) return false; - return !fetchTriggered; + return !model->m_fetchTriggered.contains(iname); } void WatchItem::fetchMore() { - if (fetchTriggered) + WatchModel *model = watchModel(); + if (model->m_fetchTriggered.contains(iname)) return; - watchModel()->m_expandedINames.insert(iname); - fetchTriggered = true; + model->m_expandedINames.insert(iname); + model->m_fetchTriggered.insert(iname); if (children().isEmpty()) { setChildrenNeeded(); - watchModel()->m_engine->updateWatchItem(this); + model->m_engine->updateWatchItem(this); } } @@ -1656,6 +1659,7 @@ QString WatchHandler::editorContents() void WatchHandler::scheduleResetLocation() { + m_model->m_fetchTriggered.clear(); m_model->m_contentsValid = false; m_model->m_resetLocationScheduled = true; } @@ -1705,24 +1709,18 @@ QSet WatchHandler::expandedINames() const // //////////////////////////////////////////////////////////////////// -WatchItem::WatchItem() - : fetchTriggered(false) -{} - WatchItem::WatchItem(const QByteArray &i, const QString &n) { - fetchTriggered = false; iname = i; name = n; } WatchItem::WatchItem(const WatchData &data) - : WatchData(data), fetchTriggered(false) + : WatchData(data) { } WatchItem::WatchItem(const GdbMi &data) - : fetchTriggered(false) { iname = data["iname"].data(); diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index c505853d6da..5f7a6cb128e 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -90,7 +90,7 @@ typedef QVector DisplayFormats; class WatchItem : public Utils::TreeItem, public WatchData { public: - WatchItem(); + WatchItem() {} WatchItem(const QByteArray &i, const QString &n); explicit WatchItem(const WatchData &data); explicit WatchItem(const GdbMi &data); @@ -123,7 +123,6 @@ private: Qt::ItemFlags flags(int column) const; void parseWatchData(const GdbMi &input); - bool fetchTriggered; }; class UpdateParameters From da67c7c6c9723e8426ebeaf73c120d9090a576d6 Mon Sep 17 00:00:00 2001 From: Lorenz Haas Date: Sat, 21 Mar 2015 20:10:12 +0100 Subject: [PATCH 36/37] C++: Fix crash when accessing an empty list in Rewrite Task-number: QTCREATORBUG-14163 Change-Id: I57eca70466bbf5d28d16afafc07ab243206fcff5 Reviewed-by: Orgad Shaneh --- src/libs/cplusplus/CppRewriter.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libs/cplusplus/CppRewriter.cpp b/src/libs/cplusplus/CppRewriter.cpp index 3e74e9b4a25..63eadd912c5 100644 --- a/src/libs/cplusplus/CppRewriter.cpp +++ b/src/libs/cplusplus/CppRewriter.cpp @@ -63,8 +63,10 @@ public: { TypeVisitor::accept(ty.type()); unsigned flags = ty.flags(); - flags |= temps.back().flags(); - temps.back().setFlags(flags); + if (!temps.isEmpty()) { + flags |= temps.back().flags(); + temps.back().setFlags(flags); + } } public: @@ -73,7 +75,7 @@ public: FullySpecifiedType operator()(const FullySpecifiedType &ty) { accept(ty); - return temps.takeLast(); + return (!temps.isEmpty()) ? temps.takeLast() : ty; } virtual void visit(UndefinedType *) @@ -241,7 +243,7 @@ public: return 0; accept(name); - return temps.takeLast(); + return (!temps.isEmpty()) ? temps.takeLast() : name; } virtual void visit(const QualifiedNameId *name) From 044eeacde5ee1add8b06a8a53b86fd5c6991d488 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Wed, 4 Mar 2015 09:25:08 +0200 Subject: [PATCH 37/37] Load only tested plugins when invoked with -test By default, a clean settings path is used for test environment. All the default plugins are loaded, although they're not needed. This change significantly improves loading time for tests. Change-Id: I24254f3e538e3f0e6d233d0989738dc1ce238209 Reviewed-by: Leena Miettinen Reviewed-by: Eike Ziller --- doc/api/plugin-metadata.qdoc | 17 +++++++- qbs/imports/QtcPlugin.qbs | 1 + qbs/modules/pluginjson/pluginjson.qbs | 4 ++ src/libs/extensionsystem/optionsparser.cpp | 1 + .../extensionsystem/plugindetailsview.cpp | 10 ++++- src/libs/extensionsystem/pluginmanager.cpp | 40 ++++++++++++++++++- src/libs/extensionsystem/pluginmanager_p.h | 1 + src/libs/extensionsystem/pluginspec.cpp | 7 +++- src/libs/extensionsystem/pluginspec.h | 3 +- src/plugins/cppeditor/cppeditor.qbs | 4 ++ .../cppeditor/cppeditor_dependencies.pri | 2 + src/plugins/cpptools/cpptools.qbs | 5 +++ .../cpptools/cpptools_dependencies.pri | 3 ++ src/qtcreatorplugin.pri | 4 ++ 14 files changed, 95 insertions(+), 7 deletions(-) diff --git a/doc/api/plugin-metadata.qdoc b/doc/api/plugin-metadata.qdoc index 4477ecb66a8..4675202ec90 100644 --- a/doc/api/plugin-metadata.qdoc +++ b/doc/api/plugin-metadata.qdoc @@ -199,8 +199,9 @@ \row \li Type \li String - \li Optional. Value \c Required or \c Optional. Defines if the dependency is - a hard requirement or optional. Defaults to \c{Required}. + \li Optional. Value \c Required, \c Optional, or \c Test. Defines if the dependency is + a hard requirement, optional, or required for running the plugin's tests. + Defaults to \c{Required}. \endtable \section3 Optional Dependencies @@ -223,6 +224,18 @@ ExtensionSystem::PluginManager::getObjectByClassName(), and use QMetaObject functions to call functions on it. + \section3 Test Dependencies + + When the user runs the application with the \c{-test} command line argument, only + the specified plugins and their dependencies are loaded. This is done in order to + speed up the execution of tests by avoiding the loading of unneeded plugins. + + A plugin can specify additional dependencies that are required for running its + tests, but not for its normal execution, by declaring dependencies with + \c {"Type" : "Test"}. Test dependencies are force loaded, and do not affect load order. + + This type of dependency is not transitive. + \section2 Command Line Arguments Plugins can register command line arguments that the user can give diff --git a/qbs/imports/QtcPlugin.qbs b/qbs/imports/QtcPlugin.qbs index 713e388c3ae..9d1e99d90ec 100644 --- a/qbs/imports/QtcPlugin.qbs +++ b/qbs/imports/QtcPlugin.qbs @@ -8,6 +8,7 @@ QtcProduct { property var pluginJsonReplacements property var pluginRecommends: [] + property var pluginTestDepends: [] property string minimumQtVersion: "5.3.1" condition: QtcFunctions.versionIsAtLeast(Qt.core.version, minimumQtVersion) diff --git a/qbs/modules/pluginjson/pluginjson.qbs b/qbs/modules/pluginjson/pluginjson.qbs index 3a2515ae139..8bbfe754e73 100644 --- a/qbs/modules/pluginjson/pluginjson.qbs +++ b/qbs/modules/pluginjson/pluginjson.qbs @@ -36,6 +36,7 @@ Module { } } cmd.plugin_recommends = product.pluginRecommends + cmd.plugin_test_depends = product.pluginTestDepends cmd.sourceCode = function() { var i; @@ -57,6 +58,9 @@ Module { for (i in plugin_recommends) { deplist.push(" { \"Name\" : \"" + plugin_recommends[i] + "\", \"Version\" : \"" + project.qtcreator_version + "\", \"Type\" : \"optional\" }"); } + for (i in plugin_test_depends) { + deplist.push(" { \"Name\" : \"" + plugin_test_depends[i] + "\", \"Version\" : \"" + project.qtcreator_version + "\", \"Type\" : \"test\" }"); + } deplist = deplist.join(",\n") vars['dependencyList'] = "\"Dependencies\" : [\n" + deplist + "\n ]"; for (i in vars) { diff --git a/src/libs/extensionsystem/optionsparser.cpp b/src/libs/extensionsystem/optionsparser.cpp index 9882c3121fe..8d50d722e75 100644 --- a/src/libs/extensionsystem/optionsparser.cpp +++ b/src/libs/extensionsystem/optionsparser.cpp @@ -91,6 +91,7 @@ bool OptionsParser::parse() } if (m_isDependencyRefreshNeeded) m_pmPrivate->resolveDependencies(); + m_pmPrivate->enableOnlyTestedSpecs(); return !m_hasError; } diff --git a/src/libs/extensionsystem/plugindetailsview.cpp b/src/libs/extensionsystem/plugindetailsview.cpp index 35e64f4ee63..310ef48b9d0 100644 --- a/src/libs/extensionsystem/plugindetailsview.cpp +++ b/src/libs/extensionsystem/plugindetailsview.cpp @@ -98,8 +98,16 @@ void PluginDetailsView::update(PluginSpec *spec) QString depString = dep.name; depString += QLatin1String(" ("); depString += dep.version; - if (dep.type == PluginDependency::Optional) + switch (dep.type) { + case PluginDependency::Required: + break; + case PluginDependency::Optional: depString += QLatin1String(", optional"); + break; + case PluginDependency::Test: + depString += QLatin1String(", test"); + break; + } depString += QLatin1Char(')'); depStrings.append(depString); } diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index 5f2785236d0..d34db47d255 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -1255,7 +1255,14 @@ bool PluginManagerPrivate::loadQueue(PluginSpec *spec, QList &queu } // add dependencies - foreach (PluginSpec *depSpec, spec->dependencySpecs()) { + QHashIterator it(spec->dependencySpecs()); + while (it.hasNext()) { + it.next(); + // Skip test dependencies since they are not real dependencies but just force-loaded + // plugins when running tests + if (it.key().type == PluginDependency::Test) + continue; + PluginSpec *depSpec = it.value(); if (!loadQueue(depSpec, queue, circularityCheckQueue)) { spec->d->hasError = true; spec->d->errorString = @@ -1299,7 +1306,7 @@ void PluginManagerPrivate::loadPlugin(PluginSpec *spec, PluginSpec::State destSt QHashIterator it(spec->dependencySpecs()); while (it.hasNext()) { it.next(); - if (it.key().type == PluginDependency::Optional) + if (it.key().type != PluginDependency::Required) continue; PluginSpec *depSpec = it.value(); if (depSpec->state() != destState) { @@ -1423,6 +1430,35 @@ void PluginManagerPrivate::resolveDependencies() } } +void PluginManagerPrivate::enableOnlyTestedSpecs() +{ + if (testSpecs.isEmpty()) + return; + + QList specsForTests; + foreach (const TestSpec &testSpec, testSpecs) { + QList circularityCheckQueue; + loadQueue(testSpec.pluginSpec, specsForTests, circularityCheckQueue); + // add plugins that must be force loaded when running tests for the plugin + // (aka "test dependencies") + QHashIterator it(testSpec.pluginSpec->dependencySpecs()); + while (it.hasNext()) { + it.next(); + if (it.key().type != PluginDependency::Test) + continue; + PluginSpec *depSpec = it.value(); + circularityCheckQueue.clear(); + loadQueue(depSpec, specsForTests, circularityCheckQueue); + } + } + foreach (PluginSpec *spec, pluginSpecs) + spec->setForceDisabled(true); + foreach (PluginSpec *spec, specsForTests) { + spec->setForceDisabled(false); + spec->setForceEnabled(true); + } +} + // Look in argument descriptions of the specs for the option. PluginSpec *PluginManagerPrivate::pluginForOption(const QString &option, bool *requiresArgument) const { diff --git a/src/libs/extensionsystem/pluginmanager_p.h b/src/libs/extensionsystem/pluginmanager_p.h index 0400ceb0fc2..f219d5c0dae 100644 --- a/src/libs/extensionsystem/pluginmanager_p.h +++ b/src/libs/extensionsystem/pluginmanager_p.h @@ -73,6 +73,7 @@ public: QList loadQueue(); void loadPlugin(PluginSpec *spec, PluginSpec::State destState); void resolveDependencies(); + void enableOnlyTestedSpecs(); void initProfiling(); void profilingSummary() const; void profilingReport(const char *what, const PluginSpec *spec = 0); diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp index 9d470cd5b20..858dfd9510e 100644 --- a/src/libs/extensionsystem/pluginspec.cpp +++ b/src/libs/extensionsystem/pluginspec.cpp @@ -86,6 +86,8 @@ Dependency is not necessarily needed. You need to make sure that the plugin is able to load without this dependency installed, so for example you may not link to the dependency's library. + \value Test + Dependency needs to be force-loaded for running tests of the plugin. */ /*! @@ -471,6 +473,7 @@ namespace { const char DEPENDENCY_TYPE[] = "Type"; const char DEPENDENCY_TYPE_SOFT[] = "optional"; const char DEPENDENCY_TYPE_HARD[] = "required"; + const char DEPENDENCY_TYPE_TEST[] = "test"; const char ARGUMENTS[] = "Arguments"; const char ARGUMENT_NAME[] = "Name"; const char ARGUMENT_PARAMETER[] = "Parameter"; @@ -763,6 +766,8 @@ bool PluginSpecPrivate::readMetaData(const QJsonObject &metaData) dep.type = PluginDependency::Required; } else if (typeValue.toLower() == QLatin1String(DEPENDENCY_TYPE_SOFT)) { dep.type = PluginDependency::Optional; + } else if (typeValue.toLower() == QLatin1String(DEPENDENCY_TYPE_TEST)) { + dep.type = PluginDependency::Test; } else { return reportError(tr("Dependency: \"%1\" must be \"%2\" or \"%3\" (is \"%4\")") .arg(QLatin1String(DEPENDENCY_TYPE), @@ -917,7 +922,7 @@ void PluginSpecPrivate::disableIndirectlyIfDependencyDisabled() QHashIterator it(dependencySpecs); while (it.hasNext()) { it.next(); - if (it.key().type == PluginDependency::Optional) + if (it.key().type != PluginDependency::Required) continue; PluginSpec *dependencySpec = it.value(); if (!dependencySpec->isEffectivelyEnabled()) { diff --git a/src/libs/extensionsystem/pluginspec.h b/src/libs/extensionsystem/pluginspec.h index 9272403e9aa..56860135a97 100644 --- a/src/libs/extensionsystem/pluginspec.h +++ b/src/libs/extensionsystem/pluginspec.h @@ -55,7 +55,8 @@ struct EXTENSIONSYSTEM_EXPORT PluginDependency { enum Type { Required, - Optional + Optional, + Test }; PluginDependency() : type(Required) {} diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs index cb1248508e1..243fb637742 100644 --- a/src/plugins/cppeditor/cppeditor.qbs +++ b/src/plugins/cppeditor/cppeditor.qbs @@ -16,6 +16,10 @@ QtcPlugin { Depends { name: "app_version_header" } + pluginTestDepends: [ + "QmakeProjectManager", + ] + files: [ "cppautocompleter.cpp", "cppautocompleter.h", "cppcanonicalsymbol.cpp", "cppcanonicalsymbol.h", diff --git a/src/plugins/cppeditor/cppeditor_dependencies.pri b/src/plugins/cppeditor/cppeditor_dependencies.pri index 2b90476fc37..751d75224ac 100644 --- a/src/plugins/cppeditor/cppeditor_dependencies.pri +++ b/src/plugins/cppeditor/cppeditor_dependencies.pri @@ -9,3 +9,5 @@ QTC_PLUGIN_DEPENDS += \ coreplugin \ cpptools \ projectexplorer +QTC_TEST_DEPENDS += \ + qmakeprojectmanager diff --git a/src/plugins/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs index 9d8e6c7d85f..72b68b9a9a1 100644 --- a/src/plugins/cpptools/cpptools.qbs +++ b/src/plugins/cpptools/cpptools.qbs @@ -14,6 +14,11 @@ QtcPlugin { Depends { name: "ProjectExplorer" } Depends { name: "app_version_header" } + pluginTestDepends: [ + "CppEditor", + "QmakeProjectManager", + ] + cpp.defines: base Properties { condition: qbs.toolchain.contains("msvc") diff --git a/src/plugins/cpptools/cpptools_dependencies.pri b/src/plugins/cpptools/cpptools_dependencies.pri index 705d6334f37..27d0f90d681 100644 --- a/src/plugins/cpptools/cpptools_dependencies.pri +++ b/src/plugins/cpptools/cpptools_dependencies.pri @@ -8,3 +8,6 @@ QTC_PLUGIN_DEPENDS += \ coreplugin \ projectexplorer \ texteditor +QTC_TEST_DEPENDS += \ + cppeditor \ + qmakeprojectmanager diff --git a/src/qtcreatorplugin.pri b/src/qtcreatorplugin.pri index 5381b6de835..0f57dfc88a9 100644 --- a/src/qtcreatorplugin.pri +++ b/src/qtcreatorplugin.pri @@ -10,6 +10,7 @@ exists($$depfile) { TARGET = $$QTC_PLUGIN_NAME plugin_deps = $$QTC_PLUGIN_DEPENDS +plugin_test_deps = $$QTC_TEST_DEPENDS plugin_recmds = $$QTC_PLUGIN_RECOMMENDS include(../qtcreator.pri) @@ -36,6 +37,9 @@ for(dep, plugin_deps) { for(dep, plugin_recmds) { dependencyList += " { \"Name\" : \"$$dependencyName($$dep)\", \"Version\" : \"$$QTCREATOR_VERSION\", \"Type\" : \"optional\" }" } +for(dep, plugin_test_deps) { + dependencyList += " { \"Name\" : \"$$dependencyName($$dep)\", \"Version\" : \"$$QTCREATOR_VERSION\", \"Type\" : \"test\" }" +} dependencyList = $$join(dependencyList, ",$$escape_expand(\\n)") dependencyList = "\"Dependencies\" : [$$escape_expand(\\n)$$dependencyList$$escape_expand(\\n) ]"