Merge remote-tracking branch 'origin/3.4'
Conflicts: src/plugins/cmakeprojectmanager/cmakeproject.cpp Change-Id: I09c5a047f7d91fecfc58c78df438afcdcdc0a8d7
2
dist/changes-3.4.0
vendored
@@ -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
|
||||
|
BIN
doc/config/images/commercial.png
Normal file
After Width: | Height: | Size: 334 B |
@@ -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\">"
|
||||
|
@@ -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
|
||||
|
BIN
doc/images/qtcreator-autotests-sort-naturally.png
Normal file
After Width: | Height: | Size: 702 B |
BIN
doc/images/qtcreator-autotests.png
Normal file
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 785 B |
BIN
doc/images/qtcreator-run-selected-tests.png
Normal file
After Width: | Height: | Size: 526 B |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 15 KiB |
@@ -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
|
||||
|
@@ -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).
|
||||
|
181
doc/src/howto/creator-autotest.qdoc
Normal 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}.
|
||||
*/
|
@@ -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.
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
*/
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -35,6 +35,8 @@
|
||||
|
||||
\title Adding Connections
|
||||
|
||||
\commercial
|
||||
|
||||
You can use the \uicontrol {Connections} view (commercial only) to:
|
||||
|
||||
\list
|
||||
|
@@ -35,6 +35,8 @@
|
||||
|
||||
\title Using Qt Quick Designer Extensions
|
||||
|
||||
\commercial
|
||||
|
||||
\image qmldesigner-extensions.png
|
||||
|
||||
\QMLD contains commercial features that make developing Qt Quick
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
||||
|
||||
|
@@ -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):
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -98,7 +98,6 @@ TimelineNotesModel *TimelineModelAggregator::notes() const
|
||||
|
||||
void TimelineModelAggregator::clear()
|
||||
{
|
||||
qDeleteAll(d->modelList);
|
||||
d->modelList.clear();
|
||||
if (d->notesModel)
|
||||
d->notesModel->clear();
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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();
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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"
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@@ -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;
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -48,6 +48,7 @@ public:
|
||||
~QmlProfilerStateWidget();
|
||||
|
||||
private slots:
|
||||
void showText(const QString &text, bool showProgress = false);
|
||||
void updateDisplay();
|
||||
void dataStateChanged();
|
||||
void profilerStateChanged();
|
||||
|
@@ -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)
|
||||
|
@@ -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");
|
||||
|
@@ -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",
|
||||
|
@@ -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"
|
||||
|
@@ -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)
|
||||
|