From 4b6c5536d78b177d36c282855ef24672c1624d61 Mon Sep 17 00:00:00 2001
From: Eike Ziller
Date: Thu, 2 Apr 2015 08:49:52 +0200
Subject: [PATCH 01/38] Add change log entry
Change-Id: I1298cf303d05cf59d3f21da6c602af4e0abe8e3f
Reviewed-by: Leena Miettinen
---
dist/changes-3.4.0 | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dist/changes-3.4.0 b/dist/changes-3.4.0
index 871cf69860e..a4c9105a109 100644
--- a/dist/changes-3.4.0
+++ b/dist/changes-3.4.0
@@ -129,6 +129,8 @@ Version Control Systems
(QTCREATORBUG-13979)
* Perforce
* Improved repository log (QTCREATORBUG-13526)
+ * Bazaar
+ * Fixed committing (QTCREATORBUG-13878)
FakeVim
* Fixed target column for various commands
From 14eb13e995d6f977f0492fb1d2435eb01256736d Mon Sep 17 00:00:00 2001
From: Ulf Hermann
Date: Thu, 26 Mar 2015 11:55:29 +0100
Subject: [PATCH 02/38] Timeline: Enforce a minimum width for detail windows.
We don't want to resize them to absurd dimensions.
Change-Id: I7f824919052c6740f291d2b0266fd009da99fd53
Reviewed-by: Kai Koehne
Reviewed-by: Joerg Bornemann
Reviewed-by: Eike Ziller
---
src/libs/timeline/qml/RangeDetails.qml | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/libs/timeline/qml/RangeDetails.qml b/src/libs/timeline/qml/RangeDetails.qml
index a8903863666..c0a765d3dbe 100644
--- a/src/libs/timeline/qml/RangeDetails.qml
+++ b/src/libs/timeline/qml/RangeDetails.qml
@@ -201,6 +201,17 @@ Item {
y: 5
spacing: 5
columns: 2
+ property int minimumWidth: {
+ var result = 150;
+ for (var i = 0; i < children.length; ++i)
+ result = Math.max(children[i].x, result);
+ return result + 20;
+ }
+
+ onMinimumWidthChanged: {
+ if (dragHandle.x < minimumWidth)
+ dragHandle.x = minimumWidth;
+ }
Repeater {
model: eventInfo
@@ -310,6 +321,7 @@ Item {
MouseArea {
anchors.fill: parent
drag.target: parent
+ drag.minimumX: col.minimumWidth
drag.axis: Drag.XAxis
cursorShape: Qt.SizeHorCursor
}
From ccbe4ee0f8bb834816561721bacd28db19839b80 Mon Sep 17 00:00:00 2001
From: Ulf Hermann
Date: Thu, 26 Mar 2015 12:01:18 +0100
Subject: [PATCH 03/38] Timeline: Properly position range detail window titles.
This way they get elided correctly.
Change-Id: I924679bd0f985f621fc62b152f3a4536e48e4492
Reviewed-by: Kai Koehne
Reviewed-by: Joerg Bornemann
Reviewed-by: Eike Ziller
---
src/libs/timeline/qml/RangeDetails.qml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/libs/timeline/qml/RangeDetails.qml b/src/libs/timeline/qml/RangeDetails.qml
index c0a765d3dbe..6138e658a83 100644
--- a/src/libs/timeline/qml/RangeDetails.qml
+++ b/src/libs/timeline/qml/RangeDetails.qml
@@ -178,7 +178,8 @@ Item {
height: 18
y: 2
verticalAlignment: Text.AlignVCenter
- width: parent.width
+ anchors.left: parent.left
+ anchors.right: editIcon.left
color: "white"
renderType: Text.NativeRendering
elide: Text.ElideRight
From b1ee6ee80cc50929374a6f051151ed144c4f2d80 Mon Sep 17 00:00:00 2001
From: Ulf Hermann
Date: Wed, 1 Apr 2015 16:49:38 +0200
Subject: [PATCH 04/38] QmlProfiler: Show a message when V8 profiler is not
supported
People frequently wonder why the V8 pane is empty and disabled. This
change makes it more explicit.
Change-Id: I381bff072840dde1fdd038b3d00dd3a400261bc9
Reviewed-by: Joerg Bornemann
Reviewed-by: Eike Ziller
---
.../qmlprofiler/qmlprofilerstatewidget.cpp | 53 +++++++++----------
1 file changed, 24 insertions(+), 29 deletions(-)
diff --git a/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp b/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp
index 4fe735257ae..9d4dc87c220 100644
--- a/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp
@@ -187,57 +187,52 @@ void QmlProfilerStateWidget::paintEvent(QPaintEvent *event)
}
-void QmlProfilerStateWidget::updateDisplay()
+void QmlProfilerStateWidget::showText(const QString &text, bool showProgress)
{
- // When datamodel is acquiring data
- if (!d->loadingDone && !d->emptyList && !d->appKilled) {
- setVisible(true);
- d->text->setText(tr("Loading data"));
+ setVisible(true);
+ if (showProgress) {
if (d->isRecording) {
d->isRecording = false;
d->estimatedProfilingTime = d->profilingTimer.elapsed();
emit newTimeEstimation(d->estimatedProfilingTime);
}
d->progressBar->setValue(d->m_modelManager->progress() * 1000);
- d->progressBar->setVisible(true);
- resize(300,70);
- reposition();
+ }
+ d->progressBar->setVisible(showProgress);
+ d->text->setText(text);
+ resize(showProgress ? 300 : 200, 70);
+ reposition();
+}
+
+void QmlProfilerStateWidget::updateDisplay()
+{
+ // When datamodel is acquiring data
+ if (!d->loadingDone && !d->emptyList && !d->appKilled) {
+ showText(tr("Loading data"), true);
return;
}
// When application is being profiled
if (d->isRecording) {
- setVisible(true);
- d->progressBar->setVisible(false);
- d->text->setText(tr("Profiling application"));
- resize(200,70);
- reposition();
+ showText(tr("Profiling application"));
return;
}
// After profiling, there is an empty trace
if (d->traceAvailable && d->loadingDone && d->emptyList) {
- setVisible(true);
- d->progressBar->setVisible(false);
- d->text->setText(tr("No QML events recorded"));
- resize(200,70);
- reposition();
+ showText(tr("No QML events recorded"));
+ return;
+ }
+
+ // View is not supported for this kind of application
+ if (d->traceAvailable && d->loadingDone && !parentWidget()->isEnabled()) {
+ showText(tr("Not supported for this application"));
return;
}
// Application died before all data could be read
if (!d->loadingDone && !d->emptyList && d->appKilled) {
- setVisible(true);
- d->text->setText(tr("Application stopped before loading all data"));
- if (d->isRecording) {
- d->isRecording = false;
- d->estimatedProfilingTime = d->profilingTimer.elapsed();
- emit newTimeEstimation(d->estimatedProfilingTime);
- }
- d->progressBar->setValue(d->m_modelManager->progress() * 1000);
- d->progressBar->setVisible(true);
- resize(300,70);
- reposition();
+ showText(tr("Application stopped before loading all data"), true);
return;
}
From 879bb9adcf9a73f542af46adb44ccf58407fb3c8 Mon Sep 17 00:00:00 2001
From: hjk
Date: Thu, 2 Apr 2015 12:27:19 +0200
Subject: [PATCH 05/38] Debugger: Remove comment on broken GDB 7.2
We require 7.5.1 now, so the case is uninteresting.
Change-Id: I40bf1c3d531b83998a45e7476ed48397b23b4ae6
Reviewed-by: Christian Stenger
---
share/qtcreator/debugger/qttypes.py | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py
index 28489889ebb..59a0829d9d5 100644
--- a/share/qtcreator/debugger/qttypes.py
+++ b/share/qtcreator/debugger/qttypes.py
@@ -549,27 +549,6 @@ def qdump__QFiniteStack(d, value):
if d.isExpanded():
d.putPlotData(value["_array"], size, d.templateArgument(value.type, 0))
-# Stock gdb 7.2 seems to have a problem with types here:
-#
-# echo -e "namespace N { struct S { enum E { zero, one, two }; }; }\n"\
-# "int main() { N::S::E x = N::S::one;\n return x; }" >> main.cpp
-# g++ -g main.cpp
-# gdb-7.2 -ex 'file a.out' -ex 'b main' -ex 'run' -ex 'step' \
-# -ex 'ptype N::S::E' -ex 'python print gdb.lookup_type("N::S::E")' -ex 'q'
-# gdb-7.1 -ex 'file a.out' -ex 'b main' -ex 'run' -ex 'step' \
-# -ex 'ptype N::S::E' -ex 'python print gdb.lookup_type("N::S::E")' -ex 'q'
-# gdb-cvs -ex 'file a.out' -ex 'b main' -ex 'run' -ex 'step' \
-# -ex 'ptype N::S::E' -ex 'python print gdb.lookup_type("N::S::E")' -ex 'q'
-#
-# gives as of 2010-11-02
-#
-# type = enum N::S::E {N::S::zero, N::S::one, N::S::two} \n
-# Traceback (most recent call last): File "", line 1,
-# in RuntimeError: No type named N::S::E.
-# type = enum N::S::E {N::S::zero, N::S::one, N::S::two} \n N::S::E
-# type = enum N::S::E {N::S::zero, N::S::one, N::S::two} \n N::S::E
-#
-# i.e. there's something broken in stock 7.2 that is was ok in 7.1 and is ok later.
def qdump__QFlags(d, value):
i = value["i"]
From e152e06f429b72c4e66243f9da44731c2963cef3 Mon Sep 17 00:00:00 2001
From: Christian Stenger
Date: Thu, 2 Apr 2015 12:30:10 +0200
Subject: [PATCH 06/38] QmlProfiler: Fix missing declaration
Change-Id: If783fe330bccd19140dd916c42dfe7f424b68a85
Reviewed-by: Ulf Hermann
---
src/plugins/qmlprofiler/qmlprofilerstatewidget.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/plugins/qmlprofiler/qmlprofilerstatewidget.h b/src/plugins/qmlprofiler/qmlprofilerstatewidget.h
index 7fbde30aa1f..9272cce1b01 100644
--- a/src/plugins/qmlprofiler/qmlprofilerstatewidget.h
+++ b/src/plugins/qmlprofiler/qmlprofilerstatewidget.h
@@ -48,6 +48,7 @@ public:
~QmlProfilerStateWidget();
private slots:
+ void showText(const QString &text, bool showProgress = false);
void updateDisplay();
void dataStateChanged();
void profilerStateChanged();
From 3e82dcad4435a9c0747f6880aaa7e0a968156780 Mon Sep 17 00:00:00 2001
From: David Schulz
Date: Thu, 2 Apr 2015 12:28:55 +0200
Subject: [PATCH 07/38] Cdbext: Dump "(null)" for an uninitialized QTimeZone.
Change-Id: I13c0541bad047aa872bdb04f50e6cd0557a40f1a
Reviewed-by: Christian Stenger
---
src/libs/qtcreatorcdbext/symbolgroupvalue.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp
index 17df7e30c2c..a8fef4a3a3b 100644
--- a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp
+++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp
@@ -2212,7 +2212,9 @@ static bool dumpQTime(const SymbolGroupValue &v, std::wostream &str, int *encodi
static bool dumpQTimeZone(const SymbolGroupValue &v, std::wostream &str, int *encoding)
{
- return dumpQByteArrayFromQPrivateClass(v, QPDM_qSharedDataPadded, SymbolGroupValue::pointerSize(), str, encoding);
+ if (!dumpQByteArrayFromQPrivateClass(v, QPDM_qSharedDataPadded, SymbolGroupValue::pointerSize(), str, encoding))
+ str << L"(null)";
+ return true;
}
// Convenience to dump a QTimeZone from the unexported private class of a Qt class.
From 3658bdac898c94a10eef2f04546c459eab424a5c Mon Sep 17 00:00:00 2001
From: hjk
Date: Wed, 1 Apr 2015 17:19:43 +0200
Subject: [PATCH 08/38] Debugger: Use primitive internal widget instead of
matplotview
This practically removes any functionality beyond plain plot display,
but does that at least reliably, cross-platform, without dependency
on 3rd party python packages.
Change-Id: Iaff2f78595394522f32264c642df20dd48b83f8b
Reviewed-by: Christian Stenger
---
share/qtcreator/debugger/dumper.py | 247 +++++++-----------------
share/qtcreator/debugger/gdbbridge.py | 2 -
share/qtcreator/debugger/qttypes.py | 17 +-
share/qtcreator/debugger/stdtypes.py | 8 +-
src/plugins/debugger/debuggerprotocol.h | 3 +-
src/plugins/debugger/imageviewer.cpp | 85 +++++++-
src/plugins/debugger/imageviewer.h | 25 ++-
src/plugins/debugger/watchdata.cpp | 57 +++++-
src/plugins/debugger/watchdata.h | 6 +
src/plugins/debugger/watchhandler.cpp | 202 +++++++++++--------
10 files changed, 356 insertions(+), 296 deletions(-)
diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py
index 584c35e1389..78f48db03d6 100644
--- a/share/qtcreator/debugger/dumper.py
+++ b/share/qtcreator/debugger/dumper.py
@@ -36,13 +36,6 @@ import re
import time
import importlib
-try:
- import subprocess
- hasSubprocess = True
-except:
- hasSubprocess = False
- hasPlot = False
-
if sys.version_info[0] >= 3:
xrange = range
toInteger = int
@@ -105,81 +98,53 @@ WatchpointAtExpression, \
BreakpointOnQmlSignalEmit, \
BreakpointAtJavaScriptThrow, \
= range(0, 14)
-#
-# matplot based display for array-like structures.
-#
-try:
- import matplotlib
- hasPlot = True
-except:
- hasPlot = False
-if hasSubprocess and hasPlot:
- matplotFigure = {}
- matplotCount = 0
- matplotProc = None
- devNull = None
+# Encodings. Keep that synchronized with DebuggerEncoding in debuggerprotocol.h
+Unencoded8Bit, \
+Base64Encoded8BitWithQuotes, \
+Base64Encoded16BitWithQuotes, \
+Base64Encoded32BitWithQuotes, \
+Base64Encoded16Bit, \
+Base64Encoded8Bit, \
+Hex2EncodedLatin1, \
+Hex4EncodedLittleEndian, \
+Hex8EncodedLittleEndian, \
+Hex2EncodedUtf8, \
+Hex8EncodedBigEndian, \
+Hex4EncodedBigEndian, \
+Hex4EncodedLittleEndianWithoutQuotes, \
+Hex2EncodedLocal8Bit, \
+JulianDate, \
+MillisecondsSinceMidnight, \
+JulianDateAndMillisecondsSinceMidnight, \
+Hex2EncodedInt1, \
+Hex2EncodedInt2, \
+Hex2EncodedInt4, \
+Hex2EncodedInt8, \
+Hex2EncodedUInt1, \
+Hex2EncodedUInt2, \
+Hex2EncodedUInt4, \
+Hex2EncodedUInt8, \
+Hex2EncodedFloat4, \
+Hex2EncodedFloat8, \
+IPv6AddressAndHexScopeId, \
+Hex2EncodedUtf8WithoutQuotes, \
+DateTimeInternal \
+ = range(30)
- def matplotInit():
- global matplotProc
- global devNull
+# Display modes. Keep that synchronized with DebuggerDisplay in watchutils.h
+StopDisplay, \
+DisplayImageData, \
+DisplayUtf16String, \
+DisplayImageFile, \
+DisplayLatin1String, \
+DisplayUtf8String, \
+DisplayPlotData \
+ = range(7)
- if matplotProc is None:
- devNull = open(os.devnull)
- # FIXME: That might not be the one we want.
- pythonExecutable = sys.executable
- matplotProc = subprocess.Popen(args=[pythonExecutable, "-i"],
- bufsize=0, stdin=subprocess.PIPE, stdout=devNull, stderr=devNull)
-
- matplotProc.stdin.write(b"import sys\n")
- matplotProc.stdin.write(b"sys.ps1=''\n")
- matplotProc.stdin.write(b"from matplotlib import pyplot\n")
- matplotProc.stdin.write(b"import time\n")
- matplotProc.stdin.write(b"pyplot.ion()\n")
- matplotProc.stdin.flush()
-
- def matplotSend(iname, show, data):
- global matplotFigure
- global matplotCount
-
- matplotInit()
-
- def s(line):
- matplotProc.stdin.write(line.encode("latin1"))
- matplotProc.stdin.write(b"\n")
- sys.stdout.flush()
- matplotProc.stdin.flush()
-
- if show:
- s("pyplot.ion()")
- if not iname in matplotFigure:
- matplotCount += 1
- matplotFigure[iname] = matplotCount
- s("pyplot.figure(%s)" % matplotFigure[iname])
- s("pyplot.suptitle('%s')" % iname)
- s("data = %s" % data)
- s("pyplot.plot([i for i in range(len(data))], data, 'b.-')")
- time.sleep(0.2)
- s("pyplot.draw()")
- matplotProc.stdin.flush()
- else:
- if iname in matplotFigure:
- s("pyplot.figure(%s)" % matplotFigure[iname])
- s("pyplot.close()")
- del matplotFigure[iname]
-
- matplotProc.stdin.flush()
-
- def matplotQuit():
- global matplotProc
- if not matplotProc is None:
- matplotProc.stdin.write(b"exit")
- matplotProc.kill()
- devNull.close()
def arrayForms():
- global hasPlot
- return [ArrayPlotFormat] if hasPlot else []
+ return [ArrayPlotFormat]
def mapForms():
return [CompactMapFormat]
@@ -612,10 +577,7 @@ class DumperBase:
self.putNumChild(0)
self.putValue(mem, encodingType, elided=elided)
- if displayFormat == Latin1StringFormat \
- or displayFormat == Utf8StringFormat:
- self.putDisplay(StopDisplay)
- elif displayFormat == SeparateLatin1StringFormat \
+ if displayFormat == SeparateLatin1StringFormat \
or displayFormat == SeparateUtf8StringFormat:
self.putField("editformat", displayType)
elided, shown = self.computeLimit(bytelen, 100000)
@@ -916,14 +878,14 @@ class DumperBase:
def putCStyleArray(self, value):
arrayType = value.type.unqualified()
innerType = value[0].type
+ innerTypeName = str(innerType.unqualified())
ts = innerType.sizeof
- #self.putAddress(value.address)
+
try:
self.putValue("@0x%x" % self.addressOf(value), priority = -1)
except:
self.putEmptyValue()
self.putType(arrayType)
- self.putNumChild(1)
try:
p = self.addressOf(value)
@@ -933,20 +895,20 @@ class DumperBase:
displayFormat = self.currentItemFormat()
n = int(arrayType.sizeof / ts)
- if p and self.tryPutSimpleFormattedPointer(p, str(arrayType), displayFormat, arrayType.sizeof):
- self.putNumChild(n)
- pass
- elif displayFormat is None:
- innerTypeName = str(innerType.unqualified())
- blob = self.readMemory(self.addressOf(value), arrayType.sizeof)
+ if displayFormat != RawFormat:
if innerTypeName == "char":
# Use Latin1 as default for char [].
+ blob = self.readMemory(self.addressOf(value), arrayType.sizeof)
self.putValue(blob, Hex2EncodedLatin1)
elif innerTypeName == "wchar_t":
+ blob = self.readMemory(self.addressOf(value), arrayType.sizeof)
if innerType.sizeof == 2:
self.putValue(blob, Hex4EncodedLittleEndian)
else:
self.putValue(blob, Hex8EncodedLittleEndian)
+ elif p:
+ self.tryPutSimpleFormattedPointer(p, arrayType, innerTypeName, displayFormat, arrayType.sizeof)
+ self.putNumChild(n)
if self.isExpanded():
try:
@@ -958,17 +920,7 @@ class DumperBase:
with Children(self, childType=innerType):
self.putFields(value)
- if hasPlot and self.isSimpleType(innerType):
- show = displayFormat == ArrayPlotFormat
- iname = self.currentIName
- data = []
- if show:
- base = self.createPointerValue(p, innerType)
- data = [str(base[i]) for i in range(0, n)]
- matplotSend(iname, show, data)
- else:
- #self.putValue(self.currentValue.value + " (not plottable)")
- self.putField("plottable", "0")
+ self.putPlotDataHelper(p, n, innerType)
def cleanAddress(self, addr):
if addr is None:
@@ -1038,29 +990,23 @@ class DumperBase:
data = self.readMemory(base, shown)
self.putValue(data, Hex2EncodedLatin1, elided=elided)
- def putDisplay(self, editFormat, value = None, cmd = None):
+ def putDisplay(self, editFormat, value):
self.put('editformat="%s",' % editFormat)
- if cmd is None:
- if not value is None:
- self.put('editvalue="%s",' % value)
- else:
- self.put('editvalue="%s|%s",' % (cmd, value))
+ self.put('editvalue="%s",' % value)
# This is shared by pointer and array formatting.
- def tryPutSimpleFormattedPointer(self, value, typeName, displayFormat, limit):
- if displayFormat == AutomaticFormat and typeName == "char":
+ def tryPutSimpleFormattedPointer(self, value, typeName, innerTypeName, displayFormat, limit):
+ if displayFormat == AutomaticFormat and innerTypeName == "char":
# Use Latin1 as default for char *.
self.putType(typeName)
(elided, data) = self.encodeCArray(value, 1, limit)
self.putValue(data, Hex2EncodedLatin1, elided=elided)
- self.putDisplay(StopDisplay)
return True
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 displayFormat == SeparateLatin1StringFormat:
@@ -1074,7 +1020,6 @@ class DumperBase:
self.putType(typeName)
(elided, data) = self.encodeCArray(value, 1, limit)
self.putValue(data, Hex2EncodedUtf8, elided=elided)
- self.putDisplay(StopDisplay)
return True
if displayFormat == SeparateUtf8StringFormat:
@@ -1088,21 +1033,18 @@ class DumperBase:
self.putType(typeName)
(elided, data) = self.encodeCArray(value, 1, limit)
self.putValue(data, Hex2EncodedLocal8Bit, elided=elided)
- self.putDisplay(StopDisplay)
return True
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 displayFormat == Ucs4StringFormat:
self.putType(typeName)
(elided, data) = self.encodeCArray(value, 4, limit)
self.putValue(data, Hex8EncodedLittleEndian, elided=elided)
- self.putDisplay(StopDisplay)
return True
return False
@@ -1155,7 +1097,7 @@ class DumperBase:
if displayFormat == SeparateLatin1StringFormat \
or displayFormat == SeparateUtf8StringFormat:
limit = 1000000
- if self.tryPutSimpleFormattedPointer(value, typeName, displayFormat, limit):
+ if self.tryPutSimpleFormattedPointer(value, typeName, innerTypeName, displayFormat, limit):
self.putNumChild(0)
return
@@ -1555,22 +1497,18 @@ class DumperBase:
self.putArrayData(addr, n, self.lookupType(typeName))
self.putAddress(addr)
- def putPlotData(self, base, n, typeobj):
+ def putPlotDataHelper(self, base, n, innerType):
+ if self.currentItemFormat() == ArrayPlotFormat and self.isSimpleType(innerType):
+ enc = self.simpleEncoding(innerType)
+ if enc:
+ self.putField("editencoding", enc)
+ self.putField("editvalue", self.readMemory(base, n * innerType.sizeof))
+ self.putField("editformat", DisplayPlotData)
+
+ def putPlotData(self, base, n, innerType):
+ self.putPlotDataHelper(base, n, innerType)
if self.isExpanded():
- self.putArrayData(base, n, typeobj)
- if hasPlot:
- if self.isSimpleType(typeobj):
- show = self.currentItemFormat() == ArrayPlotFormat
- iname = self.currentIName
- data = []
- if show:
- base = self.createPointerValue(base, typeobj)
- data = [str(base[i]) for i in range(0, toInteger(n))]
- matplotSend(iname, show, data)
- else:
- #self.putValue(self.currentValue.value + " (not plottable)")
- self.putValue(self.currentValue.value)
- self.putField("plottable", "0")
+ self.putArrayData(base, n, innerType)
def putSpecialArgv(self, value):
"""
@@ -1757,10 +1695,6 @@ class DumperBase:
self.qqEditable = {}
self.typeCache = {}
- if hasPlot: # Hack for generic array type. [] is used as "type" name.
- self.qqDumpers['[]'] = ""
- self.qqFormats['[]'] = arrayForms()
-
for mod in self.dumpermodules:
m = importlib.import_module(mod)
dic = m.__dict__
@@ -1981,48 +1915,3 @@ class DumperBase:
return items
-# Some "Enums"
-
-# Encodings. Keep that synchronized with DebuggerEncoding in debuggerprotocol.h
-Unencoded8Bit, \
-Base64Encoded8BitWithQuotes, \
-Base64Encoded16BitWithQuotes, \
-Base64Encoded32BitWithQuotes, \
-Base64Encoded16Bit, \
-Base64Encoded8Bit, \
-Hex2EncodedLatin1, \
-Hex4EncodedLittleEndian, \
-Hex8EncodedLittleEndian, \
-Hex2EncodedUtf8, \
-Hex8EncodedBigEndian, \
-Hex4EncodedBigEndian, \
-Hex4EncodedLittleEndianWithoutQuotes, \
-Hex2EncodedLocal8Bit, \
-JulianDate, \
-MillisecondsSinceMidnight, \
-JulianDateAndMillisecondsSinceMidnight, \
-Hex2EncodedInt1, \
-Hex2EncodedInt2, \
-Hex2EncodedInt4, \
-Hex2EncodedInt8, \
-Hex2EncodedUInt1, \
-Hex2EncodedUInt2, \
-Hex2EncodedUInt4, \
-Hex2EncodedUInt8, \
-Hex2EncodedFloat4, \
-Hex2EncodedFloat8, \
-IPv6AddressAndHexScopeId, \
-Hex2EncodedUtf8WithoutQuotes, \
-DateTimeInternal \
- = range(30)
-
-# Display modes. Keep that synchronized with DebuggerDisplay in watchutils.h
-StopDisplay, \
-DisplayImageData, \
-DisplayUtf16String, \
-DisplayImageFile, \
-DisplayLatin1String, \
-DisplayUtf8String \
- = range(6)
-
-
diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py
index e8f07d68f38..06ec7954479 100644
--- a/share/qtcreator/debugger/gdbbridge.py
+++ b/share/qtcreator/debugger/gdbbridge.py
@@ -1615,8 +1615,6 @@ class Dumper(DumperBase):
self.qmlBreakpoints.append(Resolver(self, args))
def exitGdb(self, _):
- if hasPlot:
- matplotQuit()
gdb.execute("quit")
def loadDumpers(self, args):
diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py
index 59a0829d9d5..8323314d346 100644
--- a/share/qtcreator/debugger/qttypes.py
+++ b/share/qtcreator/debugger/qttypes.py
@@ -62,14 +62,12 @@ def qdump__QByteArray(d, value):
elided, p = d.encodeByteArrayHelper(d.extractPointer(value), d.displayStringLimit)
displayFormat = d.currentItemFormat()
if displayFormat == AutomaticFormat or displayFormat == Latin1StringFormat:
- d.putDisplay(StopDisplay)
d.putValue(p, Hex2EncodedLatin1, elided=elided)
elif displayFormat == SeparateLatin1StringFormat:
d.putValue(p, Hex2EncodedLatin1, elided=elided)
d.putField("editformat", DisplayLatin1String)
d.putField("editvalue", d.encodeByteArray(value, limit=100000))
elif displayFormat == Utf8StringFormat:
- d.putDisplay(StopDisplay)
d.putValue(p, Hex2EncodedUtf8, elided=elided)
elif displayFormat == SeparateUtf8StringFormat:
d.putValue(p, Hex2EncodedUtf8, elided=elided)
@@ -546,8 +544,7 @@ def qdump__QFiniteStack(d, value):
size = int(value["_size"])
d.check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000)
d.putItemCount(size)
- if d.isExpanded():
- d.putPlotData(value["_array"], size, d.templateArgument(value.type, 0))
+ d.putPlotData(value["_array"], size, d.templateArgument(value.type, 0))
def qdump__QFlags(d, value):
@@ -847,9 +844,7 @@ def qdump__QImage(d, value):
d.putType("void *")
displayFormat = d.currentItemFormat()
- if displayFormat == SimpleFormat:
- d.putDisplay(StopDisplay)
- elif displayFormat == SeparateFormat:
+ if 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_")
@@ -1743,9 +1738,7 @@ def qdump__QString(d, value):
data, size, alloc = d.stringData(value)
d.putNumChild(size)
displayFormat = d.currentItemFormat()
- if displayFormat == SimpleFormat:
- d.putDisplay(StopDisplay)
- elif displayFormat == SeparateFormat:
+ if displayFormat == SeparateFormat:
d.putField("editformat", DisplayUtf16String)
d.putField("editvalue", d.encodeString(value, limit=100000))
if d.isExpanded():
@@ -1897,9 +1890,7 @@ def qdump__QUrl(d, value):
d.putValue(url, Hex4EncodedLittleEndian)
displayFormat = d.currentItemFormat()
- if displayFormat == SimpleFormat:
- d.putDisplay(StopDisplay)
- elif displayFormat == SeparateFormat:
+ if 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 54a6cc34d71..eb34ac41594 100644
--- a/share/qtcreator/debugger/stdtypes.py
+++ b/share/qtcreator/debugger/stdtypes.py
@@ -711,15 +711,15 @@ def qdump__std__vector(d, value):
d.checkPointer(alloc)
d.putItemCount(size)
- if d.isExpanded():
- if isBool:
+ if isBool:
+ if d.isExpanded():
with Children(d, size, maxNumChild=10000, childType=type):
base = d.pointerValue(start)
for i in d.childRange():
q = base + int(i / 8)
d.putBoolItem(str(i), (int(d.extractPointer(q)) >> (i % 8)) & 1)
- else:
- d.putPlotData(start, size, type)
+ else:
+ d.putPlotData(start, size, type)
def qdump__std__vector__QNX(d, value):
innerType = d.templateArgument(value.type, 0)
diff --git a/src/plugins/debugger/debuggerprotocol.h b/src/plugins/debugger/debuggerprotocol.h
index 3214fdb76e0..7bccb4356ba 100644
--- a/src/plugins/debugger/debuggerprotocol.h
+++ b/src/plugins/debugger/debuggerprotocol.h
@@ -246,7 +246,8 @@ enum DebuggerDisplay {
DisplayUtf16String = 2,
DisplayImageFile = 3,
DisplayLatin1String = 4,
- DisplayUtf8String = 5
+ DisplayUtf8String = 5,
+ DisplayPlotData = 6
};
// Decode string data as returned by the dumper helpers.
QString decodeData(const QByteArray &baIn, int encoding);
diff --git a/src/plugins/debugger/imageviewer.cpp b/src/plugins/debugger/imageviewer.cpp
index 898ef7069a2..cc3a614124b 100644
--- a/src/plugins/debugger/imageviewer.cpp
+++ b/src/plugins/debugger/imageviewer.cpp
@@ -114,11 +114,15 @@ ImageViewer::ImageViewer(QWidget *parent)
connect(m_imageWidget, &ImageWidget::clicked, this, &ImageViewer::clicked);
}
-void ImageViewer::setImage(const QImage &i)
+void ImageViewer::setImage(const QImage &image)
{
- m_imageWidget->setImage(i);
- m_info = tr("Size: %1x%2, %3 byte, format: %4, depth: %5")
- .arg(i.width()).arg(i.height()).arg(i.byteCount()).arg(i.format()).arg(i.depth());
+ m_imageWidget->setImage(image);
+ clicked(QString());
+}
+
+void ImageViewer::setInfo(const QString &info)
+{
+ m_info = info;
clicked(QString());
}
@@ -165,4 +169,77 @@ void ImageViewer::contextMenuEvent(QContextMenuEvent *ev)
openImageViewer(image);
}
+
+//
+//
+//
+
+PlotViewer::PlotViewer(QWidget *parent)
+ : QWidget(parent)
+{
+}
+
+void PlotViewer::setData(const PlotViewer::Data &data)
+{
+ m_data = data;
+ update();
+}
+
+void PlotViewer::setInfo(const QString &description)
+{
+ m_info = description;
+ update();
+}
+
+void PlotViewer::paintEvent(QPaintEvent *)
+{
+ QPainter pain(this);
+
+ const int n = int(m_data.size());
+ const int w = width();
+ const int h = height();
+ const int b = 10; // Border width.
+
+ pain.fillRect(rect(), Qt::white);
+
+ double ymin = 0;
+ double ymax = 0;
+ for (int i = 0; i < n; ++i) {
+ const double v = m_data.at(i);
+ if (v < ymin)
+ ymin = v;
+ else if (v > ymax)
+ ymax = v;
+ }
+
+ const double d = ymin == ymax ? (h / 2 - b) : (ymax - ymin);
+ const int k = 1; // Length of cross marker arms.
+
+ for (int i = 0; i + 1 < n; ++i) {
+ // Lines between points.
+ const int x1 = b + i * (w - 2 * b) / (n - 1);
+ const int x2 = b + (i + 1) * (w - 2 * b) / (n - 1);
+ const int y1 = h - (b + int((m_data[i] - ymin) * (h - 2 * b) / d));
+ const int y2 = h - (b + int((m_data[i + 1] - ymin) * (h - 2 * b) / d));
+ pain.drawLine(x1, y1, x2, y2);
+
+ if (i == 0) {
+ // Little cross marker on first point
+ pain.drawLine(x1 - k, y1 - k, x1 + k, y1 + k);
+ pain.drawLine(x1 + k, y1 - k, x1 - k, y1 + k);
+ }
+ // ... and all subsequent points.
+ pain.drawLine(x2 - k, y2 - k, x2 + k, y2 + k);
+ pain.drawLine(x2 + k, y2 - k, x2 - k, y2 + k);
+ }
+
+ if (n) {
+ pain.drawText(10, 10,
+ QString::fromLatin1("%5 items. X: %1..%2, Y: %3...%4").arg(0).arg(n).arg(ymin).arg(ymax).arg(n));
+ } else {
+ pain.drawText(10, 10,
+ QString::fromLatin1("Container is empty"));
+ }
+}
+
#include "imageviewer.moc"
diff --git a/src/plugins/debugger/imageviewer.h b/src/plugins/debugger/imageviewer.h
index 668453daa59..5ddee6f022b 100644
--- a/src/plugins/debugger/imageviewer.h
+++ b/src/plugins/debugger/imageviewer.h
@@ -33,6 +33,8 @@
#include
+#include
+
QT_BEGIN_NAMESPACE
class QScrollArea;
class QLabel;
@@ -49,19 +51,36 @@ class ImageViewer : public QWidget
public:
explicit ImageViewer(QWidget *parent = 0);
- void setImage(const QImage &);
+ void setImage(const QImage &image);
+ void setInfo(const QString &description);
protected:
void contextMenuEvent(QContextMenuEvent *);
-private slots:
+private:
void clicked(const QString &);
-private:
QScrollArea *m_scrollArea;
ImageWidget *m_imageWidget;
QLabel *m_infoLabel;
QString m_info;
};
+class PlotViewer : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit PlotViewer(QWidget *parent = 0);
+
+ typedef std::vector Data;
+ void setData(const Data &data);
+ void setInfo(const QString &description);
+
+ void paintEvent(QPaintEvent *ev);
+
+private:
+ Data m_data;
+ QString m_info;
+};
+
#endif // IMAGEVIEWER_H
diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp
index 098051d9e9e..6d468352274 100644
--- a/src/plugins/debugger/watchdata.cpp
+++ b/src/plugins/debugger/watchdata.cpp
@@ -122,6 +122,7 @@ WatchData::WatchData() :
id(0),
state(InitialState),
editformat(StopDisplay),
+ editencoding(Unencoded8Bit),
address(0),
origaddr(0),
size(0),
@@ -552,14 +553,12 @@ void parseChildrenData(const WatchData &data0, const GdbMi &item,
GdbMi children = item["children"];
data.updateType(item["type"]);
- GdbMi mi = item["editvalue"];
- if (mi.isValid())
- data.editvalue = mi.data();
- mi = item["editformat"];
- data.editformat = DebuggerDisplay(mi.toInt());
+ data.editvalue = item["editvalue"].data();
+ data.editformat = DebuggerDisplay(item["editformat"].toInt());
+ data.editencoding = DebuggerEncoding(item["editencoding"].toInt());
- mi = item["valueelided"];
+ GdbMi mi = item["valueelided"];
if (mi.isValid())
data.elided = mi.toInt();
@@ -658,6 +657,52 @@ void parseWatchData(const WatchData &data0, const GdbMi &input,
parseChildrenData(data0, input, itemHandler, childHandler, arrayDecoder);
}
+template
+void readNumericVectorHelper(std::vector *v, const QByteArray &ba)
+{
+ const T *p = (const T *) ba.data();
+ std::copy(p, p + ba.size() / sizeof(T), std::back_insert_iterator >(*v));
+}
+
+void readNumericVector(std::vector *v, const QByteArray &rawData, DebuggerEncoding encoding)
+{
+ switch (encoding) {
+ case Hex2EncodedInt1:
+ readNumericVectorHelper(v, rawData);
+ break;
+ case Hex2EncodedInt2:
+ readNumericVectorHelper(v, rawData);
+ break;
+ case Hex2EncodedInt4:
+ readNumericVectorHelper(v, rawData);
+ break;
+ case Hex2EncodedInt8:
+ readNumericVectorHelper(v, rawData);
+ break;
+ case Hex2EncodedUInt1:
+ readNumericVectorHelper(v, rawData);
+ break;
+ case Hex2EncodedUInt2:
+ readNumericVectorHelper(v, rawData);
+ break;
+ case Hex2EncodedUInt4:
+ readNumericVectorHelper(v, rawData);
+ break;
+ case Hex2EncodedUInt8:
+ readNumericVectorHelper(v, rawData);
+ break;
+ case Hex2EncodedFloat4:
+ readNumericVectorHelper(v, rawData);
+ break;
+ case Hex2EncodedFloat8:
+ readNumericVectorHelper(v, rawData);
+ break;
+ default:
+ qDebug() << "ENCODING ERROR: " << encoding;
+ }
+
+}
+
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/watchdata.h b/src/plugins/debugger/watchdata.h
index 5aa68af9652..58a61609fc7 100644
--- a/src/plugins/debugger/watchdata.h
+++ b/src/plugins/debugger/watchdata.h
@@ -37,6 +37,7 @@
#include
#include
+#include
namespace Debugger {
namespace Internal {
@@ -113,6 +114,7 @@ public:
QString value; // Displayed value
QByteArray editvalue; // Displayed value
DebuggerDisplay editformat; // Format of displayed value
+ DebuggerEncoding editencoding; // Encoding of displayed value
QByteArray type; // Type for further processing
QString displayedType; // Displayed type (optional)
quint64 address; // Displayed address of the actual object
@@ -134,6 +136,10 @@ void decodeArrayData(std::function itemHandler,
const QByteArray &rawData,
int encoding);
+void readNumericVector(std::vector *,
+ const QByteArray &rawData,
+ DebuggerEncoding encoding);
+
void parseChildrenData(const WatchData &parent, const GdbMi &child,
std::function itemHandler,
std::function childHandler,
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index 9ac7dbbedaa..cc27ae30c1d 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -53,11 +53,13 @@
#include
#include
+#include
#include
#include
#include
#include
+#include
#include
#include
@@ -109,6 +111,52 @@ static void saveWatchers()
setSessionValue("Watchers", WatchHandler::watchedExpressions());
}
+static void loadFormats()
+{
+ QVariant value = sessionValue("DefaultFormats");
+ QMapIterator it(value.toMap());
+ while (it.hasNext()) {
+ it.next();
+ if (!it.key().isEmpty())
+ theTypeFormats.insert(it.key().toUtf8(), it.value().toInt());
+ }
+
+ value = sessionValue("IndividualFormats");
+ it = QMapIterator(value.toMap());
+ while (it.hasNext()) {
+ it.next();
+ if (!it.key().isEmpty())
+ theIndividualFormats.insert(it.key().toUtf8(), it.value().toInt());
+ }
+}
+
+static void saveFormats()
+{
+ QMap formats;
+ QHashIterator it(theTypeFormats);
+ while (it.hasNext()) {
+ it.next();
+ const int format = it.value();
+ if (format != AutomaticFormat) {
+ const QByteArray key = it.key().trimmed();
+ if (!key.isEmpty())
+ formats.insert(QString::fromLatin1(key), format);
+ }
+ }
+ setSessionValue("DefaultFormats", formats);
+
+ formats.clear();
+ it = QHashIterator(theIndividualFormats);
+ while (it.hasNext()) {
+ it.next();
+ const int format = it.value();
+ const QByteArray key = it.key().trimmed();
+ if (!key.isEmpty())
+ formats.insert(QString::fromLatin1(key), format);
+ }
+ setSessionValue("IndividualFormats", formats);
+}
+
///////////////////////////////////////////////////////////////////////
//
// SeparatedView
@@ -126,17 +174,29 @@ public:
setWindowTitle(WatchHandler::tr("Debugger - Qt Creator"));
QVariant geometry = sessionValue("DebuggerSeparateWidgetGeometry");
- if (geometry.isValid())
- setGeometry(geometry.toRect());
+ if (geometry.isValid()) {
+ QRect rc = geometry.toRect();
+ if (rc.width() < 200)
+ rc.setWidth(200);
+ if (rc.height() < 200)
+ rc.setHeight(200);
+ setGeometry(rc);
+ }
}
- ~SeparatedView()
+ void saveGeometry()
{
setSessionValue("DebuggerSeparateWidgetGeometry", geometry());
}
+ ~SeparatedView()
+ {
+ saveGeometry();
+ }
+
void removeObject(const QByteArray &key)
{
+ saveGeometry();
if (QWidget *w = findWidget(key)) {
removeTab(indexOf(w));
sanitize();
@@ -145,9 +205,11 @@ public:
void closeTab(int index)
{
+ saveGeometry();
if (QObject *o = widget(index)) {
QByteArray iname = o->property(INameProperty).toByteArray();
theIndividualFormats.remove(iname);
+ saveFormats();
}
removeTab(index);
sanitize();
@@ -170,7 +232,7 @@ public:
return 0;
}
- template T *prepareObject(const QByteArray &key, const QString &title)
+ template T *prepareObject(const QByteArray &key, const QString &tabName)
{
T *t = 0;
if (QWidget *w = findWidget(key)) {
@@ -181,7 +243,7 @@ public:
if (!t) {
t = new T;
t->setProperty(KeyProperty, key);
- addTab(t, title);
+ addTab(t, tabName);
}
setCurrentWidget(t);
@@ -218,8 +280,9 @@ public:
void insertItem(WatchItem *item);
void reexpandItems();
- void showEditValue(const WatchData &data);
- void setFormat(const QByteArray &type, int format);
+ void showEditValue(const WatchItem *item);
+ void setTypeFormat(const QByteArray &type, int format);
+ void setIndividualFormat(const QByteArray &iname, int format);
QString removeNamespaces(QString str) const;
@@ -884,16 +947,12 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role
break;
case LocalsTypeFormatRole:
- setFormat(item->type, value.toInt());
+ setTypeFormat(item->type, value.toInt());
m_engine->updateWatchItem(item);
break;
case LocalsIndividualFormatRole: {
- const int format = value.toInt();
- if (format == AutomaticFormat)
- theIndividualFormats.remove(item->iname);
- else
- theIndividualFormats[item->iname] = format;
+ setIndividualFormat(item->iname, value.toInt());
m_engine->updateWatchItem(item);
break;
}
@@ -1010,7 +1069,7 @@ DisplayFormats WatchItem::typeFormatList() const
formats << watchModel()->m_reportedTypeFormats.value(t);
if (t.contains(QLatin1Char(']')))
- formats << watchModel()->m_reportedTypeFormats.value(QLatin1String("[]"));
+ formats.append(ArrayPlotFormat);
// Fixed artificial string and pointer types.
if (origaddr || isPointerType(type)) {
@@ -1132,7 +1191,7 @@ void WatchModel::reinsertAllData()
emit inameIsExpanded(parent->iname);
emit itemIsExpanded(indexFromItem(parent));
}
- showEditValue(data);
+ showEditValue(newItem); // FIXME: Needed?
}
}
@@ -1192,7 +1251,7 @@ void WatchModel::insertItem(WatchItem *item)
const int row = findInsertPosition(parent->children(), item);
parent->insertChild(row, item);
- item->walkTree([this](TreeItem *sub) { showEditValue(*static_cast(sub)); });
+ item->walkTree([this](TreeItem *sub) { showEditValue(static_cast(sub)); });
}
void WatchModel::reexpandItems()
@@ -1326,20 +1385,20 @@ static void swapEndian(char *d, int nchar)
}
}
-void WatchModel::showEditValue(const WatchData &data)
+void WatchModel::showEditValue(const WatchItem *item)
{
- const QByteArray key = data.address ? data.hexAddress() : data.iname;
- switch (data.editformat) {
+ const QByteArray key = item->address ? item->hexAddress() : item->iname;
+ switch (item->editformat) {
case StopDisplay:
- m_separatedView->removeObject(data.iname);
+ m_separatedView->removeObject(key);
break;
case DisplayImageData:
case DisplayImageFile: { // QImage
int width = 0, height = 0, nbytes = 0, format = 0;
QByteArray ba;
uchar *bits = 0;
- if (data.editformat == DisplayImageData) {
- ba = QByteArray::fromHex(data.editvalue);
+ if (item->editformat == DisplayImageData) {
+ ba = QByteArray::fromHex(item->editvalue);
QTC_ASSERT(ba.size() > 16, return);
const int *header = (int *)(ba.data());
if (!ba.at(0) && !ba.at(1)) // Check on 'width' for Python dumpers returning 4-byte swapped-data.
@@ -1349,8 +1408,8 @@ void WatchModel::showEditValue(const WatchData &data)
height = header[1];
nbytes = header[2];
format = header[3];
- } else if (data.editformat == DisplayImageFile) {
- QTextStream ts(data.editvalue);
+ } else if (item->editformat == DisplayImageFile) {
+ QTextStream ts(item->editvalue);
QString fileName;
ts >> width >> height >> nbytes >> format >> fileName;
QFile f(fileName);
@@ -1365,33 +1424,45 @@ void WatchModel::showEditValue(const WatchData &data)
QTC_ASSERT(0 < format && format < 32, return);
QImage im(width, height, QImage::Format(format));
std::memcpy(im.bits(), bits, nbytes);
- const QString title = data.address ?
- tr("%1 Object at %2").arg(QLatin1String(data.type),
- QLatin1String(data.hexAddress())) :
- tr("%1 Object at Unknown Address").arg(QLatin1String(data.type));
- ImageViewer *v = m_separatedView->prepareObject(key, title);
- v->setProperty(INameProperty, data.iname);
+ ImageViewer *v = m_separatedView->prepareObject(key, item->name);
+ v->setProperty(INameProperty, item->iname);
+ v->setInfo(item->address ?
+ tr("%1 Object at %2").arg(QLatin1String(item->type),
+ QLatin1String(item->hexAddress())) :
+ tr("%1 Object at Unknown Address").arg(QLatin1String(item->type))
+ + QLatin1String(" ") +
+ ImageViewer::tr("Size: %1x%2, %3 byte, format: %4, depth: %5")
+ .arg(width).arg(height).arg(nbytes).arg(im.format()).arg(im.depth())
+ );
v->setImage(im);
break;
}
case DisplayUtf16String:
case DisplayLatin1String:
case DisplayUtf8String: { // String data.
- QByteArray ba = QByteArray::fromHex(data.editvalue);
+ QByteArray ba = QByteArray::fromHex(item->editvalue);
QString str;
- if (data.editformat == DisplayUtf16String)
+ if (item->editformat == DisplayUtf16String)
str = QString::fromUtf16((ushort *)ba.constData(), ba.size()/2);
- else if (data.editformat == DisplayLatin1String)
+ else if (item->editformat == DisplayLatin1String)
str = QString::fromLatin1(ba.constData(), ba.size());
- else if (data.editformat == DisplayUtf8String)
+ else if (item->editformat == DisplayUtf8String)
str = QString::fromUtf8(ba.constData(), ba.size());
- QTextEdit *t = m_separatedView->prepareObject(key, data.name);
- t->setProperty(INameProperty, data.iname);
+ QTextEdit *t = m_separatedView->prepareObject(key, item->name);
+ t->setProperty(INameProperty, item->iname);
t->setText(str);
break;
}
+ case DisplayPlotData: { // Plots
+ std::vector data;
+ readNumericVector(&data, QByteArray::fromHex(item->editvalue), item->editencoding);
+ PlotViewer *v = m_separatedView->prepareObject(key, item->name);
+ v->setProperty(INameProperty, item->iname);
+ v->setData(data);
+ break;
+ }
default:
- QTC_ASSERT(false, qDebug() << "Display format: " << data.editformat);
+ QTC_ASSERT(false, qDebug() << "Display format: " << item->editformat);
break;
}
}
@@ -1439,52 +1510,6 @@ QStringList WatchHandler::watchedExpressions()
return watcherNames;
}
-static void loadFormats()
-{
- QVariant value = sessionValue("DefaultFormats");
- QMapIterator it(value.toMap());
- while (it.hasNext()) {
- it.next();
- if (!it.key().isEmpty())
- theTypeFormats.insert(it.key().toUtf8(), it.value().toInt());
- }
-
- value = sessionValue("IndividualFormats");
- it = QMapIterator(value.toMap());
- while (it.hasNext()) {
- it.next();
- if (!it.key().isEmpty())
- theIndividualFormats.insert(it.key().toUtf8(), it.value().toInt());
- }
-}
-
-static void saveFormats()
-{
- QMap formats;
- QHashIterator it(theTypeFormats);
- while (it.hasNext()) {
- it.next();
- const int format = it.value();
- if (format != AutomaticFormat) {
- const QByteArray key = it.key().trimmed();
- if (!key.isEmpty())
- formats.insert(QString::fromLatin1(key), format);
- }
- }
- setSessionValue("DefaultFormats", formats);
-
- formats.clear();
- it = QHashIterator(theIndividualFormats);
- while (it.hasNext()) {
- it.next();
- const int format = it.value();
- const QByteArray key = it.key().trimmed();
- if (!key.isEmpty())
- formats.insert(QString::fromLatin1(key), format);
- }
- setSessionValue("IndividualFormats", formats);
-}
-
void WatchHandler::saveSessionData()
{
saveWatchers();
@@ -1537,7 +1562,7 @@ const WatchItem *WatchHandler::findCppLocalVariable(const QString &name) const
return 0;
}
-void WatchModel::setFormat(const QByteArray &type0, int format)
+void WatchModel::setTypeFormat(const QByteArray &type0, int format)
{
const QByteArray type = stripForFormat(type0);
if (format == AutomaticFormat)
@@ -1548,6 +1573,15 @@ void WatchModel::setFormat(const QByteArray &type0, int format)
reinsertAllData();
}
+void WatchModel::setIndividualFormat(const QByteArray &iname, int format)
+{
+ if (format == AutomaticFormat)
+ theIndividualFormats.remove(iname);
+ else
+ theIndividualFormats[iname] = format;
+ saveFormats();
+}
+
int WatchHandler::format(const QByteArray &iname) const
{
int result = AutomaticFormat;
From 8548343ef42cd3ac40bab9eb4a314787f716323d Mon Sep 17 00:00:00 2001
From: David Schulz
Date: Thu, 2 Apr 2015 14:48:53 +0200
Subject: [PATCH 09/38] Test: Dumper: Fix Compilation and adjust cdb output of
"BigInt" test.
Change-Id: I8ecfd77cd72e155e291acdc96fcbfd49572c91e3
Reviewed-by: hjk
---
tests/auto/debugger/tst_dumpers.cpp | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp
index 4a514b588c6..845d1ba063b 100644
--- a/tests/auto/debugger/tst_dumpers.cpp
+++ b/tests/auto/debugger/tst_dumpers.cpp
@@ -5044,10 +5044,15 @@ void tst_Dumpers::dumper_data()
"qint64 d = c;\n"
"QString dummy;\n"
"unused(&a, &b, &c, &d, &dummy);\n")
- + Check("a", "-1143861252567568256", "@qint64")
- + Check("b", "17302882821141983360", "@quint64")
- + Check("c", "18446744073709551614", "@quint64")
- + Check("d", "-2", "@qint64");
+ + CoreProfile()
+ + Check("a", "-1143861252567568256", "@qint64") % NoCdbEngine
+ + Check("b", "17302882821141983360", "@quint64") % NoCdbEngine
+ + Check("c", "18446744073709551614", "@quint64") % NoCdbEngine
+ + Check("d", "-2", "@qint64") % NoCdbEngine
+ + Check("a", "-1143861252567568256", "int64") % CdbEngine
+ + Check("b", "17302882821141983360", "unsigned int64") % CdbEngine
+ + Check("c", "18446744073709551614", "unsigned int64") % CdbEngine
+ + Check("d", "-2", "int64") % CdbEngine;
QTest::newRow("Hidden")
<< Data("#include \n",
From 02b521a8ff5cf9102fbf468adc07fac5ba4f5d63 Mon Sep 17 00:00:00 2001
From: Robert Loehning
Date: Thu, 2 Apr 2015 13:07:16 +0200
Subject: [PATCH 10/38] Squish: Fix reading tooltips in tst_qml_editor
Change-Id: Ie65752d2c8c87c3802c810b98ffe7b122549c762
Reviewed-by: Christian Stenger
---
tests/system/shared/editor_utils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/system/shared/editor_utils.py b/tests/system/shared/editor_utils.py
index 41c10040196..4ba01b058aa 100644
--- a/tests/system/shared/editor_utils.py
+++ b/tests/system/shared/editor_utils.py
@@ -153,7 +153,7 @@ def verifyHoveringOnEditor(editor, lines, additionalKeyPresses, expectedTypes, e
for ty in additionalKeyPresses:
type(editor, ty)
rect = editor.cursorRect(editor.textCursor())
- expectedToolTip = "{type='%s' visible='1'}" % expectedType
+ expectedToolTip = "{type='QTipLabel' visible='1'}"
# wait for similar tooltips to disappear
checkIfObjectExists(expectedToolTip, False, 1000, True)
sendEvent("QMouseEvent", editor, QEvent.MouseMove, rect.x+rect.width/2, rect.y+rect.height/2, Qt.NoButton, 0)
From 28c06b5b58230ad201fccf012bcb3c9690b92ff1 Mon Sep 17 00:00:00 2001
From: David Schulz
Date: Thu, 2 Apr 2015 13:19:40 +0200
Subject: [PATCH 11/38] Test: Dumper: Adjust QVector test to cdb output.
Change-Id: I2da7f4b21251e1417efaf20813ce260ea286b1f2
Reviewed-by: Christian Stenger
---
tests/auto/debugger/tst_dumpers.cpp | 30 +++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp
index 845d1ba063b..3cbc36bddbc 100644
--- a/tests/auto/debugger/tst_dumpers.cpp
+++ b/tests/auto/debugger/tst_dumpers.cpp
@@ -3540,29 +3540,39 @@ void tst_Dumpers::dumper_data()
+ Check("v1.8999", "[8999]", "80982001", "int")
+ Check("v2", "<2 items>", "@QVector")
- + Check("v2.0", "[0]", "", "Foo")
+ + Check("v2.0", "[0]", "", "Foo") % NoCdbEngine
+ + Check("v2.0", "[0]", "class Foo", "Foo") % CdbEngine
+ Check("v2.0.a", "1", "int")
- + Check("v2.1", "[1]", "", "Foo")
+ + Check("v2.1", "[1]", "", "Foo") % NoCdbEngine
+ + Check("v2.1", "[1]", "class Foo", "Foo") % CdbEngine
+ Check("v2.1.a", "2", "int")
- + Check("v3", "<2 items>", "FooVector")
- + Check("v3.0", "[0]", "", "Foo")
+ + Check("v3", "<2 items>", "FooVector") % NoCdbEngine
+ + Check("v3", "<2 items>", "QVector") % CdbEngine
+ + Check("v3.0", "[0]", "", "Foo") % NoCdbEngine
+ + Check("v3.0", "[0]", "class Foo", "Foo") % CdbEngine
+ Check("v3.0.a", "1", "int")
- + Check("v3.1", "[1]", "", "Foo")
+ + Check("v3.1", "[1]", "", "Foo") % NoCdbEngine
+ + Check("v3.1", "[1]", "class Foo", "Foo") % CdbEngine
+ Check("v3.1.a", "2", "int")
+ Check("v4", "<3 items>", "@QVector")
- + CheckType("v4.0", "[0]", "Foo")
+ + CheckType("v4.0", "[0]", "Foo") % NoCdbEngine
+ + CheckType("v4.0", "[0]", "Foo *") % CdbEngine
+ Check("v4.0.a", "1", "int")
+ Check("v4.1", "[1]", "0x0", "Foo *")
- + CheckType("v4.2", "[2]", "Foo")
+ + CheckType("v4.2", "[2]", "Foo") % NoCdbEngine
+ + CheckType("v4.2", "[2]", "Foo *") % CdbEngine
+ Check("v4.2.a", "5", "int")
+ Check("v5", "<2 items>", "@QVector")
- + Check("v5.0", "[0]", "1", "bool")
- + Check("v5.1", "[1]", "0", "bool")
+ + Check("v5.0", "[0]", "1", "bool") % NoCdbEngine
+ + Check("v5.1", "[1]", "0", "bool") % NoCdbEngine
+ + Check("v5.0", "[0]", "true", "bool") % CdbEngine
+ + Check("v5.1", "[1]", "false", "bool") % CdbEngine
- + CheckType("pv", "@QVector<@QList>")
+ + CheckType("pv", "@QVector<@QList>") % NoCdbEngine
+ + CheckType("pv", "QVector > *") % CdbEngine
+ Check("pv.0", "[0]", "<1 items>", "@QList")
+ Check("pv.0.0", "[0]", "1", "int")
+ Check("pv.1", "[1]", "<2 items>", "@QList")
From 4deadb5f8bf476018736c44806cc4fac5a189810 Mon Sep 17 00:00:00 2001
From: Christian Stenger
Date: Thu, 2 Apr 2015 15:55:37 +0200
Subject: [PATCH 12/38] Dumper: Test: Fix execution of dumper tests for LLDB
Change-Id: Id4f437fe17d7989c15ad223c20605773411a1142
Reviewed-by: hjk
---
share/qtcreator/debugger/lldbbridge.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py
index 8007242e222..e8e6c29bb11 100644
--- a/share/qtcreator/debugger/lldbbridge.py
+++ b/share/qtcreator/debugger/lldbbridge.py
@@ -509,15 +509,15 @@ class Dumper(DumperBase):
return int(value.GetLoadAddress())
def extractInt(self, address):
- error = SBError()
+ error = lldb.SBError()
return int(self.process.ReadUnsignedFromMemory(address, 4, error))
def extractInt64(self, address):
- error = SBError()
+ error = lldb.SBError()
return int(self.process.ReadUnsignedFromMemory(address, 8, error))
def extractByte(self, address):
- error = SBError()
+ error = lldb.SBError()
return int(self.process.ReadUnsignedFromMemory(address, 1, error) & 0xFF)
def handleCommand(self, command):
@@ -1130,13 +1130,13 @@ class Dumper(DumperBase):
with SubItem(self, child):
self.putItem(child)
- def reportVariables(self, args = None):
+ def reportVariables(self, args = {}):
with self.outputLock:
sys.stdout.write("@\n")
self.reportVariablesHelper(args)
sys.stdout.write("@\n")
- def reportVariablesHelper(self, args = None):
+ def reportVariablesHelper(self, args = {}):
frame = self.currentFrame()
if frame is None:
return
From e6f73164c3557b0b6b5c4d8be4fecc7472b5552d Mon Sep 17 00:00:00 2001
From: hjk
Date: Thu, 2 Apr 2015 14:10:26 +0200
Subject: [PATCH 13/38] Debugger: Adjust QVariant2 dumper test
Take new QPolygon{,F} dumpers into account, also make QUrlPrivate
field accessible,
Change-Id: I2b5c122895c3ee389ba939eaeffcd613fa206009
Reviewed-by: Christian Stenger
---
share/qtcreator/debugger/qttypes.py | 1 +
tests/auto/debugger/tst_dumpers.cpp | 6 +++---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py
index 8323314d346..031c72bf48f 100644
--- a/share/qtcreator/debugger/qttypes.py
+++ b/share/qtcreator/debugger/qttypes.py
@@ -1906,6 +1906,7 @@ def qdump__QUrl(d, value):
d.putGenericItem("path", stringType, path, Hex4EncodedLittleEndian)
d.putGenericItem("query", stringType, query, Hex4EncodedLittleEndian)
d.putGenericItem("fragment", stringType, fragment, Hex4EncodedLittleEndian)
+ d.putFields(value)
def qdumpHelper_QVariant_0(d, blob):
# QVariant::Invalid
diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp
index 3cbc36bddbc..d13b7757ac8 100644
--- a/tests/auto/debugger/tst_dumpers.cpp
+++ b/tests/auto/debugger/tst_dumpers.cpp
@@ -3321,7 +3321,7 @@ void tst_Dumpers::dumper_data()
+ Check("var14", "(invalid)", "@QVariant (QDate)")
+ Check("var15", "(invalid)", "@QVariant (QTime)")
+ Check("var16", "(invalid)", "@QVariant (QDateTime)")
- + Check4("var17.d", "", "@QUrlPrivate")
+ + Check("var17.d", "", "@QUrlPrivate")
+ Check5("var17", UnsubstitutedValue("\"http://foo@qt-project.org:10/have_fun\""), "@QVariant (QUrl)")
+ Check("var17.port", "10", "int")
+ Check("var18", "\"en_US\"", "@QVariant (QLocale)")
@@ -3350,7 +3350,7 @@ void tst_Dumpers::dumper_data()
+ Check("var68", "", "@QVariant (QPalette)")
+ Check("var69", "", "@QVariant (QIcon)")
+ Check("var70", "(invalid)", "@QVariant (QImage)")
- + Check("var71", "", "@QVariant (QPolygon)")
+ + Check("var71", "<0 items>", "@QVariant (QPolygon)")
//+ Check("var72", "", "@QVariant (QRegion)") FIXME
+ Check("var73", "", "@QVariant (QBitmap)")
+ Check("var74", "", "@QVariant (QCursor)")
@@ -3364,7 +3364,7 @@ void tst_Dumpers::dumper_data()
+ Check("var83", "", "@QVariant (QVector3D)")
+ Check("var84", "", "@QVariant (QVector4D)")
+ Check("var85", "", "@QVariant (QQuaternion)")
- + Check("var86", "", "@QVariant (QPolygonF)");
+ + Check("var86", "<0 items>", "@QVariant (QPolygonF)");
QTest::newRow("QVariant4")
From 3417ffad83f4be1e55597883fb099674b8ff93d6 Mon Sep 17 00:00:00 2001
From: hjk
Date: Thu, 2 Apr 2015 14:23:10 +0200
Subject: [PATCH 14/38] Debugger: Make QHash dumper pass again
Failures were due to version specific reordering. This is still
checked in cases h1, h7, h8. Simplify maintanance by removing the
check in the other cases.
Change-Id: I481672e693f6370c75bc4739d6cca937b9f027ea
Reviewed-by: Christian Stenger
---
tests/auto/debugger/tst_dumpers.cpp | 55 +++++------------------------
1 file changed, 9 insertions(+), 46 deletions(-)
diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp
index d13b7757ac8..2de739cf9ca 100644
--- a/tests/auto/debugger/tst_dumpers.cpp
+++ b/tests/auto/debugger/tst_dumpers.cpp
@@ -1684,32 +1684,15 @@ void tst_Dumpers::dumper_data()
"QHash h3;\n"
"h3[\"22.0\"] = 22.0;\n"
- "h3[\"123.0\"] = 22.0;\n"
- "h3[\"111111ss111128.0\"] = 28.0;\n"
- "h3[\"11124.0\"] = 22.0;\n"
- "h3[\"1111125.0\"] = 22.0;\n"
- "h3[\"11111126.0\"] = 22.0;\n"
- "h3[\"111111127.0\"] = 27.0;\n"
- "h3[\"111111111128.0\"] = 28.0;\n"
- "h3[\"111111111111111111129.0\"] = 29.0;\n\n"
"QHash h4;\n"
"h4[\"22.0\"] = 22.0;\n"
- "h4[\"123.0\"] = 22.0;\n"
- "h4[\"111111ss111128.0\"] = 28.0;\n"
- "h4[\"11124.0\"] = 22.0;\n"
- "h4[\"1111125.0\"] = 22.0;\n"
- "h4[\"11111126.0\"] = 22.0;\n"
- "h4[\"111111127.0\"] = 27.0;\n"
- "h4[\"111111111128.0\"] = 28.0;\n"
- "h4[\"111111111111111111129.0\"] = 29.0;\n\n"
"QHash h5;\n"
"h5[22] = \"22.0\";\n\n"
"QHash h6;\n"
"h6[\"22.0\"] = Foo(22);\n"
- "h6[\"33.0\"] = Foo(33);\n\n"
"QObject ob;\n"
"QHash > h7;\n"
@@ -1749,45 +1732,25 @@ void tst_Dumpers::dumper_data()
+ Check("h2.0", "[0] 22", "22", "float")
+ Check("h2.1", "[1] 11", "11", "float")
- + Check("h3", "<9 items>", "@QHash<@QString, int>")
+ + Check("h3", "<1 items>", "@QHash<@QString, int>")
+ Check("h3.0", "[0]", "", "@QHashNode<@QString, int>")
- + Check("h3.0.key", "key", Value4("\"123.0\""), "@QString")
- + Check("h3.0.key", "key", Value5("\"111111111128.0\""), "@QString")
- + Check("h3.0.value", Value4("22"), "int")
- + Check("h3.0.value", Value5("28"), "int")
- + Check("h3.8", "[8]", "", "@QHashNode<@QString, int>")
- + Check("h3.8.key", "key", Value4("\"11124.0\""), "@QString")
- + Check("h3.8.key", "key", Value5("\"123.0\""), "@QString")
- + Check("h3.8.value", "value", Value4("22"), "int")
- + Check("h3.8.value", "value", Value5("22"), "int")
+ + Check("h3.0.key", "key", "\"22.0\"", "@QString")
+ + Check("h3.0.value", "22", "int")
- + Check("h4", "<9 items>", "@QHash<@QByteArray, float>")
+ + Check("h4", "<1 items>", "@QHash<@QByteArray, float>")
+ Check("h4.0", "[0]", "", "@QHashNode<@QByteArray, float>")
- + Check("h4.0.key", Value4("\"123.0\""), "@QByteArray")
- + Check("h4.0.key", Value5("\"111111111128.0\""), "@QByteArray")
- + Check("h4.0.value", Value4("22"), "float")
- + Check("h4.0.value", Value5("28"), "float")
- + Check("h4.8", "[8]", "", "@QHashNode<@QByteArray, float>")
- + Check("h4.8.key", Value4("\"11124.0\""), "@QByteArray")
- + Check("h4.8.key", Value5("\"123.0\""), "@QByteArray")
- + Check("h4.8.value", Value4("22"), "float")
- + Check("h4.8.value", Value5("22"), "float")
+ + Check("h4.0.key", "\"22.0\"", "@QByteArray")
+ + Check("h4.0.value", "22", "float")
+ Check("h5", "<1 items>", "@QHash")
+ Check("h5.0.key", "22", "int")
+ Check("h5.0.value", "\"22.0\"", "@QString")
- + Check("h6", "<2 items>", "@QHash<@QString, Foo>")
+ + Check("h6", "<1 items>", "@QHash<@QString, Foo>")
+ Check("h6.0", "[0]", "", "@QHashNode<@QString, Foo>")
- + Check("h6.0.key", Value4("\"22.0\""), "@QString")
- + Check("h6.0.key", Value5("\"33.0\""), "@QString")
+ + Check("h6.0.key", "\"22.0\"", "@QString")
+ CheckType("h6.0.value", "Foo")
- + Check("h6.0.value.a", Value4("22"), "int")
- + Check("h6.0.value.a", Value5("33"), "int")
- + Check("h6.1", "[1]", "", "@QHashNode<@QString, Foo>")
- + Check("h6.1.key", Value4("\"33.0\""), "@QString")
- + Check("h6.1.key", Value5("\"22.0\""), "@QString")
- + CheckType("h6.1.value", "Foo")
+ + Check("h6.0.value.a", "22", "int")
+ CoreProfile()
+ Check("h7", "<3 items>", "@QHash<@QString, @QPointer<@QObject>>")
From bfac365ebb2fb03e0d3b4ed261179f0353cf744a Mon Sep 17 00:00:00 2001
From: hjk
Date: Thu, 2 Apr 2015 16:45:11 +0200
Subject: [PATCH 15/38] Debugger: Fix parameter passing to LLDB dumper tests
Change-Id: Iae342ffe68385de877c7a1e9a7e61e7d4889f731
Reviewed-by: hjk
---
share/qtcreator/debugger/lldbbridge.py | 9 +++++----
tests/auto/debugger/tst_dumpers.cpp | 2 +-
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py
index e8e6c29bb11..500c0477a8d 100644
--- a/share/qtcreator/debugger/lldbbridge.py
+++ b/share/qtcreator/debugger/lldbbridge.py
@@ -1765,12 +1765,13 @@ class Tester(Dumper):
stoppedThread = self.firstStoppedThread()
if stoppedThread is None:
warn("NO STOPPED THREAD FOUND")
- for i in xrange(0, self.process.GetNumThreads()):
- thread = self.process.GetThreadAtIndex(i)
- reason = thread.GetStopReason()
- warn("THREAD: %s REASON: %s" % (thread, reason))
continue
+ #for i in xrange(0, self.process.GetNumThreads()):
+ # thread = self.process.GetThreadAtIndex(i)
+ # reason = thread.GetStopReason()
+ # warn("THREAD: %s REASON: %s" % (thread, reason))
+
try:
frame = stoppedThread.GetFrameAtIndex(0)
break
diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp
index 2de739cf9ca..39e7c3bb8a3 100644
--- a/tests/auto/debugger/tst_dumpers.cpp
+++ b/tests/auto/debugger/tst_dumpers.cpp
@@ -1274,7 +1274,7 @@ void tst_Dumpers::dumper()
"sc sys.path.insert(1, '" + dumperDir + "')\n"
"sc from lldbbridge import *\n"
"sc print(dir())\n"
- "sc Tester('" + t->buildPath.toLatin1() + "/doit', '" + expanded + "')\n"
+ "sc Tester('" + t->buildPath.toLatin1() + "/doit', [" + expandedq + "])\n"
"quit\n";
fullLldb.write(cmds);
From 27aad7dfca4ed4d782407d56c059210463d5efb9 Mon Sep 17 00:00:00 2001
From: Nikita Baryshnikov
Date: Mon, 6 Apr 2015 15:40:07 +0300
Subject: [PATCH 16/38] DiffEditorManager fix typo in assert
Change-Id: I8582fdb790f5541263eb17d1fa9418c3a48f88f6
Reviewed-by: Orgad Shaneh
---
src/plugins/diffeditor/diffeditormanager.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/diffeditor/diffeditormanager.cpp b/src/plugins/diffeditor/diffeditormanager.cpp
index 242b19bcd4f..5d3388d4a21 100644
--- a/src/plugins/diffeditor/diffeditormanager.cpp
+++ b/src/plugins/diffeditor/diffeditormanager.cpp
@@ -76,7 +76,7 @@ Core::IDocument *DiffEditorManager::findOrCreate(const QString &vcsId, const QSt
QTC_ASSERT(diffEditor, return 0);
document = qobject_cast(diffEditor->document());
- QTC_ASSERT(diffEditor, return 0);
+ QTC_ASSERT(document, return 0);
document->setPreferredDisplayName(displayName);
From f0d891758a4cb78458cd2afbae79644f779f57ed Mon Sep 17 00:00:00 2001
From: Nikolai Kosjar
Date: Thu, 2 Apr 2015 11:13:49 +0200
Subject: [PATCH 17/38] CppTools: Update project part structures consistently
When the configuration (defines and includes dirs) did not change, we
only updated the m_projectToProjectsInfo data structure, but not the
others (m_projectFileToProjectPart, m_fileToProjectParts).
Change-Id: I0ca235ea4bbe4556bd8b6d36897dedd6482f86a0
Reviewed-by: Christian Stenger
---
src/plugins/cpptools/cppmodelmanager.cpp | 56 ++++++++++++------------
1 file changed, 27 insertions(+), 29 deletions(-)
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index 6b4f8e24c0b..aad230149b7 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -748,47 +748,45 @@ QFuture CppModelManager::updateProjectInfo(const ProjectInfo &newProjectIn
if (oldProjectInfo.isValid()) {
ProjectInfoComparer comparer(oldProjectInfo, newProjectInfo);
- if (!comparer.configurationOrFilesChanged()) {
- // Some other attached data might have changed
- d->m_projectToProjectsInfo.insert(project, newProjectInfo);
- return QFuture();
- }
+ if (comparer.configurationOrFilesChanged()) {
+ d->m_dirty = true;
- // If the project configuration changed, do a full reindexing
- if (comparer.configurationChanged()) {
- removeProjectInfoFilesAndIncludesFromSnapshot(oldProjectInfo);
- filesToReindex.unite(newSourceFiles);
+ // If the project configuration changed, do a full reindexing
+ if (comparer.configurationChanged()) {
+ removeProjectInfoFilesAndIncludesFromSnapshot(oldProjectInfo);
+ filesToReindex.unite(newSourceFiles);
- // The "configuration file" includes all defines and therefore should be updated
- if (comparer.definesChanged()) {
- QMutexLocker snapshotLocker(&d->m_snapshotMutex);
- d->m_snapshot.remove(configurationFileName());
+ // The "configuration file" includes all defines and therefore should be updated
+ if (comparer.definesChanged()) {
+ QMutexLocker snapshotLocker(&d->m_snapshotMutex);
+ d->m_snapshot.remove(configurationFileName());
+ }
+
+ // Otherwise check for added and modified files
+ } else {
+ const QSet addedFiles = comparer.addedFiles();
+ filesToReindex.unite(addedFiles);
+
+ const QSet modifiedFiles = comparer.timeStampModifiedFiles(snapshot());
+ filesToReindex.unite(modifiedFiles);
}
- // Otherwise check for added and modified files
- } else {
- const QSet addedFiles = comparer.addedFiles();
- filesToReindex.unite(addedFiles);
-
- const QSet modifiedFiles = comparer.timeStampModifiedFiles(snapshot());
- filesToReindex.unite(modifiedFiles);
- }
-
- // Announce and purge the removed files from the snapshot
- const QSet removedFiles = comparer.removedFiles();
- if (!removedFiles.isEmpty()) {
- filesRemoved = true;
- emit aboutToRemoveFiles(removedFiles.toList());
- removeFilesFromSnapshot(removedFiles);
+ // Announce and purge the removed files from the snapshot
+ const QSet removedFiles = comparer.removedFiles();
+ if (!removedFiles.isEmpty()) {
+ filesRemoved = true;
+ emit aboutToRemoveFiles(removedFiles.toList());
+ removeFilesFromSnapshot(removedFiles);
+ }
}
// A new project was opened/created, do a full indexing
} else {
+ d->m_dirty = true;
filesToReindex.unite(newSourceFiles);
}
// Update Project/ProjectInfo and File/ProjectPart table
- d->m_dirty = true;
d->m_projectToProjectsInfo.insert(project, newProjectInfo);
recalculateFileToProjectParts();
From c185a15c28ae85d1dc5057e59926bce7b2b7a1b8 Mon Sep 17 00:00:00 2001
From: Ulf Hermann
Date: Tue, 7 Apr 2015 10:55:58 +0200
Subject: [PATCH 18/38] QmlProfiler: Make message boxes always 300 pixels wide.
Sometimes the text would not fit and constantly resizing them is ugly
anyway.
Change-Id: Id1136ae3b2d2f339ff6f4302b45794201221e6c4
Reviewed-by: Joerg Bornemann
---
src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp b/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp
index 9d4dc87c220..a6c8e47e322 100644
--- a/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp
@@ -200,7 +200,7 @@ void QmlProfilerStateWidget::showText(const QString &text, bool showProgress)
}
d->progressBar->setVisible(showProgress);
d->text->setText(text);
- resize(showProgress ? 300 : 200, 70);
+ resize(300, 70);
reposition();
}
From 96c78e622108ccc957a43d27d7884e250b4cbaa1 Mon Sep 17 00:00:00 2001
From: Christian Kandeler
Date: Thu, 2 Apr 2015 15:19:55 +0200
Subject: [PATCH 19/38] Update qbs submodule.
To HEAD of 1.4 branch.
Change-Id: Ib37e757f5b90db01fdc6d77a21556f214e776aa0
Reviewed-by: Jake Petroules
---
src/shared/qbs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/shared/qbs b/src/shared/qbs
index c96ef7654f6..0199fd7a839 160000
--- a/src/shared/qbs
+++ b/src/shared/qbs
@@ -1 +1 @@
-Subproject commit c96ef7654f6ea8ebd5737261aada123b52981213
+Subproject commit 0199fd7a839e3c3899833092e4fa7b3f5ea89880
From a2c770f3240f92b69bc7878090e2ea40ee24f91d Mon Sep 17 00:00:00 2001
From: Raphael da Silva Couto
Date: Tue, 7 Apr 2015 09:14:45 -0300
Subject: [PATCH 20/38] Android: Increase timeout running android.bat
At some cases, android.bat on Windows running longer.
Change-Id: I53ae90e4d7fea69b603cf8cca8c1f8ee5aa36a6a
Task-number: QTCREATORBUG-14223
Reviewed-by: Daniel Teske
---
src/plugins/android/androidconfigurations.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp
index 833de15485c..1469afd7243 100644
--- a/src/plugins/android/androidconfigurations.cpp
+++ b/src/plugins/android/androidconfigurations.cpp
@@ -380,7 +380,7 @@ void AndroidConfig::updateAvailableSdkPlatforms() const
QProcess proc;
proc.setProcessEnvironment(androidToolEnvironment().toProcessEnvironment());
proc.start(androidToolPath().toString(), QStringList() << QLatin1String("list") << QLatin1String("target")); // list avaialbe AVDs
- if (!proc.waitForFinished(5000)) {
+ if (!proc.waitForFinished(10000)) {
proc.terminate();
return;
}
@@ -671,7 +671,7 @@ QVector AndroidConfig::androidVirtualDevicesImpl(const FileNa
proc.setProcessEnvironment(environment.toProcessEnvironment());
proc.start(androidTool.toString(),
QStringList() << QLatin1String("list") << QLatin1String("avd")); // list available AVDs
- if (!proc.waitForFinished(5000)) {
+ if (!proc.waitForFinished(10000)) {
proc.terminate();
return devices;
}
From 67e8d3689ee2b498e23f54caca6ba2ceaf6bfe24 Mon Sep 17 00:00:00 2001
From: Orgad Shaneh
Date: Thu, 2 Apr 2015 07:47:45 +0300
Subject: [PATCH 21/38] C++: Remove unimplemented function in LookupContext
Should have been removed in fbb756cd.
Change-Id: I86e0fd556ac031e6a88e9397a039d67ded5f7bd7
Reviewed-by: Nikolai Kosjar
---
src/libs/cplusplus/LookupContext.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h
index 7a75cf9c8f7..5858d80c954 100644
--- a/src/libs/cplusplus/LookupContext.h
+++ b/src/libs/cplusplus/LookupContext.h
@@ -133,7 +133,6 @@ private:
Clone &cloner,
Subst &subst,
ClassOrNamespace *enclosingTemplateClassInstantiation);
- bool isInstantiateNestedClassNeeded(const QList& symbols, const Subst &subst) const;
ClassOrNamespace *findSpecialization(const TemplateNameId *templId,
const TemplateNameIdTable &specializations);
From d15e4ff2c9f31f5470c7c7dbc0ef46607e75fa6c Mon Sep 17 00:00:00 2001
From: hjk
Date: Thu, 2 Apr 2015 15:03:59 +0200
Subject: [PATCH 22/38] Debugger: Replace block access to array data by plain
loop.
This makes the GccExtension dumper test pass with GDB
Change-Id: Ia1319e878416bea8b162a1a9eef1271cb7bebc63
Reviewed-by: Christian Stenger
---
share/qtcreator/debugger/dumper.py | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py
index 78f48db03d6..e8ff7ec5080 100644
--- a/share/qtcreator/debugger/dumper.py
+++ b/share/qtcreator/debugger/dumper.py
@@ -911,14 +911,9 @@ class DumperBase:
self.putNumChild(n)
if self.isExpanded():
- try:
- # May fail on artificial items like xmm register data.
- #if not self.tryPutArrayContents(p, n, innerType):
- with Children(self, childType=innerType, addrBase=p, addrStep=ts):
- self.putFields(value)
- except:
- with Children(self, childType=innerType):
- self.putFields(value)
+ with Children(self):
+ for i in range(n):
+ self.putSubItem(i, value[i])
self.putPlotDataHelper(p, n, innerType)
From 8c472f2074c58a48ce07a6b7e12a295aa3035bd1 Mon Sep 17 00:00:00 2001
From: Leena Miettinen
Date: Wed, 8 Apr 2015 10:03:43 +0200
Subject: [PATCH 23/38] Doc: experimental Auto Test plugin
Commercial only.
Change-Id: Id2ee9a7765f226c32ec1595e32f4b53ee94d1207
Reviewed-by: Christian Stenger
---
doc/config/qtcreator-project.qdocconf | 1 +
.../qtcreator-autotests-sort-naturally.png | Bin 0 -> 702 bytes
doc/images/qtcreator-autotests.png | Bin 0 -> 16602 bytes
doc/images/qtcreator-closesidebar.png | Bin 785 -> 0 bytes
doc/images/qtcreator-run-selected-tests.png | Bin 0 -> 526 bytes
doc/src/analyze/cpu-usage-analyzer.qdoc | 2 +-
doc/src/howto/creator-autotest.qdoc | 179 ++++++++++++++++++
doc/src/howto/creator-ui.qdoc | 33 +++-
doc/src/overview/creator-advanced.qdoc | 2 +-
.../overview/creator-commercial-overview.qdoc | 1 +
doc/src/overview/creator-overview.qdoc | 8 +-
doc/src/overview/creator-testing.qdoc | 7 +-
.../projects/creator-projects-creating.qdoc | 5 +
doc/src/qtcreator.qdoc | 7 +-
14 files changed, 235 insertions(+), 10 deletions(-)
create mode 100644 doc/images/qtcreator-autotests-sort-naturally.png
create mode 100644 doc/images/qtcreator-autotests.png
delete mode 100644 doc/images/qtcreator-closesidebar.png
create mode 100644 doc/images/qtcreator-run-selected-tests.png
create mode 100644 doc/src/howto/creator-autotest.qdoc
diff --git a/doc/config/qtcreator-project.qdocconf b/doc/config/qtcreator-project.qdocconf
index 0cbfa5740f9..d4dc2f247c1 100644
--- a/doc/config/qtcreator-project.qdocconf
+++ b/doc/config/qtcreator-project.qdocconf
@@ -22,6 +22,7 @@ indexes += $QDOC_INDEX_DIR/qtwidgets/qtwidgets.index \
$QDOC_INDEX_DIR/qtlinguist/qtlinguist.index \
$QDOC_INDEX_DIR/qtscript/qtscript.index \
$QDOC_INDEX_DIR/qtsensors/qtsensors.index \
+ $QDOC_INDEX_DIR/qttestlib/qttestlib.index \
$QDOC_INDEX_DIR/qtuitools/qtuitools.index \
$QDOC_INDEX_DIR/qtwebkit/qtwebkit.index \
$QDOC_INDEX_DIR/qtxml/qtxml.index
diff --git a/doc/images/qtcreator-autotests-sort-naturally.png b/doc/images/qtcreator-autotests-sort-naturally.png
new file mode 100644
index 0000000000000000000000000000000000000000..2f349047d469dabb831090bccdcea4256f148e2a
GIT binary patch
literal 702
zcmeAS@N?(olHy`uVBq!ia0y~yVBiN~4mJh`2J356y%-o6I14-?iy0XBj({-ZRBb+K
z1_lQ95>H=O_WR7z{FW?lH!kP`3%N#=IF^=V
zGe3_(m{U=ifq{VwB<`GFP+63jo>9WEhX0He0|NseShOfL5u{Y1Br`Xa!Sp*nCj$cm
zCrBnZKdq!Zu_%=xw%|WVIX6hqC9^m=CowZOwTNN+fi3+E3=A9~;qb(wyv)3Gh6B>i
z+F?!$&Mz%WPG$J|zxg#xnR9+_Zfaf$!?!cj_A@Xruz|FOWR~QlGOT!aNu7a#vD4GV
zF+^kH+(`$$r5#0%)t@`3R_duSHRsGyZ<8qjRU-U?++S5zihO$hgg;p4QK-lHuagcx
zOOaCISSvj{CH?-5!@Cr3yKvWj@caDxUd{bIH(!+P?*EgX$soA9=z+zn$iQRS$!EGR
zuN7sOQdA&w)M))0j_li9g*NJDZ9yxKT)e2hs&1-^r&tf$hW^zXAK&cpTIv+A{_>5x
zM?c%d^&eMh7Fb)FW!<%CYuWej-!u08cd(H7@b%A}^0R6Tfg*tgcSCGupZ|X`tgL@bCN)t
z;(?~CGZnP2msW1x>Y9`mQ@{V1c1GR3`^8n2jxxtB!_xmTW^I*vTQ=Kw{h96eMEAz&
zn}@8dIo0d8d~?L6YqN@W_87LEOxaY{x^wpQ|64uIlvK^OYb*Mvd+y&m@2@hS*^4_K
W?U3IlUdF({z~JfX=d#Wzp$PyC`X^EV
literal 0
HcmV?d00001
diff --git a/doc/images/qtcreator-autotests.png b/doc/images/qtcreator-autotests.png
new file mode 100644
index 0000000000000000000000000000000000000000..ee16633a59d7b52823089fd45471e0a0f2310639
GIT binary patch
literal 16602
zcmeAS@N?(olHy`uVBq!ia0y~yU~*<)V0gsA%)r1+c==-I&YjO+zJB%k)s`(=o;`iKefxG#
z506KW9&OyXasB%B>FMcNSy?$b$=i2rDl9B)Zf=f>jEs(sPDn`b^YcqeO1ggST5wQs
zNJvOcO>J9STV7uNt=soXii=B2%POlX-Q3(RUA`U|82IAdhr0T@(6E>fA08(pr8hJ*
zbai!~efnWS|AY_kFZKJy}|
z_u)`=b#+BW#fCed-oCtd`^3V1m+oIUckcb`r)O_HK7H&2>nzrLXE$0}TE2LE^Xc7l
z?;jtVHf_qqoimp$TXE?2%TFJ#Uwi#w)yaELt{Ymcu?DvxhV4QiXTIH_QMju~?e->sKU)_8lJzp>0celq(p
zt(%%XVfTpTF%~+ueO_%~@3o%AD1snJ^XgIeERe$JU?PrYW=a3iF2f!UamH&oiXKbtAY37
z9VZHV-L80;rP#|g8%|G`beQUT$z8B`O4RxL45z<+&t_n-o$Bf07*cWT&8*6t+aVGM
zsv|sQL^Qo5{0fDRpLKntqcuT5fRW2X)7{lo@R&j#M@NeY%i{pcTPs60gf_2Ywh~d<
zw#bOrH(BA}5rL+^2S2iZw@@)#r^MnUD!NK7Hd{zy;Ux?u8Vmj7On*%vIcYj}B1o>{z@xvVQg#H@?SZIa41&G|lRA(MJvym@nF
zlGQE-5fc^N8I#`hcm**&XZ6|QAjHsm?7;Jb3l$~pCN*x8v;WnuWas4YL;GKk*gtc}
zAn#Y}4Kp8_FVp+#q-WwPzD#)X5|1;@&lBhS&pDRY9((lSl;_VU2RL>rer_=~?HA*F
zYWh&9lgWkoq0gDs!hJ^iUW*LBZP1buJTH?X<#|SdN$7K1o@CUDgejR85eX6U3F;S~
zDtaxRD^zl5+5?_^7a6ltlGeTc>@r=m8_qsntN83;29u%wId6fpFD98hoHV5(is8j1
zbyK}c*6JM$x{31&1f-qxChRP^|K@f}tMW6+5F1&|dx7e$v2Q0#E$aI+AxiM5eR@=y
zM*a#RXHMmn>YWyw3lblFb#2?mx=l)k-I~`TC7+}6WZN>w2#vCRr|+0}c4jW+mA>Bb
z%W!L5!Pljw7teUhFg5k<%&b{7O?=ZKjydlbh2IA+$
z{hi)?Q<%f$KY3#JIhpmBr#h=>JlwQm@dEj>-3@ssQwp9st;$e4#u(L+#yur-*^SDx
zTYIJR7+WpQ8pJ%d`@7G#D~PAI-aCEmGSBxl)dgydk_!u7-2T3B@$0-YSGLI|husUe
zhouB%p0d?*DPO~Ir9WVov1dcjF(>H~MxHGn8M_PJL=u;Cnt$a|@7sCz-AOaX&0*U(
zMUG<^x9_zkaVN)_rxyv0rv}c6MPUp_RL;_$=C=D0UZ0J*df&xVbyO>b`kCYv-C3
z>+27{*>`cG%iE;BoH=v%wqAew^#1><|Jm&6KlGCFKV7)~`@8%cP4Bm^oRcFSe$p_C
z@=dxuIW_Wc&pf_j?ME!$sy(#|9V`pkP9Jg;94W>eVBi9_1ise
zx7mMx-~aL0yPcBr3JUCBS)Mp;sC1mGT(x^bh0nGZ?cu8`Cf(o{cHdF;z~(}cfQIEO
zj-a#viwq?}_an1n
zhcm;GRo!ISGS?@M`?TF6t{p7W@mLaaqvg1KLUu?|Oi;+C37PY+ik`PH-nVGMcxBo6=kd{&t{{KMo
z+ofloz76l;{T;T`>!!DURB>JPOUAwj#ts63*1Ph5UB4M$?)UfG?fhUx>$JyT_z!#u
zTNG0xQr`3H(Tr`^9V8OIGg=(ro5*)}bC{(5_oWuco|hkeBU*ka-NeyQTXTz9*fj>V
zQv$gL4-JBjFPn1L&^=21G5^YnfWszV4+ZCG=k9zv(e%5G@y81%e%!j$_u8BPh;rgv
z(VoH;501#(+EQ>+*{OrYHD%V?6Q?ZQCpb-eYV`cws;frRLtd^t61%3ay?x=@!^wx;
zn;x8D^s{?DMU^pFWKlrE+ajK>naZk6tJ`wZ?Vs-aI90lxd+vnW$MSV{&FigOU#PY!RXZI)Gfbu+Ym+4p6g
zA-VFI$2d|BS+ra8eQLE}(-K;Cdfma)=-Q(y>1K`_HO#Kv`*TssX$M=NTfnBo=xiMs
zCj%diDIeRDH_7-`OEAbZJy&S&a*pj3W?v^A7k#Vf(Sdc-w=MbD-SWC4;~)q3(ugZ9
z%uGS29`c}_jOw~ZB=^4#b&!A^<>6Nu}Fp}rAUT??nY4^8;upVYu?V7
zx=G{rLl>(crUEmIkglKBi-m8mdN6?_`KImnUuO35pVgCQ&%Y?!G&7h}W>xY$XPvC_
zKTM$+&tG`2&acSSI+EGovUz_`+n3jOzrDKm^5tGd=_OgLGjI0x%$)u3%fUjww?8)7
zN-OhCT;FE(_2MdSnMaAc&K7^(IODiZklZO5FBv6&4l{+IlS`d>%6sN2mi&;sck{5J
zoIV5J!N~^}w&%y*y=ZT+^Plbg(yLzgk35+spqAV7udF+W$M=APYK!$M5iRZAf0rb2
zdPc0!Tr?|LWRJtjvnRA(C50z8?@DQi=4lH&5_T~1^TsuA+HEE!HEwP{%J@8`Y=PSEDFRM@G{ixLTmQ0uaS-C#k`decAGd_o9#_g*n>5BPHe;cu7NBrVo`L!zH
zXEZBs*?N}x2JKgAa>|Y^77H%9WVNu;fF~!D?L%8Yb7$I~l^zyTiyr?@eR1u{VOhmz
z550Eo+7@*0h>cdd_9unqn3_-)9vO)^@itDy(f3YmhJ#%K^nvECQ9B*9+Fi+-e
zO->O_*P4I6**We|(!2iXnW<4nB-|ZJx#e0HM2q$OmU-yP*FT5L_N2OSlGvvbxtXa<
zmS1}XHL~1)YWjGsVa$$~Zk0$lX&9v_H$zZyp+$j1i&e{?I@BpMQ_4)-e~EXI+xv>zAHAaH;aDj!~FY
zQd)%bp-P_<3!)yj99yPtx`Ns7_#g84#mOBcSN?t|G)
zOQY@;up~LJIlHNh+vjYwjzplrF$c};?JUVI!Z|bAw2MD?`duj4(p1}cShRPe1&ed`
zg?rtNEY>N$S%ovCr+F=x4%3(MiTrV;`{e2-$=TZ)^wm0&xXpPFoLm&TS!Pv9dct-c
zi*Cc?m!zcb&ic9J!MxY?!Uu0}JCk_uVoLVE{7d()Z#t8>F#qPl)PHR4esAlx@0{2D
z@Y=uR_2&P(Bg$SFI9hM{q@io6UnAzX?S6?}<%dK2*7Ez$xf1i*{!wJviw_RgSLUwD
zxVe00_Uzf~8*_ile&2ul&t?A!P3FtjH;eJD`}uNt|3Z1E&w^(+Ik$5^x?p-#U~)4D
z&%4U3^RJti&oQnzHQoAs-1kRf?{lYT@#XGsseE+J*e)gDzxSD2(`Wam{L^e_)3152
zDKh^}-p~0CGFn!Ljx3b7-}&rv^g+cNe(~G?_LbfazrWt{%aiEsz56!&dU;(@{?3oI
z&l7peUhqX!^W|hK#@KFIo$5KqX6M?YP3rGG-Z|xOT$wCABV^Z;kNwgAJWbJ%>>e=d&cE8>0em4p0-K={4^7Xo%FWMge=PiA4=<4~sA1;oFd9n{;K#M_%XIu^`kFJ6!mq>`tV^~lk|E{F5v
zl@qBZ&W{9Dk3DXVueqJup)MtQ^Nzl65W?_TvANi+F7-U{bdho((DQvKv@rs>IP#eH|9V?wKI
z3q2h-J>8^J;}i4w$(|jbZ9MO2c?CypJFb~3nzQri!~c$p*2^Y6ZICTy?!G2m*{s^F
z7`x!<3I|p}w&s6F@m#A8l6BvAZw$%dO6?>1S6^L53
zS8+$}p6T0L8*%6Mz1i}&&TU?9(ipVx^^t16uJ5wR@27j`
zd1i@Bf86rsbnp|`gqooD0yhq9y()FIu5x=&SV-l!nm7MnPFQJhVxe75aE)Vxd|T;j
znMYfa_O7_MaMravzJe9ge{Wm+&pCQthVa6vYTLC#rmQkdnP_dSXdJ8jZjJDIhv)vG
za$=v(T`|&LJ;j~-(cz?n7Uo>#FBa^WT+mUxa@yRsQ(9Sj@;FTbRVF{*U*K^uZqdAu
z;1zngX(m%|XL)dKHQMq#@%GB~vO!6cUbi?e;al@vp>DmL;lxziQ=izmuPpD|wW?hE
z`AXxfOFduRUQt!P_L0zpv6k)4g{t)`zkO
z%vqMl%YDcC!;!j4DtfVAtIMA+6k`?4=#Mvxntj^g;_QT&>xvf`&Th*5S}~bhapT2#
zADtHJKCbvt`LXu0|K^1DD?c(ePF&soK(Ozp?N{vHlV4W%c{AjXjkImcbkAzHJ
zbY{eVJL;wLQd8qdS`&ZVwnO`yZYm}}t>&93{FN`T@59fO%w4h%15}wcz7$+L6aD^o
z{BdFZUY3t@vmcxnsE%t){I%`PTTA95!_@~1JkIb*YThsGFp5qo=)i?ECxmTuSuiJdc|z9rCpFs9E63@WNiK#@_#(in&Bu%x=bO-_==_ImNzC-EDTr
zzVW8w<0rTIEYHnJE$HC6HQ_*e&ieD4_`O)lie9LTF!6J9HP
zC#mc2&zu^_d9`^GH@Tinobbixa&Duo){X3YWi@)cd^fT?_n3$BraOBAU+IWL6%r8FHtUj-u*x4DQwL;zP)7k_5CuFoz4h2k`
z{chIl_f|)CZV}$vr)cMPBjLi*3E8Z*o&iqh#9hm#X4{EIO`qe&oSw9Hx)`g2+8Ox*
zj)jMnC*3bSp}Mox>-^+-1(8pgt4=9yn)_Gr(=VPzbC>cZPLBH=7YL;!Gk29eezQjA
zM2gnki*0Yb%USF;YB#-A$cSy@m%MXw@{N=?22b6-Wb@s$mi{4<>iGB8YULuu|K+kt
zx%ZhI&-j_&Q563+XO*nrH1Dc+9Z?F?yQLRa>sCJx$^Eoz&a!PWo6@HGzj+xs?Py*3
zwC(0bmmSV0&H22enu+U_UHDX|(#WZHc~kpuDl#i>Q*1bJK!97?nUnKXy}gm@ugQEH
zqr9Kot;{_5Lt=}hV{E!@T<48_jqV~hweL!BbDdlB@Qu}sr`(JpySF(o#I?@8xlmuG
z=w1y=z%z?$4+O6GmtSD&{NnzBL4ZlwXQ%rrE;$xke}gC8iv%BE*tIT6+sa?c*J6vl
zUdyI^0rQ-02yBbK=@hajY}d=KJzXzuoMG~>w?D6|aGF8pye^-@Ii;{&vbSdMyEiAb
zS@zVT0FBhMBF)Yf!mqAp#qW3HS-rOEz;2}-%ry@&aBrf0m!Sj1m=
z?#Pb!r_X0Qem=P-S~^mjGk(#sG_lWSfeYRoZq2{bb6Tu9^04CMd*4xn2Ff
zaCwx?i7jv6Pkh;?^SEQ0ul}>Qb5{I5BAD-2>21>`nLT;WWZPxlJ!ch->klh(ZI3+V
ze(a^ptz}1-JFR#99NvEGm8{VGgGUpm%0)ly|6mT%@2y2&-(vYck9O)eaBz0qR(bgMxo`2k
zv%9y;|2S*=eP8jrldB|?Lc$(d$Vxb6{opKFQ?Q}nLuOIsm)qi#<|-K;kj=gP-@kRgrX`*)L
zlzo87rl<)8R4x7qHsjGu_}>C=UeQa@-F+V;8~zGgW`
zqb=w3M~R}CzufQJMYt5xf}8xObW8PgxpCI;XiF(xQH;asD>-N_UYxQ*^`)
zAy&OKkGh2+%shJwpQRtUaPF1u`=o3)Gs#C6GA4V!U0br+@qX7o(Prk)4B4LdJ)`;f
z+ttG-EjDy{@+Q@3PtF^O^UT6)jvq1Eb!B$rWeJlX3og%?aPZ_&+su1B%Nn?O-i8?$
zh-9s8o~@f+ng3`#$YT#^kE44kv%!wK@3w)`rEG{-oGS@(IhR
z3EMnbXw$W@bnR}&Ng4B%o8vd6y=~a{S~=j+>tCl`{5+!LUmRFj{(Oh$-kJ=Rubbwd
zf8c6b!^$50Iey>MU&gcj{Z93_yh(Nqu_=_!*RERj_3PAlT`MVP7rvRl9gU9s4BH+%
z<3{nlaIqtgO=QljWoqNHhRK%E?$LH&
zdf}Hy#(%3mJoqi*`rFUJyY%9%xZwR^%)&lADTjM>wg@`2{^UGxAv*rZS;HwM%Z$BO
z*eZA&1>&hK2lw=}%1)@Ziv
ztxcG=Oyc_TgRJ{_B$})vz0}@(u>56m6P>2
zSOS7>OZ>SO;3{07CucQ{L0aVS!)FR|&oaLxDaNOzzIdGDT*-7Y;J%@5@5`QjJV!d0
z7uo-NcF(Tx@B*>2xLmId$sX2e$+vsINh>=iN`L;9w`KXexh+q>@y>`+(lX1tz47DH
zlm4sYb-%Blw>=QVCc)U4Vm%efDrZ?~3cF!ru
z_kStBZ~3<`H+J3Fwtnh;!%P1!afG~UH-06jb(!|*TRDT-*_4j?EVGh1eC(3qmpsF(hP!>lc6&;-OgtN=ulHi({Qe-P
z8#%sn-g@ktv4&CTaN1_+oi~^~AI_PudR}lzWt-ZfMdxPfPCuh&^~-s`{pYjay?pF!
z7pttB*$DT$-ixp#|s
z1kGCnx^pjO#C-LgyxKTKl=bq2moD?4Mv0ybV2qg~pMK_Lzb^Rw`NF=Uxz!a%W0%Ih53MiVWc%z(tm?ybxjlabg$-SnZ`a(iZrQH=&s`!ew>rtn8@fFC{Z(yG<@4aK?OD4OSsAAMh=dWcEDw5P{Jkt19PP5bBndj})_j!EPoIkCP1YC;V9&1NO7S%tv;1;0zmm;H%~wSIm)
ze%i;>=yO@0H`hw8kYM)urf}W4AX2+grNY=Id0$f#uiT00jLr{!HwlRugj{=bcB2*AMX3?ed27h
zt9$0?uNGVOi`ArTqHAJV*ygMC1}-vZTtj8PWt9IYpS&+;-oh96g!qpHJh)k#vvp$Z
z#hO*VGeY7|h3yEnskgFZ-lcMAhR~VRC$D%8x};2%Y?of-&FOtt%dR2hdg{g_g41=(
z->zHP>7((ole;JKuIyqjCcP6s8}{19Ot{;4SdcHocUhpObeM9yTThXD;0E^ZZTAF$TglN_FwCM
z-TI3bpOV9u3$&}>WSsi$ScBKT8xcL;?aWd?FFj^-GKg8J$8l6(o6jDd({6zeGJ1oy
z&EL7=slTAm7r}Ya_t+MwPRqO^Sgs)#_WaK5GgElA{j!x!EFUu;KJK3#t6t!5m=fN>
z*4L;#;R5eOp_n-jkL5mi#M^VlXsUX%W^c)3C$Em#EXO%A7Mi=beKNelu~(|5@KJHc
zelZ4T+oN}4ePy3!X|}i*_*~f3+vm(#n_^&i=z;7>(*qWpJmS;O`7f3@G_7-b>AdqN
zZ%>p7F05Xea{L&3$cvPc%M+bqeLi%`?Ekk|)^z7zTb&gm!7DDye|)e1Qdzoro9s2m
zJwC2}9v4ObTHSmpUv)x2TK)3!kd8v3(zi<*bF0?xvj2YcUt#3MWZ!dhxSR~P%+c?j
zdPH9G{Rz!I-yf|_eJSBMZ=L$#b;+qOn>L@-xXJ9$DCWV@S!Xplho?%ZzyF!Rjy3lG
zK0W2`>SCF+uxE|B@Q04$En&>JOLP=p`Y@(U{qp|koJbMpGFK-B>*`6<=AVt2pOWe^
z!T$J#4v7NBfM*gxueyy+9-HNSQf@;1ver2Z+1P%4oG$+9PWhRCB@-0hsQxw1nCrJ7
z+Cy_=+&uZ~$11JYn=h7#Iye1ih}@eq`kr4uzxr}^ic%q
zh(-6}*QKtiwJFL!Hs#ofJ^bI3R~zxIaQ?3+vH$dKR@}Q7zuWizqtXRGKX==`*?lnJ
z;b$IE`TBMr%_3MRUgt#5+h?cRk{`41AKmxrb!NzErI`h%m5g>2
zEUcQB^}Q$J#{2VT$C^(XmU&yS#V70Jyf%Jlt=y9;(WkqtxiDKr!sm-rgMZwX_N4C4
zz~{OmPKGX>NgYWUQx{1rk|?s+Y33aA?s!n(PWdY~PbwBkEOIg2!sKjm)}%J?(WR>E
zoP}0%V&*Mue7S;O{K{X0=+|{u7VeUNmZo;+_WIu&PoK{AyxZ^pLqhD~p2yc9l?!RdGwTK7EAqoY5{D=iqC*0}4E?VBuld)VXw}b4LXA!?x1Y^FJ1;XZ@zbw!H`cVy?VMY_Xy1$<6>>bA
zR8}ax*A2a;wDAt-xscsf&eNx@{@u8Em;4W-k48W9rbfJ1Q*>D*!g=iCa*spJ-**?L
zzpmTy_BoeP5S!m#y%yz*lRAt!YcfyO?YnZ;w|?P~-&4en7sRmfe&7k$@%mWGUgDwE
zB6v_I(~E1m%mrIzSC0RJ&u>2|ntEfl=7&_S9T&Q_JA58X2VI(Re{M;Q`kPlgf6v{U
zX}>kFt*}P+j?zO81^2g!rX4b(!A{){B6rNLJ~LAhU{YD>snEKth-Fq0KkF&Mo$sxl
zYHYo5>)OlMwcCvY9%_IvkI
zr^SAf?`?m6-JSX(_GNK3-y98pi};$nyT9hHpYFG8f*S9ss~_2(M!kF{#M^7!V~
z$8cd{%Q{Xb-WS$i4qVZAv)lAd{Y?gQ*|$@)_RFqo;+M+UxbDlny|$@8nfvFhTUfbI
ze!9J^TpZq>(pZxDr_Id$^I<2TOLUZ0kS)R=haEmdU9=x}oX^4mn>nEbB?)fIv9VeT6IF8i{)LdX}m?<_V4e%zS3%b`wSf8S}P`rgbGw=pZc`?vQ4b>V)oNz=jWxaZ4erd$*^pK6ZoB;H
zzS!xdThkY;eh_>mHn;!TJlm~*b}IQ_pK$p5W6}2a?LQ2j{x-DLeYnME_czDKA{CXK
zg@p^lL$^#h-njVcX^rWd9x|+8zVX6AfA7uL!t;_sd81AjM2art_`FKXj!&Z-hx
zkDqPO>XiDm!12?bJq?_UlcM;QH4Yu(=#km5waZb&W61)&)_@p?0|#Bh7y27kx6bt_
zWj=E8vFVfYmxuf3{eE%S`}DDxh_omsO_deJ%>9!6*9AWPt!VxBw}3Co`Agl+BJT6o
z1kTo-;h*()!F%V^`Wd_z9kXAYlS+CklvrZXbnU_<(<36R?|G*Dx@mS(S$X!%R^ExW
zi#KdPr`wXU?-cJ|C({EGb0(kL{ig5S8%rIwlXW>gJvCp>y>WjM^KEgu;kU&v{ob&L
zUkfl}`X9J1GwpQzE8h|k3t#E!(;6+3(;w|I`{${+Rxw;E$>>v4(;tb-x+{y*@17Pt
z9?ZVy*YqXH&ffg@&>Q#0{S%a@vN8V-6wvYU
zUU_QsM)^N`v^e)0NZjC8?hZJ@sVBkFS}*E9ae8=xNBJWk!=7%+wD~>Ujm%3GWDNmZVZ`d
z^oKLbd9&$}j@{3HzH55E_;W!Px6ZN_dlQ+Pd%mtb>6Z9vTFqsSUAto>YL!P2WOnz-kyG=f7`J~#Sf($|8gw8(Z6MR$Y&&=L^6_~+=8bI$liEGRC%%?A
zqw-f|SLD1}9y{i_P5sWoVM+$VOIt6b+*p-V#5C*8lOzU#Pt}*dt$I-BnVm7M&E?Yb
zg@5*VbXgbh&3^9oZT4ZSnWp06!g|+@CjI3&Af9G#_Sk|ihW%unhQ_yKc9YtFjcILv
zU#!tfR{rLE{P0Fr(loB3@MRbH>4wt}OfSZsbZ+Qk(1cB!8aMr(1JNSPN8T#6whWnWn7HVozWynE;zuUY~p1t93M1Drpex{A`40&tbPmKy^{>@lB#o)y0*v&Wi
zS7*9#Gau@o`*#QL8+YrIbuKq=_V@a|VXx0v`u*8j|Io;Aey-28VcS**I=HPVCicoPR;fNiQk+&dvYHk6!dx{Rnz<
z{AhsUmzL)2i44CV%10%0u6=YeTryF2@`N|;2`etj+&Uk2SUgRG`M2N={Xl1V6AopA
zE63^%aC9ATU~*>u#JzfnP2iRe_f7IaOniE~y8cW#;NY2Mn8x4WbHjkwxW>C}bwy0|
zK_Q8rWqiv|D7Oe^q?~4UKB%d^VZXISK+~B`JPwOL=(k-vup!0Yb;FUcR>2diIQ9h}
zZmrR@%HTa)d9363)6QvvH~z_QkdJ;oL;B)*iI;o(mb!iO-yE(U<-DbBT4cqxwv2Dd
zbr;^S*UCrLecXTHg3&Lxx1A3^N*!{K-&ynXnreKM`?m$AU%uDa``xawx7%GPwO8h^
zw6F;2k}iSm)wedpng{dyZ4zA76L*7n**b|N5Kb
zdEsx`Cp^Bf-TlpRxdi(PzcC;G`2KjbW&OeL&AmGl>=*DC$ol=c5T_y|{X5Vpp=fjS-v&p6
z$5(8A&+hSjv-E@Cg^y={7ytP8#fQ9LP5I7E
z8|82PkVyZwc%QP{@*c~eIsZLoHvfImVQ6wx<&D19*|QtA9cB2vu}Jr(d!-83jecA9
zoHy)SEHYonCP?+GWe3PF{Py^1{^yVTFAJ2Ny!pM^+Nvor>5KNu9gCK>K9I>PeEa*L
z>F?jl7Dx8myBv9ZfH7sOO&>42_#`hyo1Jcr7oOTEMx8DwwpTp=S$tOGoUn$^a#MPD
zsIIq{`s@s}~*?Tx!}*2})O!XGbgRIRu<|3MVTmGqJv^JjGrKT0L}#k1Y-KYiIJ
zXJ*Tq>Cc7EocJ#RPKyVN%xW{MM54D%{5x5?uJ@mOCdcx}@f_!`1!PFbmfJSjMmtN$
zer}FCo$)RC=F$I-&TD*beLt+3!K-`syR+1sryu^V=zAbJ4X1!-`KAB?lCwHHGs;}tWmCXO#cE3L!Ft>iS_x=7&tvC5y
z=anw_-}k0nF`w_ZV1BYaPxnUozVnl}rmj8LI(PEE>AxeUrY67L%(ZCayoIW^7sa|c
zistzVz2$r{?E%F2J=$ke3|)3GKQH+9H=_4nZ0zqkhTnlNQlG?}IW2T3SNrsgFhMD;
zjT_|`#tBtsPb=9Y@-tZavfdRTuJ!&07F%ukFyZA9N#2#5>$RAEc_av=e`Ai)DJ*h}
z%eb@3fb+T1VeXCc7mj!SRrqUr>c$-7qmsY(WwormS@`_W6LHg(4T^
zsz27o3CW0_Il(@gdwJH4Z7018@)-BDaLaIqPECC&n(mdYQ|Pndz&XYLR#DF7pZ-p0
zde1)j7E`v%KKa1nT6>{A@(~BVFJ|5-zgoGv@vp>wvq|swy73=yyMA0*yE;uEncHZyZPNSR+;j_(3e4Mu4N|BS_l4sfTZXUze0%2oZHo=n`QIK}uxh0l>&;bn{(P}LdR1+Imhd0ltk=;A5}&S^MLBo>s540W
zU8iDMV{Z|!bf5oh(mr|5`iXxhM5Nv5-?H;fdzIYph4T*ArA&C!&iTvYopa36liLp}
zOrN%Wwe~8lgCCPm>?|-=6W+<1F=PzNVk)#|uy1N^J@~
z?dG71$F8t(Mn|*q!rTCf0oX@jw8cSt;`gW85vti^hp?RkJMC?{HZPj_$7!)cs
z%Vw$KjP$i@cm3`7{&z)Gu9eNa4Tm;Ny>>y?q{Y4cS*Jvz*?oTQX2pZMC3%tsBoaDw
z8_GHYtd3Zi&6$%Rn*~vNsm5ys0Hp(Yy9$t~a@LN&!v&N$|kawiq=0
zO%RaKdd$_PA@x--TH>z~+nj|r_}P-|f0TWDtZB=9ga69$7f0#}L=A%NYF@u}PnIlP
zSIp>VRFTofQo4ZO^>gB(`C>{*M>aZ|Y%Q?u;e5b#H8@UTOX$wDHjdEUixZpN4n$pW
z%+9!&-c#7~^vUmqb}wfAy%2Z&-$DoOIj0xQH>|o*7x_)ST=}-zC+#xXEp7jHwaqB`
z!~O846c^9Z$Lrenr)P64POiIzLdpa;G{uF81P%jQYgS@bKHRJaw-rj8eC5PoA;yegD738nNEoA`X2G^(ma(
zvXun>yIZskmdNOZvDr3YY?`tb(Ypiur+P`Pok*N*q9i)Qn8FweEn;)xhy|lH&
z$+1~k{`bc|_v7nj`y!cdwB2T1yYT2WBh7^spQq?MspTD-XTzSE!M*csRq6ZeBnGpt
z$vLxs7VI|+7Ypj`5B!&2u(@#_$GQ`)(o!2N_s_m{&0zuS@;!WIRwoaMZL^I%9h_ep
z%U^gn-+fD)SnO$ouRpd1y5!|7H#wqz{iey5X8V2e2W`uERZq>!Rg{i@V<0HeQg#1{
z@v2{)f?MW9a;T`L(S7#N)q%YHIN?xUvIf~MeI)7na#Ij$CLUSRsfXouKJ
zlXFZF?3a~Hothjq6~#Osb1aLL5IH-|d#O#Hxs`!Wj+oKzr3{mANKG{EaLQ6ypm(rw
z*MS{HC7S$x(#{DwC5DaNuE!WQG0Z=bG}(QEhgRaIJLhcMt_jF)Y0Kc%HO%1E^>nU-
zrggq0kJq`+gQfMGmrRfFaB)VN`Blx6kXx_#=Sb$1~<=l|d3U9qRlFQ#pdzPaE2
zqNY-E@I`c&LwYAa9
zxeMOuY)~`VeRuPM|BKsZyuV$vZw{Z*-<9Z=7hcskLo>ks7*S6)+
zqHwW_s)p5Ug%dXhpI1A`uV)p#!FbEdrgJr|BI}F7iyMBWgegg#jh!CtfBk}zW&FL}
z8HF~yq^yzc21%DX&Hc9?2JOBCb
ziTSHIneOw)&zrL$_s#SDv*z7fS5xHgDfRNDW0uCwh(Ec8tP2iC#!lChI(1vy!+rIy
zFSZYE2`+b7yi@z)iv>N>OEx*ai^!n-YD8v!7iTwxGFFsM%{Gea%d7-;|
z|L$`?FX;*iz9^p)Z$6v5-PPrX>*GfmGTfYwV(m(uF)Zg~r)6xJmRK{fLtLoo^h2c#
zK0)`*4;zHEHE$|(xgBoY$uZ|^YUhD`Wj%(eoOgtdKPo+}k<{(sRKGl~Eb;u$PygKI
zYrp)fpYfTsFiTEWZoMLpbneW&pZdl73iP}T`uWaZ3lNYkx3`(|_XGd3$LrY7)?IL1
zpSq>(-{%FUF6?U;?tcDz;;ypXw@teT
zzdfy+%RN~B&ZDw?rAt!3qR*G|6dqw>s#2c#zWaRU%IjtBeJvK*7WbalSam!HR9
zd}hyDWc=;rW2P+u0enVUrtf~aOuTkMXg+V#-mJEH_h)hLlh;q@;_j(v+>)^)?Be<0
z^t4qL;^C>UZl3tQ_}Y4d;&7!lsfVkYo;Bo5S)FP=t>uhuoB``p`I_5PR-W1s6khtp
zH+We<RiH~0$eBByHRoIUeYEX{A%YdiL}3$6EP+uAI(zaE{JAyu;|JR)Se=g+!^
zwo5^M`y;P2?31tM4Yu~+J$deX-%PiK6Tkdj!K+ZbHK)yX)Aem~T{@q=?^diRegTctSx=MM7Z%hV
z7Tf=7XPNx`9q*^-L^*e_Nqv7WT}s}4tH*pU(M#vtk34_G$GbOF
z(y-vh-#2y{ymu{k+|>yyDQB2}V0Yw2#w4+B^)@Gg&DOW{S)Ol>V2p_`Ns!<>8T>>i
zqA#bnM&r;?#)yCkJETt)i8XdEG>wT76b_XALm_uSq
z+q5MM1+3oHu~cqr`}F7Kj@Ji2x#d||}{lW=a
zFSKX3ubY2&w)ESy2#&Ri*Bz~ne(<+jm~NK4s%eRgg78;ic7GP3XHq{;v$yWBES~;E
zsiN9oT}cL4&zVE&WvXfOzucO_eRlz?-kc|$fy#T7Z?9tK<^AsUs*zb!+vv*lo&
\n\\endraw"
macro.beginfloatleft.HTML = ""
macro.beginfloatright.HTML = "
"
diff --git a/doc/config/qtcreator-project.qdocconf b/doc/config/qtcreator-project.qdocconf
index d4dc2f247c1..598bd327358 100644
--- a/doc/config/qtcreator-project.qdocconf
+++ b/doc/config/qtcreator-project.qdocconf
@@ -8,6 +8,10 @@ imagedirs = $SRCDIR/images $SRCDIR/templates/images
outputdir = $OUTDIR
exampledirs = $SRCDIR/examples
+HTML.extraimages = images/commercial.png
+qhp.QtCreator.extraFiles = images/commercial.png
+
+
indexes += $QDOC_INDEX_DIR/qtwidgets/qtwidgets.index \
$QDOC_INDEX_DIR/qtcore/qtcore.index \
$QDOC_INDEX_DIR/qtqml/qtqml.index \
diff --git a/doc/src/analyze/cpu-usage-analyzer.qdoc b/doc/src/analyze/cpu-usage-analyzer.qdoc
index 1a2971b79de..e3eb74cdfdc 100644
--- a/doc/src/analyze/cpu-usage-analyzer.qdoc
+++ b/doc/src/analyze/cpu-usage-analyzer.qdoc
@@ -30,6 +30,8 @@
\title Analyzing CPU Usage
+ \commercial
+
\QC is integrated with the Linux Perf tool (commercial only) that can be
used to analyze the CPU usage of an application on embedded devices and, to
a limited extent, on Linux desktop platforms. The CPU Usage Analyzer uses
diff --git a/doc/src/analyze/creator-clang-static-analyzer.qdoc b/doc/src/analyze/creator-clang-static-analyzer.qdoc
index 3485be704fa..b4692213793 100644
--- a/doc/src/analyze/creator-clang-static-analyzer.qdoc
+++ b/doc/src/analyze/creator-clang-static-analyzer.qdoc
@@ -31,6 +31,8 @@
\title Using Clang Static Analyzer
+ \commercial
+
\QC integrates the \l{http://clang-analyzer.llvm.org}
{Clang Static Analyzer} for finding problems in C, C++, and Objective-C
programs (commercial only).
diff --git a/doc/src/howto/creator-autotest.qdoc b/doc/src/howto/creator-autotest.qdoc
index 8500c1c1282..a394dcc62f2 100644
--- a/doc/src/howto/creator-autotest.qdoc
+++ b/doc/src/howto/creator-autotest.qdoc
@@ -35,6 +35,8 @@
\title Running Autotests
+ \commercial
+
\QC integrates the \l{Qt Test} framework for unit testing Qt based
applications and libraries (commercial only). You can use \QC to build and
run autotests for your projects.
diff --git a/doc/src/overview/creator-commercial-overview.qdoc b/doc/src/overview/creator-commercial-overview.qdoc
index 3665d5c095a..f21189d373c 100644
--- a/doc/src/overview/creator-commercial-overview.qdoc
+++ b/doc/src/overview/creator-commercial-overview.qdoc
@@ -28,6 +28,8 @@
\title Qt Creator Commercial Features
+ \commercial
+
You can use the following \QC features if you have the appropriate
\l{http://qt.io/licensing/}{Qt license}:
diff --git a/doc/src/qtquick/qtquick-connection-editor.qdoc b/doc/src/qtquick/qtquick-connection-editor.qdoc
index 6fb08767e2c..2d3aa49ccf6 100644
--- a/doc/src/qtquick/qtquick-connection-editor.qdoc
+++ b/doc/src/qtquick/qtquick-connection-editor.qdoc
@@ -35,6 +35,8 @@
\title Adding Connections
+ \commercial
+
You can use the \uicontrol {Connections} view (commercial only) to:
\list
diff --git a/doc/src/qtquick/qtquick-designer-extensions.qdoc b/doc/src/qtquick/qtquick-designer-extensions.qdoc
index 0ff8231c7a5..127a1860425 100644
--- a/doc/src/qtquick/qtquick-designer-extensions.qdoc
+++ b/doc/src/qtquick/qtquick-designer-extensions.qdoc
@@ -35,6 +35,8 @@
\title Using Qt Quick Designer Extensions
+ \commercial
+
\image qmldesigner-extensions.png
\QMLD contains commercial features that make developing Qt Quick
diff --git a/doc/src/qtquick/qtquick-pathview-editor.qdoc b/doc/src/qtquick/qtquick-pathview-editor.qdoc
index d65310f9adb..4e15cb0424a 100644
--- a/doc/src/qtquick/qtquick-pathview-editor.qdoc
+++ b/doc/src/qtquick/qtquick-pathview-editor.qdoc
@@ -35,6 +35,8 @@
\title Editing PathView Properties
+ \commercial
+
A \l{PathView} lays out data provided by data models on a \l{Path}.
A graphical spline editor enables you to specify PathView paths, which
From bcc4ab301f286a8e096dda277732c6749af31b1b Mon Sep 17 00:00:00 2001
From: Christian Kandeler
Date: Wed, 8 Apr 2015 17:01:01 +0200
Subject: [PATCH 25/38] ProjectExplorer: Fix FolderNode::addNewInformation().
We should use the actual display name of the node there, not some
hardcoded value.
Task-number: QTCREATORBUG-14240
Change-Id: Idf0fc4cdaab52d7f838d3d48d834a89b55ee593f
Reviewed-by: Daniel Teske
---
src/plugins/projectexplorer/projectnodes.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp
index 800ccfc9425..beea4f8ae75 100644
--- a/src/plugins/projectexplorer/projectnodes.cpp
+++ b/src/plugins/projectexplorer/projectnodes.cpp
@@ -367,7 +367,7 @@ bool FolderNode::renameFile(const QString &filePath, const QString &newFilePath)
FolderNode::AddNewInformation FolderNode::addNewInformation(const QStringList &files, Node *context) const
{
Q_UNUSED(files);
- return AddNewInformation(path().fileName(), context == this ? 120 : 100);
+ return AddNewInformation(displayName(), context == this ? 120 : 100);
}
/*!
From e112647397bd24d85863853e9b65ec1e16ac1c9c Mon Sep 17 00:00:00 2001
From: Leena Miettinen
Date: Thu, 9 Apr 2015 15:17:02 +0200
Subject: [PATCH 26/38] Doc: fix capitalization of BAR Descriptor
In the Issues output pane filter.
Change-Id: I3283628f74dd48c2e95eeedad93ce28f1686c25f
Reviewed-by: Leena Miettinen
---
doc/src/howto/creator-ui.qdoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/src/howto/creator-ui.qdoc b/doc/src/howto/creator-ui.qdoc
index 01941b78215..b18ce343a0a 100644
--- a/doc/src/howto/creator-ui.qdoc
+++ b/doc/src/howto/creator-ui.qdoc
@@ -329,7 +329,7 @@
\li \uicontrol Analyzer - Errors encountered while running the
\l{Analyzing Code}{Valgrind code analysis tools}.
- \li \uicontrol {Bar Descriptor} - Errors and warnings encountered when using
+ \li \uicontrol {BAR Descriptor} - Errors and warnings encountered when using
the BlackBerry 10 BAR descriptor editor to customize the appearance
and behavior of an application.
From 153a57ce80cf278b6dcc52477d5f3e51c399cf2f Mon Sep 17 00:00:00 2001
From: Ulf Hermann
Date: Wed, 8 Apr 2015 18:05:20 +0200
Subject: [PATCH 27/38] Timeline: Test parenting of equal start times
If you insert events with equal start times in a way that the model can
not reorder them by their end times the parenting follows the indexes,
not the end times. This has caused confusion multiple times and it's
good to test it.
Change-Id: I3e9ba212ff377dc2afa2a2893637bb55edebafea
Reviewed-by: Kai Koehne
---
.../timelinemodel/tst_timelinemodel.cpp | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/tests/auto/timeline/timelinemodel/tst_timelinemodel.cpp b/tests/auto/timeline/timelinemodel/tst_timelinemodel.cpp
index c253503d9a6..7080d11bbaa 100644
--- a/tests/auto/timeline/timelinemodel/tst_timelinemodel.cpp
+++ b/tests/auto/timeline/timelinemodel/tst_timelinemodel.cpp
@@ -88,6 +88,7 @@ private slots:
void insertStartEnd();
void rowCount();
void prevNext();
+ void parentingOfEqualStarts();
};
DummyModel::DummyModel(int modelId) :
@@ -443,6 +444,22 @@ void tst_TimelineModel::prevNext()
QCOMPARE(dummy.prevItemByTypeId(-1, 10, 5), 4);
}
+void tst_TimelineModel::parentingOfEqualStarts()
+{
+ DummyModel dummy;
+ // Trick it so that it cannot reorder the events and has to parent them in the "wrong" way ...
+ QCOMPARE(dummy.insert(1, 10, 998), 0);
+ QCOMPARE(dummy.insertStart(1, 999), 1);
+ dummy.insertEnd(1, 20);
+ dummy.computeNesting();
+
+ // .. which is reflected in the resulting order.
+ QCOMPARE(dummy.selectionId(0), 998);
+ QCOMPARE(dummy.selectionId(1), 999);
+ QCOMPARE(dummy.firstIndex(10), 0);
+ QCOMPARE(dummy.lastIndex(2), 1);
+}
+
QTEST_MAIN(tst_TimelineModel)
#include "tst_timelinemodel.moc"
From 7980538ef4038e1f983035be74d1dc8e5737ee57 Mon Sep 17 00:00:00 2001
From: Leena Miettinen
Date: Thu, 9 Apr 2015 15:05:43 +0200
Subject: [PATCH 28/38] Doc: sidebar view context menus
Update the screenshot, because the icons have changed.
Change-Id: I55e46f8f01d293021914fd28c1e7f7d83d8bde11
Reviewed-by: Daniel Teske
---
doc/images/qtcreator-sidebar.png | Bin 39861 -> 14946 bytes
doc/src/howto/creator-ui.qdoc | 42 +++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+)
diff --git a/doc/images/qtcreator-sidebar.png b/doc/images/qtcreator-sidebar.png
index 5a99a208a67760447c5fb0b98b80bfd1d53e7ae0..d44fe9e10ed1324df20c862257d0612bc7ae65e6 100644
GIT binary patch
literal 14946
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