diff --git a/doc/api/plugin-metadata.qdoc b/doc/api/plugin-metadata.qdoc index 4477ecb66a88a802851b5b4ea4763d4db02fedff..4675202ec90132c1f74a339c45d8e51bd3f42468 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 8485d5461e39ffb813c74d3be3c21ffe08fd3eeb..a920a3a4a837c469b06398e3c89e1e7a40907a84 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 8d150f31a0144e1da6607971fa95ebecd6b2ead2..0113072e5dc23f27fdd5199c3db78f7c20f5ad28 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 6c050c52a4d529404ef65fcccf12c250bb1a86fe..affc2d2703da7fdcf617796b1f5bdbc570bf4c2d 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 9ac5727c625c00b2944ec1e6fae7f67924a47ecd..bf658da173ef6f04a79034c39125feb1dfb486e7 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 1b9d9e08f88814bb5ee43cf0f8ae556fe208f542..f000b6473ba10f3d59c53670d8cf9323cbefb81b 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 b233941c1d39686aff563afe97a4ca3354f80230..5172e2a9502cee6cf7cf1f3b174f45617ef5da5b 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 713e388c3ae8042007cf56ce6b45a51d8ad4b6f2..9d1e99d90ecd84ef9a7518cb7e10f6c15f0f6c36 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 3a2515ae13912d2a9d9b9b540a391e593639fd30..8bbfe754e733b81ae0c7725fea738af5a280edcd 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 fc5f9cccc133d28c2abe5983f9781ced7a75a5cc..d8745366b5d492a8ed7dfee94d2a5087c6ca3116 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 6fa45a43c74ccbcdeb9b5352f0ca40352bcf2e5e..52e475e27f8a3ac8ff9942e67fa9fc6558fd1fa3 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 089c4ae46105cfd1c98693b642b78ee6debbadbf..f22bd37b1d2af5efb04da16b42aeb4787e338d02 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 4d8142238803eaba17c0b57866e251831a37a920..fdf70468a8febd86933bf5c257a62150bff56ee7 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 cff457ae44cf725bbda3fab135b837913ef51c38..f640786ceff435d204394aaa476266c8f383faf9 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 88e60f5228123c38596442539eb4758f1d1b8757..54a6cc34d71349b517b0adcbe6a1adf1615f5aef 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 016b2aa7e61cb526a6a350571c2b4bd69faff5ea..cba5d60dc4d1927b2251bb015d38d4bf8facf355 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 8c2e86d65ed8f6b34e2c0228a4a717d5b6025af9..a2a7ec952e425328f43061bdf8eeff608fabde63 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 3e74e9b4a25baa18cf58e795fca0bc41d3c5ff97..63eadd912c5716ca243e72aab038dc1e534d8149 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 9882c3121fe4fecfb25292609e1b2c7df901227e..8d50d722e7571a14df3dab0153b46caaf916aeb6 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 35e64f4ee63a64ac57eab98f5b9ef3d2849b78d7..310ef48b9d0479b183016b6ab71ca1118e5dd989 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 5f2785236d017dde3133ecaffa4469a346bafb84..d34db47d255a68bcce8e794bfa354a0ac72e78a4 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -1255,7 +1255,14 @@ bool PluginManagerPrivate::loadQueue(PluginSpec *spec, QList<PluginSpec *> &queu } // add dependencies - foreach (PluginSpec *depSpec, spec->dependencySpecs()) { + QHashIterator<PluginDependency, PluginSpec *> 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<PluginDependency, PluginSpec *> 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<PluginSpec *> specsForTests; + foreach (const TestSpec &testSpec, testSpecs) { + QList<PluginSpec *> circularityCheckQueue; + loadQueue(testSpec.pluginSpec, specsForTests, circularityCheckQueue); + // add plugins that must be force loaded when running tests for the plugin + // (aka "test dependencies") + QHashIterator<PluginDependency, PluginSpec *> 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 0400ceb0fc2ce0051869ad89e287df9d71c790ea..f219d5c0dae7b7664345b079dd83fa0647cf38b2 100644 --- a/src/libs/extensionsystem/pluginmanager_p.h +++ b/src/libs/extensionsystem/pluginmanager_p.h @@ -73,6 +73,7 @@ public: QList<PluginSpec *> 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 9d470cd5b209e6249569ba4d08ce702909507669..858dfd9510ed45a357f90612c1f7108737fecb08 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<PluginDependency, PluginSpec *> 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 9272403e9aa37fed4488c1ecee1e99d7bcf00422..56860135a973955ea2d76170bf5078bbff43902e 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 44e6aaf8ed9c770f6a87f4ad08fa8194c1b55af1..55666678aae44b58cf8b12eebc593d78f5fcff36 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 472c0174db09f60789a7f55961e5d0dcaf477997..72ecfa9371862666573900beeff3721de60e2ce7 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 0ee0ad2aba6e5fd3e2f32142923d7205985fe614..5f44fbcf0195c10fe1d7520b70ff6051c3318911 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 58f28b558a9812091c29a82103b174c8bb551338..cea5b49cd42516c07b05a6f8debce5569c2aa6d8 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 46057b78688fcc4b59c3a99d94faf16176606c1b..8807878ce4d877fb0918143b11d8dfe10e2ddb22 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 249c5e875e2a10e6810acb9ef0282e6f6d8a51e7..dda0d6f2e6ce6ad52474bf7fb1051c892545f54c 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<bool(const TreeItem *, const TreeItem *)> &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 23d2f1bea062a98569873c16919f678c395553ea..03d791707984926db993b58367a26f152600ac51 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<bool(const TreeItem *, const TreeItem *)> &cmp); void update(); void updateColumn(int column); void expand(); diff --git a/src/plugins/analyzerbase/analyzerutils.cpp b/src/plugins/analyzerbase/analyzerutils.cpp index 3d4e71747d457acf1c042a2b2239cf83b8472d45..5d8986eacc0b4f07da86a9227154b1601c53b9bf 100644 --- a/src/plugins/analyzerbase/analyzerutils.cpp +++ b/src/plugins/analyzerbase/analyzerutils.cpp @@ -41,7 +41,6 @@ #include <cplusplus/ExpressionUnderCursor.h> #include <cplusplus/TypeOfExpression.h> -#include <cpptools/cppmodelmanager.h> #include <QTextCursor> diff --git a/src/plugins/android/androidsettingswidget.cpp b/src/plugins/android/androidsettingswidget.cpp index 9274f937825188e8b3116a38c12d7ce253247b66..f8748be22942296922b4cf5973cda0b125bf4b76 100644 --- a/src/plugins/android/androidsettingswidget.cpp +++ b/src/plugins/android/androidsettingswidget.cpp @@ -45,8 +45,6 @@ #include <qtsupport/qtkitinformation.h> #include <qtsupport/qtversionmanager.h> -#include <utils/pathchooser.h> - #include <QFile> #include <QTextStream> #include <QProcess> diff --git a/src/plugins/clangcodemodel/constants.h b/src/plugins/clangcodemodel/constants.h index 30387c647b01fa20126ca06e91c03e4bd52adf9b..f67f93f5f6f70c6c6fbc973596369776729f60ed 100644 --- a/src/plugins/clangcodemodel/constants.h +++ b/src/plugins/clangcodemodel/constants.h @@ -31,7 +31,6 @@ #ifndef CONSTANTS_H #define CONSTANTS_H -#include <QtCore/QLatin1Char> #include <QtCore/QLatin1Char> namespace ClangCodeModel { diff --git a/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/src/plugins/coreplugin/dialogs/settingsdialog.cpp index cd3483776aa3c73c2c0a10d5546ade298f324845..fefce66e3b7732888f76fff1922e02bd9abddaa2 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 57f18ade22ecd5162896efec4491230e7de452de..f9cbf4a90d1a69d8274a9c189fe435ee98f2fffa 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 <QFileInfo> namespace Core { diff --git a/src/plugins/coreplugin/outputpanemanager.cpp b/src/plugins/coreplugin/outputpanemanager.cpp index e77fa29dd802f54474a1041e4094616267fe90b6..fa2672713ec79c7203e6dd6f8a6f673ca0d6cc08 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 65182b46d97038c5d07ba0ff914f954808b6fd7f..f4ec9e84735cd7ee22ec03ee77807c159dee43ae 100644 --- a/src/plugins/coreplugin/vcsmanager.cpp +++ b/src/plugins/coreplugin/vcsmanager.cpp @@ -491,7 +491,6 @@ void VcsManager::handleConfigurationChanges() #include <QtTest> #include "coreplugin.h" -#include "iversioncontrol.h" #include <extensionsystem/pluginmanager.h> diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index c88e42135869be6cc912f593675f35e648f1d02a..460d8b7c3a0af55c2a3c84ab0734a9a9adf8effb 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -48,7 +48,6 @@ #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/documentmodel.h> -#include <cpptools/cppchecksymbols.h> #include <cpptools/cppchecksymbols.h> #include <cpptools/cppcodeformatter.h> #include <cpptools/cppcompletionassistprovider.h> diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs index 5b1e536dccbbe7713d331efdc0cbd4dd09859441..bc2a8ea3a731785e896a23df7453e40a70949ddc 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 8f1da424e1d8673f1676983573dbb9f1c8266019..c9a690b079e8c0f58193c859240b7aebc62331f5 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 58d094326773ec967099e2f39f6b033c69953506..bb482038ec4de822a850fcf1c1633b39071c64bd 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 09a3c7cc85db9679592aec151c6cc0c44670fa38..27c540fae922aafe80da12c4af16ce20a9059519 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 <coreplugin/coreconstants.h> diff --git a/src/plugins/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs index 306b3c4e1a8255503f01cc2724920d48c2475198..f5ffb85f46e1c2dd0ed05d0df95a94db6499419e 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 0b43917151963311573cd7fe4145e39d9a22afd4..9ff54010ad71f0afb607d51bbbb9ae91861fb216 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 657972e89948d6170423c0712ceaa962abfedfb1..c9c49200846b50de4d150ba71bba6d1f912ce971 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<QByteArray> toDelete; if (newFrame) { foreach (WatchItem *item, handler->model()->treeLevelItems<WatchItem *>(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 76ecd6a472cf63d1fd17bddcec424273b9a022b9..e57b2ca1ab6c8726c43e58a5e144eaeb9551085c 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 7b724bad3d0d97a874ae12d31f2a9e9b97a9e655..066323c193d9a568f6032bd453ae862646c913b1 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 eee9ee11c4a1a4d4078c6f2f6d246bac97f91278..9b0ddc4673b0905bb9adbe3e22a8c197a32370e2 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 <projectexplorer/kitchooser.h> #include <projectexplorer/abi.h> @@ -162,8 +164,6 @@ private: QDialogButtonBox *m_box; }; -typedef QHash<QString, QStringList> 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 c2a826b3902ac178d7621950a784b84a8b4f0c44..8c7989bd72c15b6e593f861f762908b261350335 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 2ff08231cc9f8d916b23775b5374894be0b8d902..fb11e6553bf45a20c1ec44b44b60cd1c5665d5f1 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 aff64de8f8d52e2e40ab60c2edb0f538cb38435b..c9d2d71a4bd7ef39aeac5c71d527b6d4fbad6305 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<QDockWidget *>(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<QDockWidget *>(objectName); + return dock && dock->toggleViewAction()->isChecked(); } void openMemoryEditor() diff --git a/src/plugins/debugger/debuggertooltipmanager.cpp b/src/plugins/debugger/debuggertooltipmanager.cpp index fc1bd3626b51d15a88b9c1c03c8074dd25445b27..07028a144d004cea0b7df1d76c75ea32c890306b 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<WatchItem *>(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 d4ecc5fd9083468e4c126cb2657557090d3167fb..fa6810d8400e19bf370d44ac1e15a6db469ff755 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(_("<Rebuild Watchmodel %1>").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<IOptionsPage *> *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<QByteArray> toDelete; if (!partial) { foreach (WatchItem *item, handler->model()->treeLevelItems<WatchItem *>(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(_("<Rebuild Watchmodel %1 @ %2 >") + .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 bfa310770a8fd86b3f93724ae825c9999a9367c9..dff3c80d3efcb9cf4413b3cb4bd2860ccd7f23b8 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 863d13968f2af5f17b815fd5286a80d3a1347fca..1be58dd442b912b028b44bbcf9475c7881f67da1 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<QByteArray> toDelete; foreach (WatchItem *item, handler->model()->treeLevelItems<WatchItem *>(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 31c404e42498306352a8290c297e6450edf217ab..280f7ba78c5b6dfee3fc5c0189a1df767e84ab75 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 c4bb9acd6897253d1ddf89e1f0c984b5b501ec7c..88d3bb7abf37d9c0c62c9966d98e6017e64c2966 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<QByteArray> toDelete; foreach (WatchItem *item, handler->model()->treeLevelItems<WatchItem *>(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 9d190d31e8fc471d669566fecaca3f9d4ec32f48..751ebbc943d52a2194be8c1a044dd7e9e9ed09a5 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 409a3dc9c5b68c0a168d441405e9ba065d05c7ef..47435fbf996e98bc67252773bf929a50b55fbff1 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 dab64a71a4937b6798a86de0ef68636b6506622f..222fc097e642fc5b38040cd2de7dc9ed1c3725db 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 6960cde7fced3f6d8f72b1efd2e119af787fe651..3ea2b14ff34b684aa73e7bbfd77f98bdfa26c37a 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 6f6e7d2ccd608ecefc27145491baa22a518d5b7c..eb32ddfe11421b654be2d349157c2aa4ecc66269 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 60fd23dd2cffe7f70a35e9786b6e000ac96c098c..621947dfe488aeaee82e31a0bfbf6d501770ed07 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 7e2aecc4697932d03c381b3f7682fe8fe0b54ff4..ece99ccb7616b71d76c0573c196fe5e8f73eb46a 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<int,QString> QmlInspectorAgent::rootObjectIds() const { QHash<int,QString> 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> 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<WatchData> 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<WatchData> 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(); - - list.append(objWatch); - addObjectWatch(objWatch.id); + auto objWatch = new WatchItem(objIname, name); + objWatch->id = objDebugId; + objWatch->exp = name.toLatin1(); + objWatch->type = obj.className().toLatin1(); + objWatch->value = _("object"); + objWatch->wantsChildren = true; + objWatch->setAllUnneeded(); + + m_debuggerEngine->watchHandler()->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<WatchData> 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 3c01307f1504dff5e30af68deb84e88fe00b7383..4719ed2782abfa8d01284d3c497da9ae5cab9338 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<WatchData> 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 f2e5fd250e7498adaf335a0401b5e15bb415c4d5..65b02fbfe476a116041cced33fa107d3dd7528d2 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<quint64, QByteArray> 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<int> handlesToLookup; - QList<WatchData> 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<int>() << 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<WatchData> 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<WatchData> 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<WatchData> QmlV8DebuggerClient::createWatchDataList(const WatchData *parent, +void QmlV8DebuggerClient::createWatchDataList(const WatchItem *parent, const QVariantList &properties, const QVariant &refsVal) { - QList<WatchData> 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 524084a11f9b053f59106146a16ad870a8dab6e2..ae78443e77a67a830a105ff7ae5540ec535c3d7f 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<WatchData> 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 923a1bcb89026892f789b6364cc9229fadc8f145..fd9b246557e996003a10f40407e9c98a7f0ec710 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<WatchData> 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<WatchData> &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<WatchData> &locals, } } - foreach (WatchData data, locals) { - if (data.name == QLatin1String("<no initialized data>")) - 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("<no initialized data>")) + 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 818301a4ea358fed123f018bdb1833feb6ffe3b2..f96e5785a3d2f5324bd114c2705535317ff62dc7 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 <utils/savedaction.h> #include <utils/qtcassert.h> diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp index d010768c4fa89fde96d6737a3c1b22a720a989ba..ef12026510981fd1718251868b3b1e8f0ac5d8c8 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=<needed>,"; - 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=<needed>,"; - if (isTypeKnown() && !type.isEmpty()) - str << "type=\"" << type << doubleQuoteComma; + str << "type=\"" << type << doubleQuoteComma; - if (isHasChildrenNeeded()) - str << "hasChildren=<needed>,"; - if (isHasChildrenKnown()) - str << "hasChildren=\"" << (hasChildren ? "true" : "false") << doubleQuoteComma; + str << "wantsChildren=\"" << (wantsChildren ? "true" : "false") << doubleQuoteComma; if (isChildrenNeeded()) str << "children=<needed>,"; @@ -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 b00de93220549ecf60ecded6e64ee6e9d5a46c40..7191e58637af35c3df376e76d64105139283e6c6 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 107d59fc05a11667f9c24cf340970dbb5937c9d9..8b67ee91d4f23076843601c6cbae6588573ceb39 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 <coreplugin/icore.h> @@ -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<WatchData> *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<WatchItem *>(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<QByteArray> m_expandedINames; + QSet<QByteArray> 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<QByteArray, QString> ValueCache; - ValueCache m_valueCache; - - void insertItem(WatchItem *item); - void reexpandItems(); + QHash<QString, DisplayFormats> m_reportedTypeFormats; // Type name -> Dumper Formats + QHash<QByteArray, QString> 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<WatchItem *>(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<WatchData> list; - foreach (TreeItem *child, rootItem()->children()) - reinsertAllDataHelper(static_cast<WatchItem *>(child), &list); - reinitialize(true); - for (int i = 0, n = list.size(); i != n; ++i) - insertDataItem(list.at(i)); -} - void WatchModel::reinsertAllDataHelper(WatchItem *item, QList<WatchData> *data) { - data->append(item->d); + data->append(*item); // Slices intentionally. data->back().setAllUnneeded(); foreach (TreeItem *child, item->children()) reinsertAllDataHelper(static_cast<WatchItem *>(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<WatchItem *>(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<const WatchItem *>(item1); const WatchItem *it2 = static_cast<const WatchItem *>(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<TreeItem *> &list, const WatchItem *item) @@ -1121,35 +1094,38 @@ static int findInsertPosition(const QVector<TreeItem *> &list, const WatchItem * return it - list.begin(); } -int WatchItem::requestedFormat() const +void WatchModel::reinsertAllData() { - int format = theIndividualFormats.value(d.iname, AutomaticFormat); - if (format == AutomaticFormat) - format = theTypeFormats.value(stripForFormat(d.type), AutomaticFormat); - return format; + QList<WatchData> list; + foreach (TreeItem *child, rootItem()->children()) + reinsertAllDataHelper(static_cast<WatchItem *>(child), &list); + + reinitialize(true); + + for (int i = 0, n = list.size(); i != n; ++i) { + const WatchData &data = list.at(i); + QTC_ASSERT(!data.iname.isEmpty(), qDebug() << data.toString(); return); + // Add new entry. + WatchItem *parent = findItem(parentName(data.iname)); + QTC_ASSERT(parent, return); + WatchItem *newItem = new WatchItem(data); + newItem->sortChildren(&watchItemSorter); + const int row = findInsertPosition(parent->children(), newItem); + parent->insertChild(row, newItem); + if (m_expandedINames.contains(parent->iname)) { + emit inameIsExpanded(parent->iname); + emit itemIsExpanded(indexFromItem(parent)); + } + showEditValue(data); + } } -void WatchItem::showInEditorHelper(QString *contents, int depth) const +int WatchItem::requestedFormat() const { - const QChar tab = QLatin1Char('\t'); - const QChar nl = QLatin1Char('\n'); - contents->append(QString(depth, tab)); - contents->append(d.name); - contents->append(tab); - contents->append(d.value); - contents->append(tab); - contents->append(QString::fromLatin1(d.type)); - contents->append(nl); - foreach (const TreeItem *child, children()) - static_cast<const WatchItem *>(child)->showInEditorHelper(contents, depth + 1); -} - -void WatchModel::setCurrentItem(const QByteArray &iname) -{ - if (WatchItem *item = findItem(iname)) { - QModelIndex idx = indexFromItem(item); - emit currentIndexRequested(idx); - } + int format = theIndividualFormats.value(iname, AutomaticFormat); + if (format == AutomaticFormat) + format = theTypeFormats.value(stripForFormat(type), AutomaticFormat); + return format; } /////////////////////////////////////////////////////////////////////// @@ -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<WatchData> &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<WatchItem *>(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<QByteArray> &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<QString, QVariant> it(value.toMap()); @@ -1514,7 +1441,7 @@ void WatchHandler::loadFormats() } } -void WatchHandler::saveFormats() +static void saveFormats() { QMap<QString, QVariant> formats; QHashIterator<QByteArray, int> 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<WatchItem *>(item)->d : 0; + return static_cast<WatchItem *>(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); } -QString WatchHandler::editorContents() -{ - QString contents; - m_model->root()->showInEditorHelper(&contents, 0); - return contents; -} - -void WatchHandler::setTypeFormats(const DumperTypeFormats &typeFormats) +static void showInEditorHelper(const WatchItem *item, QTextStream &ts, int depth) { - m_model->m_reportedTypeFormats = typeFormats; -} - -DumperTypeFormats WatchHandler::typeFormats() const -{ - return m_model->m_reportedTypeFormats; + 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<const WatchItem *>(child), ts, depth + 1); } -void WatchHandler::editTypeFormats(bool includeLocals, const QByteArray &iname) +QString WatchHandler::editorContents() { - Q_UNUSED(includeLocals); - TypeFormatsDialog dlg(0); - - //QHashIterator<QString, QStringList> it(m_reportedTypeFormats); - QList<QString> 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()); + QString contents; + QTextStream ts(&contents); + showInEditorHelper(m_model->root(), ts, 0); + return contents; } 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<QByteArray, int> WatchHandler::watcherNames() @@ -1797,67 +1703,37 @@ QSet<QByteArray> 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<WatchData *>(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 e99e449319d4549f8c44bc5da62a0208af9fc69b..5f7a6cb128efdcb9bf9442858fd026829c9bbbca 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -35,68 +35,29 @@ #include <utils/treemodel.h> -#include <QPointer> #include <QVector> namespace Debugger { namespace Internal { class DebuggerCommand; -class SeparatedView; +class DebuggerEngine; class WatchModel; -class WatchItem : public Utils::TreeItem -{ -public: - 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; - QString displayType() const; - QString displayValue() const; - QString formattedValue() const; - QString expression() const; - - int itemFormat() const; - - QVariant editValue() const; - int editType() const; - QColor valueColor() const; - - int requestedFormat() const; - void showInEditorHelper(QString *contents, int depth) const; - WatchItem *findItem(const QByteArray &iname); - void parseWatchData(const GdbMi &input); - -public: - WatchData d; - 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, + AutomaticFormat, // Based on type for individuals, dumper default for types. + RawFormat, - // Values between 1 and 99 refer to dumper provided custom formats. + 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 - // Values between 100 and 199 refer to well-known formats handled in dumpers. - KnownDumperFormatBase = 100, Latin1StringFormat, + SeparateLatin1StringFormat, Utf8StringFormat, + SeparateUtf8StringFormat, Local8BitStringFormat, Utf16StringFormat, Ucs4StringFormat, @@ -105,14 +66,13 @@ enum DisplayFormat Array100Format, Array1000Format, Array10000Format, + ArrayPlotFormat, - SeparateLatin1StringFormat, - SeparateUtf8StringFormat, - - - // Values above 200 refer to format solely handled in the WatchHandler code - ArtificialFormatBase = 200, + CompactMapFormat, + DirectQListStorageFormat, + IndirectQListStorageFormat, + // Not used in *.py. BoolTextFormat, BoolIntegerFormat, @@ -125,34 +85,45 @@ enum DisplayFormat ScientificFloatFormat, }; +typedef QVector<DisplayFormat> DisplayFormats; -class TypeFormatItem +class WatchItem : public Utils::TreeItem, public WatchData { public: - TypeFormatItem() : format(-1) {} - TypeFormatItem(const QString &display, int format); + WatchItem() {} + WatchItem(const QByteArray &i, const QString &n); + explicit WatchItem(const WatchData &data); + explicit WatchItem(const GdbMi &data); - QString display; - int format; -}; + void fetchMore(); -class TypeFormatList : public QVector<TypeFormatItem> -{ -public: - using QVector::append; - void append(int format); - TypeFormatItem find(int format) const; -}; + QString displayName() const; + QString displayType() const; + QString displayValue() const; + QString formattedValue() const; + QString expression() const; -} // namespace Internal -} // namespace Debugger + int itemFormat() const; -Q_DECLARE_METATYPE(Debugger::Internal::TypeFormatList) + QVariant editValue() const; + int editType() const; + QColor valueColor() const; -namespace Debugger { -namespace Internal { + int requestedFormat() const; + WatchItem *findItem(const QByteArray &iname); -class DebuggerEngine; +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); +}; class UpdateParameters { @@ -163,8 +134,6 @@ public: QByteArray varList; }; -typedef QHash<QString, QStringList> 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<WatchData> &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<QByteArray> &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 6ff501c61e3427dbdfeabe66892b120f8cc752a2..c8f145fb29a6037dfa48b518dbc390f3d8c7061f 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<TypeFormatList>(); - int typeFormat = - mi.data(LocalsTypeFormatRole).toInt(); - const int individualFormat = - mi.data(LocalsIndividualFormatRole).toInt(); + const DisplayFormats alternativeFormats = + mi.data(LocalsTypeFormatListRole).value<DisplayFormats>(); + 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</a>.")); 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 bd514fd9133ae818d7382d538fdf0e1b49485d05..f1d3c86640fa26b821aa110b89bd0ca699d6919b 100644 --- a/src/plugins/diffeditor/diffeditor.cpp +++ b/src/plugins/diffeditor/diffeditor.cpp @@ -55,7 +55,6 @@ #include <QHBoxLayout> #include <QToolBar> #include <QComboBox> -#include <QAction> #include <QDir> #include <QTextCodec> #include <QTextBlock> diff --git a/src/plugins/diffeditor/diffeditormanager.cpp b/src/plugins/diffeditor/diffeditormanager.cpp index d59444181995a7f40b691aec5cd035db97e6183c..242b19bcd4f2bc6d1c4218300f108e7a3a1ed3cf 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 <coreplugin/editormanager/editormanager.h> diff --git a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp index 22ef037c3d17ab0ba79f95281a6318b6e9ccdff8..e94f21b2380f0d805a29c8e229ed78c73f1e0d44 100644 --- a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp +++ b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp @@ -45,7 +45,6 @@ #include <texteditor/textdocument.h> #include <texteditor/textdocumentlayout.h> -#include <texteditor/textdocument.h> #include <texteditor/texteditorsettings.h> #include <texteditor/fontsettings.h> #include <texteditor/displaysettings.h> diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 710270cfe3a6aa73da5819e2a5cccb1d70d009cc..3956a3454fa25fe1bcf4cf832c731b45ff09bd87 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 7c5c9ae4c232ca85c917d2578a21358ab780b195..2decbf68e5ce0f15a9b8bfc4aae4b999ca88590c 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 3f5d39a2a453dd7b504b18012b16513b28a78f78..3e2f1b8c2834dce395eb6f4f0b3daf654dd96f37 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -61,7 +61,6 @@ #include <coreplugin/editormanager/ieditor.h> #include <coreplugin/locator/commandlocator.h> #include <coreplugin/vcsmanager.h> -#include <coreplugin/coreconstants.h> #include <coreplugin/messagebox.h> #include <utils/mimetypes/mimedatabase.h> diff --git a/src/plugins/ios/iosdsymbuildstep.cpp b/src/plugins/ios/iosdsymbuildstep.cpp index 1eb5874ed04ca38b8e73ab2af2504e906d4482b5..2b08097d9b65b5350a512158356bb0440daf43cd 100644 --- a/src/plugins/ios/iosdsymbuildstep.cpp +++ b/src/plugins/ios/iosdsymbuildstep.cpp @@ -48,7 +48,6 @@ #include <utils/stringutils.h> #include <utils/qtcassert.h> #include <utils/qtcprocess.h> -#include <utils/qtcassert.h> using namespace Core; using namespace ProjectExplorer; diff --git a/src/plugins/ios/iosrunfactories.cpp b/src/plugins/ios/iosrunfactories.cpp index f351fd56aada1f10f495307d0420b8734d47a584..f267153905096dd2d18fbfe22b8ac5fcb0b65511 100644 --- a/src/plugins/ios/iosrunfactories.cpp +++ b/src/plugins/ios/iosrunfactories.cpp @@ -101,7 +101,7 @@ QList<Core::Id> IosRunConfigurationFactory::availableCreationIds(Target *parent, QList<QmakeProFileNode *> nodes = project->allProFiles(QList<QmakeProjectType>() << 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 707bc15fb473a067ea5dfbabadadd3c85d8abe5e..1ddf2d8d5cf2e5bd6d8e4a9ec7e8ec1614c65027 100644 --- a/src/plugins/projectexplorer/compileoutputwindow.cpp +++ b/src/plugins/projectexplorer/compileoutputwindow.cpp @@ -42,6 +42,7 @@ #include <texteditor/texteditorsettings.h> #include <texteditor/fontsettings.h> #include <utils/ansiescapecodehandler.h> +#include <utils/theme/theme.h> #include <QIcon> #include <QTextCharFormat> @@ -184,30 +185,26 @@ QList<QWidget *> CompileOutputWindow::toolBarWidgets() const return QList<QWidget *>() << 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 14b300f3f1cc8b3848ec16cdeaab0afd1117097d..e76faef254ffcc295aac4b7690acbd5e55544352 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp @@ -37,7 +37,6 @@ #include <projectexplorer/project.h> #include <projectexplorer/projectexplorerconstants.h> #include <ssh/sshhostkeydatabase.h> -#include <utils/qtcassert.h> #include <utils/fileutils.h> #include <utils/persistentsettings.h> #include <utils/qtcassert.h> diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 2d0ab8c20c9579f1ade875a61247ad4139c1a59f..73a4348d8af1803fcad61f40d6c1e13f6b3d343d 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 7b0716ffc240921f7e70fce65806c0bd1ab0bdaa..a4feac93632db92d9f7ca9a126a05df61dfee5a7 100644 --- a/src/plugins/projectexplorer/session.cpp +++ b/src/plugins/projectexplorer/session.cpp @@ -48,7 +48,6 @@ #include <utils/algorithm.h> #include <utils/stylehelper.h> -#include <utils/algorithm.h> #include <QDebug> #include <QDir> diff --git a/src/plugins/projectexplorer/targetselector.cpp b/src/plugins/projectexplorer/targetselector.cpp index a39c3f9df7a6d7baa2891f2fc84b71a02daace69..6ad1576d2fa4b05daf7892f2fb6b3807ccc83fd7 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 e1f12943c0e305a378bfd100f2400fb8ba730857..433b4a0cfe8268a41d3918b96eac371217763eaa 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 dbf112f7a07d9504f8d4ba7923417239ccd9a307..8de0fa3ed5dbd2a88865ab38a434b7498e0e1449 100644 --- a/src/plugins/qmakeandroidsupport/qmakeandroidrunfactories.cpp +++ b/src/plugins/qmakeandroidsupport/qmakeandroidrunfactories.cpp @@ -92,7 +92,7 @@ QList<Core::Id> QmakeAndroidRunConfigurationFactory::availableCreationIds(Target QmakeProject *project = static_cast<QmakeProject *>(parent->project()); QList<QmakeProFileNode *> nodes = project->allProFiles(QList<QmakeProjectType>() << 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 fd8761b47e8e6c95825e390c0f54c15a46580d97..9770c70ee4ae0154350bbb548152faf9793b9443 100644 --- a/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp +++ b/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp @@ -1048,7 +1048,7 @@ void InternalLibraryDetailsController::updateProFile() QList<QmakeProFileNode *> 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 9a10b03850b31e7d52b35d43ebd908edcc9e0e69..6a18db582473aa309fb24041b62d888230df1fd1 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -917,7 +917,8 @@ QList<ProjectAction> 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 2a005c4a351cc98d1e25bad86ba1f572ed0f2fe4..59344ed56110f41ba1acb9ec298708a1dfabe30c 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 92d279d671dfe8cc41a1e2bc61e649316f58b801..aaab37486b7e32f9028886b9be5deae6c183724c 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 85891a7fff942cf11ff2e978619cdb5ad30b2385..0f3fb7be4bacb812213b45a230acb83968284ff2 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 8f364adea4336046c58728ae32608a6977b3dc19..135252ea9d703061290470d413dff2bf985f362b 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 0a5e05f1f9f747308b861c7011625842d5153233..0c4b3d431c90d29d6e3dd61c4cfd00abc2f3cb72 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 978095a4d429921d6f2ce39b0d32fa375ffd333e..d71bdcbed34b61913a3307374239d227c1e6f37d 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 234e81e97f627cde4f64f52afed8ee59a9236854..d5100209ed3496eece9ea93ab1d9d1cc134f74a8 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 5381b6de835e92b665c139a5ded3b9339678c786..0f57dfc88a9b66dab0463854959f8d0ebdaafeb7 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 af823daf84ae6e76a6ef4789e78f6b287b2a272f..36bb033afa4f25f4c7d7a5b5f29cf63fba024145 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 5ededbc1764d5a0c913641105a18dc3e948312de..7249eef1afefe1fd2703842122695d55e80e2985 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 22710817cd9fe3215a396cbf603b334b849182a2..6117c31b28fbb5e7c18640ceaa33e7bf77e0c60c 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")