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/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. 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 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. 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/share/qtcreator/debugger/creatortypes.py b/share/qtcreator/debugger/creatortypes.py index fc5f9cccc13..d8745366b5d 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/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/share/qtcreator/themes/dark.creatortheme b/share/qtcreator/themes/dark.creatortheme index 016b2aa7e61..cba5d60dc4d 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 8c2e86d65ed..a2a7ec952e4 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/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) 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/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 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/libs/utils/theme/theme.h b/src/libs/utils/theme/theme.h index 46057b78688..8807878ce4d 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/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/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/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)); 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/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); } 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/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs index 5b1e536dccb..bc2a8ea3a73 100644 --- a/src/plugins/cppeditor/cppeditor.qbs +++ b/src/plugins/cppeditor/cppeditor.qbs @@ -15,6 +15,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 8f1da424e1d..c9a690b079e 100644 --- a/src/plugins/cppeditor/cppeditor_dependencies.pri +++ b/src/plugins/cppeditor/cppeditor_dependencies.pri @@ -8,3 +8,5 @@ QTC_PLUGIN_DEPENDS += \ coreplugin \ cpptools \ projectexplorer +QTC_TEST_DEPENDS += \ + qmakeprojectmanager 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/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs index 306b3c4e1a8..f5ffb85f46e 100644 --- a/src/plugins/cpptools/cpptools.qbs +++ b/src/plugins/cpptools/cpptools.qbs @@ -13,6 +13,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 0b439171519..9ff54010ad7 100644 --- a/src/plugins/cpptools/cpptools_dependencies.pri +++ b/src/plugins/cpptools/cpptools_dependencies.pri @@ -7,3 +7,6 @@ QTC_PLUGIN_DEPENDS += \ coreplugin \ projectexplorer \ texteditor +QTC_TEST_DEPENDS += \ + cppeditor \ + qmakeprojectmanager diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 657972e8994..c9c49200846 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); @@ -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); } @@ -974,46 +978,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); } } @@ -1165,8 +1170,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()); @@ -1269,7 +1274,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 +1876,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/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/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/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index aff64de8f8d..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); @@ -919,6 +911,7 @@ public slots: exp = removeObviousSideEffects(exp); else exp = fixCppExpression(exp); + exp = exp.trimmed(); if (exp.isEmpty()) return; currentEngine()->watchHandler()->watchVariable(exp); @@ -1822,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) @@ -2048,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); @@ -3196,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() diff --git a/src/plugins/debugger/debuggertooltipmanager.cpp b/src/plugins/debugger/debuggertooltipmanager.cpp index fc1bd3626b5..07028a144d0 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))); @@ -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); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index d4ecc5fd908..fa6810d8400 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3724,27 +3724,14 @@ 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); } -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. @@ -3759,14 +3746,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); } @@ -4711,7 +4698,6 @@ void addGdbOptionPages(QList *opts) void GdbEngine::updateLocalsPython(const UpdateParameters ¶ms) { - //m_pendingWatchRequests = 0; m_pendingBreakpointRequests = 0; DebuggerCommand cmd("showData"); @@ -4805,32 +4791,31 @@ 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); - //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 bfa310770a8..dff3c80d3ef 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,7 @@ 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 7e2aecc4697..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(); } } @@ -661,12 +657,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 +670,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 +682,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,38 +731,34 @@ 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); if (append) { - WatchData objWatch; QString name = obj.idString(); if (name.isEmpty()) name = obj.className(); if (name.isEmpty()) - return list; + 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(); - list.append(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 @@ -784,44 +773,38 @@ 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 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(); - - list.append(propertiesWatch); + QByteArray iname = objIname + ".[properties]"; + auto propertiesWatch = new WatchItem(iname, tr("Properties")); + 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; - 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); - list.append(propertyWatch); + auto propertyWatch = new WatchItem(buildIName(iname, propertyName), propertyName); + 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); } + + m_debuggerEngine->watchHandler()->insertItem(propertiesWatch); } // 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..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, @@ -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..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(); @@ -1553,36 +1549,32 @@ 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; - 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()); - locals << 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); } } if (!handlesToLookup.isEmpty()) d->lookup(handlesToLookup); - - if (!locals.isEmpty()) - d->engine->watchHandler()->insertDataList(locals); } QmlJS::ConsoleItem *constructLogItemTree(QmlJS::ConsoleItem *parent, @@ -1640,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); @@ -1662,32 +1654,29 @@ 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); + 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()); } - watchDataList << data << createWatchDataList(&data, body.properties, refsVal); + watchHandler->insertItem(item); + createWatchDataList(item, body.properties, refsVal); } //Insert the newly evaluated expression to the Watchers Window - watchHandler->insertDataList(watchDataList); } } } @@ -1704,7 +1693,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,63 +1701,59 @@ 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 - const WatchData *parent = watchHandler->findData(prepend); - watchDataList << createWatchDataList(parent, bodyObjectData.properties, refsVal); + // Data for expanded local/watch. + // Could be an object or function. + 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()); - watchDataList << data; + d->engine->watchHandler()->insertItem(item); } } - - watchHandler->insertDataList(watchDataList); } -QList QmlV8DebuggerClient::createWatchDataList(const WatchData *parent, +void QmlV8DebuggerClient::createWatchDataList(const WatchItem *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; - 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()); - watchDataList << 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); } } - 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..ae78443e77a 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 WatchItem *parent, + const QVariantList &properties, + const QVariant &refsVal); void highlightExceptionCode(int lineNumber, const QString &filePath, const QString &errorMessage); 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/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/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp index d010768c4fa..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")) { @@ -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 << "wantsChildren=\"" << (wantsChildren ? "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) @@ -613,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 b00de932205..7191e58637a 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) { wantsChildren = c; if (!c) setChildrenUnneeded(); } bool isLocal() const { return iname.startsWith("local."); } bool isWatcher() const { return iname.startsWith("watch."); } @@ -130,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 @@ -139,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 107d59fc05a..8b67ee91d4f 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 @@ -102,6 +103,11 @@ static QByteArray stripForFormat(const QByteArray &ba) return res; } +static void saveWatchers() +{ + setSessionValue("Watchers", WatchHandler::watchedExpressions()); +} + /////////////////////////////////////////////////////////////////////// // // SeparatedView @@ -110,8 +116,6 @@ static QByteArray stripForFormat(const QByteArray &ba) class SeparatedView : public QTabWidget { - Q_OBJECT - public: SeparatedView() : QTabWidget(Internal::mainWindow()) { @@ -196,30 +200,33 @@ public: class WatchModel : public WatchModelBase { public: - explicit WatchModel(WatchHandler *handler); + WatchModel(WatchHandler *handler, DebuggerEngine *engine); 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); + 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. @@ -228,28 +235,25 @@ public: WatchItem *m_returnRoot; // Not owned. WatchItem *m_tooltipRoot; // Not owned. + SeparatedView *m_separatedView; // Not owned. + QSet m_expandedINames; + QSet m_fetchTriggered; 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_reportedTypeFormats; // Type name -> Dumper Formats + QHash m_valueCache; }; -WatchModel::WatchModel(WatchHandler *handler) - : m_handler(handler) +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"))); @@ -281,11 +285,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); @@ -293,31 +292,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); @@ -346,7 +335,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); } @@ -498,64 +487,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 +561,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 +578,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,25 +606,27 @@ QVariant WatchItem::editValue() const bool WatchItem::canFetchMore() const { - if (!d.hasChildren) + if (!wantsChildren) return false; - if (!watchModel()) + const WatchModel *model = watchModel(); + if (!model) return false; - if (!watchModel()->contentIsValid() && !d.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(d.iname); - fetchTriggered = true; + model->m_expandedINames.insert(iname); + model->m_fetchTriggered.insert(iname); if (children().isEmpty()) { - d.setChildrenNeeded(); - watchModel()->engine()->updateWatchData(d); + setChildrenNeeded(); + model->m_engine->updateWatchItem(this); } } @@ -654,34 +644,25 @@ 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); -} - -bool WatchModel::contentIsValid() const -{ - // FIXME: - // inspector doesn't follow normal beginCycle()/endCycle() - //if (m_type == InspectWatch) - // return true; - return m_handler->m_contentsValid; + return theTypeFormats.value(stripForFormat(type), AutomaticFormat); } 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 +670,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 +690,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 +714,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()->m_contentsValid && !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 +733,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 +748,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 +767,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,52 +777,52 @@ 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; - return watchModel()->engine()->breakHandler()->findWatchpoint(bp) != 0; + bp.address = address; + return watchModel()->m_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); - return watchModel()->engine()->breakHandler()->findWatchpoint(bp) != 0; + bp.address = pointerValue(value); + return watchModel()->m_engine->breakHandler()->findWatchpoint(bp) != 0; } return false; @@ -871,45 +852,44 @@ 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: switch (idx.column()) { case 0: { - m_handler->watchExpression(value.toString()); + m_handler->watchExpression(value.toString().trimmed()); break; } case 1: // Change value - engine()->assignValueInDebugger(&data, item->expression(), value); + m_engine->assignValueInDebugger(item, item->expression(), value); break; case 2: // TODO: Implement change type. - engine()->assignValueInDebugger(&data, item->expression(), value); + m_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); + setFormat(item->type, value.toInt()); + m_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; + m_engine->updateWatchItem(item); break; } } @@ -921,7 +901,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(); @@ -931,29 +911,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; @@ -967,22 +947,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"); } @@ -991,26 +980,24 @@ QString WatchModel::nameForFormat(int format) return QString(); } -TypeFormatList WatchModel::typeFormatList(const WatchData &data) const +DisplayFormats WatchItem::typeFormatList() const { - TypeFormatList formats; + DisplayFormats 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); - for (int i = 0, n = reported.size(); i != n; ++i) - formats.append(TypeFormatItem(reported.at(i), i)); + t.truncate(pos); + t.replace(QLatin1Char(':'), QLatin1Char('_')); + formats << watchModel()->m_reportedTypeFormats.value(t); // 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 +1010,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 +1023,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 +1080,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,37 +1094,40 @@ static int findInsertPosition(const QVector &list, const WatchItem * return it - list.begin(); } +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) { + 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); + } +} + int WatchItem::requestedFormat() const { - int format = theIndividualFormats.value(d.iname, AutomaticFormat); + int format = theIndividualFormats.value(iname, AutomaticFormat); if (format == AutomaticFormat) - format = theTypeFormats.value(stripForFormat(d.type), AutomaticFormat); + format = theTypeFormats.value(stripForFormat(type), AutomaticFormat); return format; } -void WatchItem::showInEditorHelper(QString *contents, int depth) 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); -} - -void WatchModel::setCurrentItem(const QByteArray &iname) -{ - if (WatchItem *item = findItem(iname)) { - QModelIndex idx = indexFromItem(item); - emit currentIndexRequested(idx); - } -} - /////////////////////////////////////////////////////////////////////// // // WatchHandler @@ -1160,18 +1136,11 @@ 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_separatedView = new SeparatedView; + m_model = new WatchModel(this, engine); } WatchHandler::~WatchHandler() { - delete m_separatedView; - m_separatedView = 0; // Do it manually to prevent calling back in model destructors // after m_cache is destroyed. delete m_model; @@ -1185,7 +1154,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 +1164,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,17 +1192,6 @@ void WatchModel::reexpandItems() } } -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); @@ -1271,7 +1204,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; }); } @@ -1283,13 +1216,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(); @@ -1304,7 +1237,7 @@ void WatchHandler::purgeOutdatedItems(const QSet &inames) m_model->layoutChanged(); m_model->reexpandItems(); - m_contentsValid = true; + m_model->m_contentsValid = true; updateWatchersWindow(); } @@ -1313,8 +1246,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); @@ -1336,19 +1269,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); + if (m_model->m_engine->state() == DebuggerNotReady) { + item->setAllUnneeded(); + item->setValue(QString(QLatin1Char(' '))); + m_model->insertItem(item); } else { - m_engine->updateWatchData(data); + m_model->m_engine->updateWatchItem(item); } updateWatchersWindow(); } @@ -1377,7 +1309,7 @@ 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) { @@ -1490,12 +1422,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()); @@ -1514,7 +1441,7 @@ void WatchHandler::loadFormats() } } -void WatchHandler::saveFormats() +static void saveFormats() { QMap formats; QHashIterator it(theTypeFormats); @@ -1555,7 +1482,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 @@ -1563,37 +1490,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)) @@ -1601,12 +1520,7 @@ const WatchData *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) @@ -1614,20 +1528,25 @@ void WatchHandler::setFormat(const QByteArray &type0, int format) else theTypeFormats[type] = format; saveFormats(); - m_model->reinsertAllData(); + reinsertAllData(); } 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; } +QString WatchHandler::nameForFormat(int format) +{ + return WatchModel::nameForFormat(format); +} + QByteArray WatchHandler::typeFormatRequests() const { QByteArray ba; @@ -1636,7 +1555,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)); @@ -1656,7 +1575,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())); @@ -1685,7 +1604,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(); @@ -1695,7 +1614,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(); @@ -1704,71 +1623,58 @@ 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); } +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; } -void WatchHandler::setTypeFormats(const DumperTypeFormats &typeFormats) -{ - m_model->m_reportedTypeFormats = typeFormats; -} - -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; - m_resetLocationScheduled = true; + m_model->m_fetchTriggered.clear(); + 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() @@ -1797,67 +1703,37 @@ 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 // //////////////////////////////////////////////////////////////////// -WatchItem::WatchItem() - : fetchTriggered(false) -{} - 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) { } 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 @@ -1878,8 +1754,9 @@ WatchModel *WatchItem::watchModel() void WatchItem::parseWatchData(const GdbMi &input) { auto itemHandler = [this](const WatchData &data) { - d = data; + static_cast(this)->operator=(data); // FIXME with 3.5 }; + auto childHandler = [this](const WatchData &innerData, const GdbMi &innerInput) { WatchItem *item = new WatchItem(innerData); item->parseWatchData(innerInput); @@ -1895,10 +1772,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 e99e449319d..5f7a6cb128e 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -35,32 +35,66 @@ #include -#include #include namespace Debugger { namespace Internal { class DebuggerCommand; -class SeparatedView; +class DebuggerEngine; class WatchModel; -class WatchItem : public Utils::TreeItem +// Special formats. Keep in sync with dumper.py. +enum DisplayFormat +{ + AutomaticFormat, // Based on type for individuals, dumper default for types. + RawFormat, + + 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, +}; + +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); - 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,84 +110,21 @@ public: QColor valueColor() const; int requestedFormat() const; - void showInEditorHelper(QString *contents, int depth) const; WatchItem *findItem(const QByteArray &iname); + +private: + WatchItem *parentItem() const; + const WatchModel *watchModel() const; + WatchModel *watchModel(); + DisplayFormats typeFormatList() const; + + bool canFetchMore() const; + QVariant data(int column, int role) const; + Qt::ItemFlags flags(int column) const; + void parseWatchData(const GdbMi &input); - -public: - WatchData d; - 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 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: @@ -163,8 +134,6 @@ public: QByteArray varList; }; -typedef QHash DumperTypeFormats; // Type name -> Dumper Formats - class WatchModelBase : public Utils::TreeModel { Q_OBJECT @@ -196,14 +165,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; - bool hasItem(const QByteArray &iname) const; + const WatchItem *findCppLocalVariable(const QString &name) const; void loadSessionData(); void saveSessionData(); @@ -218,18 +183,16 @@ 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(); QByteArray watcherName(const QByteArray &exp); QString editorContents(); - void editTypeFormats(bool includeLocals, const QByteArray &iname); void scheduleResetLocation(); void resetLocation(); @@ -238,8 +201,6 @@ public: void updateWatchersWindow(); 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); @@ -250,25 +211,13 @@ 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. - SeparatedView *m_separatedView; // Owned. - - bool m_contentsValid; - bool m_resetLocationScheduled; }; } // namespace Internal } // namespace Debugger Q_DECLARE_METATYPE(Debugger::Internal::UpdateParameters) +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 6ff501c61e3..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); @@ -1108,7 +1106,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); } 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/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 710270cfe3a..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; } @@ -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)) { @@ -6926,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) { @@ -6936,9 +6942,12 @@ 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. + } else if (m_register != '_') { + // Always copy to " register too (except black hole register). setRegister('"', text, range.rangemode); } 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 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/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/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; 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/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 2d0ab8c20c9..73a4348d8af 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: @@ -566,7 +565,9 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er connect(dd->m_outputPane, &AppOutputPane::runControlStarted, this, &ProjectExplorerPlugin::runControlStarted); connect(dd->m_outputPane, &AppOutputPane::runControlFinished, - dd, &ProjectExplorerPluginPrivate::handleRunControlFinished); + this, &ProjectExplorerPlugin::runControlFinished); + connect(dd->m_outputPane, &AppOutputPane::runControlFinished, + this, &ProjectExplorerPlugin::updateRunActions); addAutoReleasedObject(new AllProjectsFilter); addAutoReleasedObject(new CurrentProjectFilter); @@ -1964,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); @@ -1978,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(); } 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 diff --git a/src/plugins/projectexplorer/targetselector.cpp b/src/plugins/projectexplorer/targetselector.cpp index a39c3f9df7a..6ad1576d2fa 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; } @@ -227,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) @@ -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 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/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) { 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; diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp index 0a5e05f1f9f..0c4b3d431c9 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; - } -} void QmlProfilerTraceView::changeEvent(QEvent *e) { diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.h b/src/plugins/qmlprofiler/qmlprofilertraceview.h index 978095a4d42..d71bdcbed34 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: void changeEvent(QEvent *e) Q_DECL_OVERRIDE; 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))); 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) ]" 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 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")