Merge remote-tracking branch 'origin/3.4'

Conflicts:
	src/plugins/cmakeprojectmanager/cmakeproject.cpp

Change-Id: I09c5a047f7d91fecfc58c78df438afcdcdc0a8d7
This commit is contained in:
Eike Ziller
2015-04-13 10:53:03 +02:00
56 changed files with 841 additions and 517 deletions

2
dist/changes-3.4.0 vendored
View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

View File

@@ -34,6 +34,7 @@ macro.begincomment = "\\c{/*}"
macro.endcomment = "\\c{*/}"
macro.uuml.HTML = "ü"
macro.mdash.HTML = "—"
macro.commercial = "\\raw HTML\n<p><a title=\"Available under certain Qt licenses.\"><img src=\"images/commercial.png\"/></a></p>\n\\endraw"
macro.beginfloatleft.HTML = "<div style=\"float: left; margin-right: 2em\">"
macro.beginfloatright.HTML = "<div style=\"float: right; margin-left: 2em\">"

View File

@@ -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 \
@@ -22,6 +26,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

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 785 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -26,10 +26,12 @@
\contentspage {Qt Creator Manual}
\previouspage creator-clang-static-analyzer.html
\page creator-cpu-usage-analyzer.html
\nextpage creator-advanced.html
\nextpage creator-autotest.html
\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

View File

@@ -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).

View File

@@ -0,0 +1,181 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
/*!
\contentspage {Qt Creator Manual}
\previouspage creator-cpu-usage-analyzer.html
\page creator-autotest.html
\nextpage creator-advanced.html
\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.
\image qtcreator-autotests.png
To enable the experimental Auto Test plugin, select \uicontrol Help >
\uicontrol {About Plugins} > \uicontrol Utilities > \uicontrol {Auto Test}.
Restart \QC to be able to use the plugin.
\section1 Creating Autotests
You can use a wizard to create projects that contain autotests:
\list 1
\li Select \uicontrol File > \uicontrol {New File or Project} >
\uicontrol {Other Project} > \uicontrol {Auto Test} >
\uicontrol Choose to create a project with boilerplate code for an
autotest.
\li In the \uicontrol {Project and Test Information} dialog, specify
settings for the project and autotest:
\list 1
\li Select the \uicontrol {GUI Application} check box to create
a Qt application.
\li In the \uicontrol {Test case name} field, enter a name for
the test case.
\li Select the \uicontrol {Requires QApplication} check box to
add the include statement for QApplication to the main.cpp
file of the project.
\li Select the \uicontrol {Generate initialization and cleanup
code} checkbox to add functions to your test that are
executed by the testing framework to initialize and clean
up the test.
\li In the \uicontrol {Build auto tests} field, select
\uicontrol Always to always build the autotest when building
the project or \uicontrol {Debug Only} to only build it
during debug builds.
\endlist
\endlist
\QC creates the autotest in the \c{tests\auto} directory in the project
directory. Edit the .cpp file to add private slots for each test
function in your test. For more information about creating autotests, see
\l{Creating a Test}.
\section1 Building and Running Autotests
To build and run autotests:
\list 1
\li Open a project that contains autotests.
\li In the \uicontrol {Test Results} output pane, select
\inlineimage qtcreator-run.png
(\uicontrol {Run All Tests}) to run all test or
\inlineimage qtcreator-run-selected-tests.png
(\uicontrol {Run Selected Tests}) to run the selected tests.
You can select the tests to run in the \uicontrol Tests view in the
\uicontrol Projects pane. For more information, see
\l{Viewing Tests}.
\note By default, \QC builds a project before deploying and running
it.
\endlist
If a test takes more than a minute to execute, the default timeout might
stop the test execution. To increase the timeout, select \uicontrol Tools >
\uicontrol Options > \uicontrol {Test Settings}.
The code inside a benchmark test is measured, and possibly also repeated
several times in order to get an accurate measurement. This depends on the
measurement back-end that you can select in \uicontrol {Test Settings}:
walltime, CPU tick counter, event counter, Vallgrind Callgring, and Linux
Perf. For more information, see \l{Creating a Benchmark}.
\section1 Viewing Test Output
The test results are displayed in the \uicontrol {Test Results} output pane.
\table
\header
\li Result
\li Description
\row
\li BENCH
\li Benchmark test.
\row
\li BFAIL
\li Blacklisted test case failed. Since Qt 5.4, you can
provide a BLACKLIST file for tests. It is mainly used internally
by the Qt CI system.
\row
\li BPASS
\li Blacklisted test case passed.
\row
\li DEBUG
\li Debug message.
\row
\li XFAIL
\li Test case is expected to fail, so it is marked by using the
QEXPECT_FAIL macro. If the test case passes instead, an
unexpected pass (XPASS) is written to the test log.
\row
\li FAIL
\li Test case failed. Double-click the line for more information.
\row
\li INTERNAL
\li Internal message.
\row
\li PASS
\li Test case passed.
\row
\li SKIP
\li Test case was skipped.
\row
\li XPASS
\li Test case passed even though it was expected to fail.
\row
\li WARN
\li Warning message.
\endtable
To view only messages of a particular type, select
\inlineimage qtcreator-filter.png
(\uicontrol {Filter Test Results}), and then select the types of messages to
show.
To hide internal messages and run configuration warnings, select
\uicontrol Tools > \uicontrol Options > \uicontrol {Test Settings}.
*/

View File

@@ -132,6 +132,9 @@
\li \uicontrol Outline shows the symbol hierarchy of a C++ file and the type
hierarchy of a QML file.
\li \uicontrol Tests lists autotests and Qt Quick tests in the project
(commercial only).
\li \uicontrol {Type Hierarchy} shows the base classes of a class.
\li \uicontrol {Include Hierarchy} shows which files are included in the current file
@@ -154,7 +157,7 @@
(\uicontrol {Split}). Select new content to view in the split view.
\li To close a sidebar view, click
\inlineimage qtcreator-closesidebar.png
\inlineimage qtcreator-remove-split-button.png
(\uicontrol {Close}).
\endlist
@@ -162,6 +165,9 @@
The additional options in each view are described in the following
sections.
In some views, right-clicking opens a context menu that contains functions
for managing the objects listed in the view.
\section2 Viewing Project Files
The sidebar displays projects in a project tree. The project tree contains
@@ -208,6 +214,30 @@
the .pro file. This way they also become known to \QC, so that they are
visible in the \uicontrol Projects view and are known to the locator and search.
The \uicontrol Projects view contains context menus for managing projects,
subprojects, folders, and files. The following functions are available for
managing projects and subprojects:
\list
\li Set a project as the active project.
\li Execute the \uicontrol Build menu commands.
\li Add subprojects, libraries, directories, and files.
\li Remove subprojects.
\li Search from the selected directory.
\li Close projects.
\endlist
For managing files and directories, the same functions are available as in
the \uicontrol {File System} view. In addition, you can remove and rename
files.
\section2 Viewing the File System
If you cannot see a file in the \uicontrol Projects view, switch to the
@@ -218,6 +248,21 @@
To keep the position in the tree synchronized with the file
opened in the editor, select \uicontrol {Synchronize with Editor}.
Use the context menu functions to:
\list
\li Open files with the default editor or some other editor.
\li Show the file or directory in the file explorer.
\li Open a terminal window in the selected directory or in the directory
that contains the file.
\li Search from the selected directory.
\endlist
\section2 Viewing the Class Hierarchy
The \uicontrol {Class View} shows the class hierarchy of the currently
@@ -242,6 +287,29 @@
\endlist
\section2 Viewing Tests
The \uicontrol Tests view shows the autotests and Qt Quick tests in the
current project (commercial only). Select the test cases to run. If a Qt
Quick test case does not have a name, it is marked \uicontrol Unnamed in the
list. Unnamed test cases are always executed when the application that
contains them is run, and therefore you cannot select or deselect them.
To show or hide init and cleanup or data functions, select
\uicontrol {Filter Test Tree} > \uicontrol {Show Init and Cleanup Functions}
or \uicontrol {Show Data Functions}. Double-click a function in the list
to open its source code in the code editor.
The test cases are listed in alphabetic order. To list them in the order in
which they are defined in the source code, select
\inlineimage qtcreator-autotests-sort-naturally.png
(\uicontrol {Sort Naturally}).
To run tests, select \uicontrol {Run All Tests} or
\uicontrol {Run Selected Tests} in the context menu.
To refresh the view, select \uicontrol {Rescan Tests} in the context menu.
\section2 Viewing Type Hierarchy
To view the base classes of a class, right-click the class and select
@@ -275,6 +343,8 @@
\li \uicontrol{General Messages}
\li \uicontrol{Test Results} (commercial only)
\endlist
Output panes are available in all \l{Modes}{modes}. Click the name of an
@@ -289,7 +359,8 @@
To open the \uicontrol{General Messages} and \l{Using Version Control Systems}
{Version Control} panes, select
\uicontrol {Window > Output Panes}. To display the \uicontrol {To-Do Entries} pane,
enable the Todo plugin.
enable the Todo plugin and to display the \l{Running Autotests}
{Test Results} pane, enable the Auto Tests plugin.
\section2 Issues
@@ -300,7 +371,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.

View File

@@ -24,7 +24,7 @@
/*!
\contentspage {Qt Creator Manual}
\previouspage creator-cpu-usage-analyzer.html
\previouspage creator-autotest.html
\page creator-advanced.html
\nextpage creator-os-supported-platforms.html

View File

@@ -28,10 +28,13 @@
\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}:
\list
\li \l{Running Autotests}
\li \l{Using Clang Static Analyzer}{Clang Static Analyzer} integration.
\li Additional \l{Understanding the Data}{QML Profiler} event
categories:

View File

@@ -92,7 +92,7 @@
different setups and target platforms.
For more information, see \l{Building and Running}.
\li \b {\l{Debugging and Analyzing}}
\li \b {\l{Testing}}
\QC is integrated to several external native debuggers: GNU
Symbolic Debugger (GDB), Microsoft Console Debugger (CDB), and
@@ -105,7 +105,11 @@
execution. In addition, the QML Profiler enables you to profile
Qt Quick applications.
For more information, see \l{Debugging and Analyzing}.
\QC is integrated to the \l{Qt Test} framework for unit testing
Qt based applications and libraries. You can use \QC to build
and run autotests (commercial only).
For more information, see \l{Testing}.
\li \b {Publishing}
\QC allows you to create installation packages for mobile

View File

@@ -28,7 +28,7 @@
\page creator-testing.html
\nextpage creator-debugging.html
\title Debugging and Analyzing
\title Testing
\image creator_testing.png
@@ -51,6 +51,11 @@
installed as part of \QC. It enables you to profile your Qt Quick
applications.
\li \l{Running Autotests}
You can use an experimental Auto Test plugin to build and run
autotests using \QC (commercial only).
\endlist
*/

View File

@@ -159,6 +159,11 @@
Qt unit tests for features or classes
\li Qt Auto Test (commercial only)
Projects with boilerplate code for an autotest. For more
information, see \l {Creating Autotests}.
\li Qt Custom Designer Widgets
Custom \QD widget or widget collection

View File

@@ -87,10 +87,11 @@
\li \l{Deploying to Mobile Devices}
\li \l{Connecting Mobile Devices}
\endlist
\li \b {\l{Debugging and Analyzing}}
\li \b {\l{Testing}}
\list
\li \l{Debugging}
\li \l{Analyzing Code}
\li \l{Running Autotests}
\endlist
\row
\li \inlineimage creator_advanceduse.png
@@ -245,7 +246,7 @@
\endlist
\li \l{Customizing the Build Process}
\endlist
\li \l{Debugging and Analyzing}
\li \l{Testing}
\list
\li \l{Debugging}
\list
@@ -270,7 +271,7 @@
\li \l{Using Clang Static Analyzer}
\li \l{Analyzing CPU Usage}
\endlist
\li \l{Running Autotests}
\endlist
\li \l{Advanced Use}
\list

View File

@@ -35,6 +35,8 @@
\title Adding Connections
\commercial
You can use the \uicontrol {Connections} view (commercial only) to:
\list

View File

@@ -35,6 +35,8 @@
\title Using Qt Quick Designer Extensions
\commercial
\image qmldesigner-extensions.png
\QMLD contains commercial features that make developing Qt Quick

View File

@@ -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

View File

@@ -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,42 +895,27 @@ 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:
# 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])
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 +985,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 +1015,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 +1028,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 +1092,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 +1492,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 +1690,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 +1910,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)

View File

@@ -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):

View File

@@ -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
@@ -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

View File

@@ -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)
@@ -548,27 +546,6 @@ def qdump__QFiniteStack(d, value):
d.putItemCount(size)
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 "<string>", line 1,
# in <module> 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"]
@@ -867,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_")
@@ -1763,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():
@@ -1917,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)
@@ -1935,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

View File

@@ -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)

View File

@@ -133,7 +133,6 @@ private:
Clone &cloner,
Subst &subst,
ClassOrNamespace *enclosingTemplateClassInstantiation);
bool isInstantiateNestedClassNeeded(const QList<Symbol *>& symbols, const Subst &subst) const;
ClassOrNamespace *findSpecialization(const TemplateNameId *templId,
const TemplateNameIdTable &specializations);

View File

@@ -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.

View File

@@ -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
@@ -201,6 +202,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 +322,7 @@ Item {
MouseArea {
anchors.fill: parent
drag.target: parent
drag.minimumX: col.minimumWidth
drag.axis: Drag.XAxis
cursorShape: Qt.SizeHorCursor
}

View File

@@ -98,7 +98,6 @@ TimelineNotesModel *TimelineModelAggregator::notes() const
void TimelineModelAggregator::clear()
{
qDeleteAll(d->modelList);
d->modelList.clear();
if (d->notesModel)
d->notesModel->clear();

View File

@@ -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<AndroidDeviceInfo> 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;
}

View File

@@ -224,7 +224,9 @@ void CMakeCbpParser::parseBuildTarget()
while (!atEnd()) {
readNext();
if (isEndElement()) {
if (!m_buildTarget.title.endsWith(QLatin1String("/fast")))
if (!m_buildTarget.title.endsWith(QLatin1String("/fast"))
&& !m_buildTarget.title.endsWith(QLatin1String("_automoc"))
&& !m_buildTarget.title.endsWith(QLatin1String("_unittest")))
m_buildTargets.append(m_buildTarget);
return;
} else if (name() == QLatin1String("Compiler")) {
@@ -249,28 +251,10 @@ void CMakeCbpParser::parseBuildTargetOption()
m_buildTarget.targetType = TargetType(value.toInt());
} else if (attributes().hasAttribute(QLatin1String("working_dir"))) {
m_buildTarget.workingDirectory = attributes().value(QLatin1String("working_dir")).toString();
QFile cmakeSourceInfoFile(m_buildTarget.workingDirectory
+ QStringLiteral("/CMakeFiles/CMakeDirectoryInformation.cmake"));
if (cmakeSourceInfoFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream stream(&cmakeSourceInfoFile);
const QLatin1String searchSource("SET(CMAKE_RELATIVE_PATH_TOP_SOURCE \"");
while (!stream.atEnd()) {
const QString lineTopSource = stream.readLine().trimmed();
if (lineTopSource.startsWith(searchSource)) {
m_buildTarget.sourceDirectory = lineTopSource.mid(searchSource.size());
m_buildTarget.sourceDirectory.chop(2); // cut off ")
break;
}
}
}
if (m_buildTarget.sourceDirectory.isEmpty()) {
QDir dir(m_buildDirectory);
const QString relative = dir.relativeFilePath(m_buildTarget.workingDirectory);
m_buildTarget.sourceDirectory
= FileName::fromString(m_sourceDirectory).appendPath(relative).toString();
}
QDir dir(m_buildDirectory);
const QString relative = dir.relativeFilePath(m_buildTarget.workingDirectory);
m_buildTarget.sourceDirectory
= FileName::fromString(m_sourceDirectory).appendPath(relative).toString();
}
while (!atEnd()) {
readNext();

View File

@@ -748,47 +748,45 @@ QFuture<void> 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<void>();
}
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<QString> addedFiles = comparer.addedFiles();
filesToReindex.unite(addedFiles);
const QSet<QString> modifiedFiles = comparer.timeStampModifiedFiles(snapshot());
filesToReindex.unite(modifiedFiles);
}
// Otherwise check for added and modified files
} else {
const QSet<QString> addedFiles = comparer.addedFiles();
filesToReindex.unite(addedFiles);
const QSet<QString> modifiedFiles = comparer.timeStampModifiedFiles(snapshot());
filesToReindex.unite(modifiedFiles);
}
// Announce and purge the removed files from the snapshot
const QSet<QString> 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<QString> 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();

View File

@@ -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);

View File

@@ -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"

View File

@@ -33,6 +33,8 @@
#include <QWidget>
#include <vector>
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<double> 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

View File

@@ -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 <class T>
void readNumericVectorHelper(std::vector<double> *v, const QByteArray &ba)
{
const T *p = (const T *) ba.data();
std::copy(p, p + ba.size() / sizeof(T), std::back_insert_iterator<std::vector<double> >(*v));
}
void readNumericVector(std::vector<double> *v, const QByteArray &rawData, DebuggerEncoding encoding)
{
switch (encoding) {
case Hex2EncodedInt1:
readNumericVectorHelper<signed char>(v, rawData);
break;
case Hex2EncodedInt2:
readNumericVectorHelper<short>(v, rawData);
break;
case Hex2EncodedInt4:
readNumericVectorHelper<int>(v, rawData);
break;
case Hex2EncodedInt8:
readNumericVectorHelper<qint64>(v, rawData);
break;
case Hex2EncodedUInt1:
readNumericVectorHelper<uchar>(v, rawData);
break;
case Hex2EncodedUInt2:
readNumericVectorHelper<ushort>(v, rawData);
break;
case Hex2EncodedUInt4:
readNumericVectorHelper<uint>(v, rawData);
break;
case Hex2EncodedUInt8:
readNumericVectorHelper<quint64>(v, rawData);
break;
case Hex2EncodedFloat4:
readNumericVectorHelper<float>(v, rawData);
break;
case Hex2EncodedFloat8:
readNumericVectorHelper<double>(v, rawData);
break;
default:
qDebug() << "ENCODING ERROR: " << encoding;
}
}
} // namespace Internal
} // namespace Debugger

View File

@@ -37,6 +37,7 @@
#include <QMetaType>
#include <functional>
#include <vector>
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<void(const WatchData &)> itemHandler,
const QByteArray &rawData,
int encoding);
void readNumericVector(std::vector<double> *,
const QByteArray &rawData,
DebuggerEncoding encoding);
void parseChildrenData(const WatchData &parent, const GdbMi &child,
std::function<void(const WatchData &)> itemHandler,
std::function<void(const WatchData &, const GdbMi &)> childHandler,

View File

@@ -53,11 +53,13 @@
#include <QDebug>
#include <QFile>
#include <QPainter>
#include <QProcess>
#include <QTabWidget>
#include <QTextEdit>
#include <QTimer>
#include <algorithm>
#include <cstring>
#include <ctype.h>
@@ -109,6 +111,52 @@ static void saveWatchers()
setSessionValue("Watchers", WatchHandler::watchedExpressions());
}
static void loadFormats()
{
QVariant value = sessionValue("DefaultFormats");
QMapIterator<QString, QVariant> 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<QString, QVariant>(value.toMap());
while (it.hasNext()) {
it.next();
if (!it.key().isEmpty())
theIndividualFormats.insert(it.key().toUtf8(), it.value().toInt());
}
}
static void saveFormats()
{
QMap<QString, QVariant> formats;
QHashIterator<QByteArray, int> 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<QByteArray, int>(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 <class T> T *prepareObject(const QByteArray &key, const QString &title)
template <class T> 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<WatchItem *>(sub)); });
item->walkTree([this](TreeItem *sub) { showEditValue(static_cast<WatchItem *>(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<ImageViewer>(key, title);
v->setProperty(INameProperty, data.iname);
ImageViewer *v = m_separatedView->prepareObject<ImageViewer>(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<QTextEdit>(key, data.name);
t->setProperty(INameProperty, data.iname);
QTextEdit *t = m_separatedView->prepareObject<QTextEdit>(key, item->name);
t->setProperty(INameProperty, item->iname);
t->setText(str);
break;
}
case DisplayPlotData: { // Plots
std::vector<double> data;
readNumericVector(&data, QByteArray::fromHex(item->editvalue), item->editencoding);
PlotViewer *v = m_separatedView->prepareObject<PlotViewer>(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<QString, QVariant> 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<QString, QVariant>(value.toMap());
while (it.hasNext()) {
it.next();
if (!it.key().isEmpty())
theIndividualFormats.insert(it.key().toUtf8(), it.value().toInt());
}
}
static void saveFormats()
{
QMap<QString, QVariant> formats;
QHashIterator<QByteArray, int> 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<QByteArray, int>(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;

View File

@@ -48,7 +48,6 @@ DiffEditorController::DiffEditorController(Core::IDocument *document) :
m_chunkIndex(-1)
{
QTC_ASSERT(m_document, return);
QTC_CHECK(!m_document->controller());
m_document->setController(this);
}

View File

@@ -76,7 +76,7 @@ Core::IDocument *DiffEditorManager::findOrCreate(const QString &vcsId, const QSt
QTC_ASSERT(diffEditor, return 0);
document = qobject_cast<Internal::DiffEditorDocument *>(diffEditor->document());
QTC_ASSERT(diffEditor, return 0);
QTC_ASSERT(document, return 0);
document->setPreferredDisplayName(displayName);

View File

@@ -781,19 +781,15 @@ void GitClient::requestReload(const QString &documentId, const QString &source,
const QString &title,
std::function<DiffEditorController *(IDocument *)> factory) const
{
DiffEditorController *controller = 0;
IDocument *document = DiffEditorManager::findOrCreate(documentId, title);
QTC_ASSERT(document, return);
controller = DiffEditorManager::controller(document);
if (!controller) {
controller = factory(document);
QTC_ASSERT(controller, return);
DiffEditorController *controller = factory(document);
QTC_ASSERT(controller, return);
connect(controller, &DiffEditorController::chunkActionsRequested,
this, &GitClient::slotChunkActionsRequested, Qt::DirectConnection);
connect(controller, &DiffEditorController::requestInformationForCommit,
this, &GitClient::branchesForCommit);
}
connect(controller, &DiffEditorController::chunkActionsRequested,
this, &GitClient::slotChunkActionsRequested, Qt::DirectConnection);
connect(controller, &DiffEditorController::requestInformationForCommit,
this, &GitClient::branchesForCommit);
VcsBasePlugin::setSource(document, source);
EditorManager::activateEditorForDocument(document);
@@ -2137,8 +2133,8 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory, St
statusArgs << QLatin1String("--ignore-submodules=all");
statusArgs << QLatin1String("--porcelain") << QLatin1String("-b");
const bool statusRc = fullySynchronousGit(workingDirectory, statusArgs,
&outputText, &errorText, false);
const bool statusRc = fullySynchronousGit(workingDirectory, statusArgs, &outputText, &errorText,
VcsBasePlugin::SuppressCommandLogging);
if (output)
*output = commandOutputFromLocal8Bit(outputText);

View File

@@ -30,6 +30,7 @@
#include "helpplugin.h"
#include "bookmarkmanager.h"
#include "centralwidget.h"
#include "docsettingspage.h"
#include "filtersettingspage.h"
@@ -668,6 +669,7 @@ void HelpPlugin::doSetupIfNeeded()
resetFilter();
m_setupNeeded = false;
OpenPagesManager::instance().setupInitialPages();
LocalHelpManager::bookmarkManager().setupBookmarkModels();
}
}

View File

@@ -140,10 +140,8 @@ BookmarkManager& LocalHelpManager::bookmarkManager()
{
if (!m_bookmarkManager) {
QMutexLocker _(&m_bkmarkMutex);
if (!m_bookmarkManager) {
if (!m_bookmarkManager)
m_bookmarkManager = new BookmarkManager;
m_bookmarkManager->setupBookmarkModels();
}
}
return *m_bookmarkManager;
}

View File

@@ -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);
}
/*!

View File

@@ -519,10 +519,11 @@ void QbsGroupNode::setupFolder(ProjectExplorer::FolderNode *root, const qbs::Gro
// Handle files:
if (c->isFile()) {
const ProjectExplorer::FileType newFileType = fileType(group, c->path());
ProjectExplorer::FileNode *fn = 0;
foreach (ProjectExplorer::FileNode *f, root->fileNodes()) {
// There can be one match only here!
if (f->path() != path)
if (f->path() != path || f->fileType() != newFileType)
continue;
fn = f;
break;
@@ -532,7 +533,7 @@ void QbsGroupNode::setupFolder(ProjectExplorer::FolderNode *root, const qbs::Gro
if (updateExisting)
fn->emitNodeUpdated();
} else {
fn = new ProjectExplorer::FileNode(path, fileType(group, c->path()), false);
fn = new ProjectExplorer::FileNode(path, newFileType, false);
filesToAdd.append(fn);
}
continue;

View File

@@ -295,6 +295,7 @@ bool QbsProject::addFilesToProduct(QbsBaseProjectNode *node, const QStringList &
QbsGroupNode::setupFiles(node, reRetrieveGroupData(productData, groupData),
allPaths, QFileInfo(productFilePath).absolutePath(), true);
m_rootProjectNode->update();
emit fileListChanged();
}
return notAdded->isEmpty();
}
@@ -323,6 +324,7 @@ bool QbsProject::removeFilesFromProduct(QbsBaseProjectNode *node, const QStringL
QbsGroupNode::setupFiles(node, reRetrieveGroupData(productData, groupData), allPaths,
QFileInfo(productFilePath).absolutePath(), true);
m_rootProjectNode->update();
emit fileListChanged();
}
return notRemoved->isEmpty();
}

View File

@@ -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(300, 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;
}

View File

@@ -48,6 +48,7 @@ public:
~QmlProfilerStateWidget();
private slots:
void showText(const QString &text, bool showProgress = false);
void updateDisplay();
void dataStateChanged();
void profilerStateChanged();

View File

@@ -115,6 +115,8 @@ public:
void accept();
bool event(QEvent *event);
private slots:
void changed()
{
@@ -157,6 +159,18 @@ void CustomExecutableDialog::accept()
QDialog::accept();
}
bool CustomExecutableDialog::event(QEvent *event)
{
if (event->type() == QEvent::ShortcutOverride) {
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
if (ke->key() == Qt::Key_Escape && !ke->modifiers()) {
ke->accept();
return true;
}
}
return QDialog::event(event);
}
// CustomExecutableRunConfiguration
RunConfiguration::ConfigurationState CustomExecutableRunConfiguration::ensureConfigured(QString *errorMessage)

View File

@@ -38,7 +38,6 @@
using namespace TextEditor;
const char NOMANGLER_ID[] = "TextEditor::NoMangler";
const char UCMANGLER_ID[] = "TextEditor::UppercaseMangler";
const char LCMANGLER_ID[] = "TextEditor::LowercaseMangler";
const char TCMANGLER_ID[] = "TextEditor::TitlecaseMangler";
@@ -276,6 +275,8 @@ Snippet::ParsedSnippet Snippet::parse(const QString &snippet)
# include "../texteditorplugin.h"
const char NOMANGLER_ID[] = "TextEditor::NoMangler";
void Internal::TextEditorPlugin::testSnippetParsing_data()
{
QTest::addColumn<QString>("input");

View File

@@ -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);
@@ -1684,32 +1684,15 @@ void tst_Dumpers::dumper_data()
"QHash<QString, int> 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<QByteArray, float> 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<int, QString> h5;\n"
"h5[22] = \"22.0\";\n\n"
"QHash<QString, Foo> h6;\n"
"h6[\"22.0\"] = Foo(22);\n"
"h6[\"33.0\"] = Foo(33);\n\n"
"QObject ob;\n"
"QHash<QString, QPointer<QObject> > 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<int, @QString>")
+ 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>>")
@@ -3321,7 +3284,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 +3313,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 +3327,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")
@@ -3540,29 +3503,39 @@ void tst_Dumpers::dumper_data()
+ Check("v1.8999", "[8999]", "80982001", "int")
+ Check("v2", "<2 items>", "@QVector<Foo>")
+ 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<Foo>") % 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<Foo*>")
+ 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<bool>")
+ 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<int>>")
+ CheckType("pv", "@QVector<@QList<int>>") % NoCdbEngine
+ CheckType("pv", "QVector<QList<int> > *") % CdbEngine
+ Check("pv.0", "[0]", "<1 items>", "@QList<int>")
+ Check("pv.0.0", "[0]", "1", "int")
+ Check("pv.1", "[1]", "<2 items>", "@QList<int>")
@@ -5044,10 +5017,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 <QString>\n",

View File

@@ -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"

View File

@@ -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)