Merge remote-tracking branch 'origin/3.4'

This commit is contained in:
Eike Ziller
2015-03-26 12:51:06 +01:00
70 changed files with 786 additions and 366 deletions

56
dist/changes-3.4.0 vendored
View File

@@ -42,8 +42,48 @@ QML-Only Projects (.qmlproject)
* Disabled plugin by default
Debugging
* LLDB
* Fixed general tooltip behavior (QTCREATORBUG-13957, QTCREATORBUG-13774 et al)
* Improved display of register contents
* Added various display options for QByteArray, QString, std::string and char[]
* Added dumpers for QPolygon{,F} and QGraphicsPolygonItem
* Updated QV4::Value and std::unordered_* dumpers
* Fixed display of location marker in mixed master engine (QTCREATORBUG-13695)
* Allowed evaluation of children of evaluated expressions (QTCREATORBUG-5920)
* Added %{Debugger:Name,Type,Version,...} expandable macros for use in kits
* Fixed reloading of dumpers within a running debugger session
* Fixed "Show Address" stack window context menu action
* Fixed off-by-one error in tooltip context line number computation
* Improved display of function names in disassembler view
* Improved "Attach to unstarted application" startup sequence
* Replaced gnuplot with matplotlib for graphical display of vector data
* Delayed auto-collapsing of unused dockwidget titlebars
* Added parsing and display of debugger type and version in
Tools > Options > Build & Run > Debuggers
* Added progress indicator in some views for long operations
* GDB:
* Replaced MI with a Python function for stack generation
NOTE: This makes GDB 7.5 the minimum supported version
* Disabled GDB's own pretty printers by default
* Improved optional import of GDB's own pretty printers
* Added experimental code for native combined QML and C++ debugging
* LLDB:
* Fixed debugging of console applications (QTCREATORBUG-13803)
* Avoided unwanted disassembler display on certain application start ups
* Fixed ramp down of LLDB process on exit (QTCREATORBUG-14083)
* Fixed array access with long indices
* Improved handling of user-defined dumpers
* Inverted LLDB/Python startup order to ensure use of suitable Python version
* CDB:
* Limited string size in QByteArray dumper
* Fixed QDateTime dumper (QTCREATORBUG-13263)
* Fixed handling of added evaluated expressions
* Fixed expression returned for watchers (QTCREATORBUG-12801)
* Improved detection of used Qt version
* Added support for Qt builds with namespaces and libinfix
* PDB:
* Fixed "step out" operation
* Implemented assignment of simple values
* Added tooltip handling
Analyzer
* Added Valgrind Memory Analyzer with GDB
@@ -70,6 +110,7 @@ C++ Support
QML Support
* Fixed crash on closing one of multiple outline views (QTCREATORBUG-13614)
* Fixed crash in PathsAndLanguages::compact (QTCREATORBUG-13786)
Version Control Systems
* Git
@@ -87,9 +128,20 @@ Version Control Systems
FakeVim
* Fixed target column for various commands
* Fixed behavior of "D" in visual block mode
* Fixed behavior of D in visual block mode
* Fixed cursor shape after failing search
* Fixed cursor shape when selecting using the mouse
* Fixed issues with pasting in presence of splits (QTCREATORBUG-13481)
* Fixed black hole and yank register
* Fixed cursor shape after failed searches
* Fixed some off-by-one cursor positioning error at document end
* Fixed block indentation after >i{
* Fixed target column after | and visual movement
* Improved replay of macros containing ex commands
* Improved handling of upper case registers
* Implemented C-u in insert mode
* Implemented operations on paragraph objects
* Changed default key sequence for mode activation on OS X (QTCREATORBUG-14082)
Platform Specific

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -33,10 +33,7 @@
\QC integrates the \l{http://clang-analyzer.llvm.org}
{Clang Static Analyzer} for finding problems in C, C++, and Objective-C
programs (commercial only). You must have Clang installed to use the plugin.
At the time of
this writing, the plugin is experimental and only available on Linux and
OS X.
programs (commercial only).
\image qtcreator-clang-static-analyzer.png
@@ -44,36 +41,31 @@
more information about the checkers, see
\l{http://clang-analyzer.llvm.org/available_checks.html}{Available Checkers}.
To set up the Clang Static Analyzer:
To suppress diagnostics, select \uicontrol {Suppress This Diagnostic} in the
context menu.
\list 1
\section1 Setting Up Clang Static Analyzer
\li Select \uicontrol Help > \uicontrol {About Plugins} >
\uicontrol {Code Analyzer} > \uicontrol {Clang Static Analyzer} to
enable the experimental plugin.
You must have Clang installed to use the Clang Static Analyzer. On Windows,
Clang version 3.6, or later, is required to use the MSVC tool chain.
\li Restart \QC to be able to use the plugin.
\li Select \uicontrol Tools > \uicontrol Options > \uicontrol Analyzer >
\uicontrol {Clang Static Analyzer} to check that the path to the Clang
To set up the Clang Static Analyzer, select \uicontrol Tools >
\uicontrol Options > \uicontrol Analyzer >
\uicontrol {Clang Static Analyzer} and check that the path to the Clang
executable is set correctly in the \uicontrol {Clang executable} field.
\image qtcreator-clang-static-analyzer-options.png
\endlist
\section1 Running Clang Static Analyzer
To run the Clang Static Analyzer to analyze an open project:
To run the Clang Static Analyzer to analyze an open project, select
\uicontrol Analyze > \uicontrol {Clang Static Analyzer} on the menu bar. The
Clang Static Analyzer starts automatically.
\list 1
\li Select \uicontrol Analyze > \uicontrol {Clang Static Analyzer}.
\li Select the
However, if you select \uicontrol Analyze in the mode selector to open the
\uicontrol Analyze mode and then select \uicontrol {Clang Static Analyzer},
you must start the Clang Static Analyzer by selecting the
\inlineimage qtcreator-analyze-start-button.png
(\uicontrol Start) button to run the Clang Static Analyzer on the
application.
\endlist
(\uicontrol Start) button.
*/

View File

@@ -95,6 +95,8 @@
You can change the configuration of preconfigured tools and configure
additional tools in \QC \uicontrol Options.
\image qtcreator-external-tools.png
To configure external tools:
\list 1
@@ -115,18 +117,18 @@
\li In the \uicontrol {Working directory} field, specify the path to the
working directory.
\li In the \uicontrol Environment field, select \uicontrol Change to modify
environment variable values for build and run environments in
the \uicontrol {Edit Environment Changes} dialog. For more information
about how to add and remove variable values, see \l{Batch Editing}.
\li In the \uicontrol {Output pane}, select how to handle output from the
\li In the \uicontrol Output field, select how to handle output from the
tool. You can ignore the output, view it in the \uicontrol {General
Messages} output pane, or replace the selected text with the
output in the code editor.
\li In the \uicontrol {Error output pane}, select how to handle error messages
from the tool.
\li In the \uicontrol {Error output} field, select how to handle error
messages from the tool.
\li In the \uicontrol Environment field, select \uicontrol Change to modify
environment variable values for build and run environments in
the \uicontrol {Edit Environment Changes} dialog. For more information
about how to add and remove variable values, see \l{Batch Editing}.
\li Select the \uicontrol {Modifies current document} check box to make sure
that if the current document is modified by the tool, it is saved
@@ -140,7 +142,7 @@
The category and tool are added to the \uicontrol {Tools > External} menu.
If you change the configuration of preconfigured tools, you can later
revert the changes by selecting the \uicontrol Revert button.
revert the changes by selecting the \uicontrol Reset button.
The tool configurations that you add and modify are stored in XML format in
the user configuration folder. For example,

View File

@@ -0,0 +1,55 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator
**
**
** GNU Free Documentation License
**
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of this
** file.
**
**
****************************************************************************/
// **********************************************************************
// NOTE: the sections are not ordered by their logical order to avoid
// reshuffling the file each time the index order changes (i.e., often).
// Run the fixnavi.pl script to adjust the links to the index order.
// **********************************************************************
/*!
\contentspage {Qt Creator Manual}
\page creator-commercial-overview.html
\title Qt Creator Commercial Features
You can use the following \QC features if you have the appropriate
\l{http://qt.io/licensing/}{Qt license}:
\list
\li \l{Using Clang Static Analyzer}{Clang Static Analyzer} integration.
\li Additional \l{Understanding the Data}{QML Profiler} event
categories:
\list
\li Pixmap cache
\li \l{Analyzing Scene Graph Events}{Scene graph}
\li Memory usage
\li Input events
\endlist
\li \l{http://doc.qt.io/QtQuickCompiler/}{Qt Quick Compiler}
integration
\li \l{Using Qt Quick Designer Extensions}
{Qt Quick Designer extensions}:
\list
\li \l{Adding Connections}{Connections view}
\li \l{Editing PathView Properties}{PathView property editor}
\li \l{Using Qt Quick UI Forms}{Export button} for exporting
items as alias properties
\endlist
\endlist
*/

View File

@@ -47,6 +47,8 @@
\li Select \uicontrol Tools > \uicontrol Options > \uicontrol {Build & Run} >
\uicontrol Debuggers > \uicontrol Add.
\image qtcreator-options-build-run-debuggers.png
\li In the \uicontrol Name field, give a descriptive name for the debugger.
\li In the \uicontrol Path field, specify the path to the debugger binary:
@@ -65,6 +67,9 @@
\endlist
\QC attempts to identify the type and version of the debugger and
shows them in the \uicontrol Type and \uicontrol Version fields.
\li In the \uicontrol ABIs field, specify the ABI versions to use on embedded
devices.

View File

@@ -37,6 +37,10 @@
Windows
operating systems. For more information, see \l{Supported Platforms}.
This manual also describes features that are only available if you have the
appropriate \l{http://qt.io/licensing/}{Qt license}. For more information,
see \l{Qt Creator Commercial Features}.
\table
\row
\li \inlineimage creator_gettingstarted.png

View File

@@ -30,19 +30,45 @@
from dumper import *
def dumpLiteral(d, value):
def readTemplateName(d, value):
name = readLiteral(d, value["_identifier"]) + "<"
args = value["_templateArguments"]
impl = args["_M_impl"]
start = impl["_M_start"]
size = impl["_M_finish"] - start
for i in range(size):
if i > 0:
name += ", "
typeVal = d.downcast(start[i]["_type"])
postfix = ""
while str(typeVal.type.target().unqualified()) == "CPlusPlus::PointerType":
postfix += "*"
typeVal = d.downcast(typeVal["_elementType"]["_type"])
name += readLiteral(d, typeVal["_name"]) + postfix
name += ">"
return name
def readLiteral(d, value):
if d.isNull(value):
d.putValue("<null>")
return
return "<null>"
value = d.downcast(value)
type = value.type.unqualified()
try:
type = type.target()
except:
pass
if str(type) == "CPlusPlus::TemplateNameId":
dumpLiteral(d, value["_identifier"])
else:
d.putSimpleCharArray(value["_chars"], value["_size"])
typestr = str(type)
if typestr == "CPlusPlus::TemplateNameId":
return readTemplateName(d, value)
elif typestr == "CPlusPlus::QualifiedNameId":
return readLiteral(d, value["_base"]) + "::" + readLiteral(d, value["_name"])
try:
return d.extractBlob(value["_chars"], value["_size"]).toBytes()
except:
return "<unsupported>"
def dumpLiteral(d, value):
d.putValue('"' + readLiteral(d, value) + '"')
def qdump__Core__Id(d, value):
try:
@@ -87,8 +113,7 @@ def qdump__CPlusPlus__Identifier(d, value):
d.putPlainChildren(value)
def qdump__CPlusPlus__Symbol(d, value):
name = d.downcast(value["_name"])
dumpLiteral(d, name)
dumpLiteral(d, value["_name"])
d.putBetterType(value.type)
d.putPlainChildren(value)
@@ -97,13 +122,12 @@ def qdump__CPlusPlus__IntegerType(d, value):
d.putPlainChildren(value)
def qdump__CPlusPlus__NamedType(d, value):
literal = d.downcast(value["_name"])
dumpLiteral(d, literal)
dumpLiteral(d, value["_name"])
d.putBetterType(value.type)
d.putPlainChildren(value)
def qdump__CPlusPlus__TemplateNameId(d, value):
dumpLiteral(d, value["_identifier"].dereference())
dumpLiteral(d, value)
d.putBetterType(value.type)
d.putPlainChildren(value)

View File

@@ -782,7 +782,8 @@ class Dumper(DumperBase):
return thread
return None
def reportThreads(self):
def reportThreads(self, args):
self.reportToken(args)
result = 'threads={threads=['
for i in xrange(0, self.process.GetNumThreads()):
thread = self.process.GetThreadAtIndex(i)
@@ -810,9 +811,13 @@ class Dumper(DumperBase):
result += ',file="%s"' % fileName(frame.line_entry.file)
result += '}},'
result += '],current-thread-id="%s"},' % self.currentThread().id
result += ']},'
self.report(result)
def reportCurrentThread(self, args):
self.reportToken(args)
self.report('current-thread={id="%s"}' % self.currentThread().id)
def firstUsableFrame(self, thread):
for i in xrange(10):
frame = thread.GetFrameAtIndex(i)
@@ -1210,7 +1215,6 @@ class Dumper(DumperBase):
else:
state = self.process.GetState()
if state == lldb.eStateStopped:
self.reportThreads()
self.reportVariables()
def reportRegisters(self, _ = None):
@@ -1329,7 +1333,6 @@ class Dumper(DumperBase):
stoppedThread = self.firstStoppedThread()
if stoppedThread:
self.process.SetSelectedThread(stoppedThread)
self.reportThreads()
elif eventType == lldb.SBProcess.eBroadcastBitInterrupt: # 2
pass
elif eventType == lldb.SBProcess.eBroadcastBitSTDOUT:

View File

@@ -188,12 +188,7 @@ def qdump__QModelIndex(d, value):
% (mm_, row, column, mi_))
d.putItem(mi2)
i = i + 1
d.putFields(value)
#d.putCallItem("parent", val, "parent")
#with SubItem(d, "model"):
# d.putValue(m)
# d.putType(ns + "QAbstractItemModel*")
# d.putNumChild(1)
d.putCallItem("parent", value, "parent")
#gdb.execute("call free($mi)")
@@ -421,10 +416,20 @@ def qdump__QDir(d, value):
def qdump__QFile(d, value):
# 9fc0965 changes the layout of the private structure
# 9fc0965 and a373ffcd change the layout of the private structure
qtVersion = d.qtVersion()
is32bit = d.is32bit()
if qtVersion > 0x050200:
if qtVersion >= 0x050500:
if d.isWindowsTarget():
offset = 164 if is32bit else 248
else:
offset = 156 if is32bit else 248
elif qtVersion >= 0x050400:
if d.isWindowsTarget():
offset = 188 if is32bit else 272
else:
offset = 180 if is32bit else 272
elif qtVersion > 0x050200:
if d.isWindowsTarget():
offset = 180 if is32bit else 272
else:

View File

@@ -91,6 +91,16 @@ CompileOutput_ErrorOutput=ffff6c6c
CompileOutput_MessageOutput=ff008787
CompileOutput_ErrorMessageOutput=ffff6c6c
Debugger_LogWindow_LogInput=ff00acac
Debugger_LogWindow_LogStatus=ff00875a
Debugger_LogWindow_LogWarning=fff3c300
Debugger_LogWindow_LogError=ffff6c6c
Debugger_LogWindow_LogTime=ffbf0303
Debugger_WatchItem_ValueNormal=text
Debugger_WatchItem_ValueInvalid=textDisabled
Debugger_WatchItem_ValueChanged=ffbf0303
Welcome_BackgroundColorNormal=normalBackground
Welcome_Button_BorderColorNormal=0
Welcome_Button_BorderColorPressed=0

View File

@@ -85,6 +85,16 @@ CompileOutput_ErrorOutput=ffaa0000
CompileOutput_MessageOutput=ff0000aa
CompileOutput_ErrorMessageOutput=ffaa0000
Debugger_LogWindow_LogInput=ff0000ff
Debugger_LogWindow_LogStatus=ff008000
Debugger_LogWindow_LogWarning=ff808000
Debugger_LogWindow_LogError=ffff0000
Debugger_LogWindow_LogTime=ff800000
Debugger_WatchItem_ValueNormal=ff000000
Debugger_WatchItem_ValueInvalid=ff8c8c8c
Debugger_WatchItem_ValueChanged=ffc80000
Welcome_BackgroundColorNormal=ffffffff
Welcome_Button_BorderColorNormal=ff737373
Welcome_Button_BorderColorPressed=ff333333

View File

@@ -1205,7 +1205,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
oo.showReturnTypes = true;
oo.showTemplateParameters = true;
qDebug() << "cloned" << oo(clone->type());
if (Class *klass = s->asClass()) {
if (Class *klass = clone->asClass()) {
const unsigned klassMemberCount = klass->memberCount();
for (unsigned i = 0; i < klassMemberCount; ++i){
Symbol *klassMemberAsSymbol = klass->memberAt(i);

View File

@@ -32,3 +32,19 @@ Various utilities are provided in the QML code. CategoryLabels can be used to pr
data rendered using a TimelineRenderer. TimeMarks provides colored bars that can be layered behind
a TimelineRenderer to make the rows easier to distinguish. TimeDisplay provides a legend for the
time spanned by a timeline.
Render Passes
-------------
Render passes for TimelineRenderer and TimelineOverviewRenderer are used to create the scene graph
nodes to display data from TimelineModels. You can add your own RenderPasses. For an example, see
QmlProfilerBindingLoopsRenderPass in the qmlprofiler plugin. In general, a render pass is stateless
and will update only the render pass state specific to itself and the model being rendered. A render
pass state can contain scene graph subtrees for each row in both the expanded and collapsed states
of the view, as well as scene graph subtrees to be overlayed on top of the whole category. The
renderer will layer the subtrees according to the order in which the render passes are given.
Each render pass has to provide an update() method which is called to update data in the given
render state or create a new render state. The rows in expanded state can be vertically resized. To
deal with this, keep the nodes in rows with a QSGTransformNode as parent for each of them. The
overlay mode should only be used for things that span multiple rows.

View File

@@ -32,12 +32,11 @@ import QtQuick 2.1
Text {
property bool isLabel: false
property int labelWidth: 85
property int valueWidth: 170
font.pixelSize: 12
font.bold: isLabel
textFormat: Text.PlainText
renderType: Text.NativeRendering
elide: Text.ElideRight
width: text === "" ? 0 : (isLabel ? labelWidth : valueWidth)
width: text === "" ? 0 : (isLabel ? implicitWidth : valueWidth)
}

View File

@@ -47,8 +47,6 @@ Rectangle {
property bool selectionRangeMode: false
property bool selectionRangeReady: selectionRange.ready
property real selectionRangeStart: selectionRange.startTime
property real selectionRangeEnd: selectionRange.startTime + selectionRange.duration
property int typeId: content.typeId
onTypeIdChanged: updateCursorPosition()
@@ -313,7 +311,12 @@ Rectangle {
visible: parent.visible
onRangeDoubleClicked: {
zoomControl.setRange(startTime, endTime);
var diff = 500 - zoomer.selectionDuration;
if (diff > 0)
zoomControl.setRange(zoomer.selectionStart - diff / 2,
zoomer.selectionEnd + diff / 2);
else
zoomControl.setRange(zoomer.selectionStart, zoomer.selectionEnd);
root.selectionRangeMode = false;
}
@@ -327,16 +330,17 @@ Rectangle {
id: selectionRangeDetails
visible: selectionRange.visible
startTime: selectionRange.startTime
duration: selectionRange.duration
endTime: selectionRange.endTime
startTime: zoomControl.selectionStart
duration: zoomControl.selectionDuration
endTime: zoomControl.selectionEnd
showDuration: selectionRange.rangeWidth > 1
onRecenter: {
if ((selectionRange.startTime < zoomControl.rangeStart) ^
(selectionRange.endTime > zoomControl.rangeEnd)) {
var center = selectionRange.startTime + selectionRange.duration / 2;
var halfDuration = Math.max(selectionRange.duration, zoomControl.rangeDuration / 2);
if ((zoomControl.selectionStart < zoomControl.rangeStart) ^
(zoomControl.selectionEnd > zoomControl.rangeEnd)) {
var center = (zoomControl.selectionStart + zoomControl.selectionEnd) / 2;
var halfDuration = Math.max(zoomControl.selectionDuration,
zoomControl.rangeDuration) / 2;
zoomControl.setRange(center - halfDuration, center + halfDuration);
}
}

View File

@@ -41,10 +41,6 @@ RangeMover {
property bool ready: visible && creationState === creationFinished
property double startTime: rangeLeft * viewTimePerPixel + zoomer.windowStart
property double duration: Math.max(rangeWidth * viewTimePerPixel, 500)
property double endTime: startTime + duration
property double viewTimePerPixel: 1
property double creationReference : 0
property int creationState : creationInactive
@@ -55,6 +51,31 @@ RangeMover {
creationReference = 0;
}
function updateZoomer() {
zoomer.setSelection(rangeLeft * viewTimePerPixel + zoomer.windowStart,
rangeRight * viewTimePerPixel + zoomer.windowStart)
}
function updateRange() {
var left = (zoomer.selectionStart - zoomer.windowStart) / viewTimePerPixel;
var right = (zoomer.selectionEnd - zoomer.windowStart) / viewTimePerPixel;
if (left < rangeLeft) {
rangeLeft = left;
rangeRight = right;
} else {
rangeRight = right;
rangeLeft = left;
}
}
onRangeWidthChanged: updateZoomer()
onRangeLeftChanged: updateZoomer()
Connections {
target: zoomer
onWindowChanged: updateRange()
}
function setPos(pos) {
if (pos < 0)
pos = 0;

View File

@@ -42,6 +42,7 @@ TimelineAbstractRenderer::TimelineAbstractRenderer(TimelineAbstractRendererPriva
QQuickItem *parent) :
QQuickItem(parent), d_ptr(&dd)
{
setFlag(ItemHasContents);
}
int TimelineAbstractRenderer::selectedItem() const
@@ -63,6 +64,7 @@ void TimelineAbstractRenderer::setSelectedItem(int itemIndex)
TimelineAbstractRenderer::TimelineAbstractRenderer(QQuickItem *parent) : QQuickItem(parent),
d_ptr(new TimelineAbstractRendererPrivate)
{
setFlag(ItemHasContents);
}
bool TimelineAbstractRenderer::selectionLocked() const

View File

@@ -37,7 +37,6 @@ TimelineOverviewRenderer::TimelineOverviewRenderer(QQuickItem *parent) :
TimelineAbstractRenderer(*(new TimelineOverviewRendererPrivate), parent)
{
Q_D(TimelineOverviewRenderer);
setFlag(QQuickItem::ItemHasContents);
d->renderState = 0;
}

View File

@@ -57,7 +57,6 @@ TimelineRenderer::TimelineRendererPrivate::TimelineRendererPrivate(TimelineRende
TimelineRenderer::TimelineRenderer(QQuickItem *parent) :
TimelineAbstractRenderer(*(new TimelineRendererPrivate(this)), parent)
{
setFlag(QQuickItem::ItemHasContents);
setAcceptedMouseButtons(Qt::LeftButton);
setAcceptHoverEvents(true);
}

View File

@@ -31,8 +31,10 @@
namespace Timeline {
TimelineZoomControl::TimelineZoomControl(QObject *parent) : QObject(parent), m_traceStart(-1), m_traceEnd(-1),
m_windowStart(-1), m_windowEnd(-1), m_rangeStart(-1), m_rangeEnd(-1), m_windowLocked(false)
TimelineZoomControl::TimelineZoomControl(QObject *parent) : QObject(parent),
m_traceStart(-1), m_traceEnd(-1), m_windowStart(-1), m_windowEnd(-1),
m_rangeStart(-1), m_rangeEnd(-1), m_selectionStart(-1), m_selectionEnd(-1),
m_windowLocked(false)
{
connect(&m_timer, &QTimer::timeout, this, &TimelineZoomControl::moveWindow);
}
@@ -45,28 +47,6 @@ void TimelineZoomControl::clear()
setTrace(-1, -1);
}
void TimelineZoomControl::setTraceStart(qint64 start)
{
if (start != m_traceStart) {
if (m_traceEnd < start)
m_traceEnd = start;
m_traceStart = start;
emit traceChanged(start, m_traceEnd);
rebuildWindow();
}
}
void TimelineZoomControl::setTraceEnd(qint64 end)
{
if (end != m_traceEnd) {
if (m_traceStart > end)
m_traceStart = end;
m_traceEnd = end;
emit traceChanged(m_traceStart, end);
rebuildWindow();
}
}
void TimelineZoomControl::setTrace(qint64 start, qint64 end)
{
Q_ASSERT(start <= end);
@@ -90,6 +70,15 @@ void TimelineZoomControl::setRange(qint64 start, qint64 end)
}
}
void TimelineZoomControl::setSelection(qint64 start, qint64 end)
{
if (m_selectionStart != start || m_selectionEnd != end) {
m_selectionStart = start;
m_selectionEnd = end;
emit selectionChanged(start, end);
}
}
void TimelineZoomControl::setWindowLocked(bool windowLocked)
{
if (windowLocked != m_windowLocked) {

View File

@@ -39,8 +39,8 @@ namespace Timeline {
class TIMELINE_EXPORT TimelineZoomControl : public QObject {
Q_OBJECT
Q_PROPERTY(qint64 traceStart READ traceStart WRITE setTraceStart NOTIFY traceChanged)
Q_PROPERTY(qint64 traceEnd READ traceEnd WRITE setTraceEnd NOTIFY traceChanged)
Q_PROPERTY(qint64 traceStart READ traceStart NOTIFY traceChanged)
Q_PROPERTY(qint64 traceEnd READ traceEnd NOTIFY traceChanged)
Q_PROPERTY(qint64 traceDuration READ traceDuration NOTIFY traceChanged)
Q_PROPERTY(qint64 windowStart READ windowStart NOTIFY windowChanged)
@@ -51,6 +51,10 @@ class TIMELINE_EXPORT TimelineZoomControl : public QObject {
Q_PROPERTY(qint64 rangeEnd READ rangeEnd NOTIFY rangeChanged)
Q_PROPERTY(qint64 rangeDuration READ rangeDuration NOTIFY rangeChanged)
Q_PROPERTY(qint64 selectionStart READ selectionStart NOTIFY selectionChanged)
Q_PROPERTY(qint64 selectionEnd READ selectionEnd NOTIFY selectionChanged)
Q_PROPERTY(qint64 selectionDuration READ selectionDuration NOTIFY selectionChanged)
Q_PROPERTY(bool windowLocked READ windowLocked WRITE setWindowLocked NOTIFY windowLockedChanged)
public:
@@ -69,6 +73,10 @@ public:
qint64 rangeEnd() const { return m_rangeEnd; }
qint64 rangeDuration() const { return m_rangeEnd - m_rangeStart; }
qint64 selectionStart() const { return m_selectionStart; }
qint64 selectionEnd() const { return m_selectionEnd; }
qint64 selectionDuration() const { return m_selectionEnd - m_selectionStart; }
bool windowLocked() const { return m_windowLocked; }
virtual void clear();
@@ -76,13 +84,13 @@ signals:
void traceChanged(qint64 start, qint64 end);
void windowChanged(qint64 start, qint64 end);
void rangeChanged(qint64 start, qint64 end);
void selectionChanged(qint64 start, qint64 end);
void windowLockedChanged(bool windowLocked);
public slots:
void setTraceStart(qint64 start);
void setTraceEnd(qint64 end);
void setTrace(qint64 start, qint64 end);
void setRange(qint64 start, qint64 end);
void setSelection(qint64 start, qint64 end);
void setWindowLocked(bool windowLocked);
protected slots:
@@ -95,6 +103,8 @@ protected:
qint64 m_windowEnd;
qint64 m_rangeStart;
qint64 m_rangeEnd;
qint64 m_selectionStart;
qint64 m_selectionEnd;
QTimer m_timer;
bool m_windowLocked;

View File

@@ -466,7 +466,7 @@ public:
GlobalMacroExpander()
{
setDisplayName(MacroExpander::tr("Global variables"));
registerPrefix("Env", tr("Access environment variables."),
registerPrefix("Env", MacroExpander::tr("Access environment variables."),
[](const QString &value) { return QString::fromLocal8Bit(qgetenv(value.toLocal8Bit())); });
}
};

View File

@@ -35,6 +35,7 @@
#include "mimemagicrule_p.h"
#include <QtCore/QList>
#include <QtCore/QRegularExpression>
#include <QtCore/QDebug>
#include <qendian.h>
@@ -45,6 +46,7 @@ using namespace Utils::Internal;
static const char magicRuleTypes_string[] =
"invalid\0"
"string\0"
"regexp\0"
"host16\0"
"host32\0"
"big16\0"
@@ -55,7 +57,7 @@ static const char magicRuleTypes_string[] =
"\0";
static const int magicRuleTypes_indices[] = {
0, 8, 15, 22, 29, 35, 41, 50, 59, 65, 0
0, 8, 15, 22, 29, 36, 42, 48, 57, 66, 71, 0
};
MimeMagicRule::Type MimeMagicRule::type(const QByteArray &theTypeName)
@@ -86,6 +88,7 @@ public:
int endPos;
QByteArray mask;
QRegularExpression regexp;
QByteArray pattern;
quint32 number;
quint32 numberMask;
@@ -166,6 +169,16 @@ static bool matchString(const MimeMagicRulePrivate *d, const QByteArray &data)
return MimeMagicRule::matchSubstring(data.constData(), data.size(), d->startPos, rangeLength, d->pattern.size(), d->pattern.constData(), d->mask.constData());
}
static bool matchRegExp(const MimeMagicRulePrivate *d, const QByteArray &data)
{
const QString str = QString::fromUtf8(data);
int length = d->endPos;
if (length == d->startPos)
length = -1; // from startPos to end of string
const QString subStr = str.left(length);
return d->regexp.match(subStr, d->startPos).hasMatch();
}
template <typename T>
static bool matchNumber(const MimeMagicRulePrivate *d, const QByteArray &data)
{
@@ -185,7 +198,7 @@ static bool matchNumber(const MimeMagicRulePrivate *d, const QByteArray &data)
return false;
}
QByteArray MimeMagicRule::makePattern(const QByteArray &value)
static inline QByteArray makePattern(const QByteArray &value)
{
QByteArray pattern(value.size(), Qt::Uninitialized);
char *data = pattern.data();
@@ -295,6 +308,23 @@ MimeMagicRule::MimeMagicRule(MimeMagicRule::Type theType,
d->mask.squeeze();
d->matchFunction = matchString;
break;
case RegExp:
d->regexp.setPatternOptions(QRegularExpression::MultilineOption
| QRegularExpression::DotMatchesEverythingOption
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
| QRegularExpression::OptimizeOnFirstUsageOption
#endif
);
d->regexp.setPattern(QString::fromUtf8(d->value));
if (!d->regexp.isValid()) {
d->type = Invalid;
if (errorString)
*errorString = QString::fromLatin1("Invalid magic rule regexp value \"%1\"").arg(
QString::fromLatin1(d->value));
return;
}
d->matchFunction = matchRegExp;
break;
case Byte:
if (d->number <= quint8(-1)) {
if (d->numberMask == 0)

View File

@@ -63,7 +63,7 @@ class MimeMagicRulePrivate;
class QTCREATOR_UTILS_EXPORT MimeMagicRule
{
public:
enum Type { Invalid = 0, String, Host16, Host32, Big16, Big32, Little16, Little32, Byte };
enum Type { Invalid = 0, String, RegExp, Host16, Host32, Big16, Big32, Little16, Little32, Byte };
MimeMagicRule(Type type, const QByteArray &value, int startPos, int endPos,
const QByteArray &mask = QByteArray(), QString *errorString = 0);
@@ -90,8 +90,6 @@ public:
static QByteArray typeName(Type type);
static bool matchSubstring(const char *dataPtr, int dataSize, int rangeStart, int rangeLength, int valueLength, const char *valueData, const char *mask);
// Qt Creator additions
static QByteArray makePattern(const QByteArray &value); // necessary to be able to verify magic because otherwise MimMagicRule constructor asserts...
private:
const QScopedPointer<MimeMagicRulePrivate> d;

View File

@@ -285,7 +285,11 @@ void Theme::readSettings(QSettings &settings)
QMetaEnum e = m.enumerator(m.indexOfEnumerator("Color"));
for (int i = 0, total = e.keyCount(); i < total; ++i) {
const QString key = QLatin1String(e.key(i));
QTC_ASSERT(settings.contains(key), return);;
if (!settings.contains(key)) {
qWarning("Theme \"%s\" misses color setting for key \"%s\".",
qPrintable(d->fileName), qPrintable(key));
continue;
}
d->colors[i] = readNamedColor(settings.value(key).toString());
}
settings.endGroup();

View File

@@ -139,6 +139,20 @@ public:
CompileOutput_MessageOutput,
CompileOutput_ErrorMessageOutput,
/* Debugger Log Window */
Debugger_LogWindow_LogInput,
Debugger_LogWindow_LogStatus,
Debugger_LogWindow_LogWarning,
Debugger_LogWindow_LogError,
Debugger_LogWindow_LogTime,
/* Debugger Watch Item */
Debugger_WatchItem_ValueNormal,
Debugger_WatchItem_ValueInvalid,
Debugger_WatchItem_ValueChanged,
/* Welcome Plugin */
Welcome_TextColorNormal,

View File

@@ -102,7 +102,7 @@ public:
: IMode(parent)
{
setContext(Context(C_ANALYZEMODE, C_NAVIGATION_PANE));
setDisplayName(tr("Analyze"));
setDisplayName(AnalyzerManager::tr("Analyze"));
setIcon(QIcon(QLatin1String(":/images/analyzer_mode.png")));
setPriority(P_MODE_ANALYZE);
setId(MODE_ANALYZE);
@@ -125,6 +125,7 @@ public:
class AnalyzerManagerPrivate : public QObject
{
Q_DECLARE_TR_FUNCTIONS(Analyzer::AnalyzerManager)
public:
typedef QHash<QString, QVariant> FancyMainWindowSettings;

View File

@@ -105,6 +105,8 @@ QMap<QString, QKeySequence> CommandsFile::importCommands() const
case QXmlStreamReader::StartElement: {
const QStringRef name = r.name();
if (name == ctx.shortCutElement) {
if (!currentId.isEmpty()) // shortcut element without key element == empty shortcut
result.insert(currentId, QKeySequence());
currentId = r.attributes().value(ctx.idAttribute).toString();
} else if (name == ctx.keyElement) {
QTC_ASSERT(!currentId.isEmpty(), return result);

View File

@@ -63,9 +63,21 @@ MimeTypeMagicDialog::MimeTypeMagicDialog(QWidget *parent) :
connect(ui.informationLabel, &QLabel::linkActivated, this, [](const QString &link) {
QDesktopServices::openUrl(QUrl(link));
});
connect(ui.typeSelector, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
this, [this]() {
if (ui.useRecommendedGroupBox->isChecked())
setToRecommendedValues();
});
ui.valueLineEdit->setFocus();
}
void MimeTypeMagicDialog::setToRecommendedValues()
{
ui.startRangeSpinBox->setValue(0);
ui.endRangeSpinBox->setValue(ui.typeSelector->currentIndex() == 1/*regexp*/ ? 200 : 0);
ui.prioritySpinBox->setValue(50);
}
void MimeTypeMagicDialog::applyRecommended(bool checked)
{
if (checked) {
@@ -73,9 +85,7 @@ void MimeTypeMagicDialog::applyRecommended(bool checked)
m_customRangeStart = ui.startRangeSpinBox->value();
m_customRangeEnd = ui.endRangeSpinBox->value();
m_customPriority = ui.prioritySpinBox->value();
ui.startRangeSpinBox->setValue(0);
ui.endRangeSpinBox->setValue(0);
ui.prioritySpinBox->setValue(50);
setToRecommendedValues();
} else {
// restore previous custom values
ui.startRangeSpinBox->setValue(m_customRangeStart);

View File

@@ -64,6 +64,7 @@ public:
class MimeTypeMagicDialog : public QDialog
{
Q_DECLARE_TR_FUNCTIONS(Core::Internal::MimeTypeMagicDialog)
public:
explicit MimeTypeMagicDialog(QWidget *parent = 0);
@@ -71,6 +72,7 @@ public:
MagicData magicData() const;
private:
void setToRecommendedValues();
void applyRecommended(bool checked);
void validateAccept();
Utils::Internal::MimeMagicRule createRule(QString *errorMessage = 0) const;

View File

@@ -52,6 +52,11 @@
<string>String</string>
</property>
</item>
<item>
<property name="text">
<string>RegExp</string>
</property>
</item>
<item>
<property name="text">
<string>Host16</string>

View File

@@ -91,7 +91,7 @@ public:
{
m_iconButton = new IconButton;
m_iconButton->setPixmap(QPixmap(QLatin1String(":/core/images/replace.png")));
m_iconButton->setToolTip(tr("Insert variable"));
m_iconButton->setToolTip(VariableChooser::tr("Insert variable"));
m_iconButton->hide();
connect(m_iconButton.data(), static_cast<void(QAbstractButton::*)(bool)>(&QAbstractButton::clicked),
this, &VariableChooserPrivate::updatePositionAndShow);
@@ -197,17 +197,17 @@ void VariableTreeView::contextMenuEvent(QContextMenuEvent *ev)
QAction *insertExpandedAction = 0;
if (unexpandedText.isEmpty()) {
insertUnexpandedAction = menu.addAction(tr("Insert unexpanded value"));
insertUnexpandedAction = menu.addAction(VariableChooser::tr("Insert unexpanded value"));
insertUnexpandedAction->setEnabled(false);
} else {
insertUnexpandedAction = menu.addAction(tr("Insert \"%1\"").arg(unexpandedText));
insertUnexpandedAction = menu.addAction(VariableChooser::tr("Insert \"%1\"").arg(unexpandedText));
}
if (expandedText.isEmpty()) {
insertExpandedAction = menu.addAction(tr("Insert expanded value"));
insertExpandedAction = menu.addAction(VariableChooser::tr("Insert expanded value"));
insertExpandedAction->setEnabled(false);
} else {
insertExpandedAction = menu.addAction(tr("Insert \"%1\"").arg(expandedText));
insertExpandedAction = menu.addAction(VariableChooser::tr("Insert \"%1\"").arg(expandedText));
}

View File

@@ -612,6 +612,38 @@ void CppEditorPlugin::test_quickfix_data()
"}\n"
);
// Checks if getter uses 'get' prefix if member function with such a prefix is found
QTest::newRow("GenerateGetterSetter_getterWithGetPrefix")
<< CppQuickFixFactoryPtr(new GenerateGetterSetter) << _(
"\n"
"class Something\n"
"{\n"
" int getFoo();\n"
" int @m_it;\n"
"};\n"
) << _(
"\n"
"class Something\n"
"{\n"
" int getFoo();\n"
" int m_it;\n"
"\n"
"public:\n"
" int getIt() const;\n"
" void setIt(int it);\n"
"};\n"
"\n"
"int Something::getIt() const\n"
"{\n"
" return m_it;\n"
"}\n"
"\n"
"void Something::setIt(int it)\n"
"{\n"
" m_it = it;\n"
"}\n"
);
// Check: Setter: Use pass by reference for parameters which
// are not integer, float or pointers.
QTest::newRow("GenerateGetterSetter_customType")
@@ -914,6 +946,36 @@ void CppEditorPlugin::test_quickfix_data()
"}\n"
);
// Checks if the declaration inside Q_PROPERTY macro is ignored and a getter created
QTest::newRow("GenerateGetterSetter_ignoreQPropertiesMacro")
<< CppQuickFixFactoryPtr(new GenerateGetterSetter) << _(
"class Something\n"
"{\n"
" Q_PROPERTY(int foo)\n"
" int @m_foo;\n"
"};\n"
) << _(
"class Something\n"
"{\n"
" Q_PROPERTY(int foo)\n"
" int m_foo;\n"
"\n"
"public:\n"
" int foo() const;\n"
" void setFoo(int foo);\n"
"};\n"
"\n"
"int Something::foo() const\n"
"{\n"
" return m_foo;\n"
"}\n"
"\n"
"void Something::setFoo(int foo)\n"
"{\n"
" m_foo = foo;\n"
"}\n"
);
QTest::newRow("MoveDeclarationOutOfIf_ifOnly")
<< CppQuickFixFactoryPtr(new MoveDeclarationOutOfIf) << _(
"void f()\n"

View File

@@ -2730,6 +2730,25 @@ void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOpe
namespace {
bool hasClassMemberWithGetPrefix(const Class *klass)
{
if (!klass)
return false;
for (unsigned i = 0; i < klass->memberCount(); ++i) {
const Symbol *symbol = klass->memberAt(i);
if (symbol->isFunction() || symbol->isDeclaration()) {
if (const Name *symbolName = symbol->name()) {
if (const Identifier *id = symbolName->identifier()) {
if (!strncmp(id->chars(), "get", 3))
return true;
}
}
}
}
return false;
}
class GenerateGetterSetterOperation : public CppQuickFixOperation
{
public:
@@ -2811,23 +2830,27 @@ public:
if (m_baseName.isEmpty())
m_baseName = QLatin1String("value");
m_getterName = m_baseName != m_variableString
m_getterName = !(m_baseName == m_variableString
|| hasClassMemberWithGetPrefix(m_classSpecifier->symbol))
? m_baseName
: QString::fromLatin1("get%1%2")
.arg(m_baseName.left(1).toUpper()).arg(m_baseName.mid(1));
m_setterName = QString::fromLatin1("set%1%2")
.arg(m_baseName.left(1).toUpper()).arg(m_baseName.mid(1));
// Check if the class has already both a getter and setter.
// Check if the class has already a getter and/or a setter.
// This is only a simple check which should suffice not triggering the
// same quick fix again. Limitations:
// 1) It only checks in the current class, but not in base classes.
// 2) It compares only names instead of types/signatures.
// 3) Symbols in Qt property declarations are ignored.
bool hasGetter = false;
bool hasSetter = false;
if (Class *klass = m_classSpecifier->symbol) {
for (unsigned i = 0; i < klass->memberCount(); ++i) {
Symbol *symbol = klass->memberAt(i);
if (symbol->isQtPropertyDeclaration())
continue;
if (const Name *symbolName = symbol->name()) {
if (const Identifier *id = symbolName->identifier()) {
const QString memberName = QString::fromUtf8(id->chars(), id->size());

View File

@@ -319,7 +319,8 @@ void CppToolsPlugin::test_completion()
QEXPECT_FAIL("enum_in_function_in_struct_in_function_anon", "QTCREATORBUG-13757", Abort);
QEXPECT_FAIL("enum_in_class_accessed_in_member_func_cxx11", "QTCREATORBUG-13757", Abort);
QEXPECT_FAIL("enum_in_class_accessed_in_member_func_inline_cxx11", "QTCREATORBUG-13757", Abort);
QEXPECT_FAIL("pointer_partial_specialization", "QTCREATORBUG-14036", Abort);
QEXPECT_FAIL("pointer_indirect_specialization", "QTCREATORBUG-14141", Abort);
QEXPECT_FAIL("pointer_indirect_specialization_typedef", "QTCREATORBUG-14141", Abort);
QCOMPARE(actualCompletions, expectedCompletions);
}
@@ -2656,7 +2657,7 @@ void CppToolsPlugin::test_completion_data()
<< QLatin1String("t")
<< QLatin1String("iterator"));
QTest::newRow("pointer_partial_specialization") << _(
QTest::newRow("pointer_indirect_specialization") << _(
"template<typename T>\n"
"struct Traits { typedef typename T::pointer pointer; };\n"
"\n"
@@ -2684,6 +2685,35 @@ void CppToolsPlugin::test_completion_data()
) << _("t.p->") << (QStringList()
<< QLatin1String("Foo")
<< QLatin1String("bar"));
QTest::newRow("pointer_indirect_specialization_typedef") << _(
"template<typename T>\n"
"struct Traits { typedef typename T::pointer pointer; };\n"
"\n"
"template<typename _Tp>\n"
"struct Traits<_Tp*> { typedef _Tp *pointer; };\n"
"\n"
"struct Foo { int bar; };\n"
"\n"
"class Temp\n"
"{\n"
"protected:\n"
" typedef Foo *FooPtr;\n"
" typedef Traits<FooPtr> TraitsT;\n"
"\n"
"public:\n"
" typedef typename TraitsT::pointer pointer;\n"
" pointer p;\n"
"};\n"
"\n"
"void func()\n"
"{\n"
" Temp t;\n"
" @\n"
"}\n"
) << _("t.p->") << (QStringList()
<< QLatin1String("Foo")
<< QLatin1String("bar"));
}
void CppToolsPlugin::test_completion_member_access_operator()

View File

@@ -37,6 +37,7 @@
#include <QList>
#include <QObject>
#include <QString>
#include <QCoreApplication>
namespace Utils { class FileName; }
@@ -49,6 +50,7 @@ class DebuggerItem;
class DEBUGGER_EXPORT DebuggerItemManager : public QObject
{
Q_DECLARE_TR_FUNCTIONS(Debugger::DebuggerItemManager)
public:
DebuggerItemManager();
~DebuggerItemManager();

View File

@@ -353,6 +353,7 @@ void DebuggerItemConfigWidget::binaryPathHasChanged()
class DebuggerConfigWidget : public QWidget
{
Q_DECLARE_TR_FUNCTIONS(Debugger::DebuggerOptionsPage)
public:
DebuggerConfigWidget()
{

View File

@@ -109,8 +109,8 @@ const char modelItemElementC[] = "item";
static void purgeClosedToolTips();
class DebuggerToolTipHolder;
QList<QPointer<DebuggerToolTipHolder>> m_tooltips;
bool m_debugModeActive;
static QVector<DebuggerToolTipHolder *> m_tooltips;
static bool m_debugModeActive;
// Forward a stream reader across end elements looking for the
// next start element of a desired type.
@@ -238,9 +238,9 @@ public:
ToolTipModel()
{
QStringList headers;
headers.append(tr("Name"));
headers.append(tr("Value"));
headers.append(tr("Type"));
headers.append(DebuggerToolTipManager::tr("Name"));
headers.append(DebuggerToolTipManager::tr("Value"));
headers.append(DebuggerToolTipManager::tr("Type"));
setHeader(headers);
m_enabled = true;
auto item = new ToolTipWatchItem;
@@ -623,15 +623,15 @@ enum DebuggerTooltipState
New, // All new, widget not shown, not async (yet)
PendingUnshown, // Widget not (yet) shown, async.
PendingShown, // Widget shown, async
Acquired, // Widget shown, engine attached
Acquired, // Widget shown sync, engine attached
Released // Widget shown, engine released
};
class DebuggerToolTipHolder : public QObject
class DebuggerToolTipHolder
{
public:
DebuggerToolTipHolder(const DebuggerToolTipContext &context);
~DebuggerToolTipHolder();
~DebuggerToolTipHolder() { delete widget; }
void acquireEngine(DebuggerEngine *engine);
void releaseEngine();
@@ -692,10 +692,10 @@ bool DebuggerToolTipContext::matchesFrame(const StackFrame &frame) const
bool DebuggerToolTipContext::isSame(const DebuggerToolTipContext &other) const
{
return filesMatch(fileName, other.fileName)
return iname == other.iname
&& scopeFromLine == other.scopeFromLine
&& scopeToLine == other.scopeToLine
&& iname == other.iname;
&& filesMatch(fileName, other.fileName);
}
void DebuggerToolTipContext::appendFormatRequest(DebuggerCommand *cmd) const
@@ -773,14 +773,9 @@ DebuggerToolTipHolder::DebuggerToolTipHolder(const DebuggerToolTipContext &conte
else
widget->pin();
});
DEBUG("CREATE DEBUGGERTOOLTIPHOLDER" << context.iname);
}
DebuggerToolTipHolder::~DebuggerToolTipHolder()
{
DEBUG("DESTROY DEBUGGERTOOLTIPHOLDER" << context.iname << " STATE: " << state);
delete widget; widget.clear();
}
// This is called back from the engines after they populated the
// WatchModel. If the populating result from evaluation of this
@@ -812,12 +807,11 @@ void DebuggerToolTipHolder::updateTooltip(DebuggerEngine *engine)
<< "SAME FRAME: " << sameFrame);
if (state == PendingUnshown) {
ToolTip::show(context.mousePosition, widget, Internal::mainWindow());
setState(PendingShown);
ToolTip::show(context.mousePosition, widget, Internal::mainWindow());
}
if (item && sameFrame) {
setState(Acquired);
DEBUG("ACQUIRE ENGINE: STATE " << state);
widget->setContents(new ToolTipWatchItem(item));
} else {
@@ -829,16 +823,9 @@ void DebuggerToolTipHolder::updateTooltip(DebuggerEngine *engine)
void DebuggerToolTipHolder::setState(DebuggerTooltipState newState)
{
bool ok = (state == New && newState == PendingUnshown)
|| (state == New && newState == Acquired)
|| (state == PendingUnshown && newState == PendingShown)
|| (state == PendingShown && newState == Acquired)
|| (state == Acquired && newState == Released)
|| (state == Acquired && newState == Acquired)
|| (state == Released && newState == Acquired);
// FIXME: These happen when a tooltip is re-used in findOrCreate.
ok = ok
|| (state == Acquired && newState == PendingShown)
|| (state == Released && newState == PendingShown);
|| newState == Released;
DEBUG("TRANSITION STATE FROM " << state << " TO " << newState);
QTC_ASSERT(ok, qDebug() << "Unexpected tooltip state transition from "
@@ -861,25 +848,23 @@ void DebuggerToolTipHolder::releaseEngine()
if (state == Released)
return;
QTC_ASSERT(widget, return);
if (state == PendingShown) {
setState(Released);
// This happens after hovering over something that looks roughly like
// a valid expression but can't be resolved by the debugger backend.
// (Out of scope items, keywords, ...)
ToolTip::show(context.mousePosition,
DebuggerToolTipManager::tr("No valid expression"),
Internal::mainWindow());
QTC_ASSERT(widget, return);
widget->deleteLater();
return;
}
setState(Released);
QTC_ASSERT(widget, return);
widget->model.m_enabled = false;
widget->model.layoutChanged();
widget->titleLabel->setText(DebuggerToolTipManager::tr("%1 (Previous)").arg(context.expression));
// widget->treeView->setEnabled(false);
}
void DebuggerToolTipHolder::positionShow(const TextEditorWidget *editorWidget)
@@ -913,25 +898,6 @@ void DebuggerToolTipHolder::positionShow(const TextEditorWidget *editorWidget)
}
}
static DebuggerToolTipHolder *findOrCreateTooltip(const DebuggerToolTipContext &context, bool allowReuse = true)
{
purgeClosedToolTips();
for (int i = 0, n = m_tooltips.size(); i != n; ++i) {
DebuggerToolTipHolder *tooltip = m_tooltips.at(i);
if (tooltip->context.isSame(context)) {
if (allowReuse)
return tooltip;
tooltip->destroy();
}
}
purgeClosedToolTips();
auto newTooltip = new DebuggerToolTipHolder(context);
m_tooltips.push_back(newTooltip);
return newTooltip;
}
//// Parse a 'yyyyMMdd' date
static QDate dateFromString(const QString &date)
{
@@ -1087,6 +1053,7 @@ void DebuggerToolTipManager::sessionAboutToChange()
void DebuggerToolTipManager::loadSessionData()
{
closeAllToolTips();
const QString data = sessionValue(sessionSettingsKeyC).toString();
QXmlStreamReader r(data);
r.readNextStartElement();
@@ -1125,7 +1092,8 @@ void DebuggerToolTipManager::loadSessionData()
}
if (readTree) {
DebuggerToolTipHolder *tw = findOrCreateTooltip(context);
auto tw = new DebuggerToolTipHolder(context);
m_tooltips.push_back(tw);
tw->widget->model.restoreTreeModel(r);
tw->widget->pin();
tw->widget->titleLabel->setText(DebuggerToolTipManager::tr("%1 (Restored)").arg(context.expression));
@@ -1205,6 +1173,8 @@ static void slotTooltipOverrideRequested
return;
}
purgeClosedToolTips();
// Prefer a filter on an existing local variable if it can be found.
const WatchData *localVariable = engine->watchHandler()->findCppLocalVariable(context.expression);
if (localVariable) {
@@ -1212,38 +1182,47 @@ static void slotTooltipOverrideRequested
if (context.expression.isEmpty())
context.expression = localVariable->name;
context.iname = localVariable->iname;
} else {
context.iname = "tooltip." + context.expression.toLatin1().toHex();
}
bool allowReuse = false;
DebuggerToolTipHolder *tooltip = findOrCreateTooltip(context, allowReuse);
auto reusable = [context] (DebuggerToolTipHolder *tooltip) {
return tooltip->context.isSame(context);
};
DebuggerToolTipHolder *tooltip = Utils::findOrDefault(m_tooltips, reusable);
if (tooltip) {
DEBUG("REUSING LOCALS TOOLTIP");
tooltip->context.mousePosition = point;
if (tooltip->state == PendingUnshown || tooltip->state == PendingShown) {
DEBUG("FOUND PENDING TOOLTIP, WAITING...");
*handled = true;
return;
}
if (localVariable) {
DEBUG("SYNC IN STATE" << tooltip->state);
if (tooltip->state == New) {
tooltip->setState(PendingUnshown);
tooltip->setState(PendingShown);
ToolTip::show(point, tooltip->widget, Internal::mainWindow());
} else {
ToolTip::move(point, Internal::mainWindow());
}
*handled = true;
tooltip->updateTooltip(engine);
} else {
DEBUG("ASYNC TIP IN STATE" << tooltip->state);
if (tooltip->state == New)
DEBUG("CREATING LOCALS, WAITING...");
tooltip = new DebuggerToolTipHolder(context);
tooltip->setState(Acquired);
m_tooltips.push_back(tooltip);
ToolTip::show(point, tooltip->widget, Internal::mainWindow());
}
DEBUG("SYNC IN STATE" << tooltip->state);
tooltip->updateTooltip(engine);
*handled = true;
} else {
context.iname = "tooltip." + context.expression.toLatin1().toHex();
auto reusable = [context] (DebuggerToolTipHolder *tooltip) {
return tooltip->context.isSame(context);
};
DebuggerToolTipHolder *tooltip = Utils::findOrDefault(m_tooltips, reusable);
if (tooltip) {
//tooltip->destroy();
tooltip->context.mousePosition = point;
ToolTip::move(point, Internal::mainWindow());
DEBUG("UPDATING DELAYED.");
*handled = true;
} else {
DEBUG("CREATING DELAYED.");
tooltip = new DebuggerToolTipHolder(context);
tooltip->context.mousePosition = point;
m_tooltips.push_back(tooltip);
tooltip->setState(PendingUnshown);
else if (tooltip->state == Acquired || tooltip->state == Released)
tooltip->setState(PendingShown);
else
QTC_CHECK(false);
*handled = engine->setToolTipExpression(context);
if (!*handled) {
ToolTip::show(point, DebuggerToolTipManager::tr("Expression too complex"),
@@ -1252,7 +1231,7 @@ static void slotTooltipOverrideRequested
}
}
}
}
static void slotEditorOpened(IEditor *e)
{
@@ -1325,11 +1304,12 @@ bool DebuggerToolTipManager::eventFilter(QObject *o, QEvent *e)
const QMoveEvent *me = static_cast<const QMoveEvent *>(e);
const QPoint dist = me->pos() - me->oldPos();
purgeClosedToolTips();
foreach (DebuggerToolTipHolder *tooltip, m_tooltips)
foreach (DebuggerToolTipHolder *tooltip, m_tooltips) {
if (tooltip->widget && tooltip->widget->isVisible())
tooltip->widget->move(tooltip->widget->pos() + dist);
}
break;
}
case QEvent::WindowStateChange: { // Hide/Show along with parent (toplevel)
const QWindowStateChangeEvent *se = static_cast<const QWindowStateChangeEvent *>(e);
const bool wasMinimized = se->oldState() & Qt::WindowMinimized;
@@ -1339,8 +1319,8 @@ bool DebuggerToolTipManager::eventFilter(QObject *o, QEvent *e)
foreach (DebuggerToolTipHolder *tooltip, m_tooltips)
tooltip->widget->setVisible(!isMinimized);
}
}
break;
}
default:
break;
}
@@ -1351,13 +1331,12 @@ static void purgeClosedToolTips()
{
for (int i = m_tooltips.size(); --i >= 0; ) {
DebuggerToolTipHolder *tooltip = m_tooltips.at(i);
if (!tooltip || !tooltip->widget) {
if (!tooltip->widget) {
DEBUG("PURGE TOOLTIP, LEFT: " << m_tooltips.size());
m_tooltips.removeAt(i);
}
}
}
} // namespace Internal
} // namespace Debugger

View File

@@ -456,6 +456,8 @@ void LldbEngine::handleResponse(const QByteArray &response)
refreshRegisters(item);
else if (name == "threads")
refreshThreads(item);
else if (name == "current-thread")
refreshCurrentThread(item);
else if (name == "typeinfo")
refreshTypeInfo(item);
else if (name == "state")
@@ -567,10 +569,15 @@ void LldbEngine::activateFrame(int frameIndex)
void LldbEngine::selectThread(ThreadId threadId)
{
DebuggerCommand cmd("selectThread");
cmd.arg("id", threadId.raw());
DebuggerCommand cmd1("selectThread");
cmd1.arg("id", threadId.raw());
runCommand(cmd1);
DebuggerCommand cmd("reportStack");
cmd.arg("nativeMixed", isNativeMixedActive());
cmd.arg("stacklimit", action(MaximalStackDepth)->value().toInt());
cmd.arg("continuation", "updateLocals");
runCommand(cmd);
updateAll();
}
bool LldbEngine::stateAcceptsBreakpointChanges() const
@@ -823,6 +830,12 @@ bool LldbEngine::setToolTipExpression(const DebuggerToolTipContext &context)
void LldbEngine::updateAll()
{
DebuggerCommand cmd1("reportThreads");
runCommand(cmd1);
DebuggerCommand cmd2("reportCurrentThread");
runCommand(cmd2);
DebuggerCommand cmd("reportStack");
cmd.arg("nativeMixed", isNativeMixedActive());
cmd.arg("stacklimit", action(MaximalStackDepth)->value().toInt());
@@ -1061,11 +1074,14 @@ void LldbEngine::refreshThreads(const GdbMi &threads)
{
ThreadsHandler *handler = threadsHandler();
handler->updateThreads(threads);
if (!handler->currentThread().isValid()) {
ThreadId other = handler->threadAt(0);
if (other.isValid())
selectThread(other);
updateViews(); // Adjust Threads combobox.
}
void LldbEngine::refreshCurrentThread(const GdbMi &data)
{
ThreadsHandler *handler = threadsHandler();
ThreadId id(data["id"].toInt());
handler->setCurrentThread(id);
updateViews(); // Adjust Threads combobox.
}
@@ -1102,9 +1118,10 @@ void LldbEngine::refreshState(const GdbMi &reportedState)
} else {
updateAll();
}
} else if (newState == "inferiorstopok")
} else if (newState == "inferiorstopok") {
notifyInferiorStopOk();
else if (newState == "inferiorstopfailed")
updateAll();
} else if (newState == "inferiorstopfailed")
notifyInferiorStopFailed();
else if (newState == "inferiorill")
notifyInferiorIll();

View File

@@ -148,6 +148,7 @@ private:
void refreshAll(const GdbMi &all);
void refreshThreads(const GdbMi &threads);
void refreshCurrentThread(const GdbMi &data);
void refreshStack(const GdbMi &stack);
void refreshRegisters(const GdbMi &registers);
void refreshLocals(const GdbMi &vars);

View File

@@ -54,6 +54,7 @@
#include <utils/savedaction.h>
#include <utils/fancylineedit.h>
#include <utils/fileutils.h>
#include <utils/theme/theme.h>
namespace Debugger {
namespace Internal {
@@ -74,26 +75,28 @@ public:
private:
void highlightBlock(const QString &text)
{
using Utils::Theme;
QTextCharFormat format;
Theme *theme = Utils::creatorTheme();
switch (LogWindow::channelForChar(text.isEmpty() ? QChar() : text.at(0))) {
case LogInput:
format.setForeground(Qt::blue);
format.setForeground(theme->color(Theme::Debugger_LogWindow_LogInput));
setFormat(1, text.size(), format);
break;
case LogStatus:
format.setForeground(Qt::darkGreen);
format.setForeground(theme->color(Theme::Debugger_LogWindow_LogStatus));
setFormat(1, text.size(), format);
break;
case LogWarning:
format.setForeground(Qt::darkYellow);
format.setForeground(theme->color(Theme::Debugger_LogWindow_LogWarning));
setFormat(1, text.size(), format);
break;
case LogError:
format.setForeground(Qt::red);
format.setForeground(theme->color(Theme::Debugger_LogWindow_LogError));
setFormat(1, text.size(), format);
break;
case LogTime:
format.setForeground(Qt::darkRed);
format.setForeground(theme->color(Theme::Debugger_LogWindow_LogTime));
setFormat(1, text.size(), format);
break;
default:
@@ -125,9 +128,11 @@ public:
private:
void highlightBlock(const QString &text)
{
using Utils::Theme;
Theme *theme = Utils::creatorTheme();
if (text.size() > 3 && text.at(2) == QLatin1Char(':')) {
QTextCharFormat format;
format.setForeground(Qt::darkRed);
format.setForeground(theme->color(Theme::Debugger_LogWindow_LogTime));
setFormat(1, text.size(), format);
}
}

View File

@@ -340,6 +340,7 @@ QByteArray RegisterValue::toByteArray(int base, RegisterKind kind, int size) con
RegisterValue RegisterValue::subValue(int size, int index) const
{
RegisterValue value;
value.known = known;
switch (size) {
case 1:
value.v.u8[0] = v.u8[index];

View File

@@ -32,12 +32,14 @@
#define DEBUGGER_STACKWINDOW_H
#include <utils/basetreeview.h>
#include <QCoreApplication>
namespace Debugger {
namespace Internal {
class StackTreeView : public Utils::BaseTreeView
{
Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::StackTreeView)
public:
StackTreeView();

View File

@@ -121,7 +121,7 @@ bool isIntOrFloatType(const QByteArray &type)
WatchData::WatchData() :
id(0),
state(InitialState),
editformat(0),
editformat(StopDisplay),
address(0),
origaddr(0),
size(0),
@@ -131,31 +131,10 @@ WatchData::WatchData() :
wantsChildren(false),
valueEnabled(true),
valueEditable(true),
error(false),
sortId(0),
source(0)
sortId(0)
{
}
bool WatchData::isEqual(const WatchData &other) const
{
return iname == other.iname
&& exp == other.exp
&& name == other.name
&& value == other.value
&& editvalue == other.editvalue
&& type == other.type
&& displayedType == other.displayedType
&& variable == other.variable
&& address == other.address
&& size == other.size
&& elided == other.elided
&& wantsChildren == other.wantsChildren
&& valueEnabled == other.valueEnabled
&& valueEditable == other.valueEditable
&& error == other.error;
}
bool WatchData::isAncestorOf(const QByteArray &childIName) const
{
if (iname.size() >= childIName.size())
@@ -180,7 +159,6 @@ void WatchData::setError(const QString &msg)
wantsChildren = false;
valueEnabled = false;
valueEditable = false;
error = true;
}
void WatchData::setValue(const QString &value0)
@@ -299,8 +277,6 @@ QString WatchData::toString() const
str << "sortId=\"" << sortId << doubleQuoteComma;
if (!name.isEmpty() && name != QLatin1String(iname))
str << "name=\"" << name << doubleQuoteComma;
if (error)
str << "error,";
if (address) {
str.setIntegerBase(16);
str << "addr=\"0x" << address << doubleQuoteComma;
@@ -314,9 +290,6 @@ QString WatchData::toString() const
if (!exp.isEmpty())
str << "exp=\"" << exp << doubleQuoteComma;
if (!variable.isEmpty())
str << "variable=\"" << variable << doubleQuoteComma;
if (isValueNeeded())
str << "value=<needed>,";
if (!value.isEmpty())
@@ -327,10 +300,6 @@ QString WatchData::toString() const
if (!editvalue.isEmpty())
str << "editvalue=\"<...>\",";
// str << "editvalue=\"" << editvalue << doubleQuoteComma;
if (!dumperFlags.isEmpty())
str << "dumperFlags=\"" << dumperFlags << doubleQuoteComma;
str << "type=\"" << type << doubleQuoteComma;
@@ -466,7 +435,7 @@ static void setWatchDataAddress(WatchData &data, quint64 address)
{
data.address = address;
if (data.exp.isEmpty() && !data.dumperFlags.startsWith('$')) {
if (data.exp.isEmpty()) {
if (data.iname.startsWith("local.") && data.iname.count('.') == 1)
// Solve one common case of adding 'class' in
// *(class X*)0xdeadbeef for gdb.
@@ -476,19 +445,6 @@ static void setWatchDataAddress(WatchData &data, quint64 address)
}
}
void WatchData::updateAddress(const GdbMi &mi)
{
if (!mi.isValid())
return;
const QByteArray addressBA = mi.data();
if (!addressBA.startsWith("0x")) { // Item model dumpers pull tricks.
dumperFlags = addressBA;
return;
}
const quint64 address = mi.toAddress();
setWatchDataAddress(*this, address);
}
static void setWatchDataSize(WatchData &data, const GdbMi &mi)
{
if (mi.isValid()) {
@@ -590,7 +546,6 @@ void parseChildrenData(const WatchData &data0, const GdbMi &item,
std::function<void(const WatchData &, const GdbMi &)> childHandler,
std::function<void(const WatchData &childTemplate, const QByteArray &encodedData, int encoding)> arrayDecoder)
{
//qDebug() << "HANDLE CHILDREN: " << data0.toString() << item.toString();
WatchData data = data0;
data.setChildrenUnneeded();
@@ -602,7 +557,7 @@ void parseChildrenData(const WatchData &data0, const GdbMi &item,
data.editvalue = mi.data();
mi = item["editformat"];
data.editformat = mi.toInt();
data.editformat = DebuggerDisplay(mi.toInt());
mi = item["valueelided"];
if (mi.isValid())
@@ -620,7 +575,10 @@ void parseChildrenData(const WatchData &data0, const GdbMi &item,
if (mi.isValid())
data.origaddr = mi.toAddress();
data.updateAddress(item["addr"]);
mi = item["addr"];
if (mi.isValid())
setWatchDataAddress(data, mi.toAddress());
data.updateValue(item);
setWatchDataSize(data, item["size"]);
@@ -632,7 +590,6 @@ void parseChildrenData(const WatchData &data0, const GdbMi &item,
setWatchDataValueEnabled(data, item["valueenabled"]);
setWatchDataValueEditable(data, item["valueeditable"]);
data.updateChildCount(item["numchild"]);
//qDebug() << "\nAPPEND TO LIST: " << data.toString() << "\n";
itemHandler(data);
bool ok = false;
@@ -643,7 +600,6 @@ void parseChildrenData(const WatchData &data0, const GdbMi &item,
WatchData childtemplate;
childtemplate.updateType(item["childtype"]);
childtemplate.updateChildCount(item["childnumchild"]);
//qDebug() << "CHILD TEMPLATE:" << childtemplate.toString();
mi = item["arraydata"];
if (mi.isValid()) {

View File

@@ -31,6 +31,8 @@
#ifndef DEBUGGER_WATCHDATA_H
#define DEBUGGER_WATCHDATA_H
#include "debuggerprotocol.h"
#include <QCoreApplication>
#include <QMetaType>
@@ -80,7 +82,6 @@ public:
bool isValid() const { return !iname.isEmpty(); }
bool isVTablePointer() const;
bool isEqual(const WatchData &other) const;
bool isAncestorOf(const QByteArray &childIName) const;
void setError(const QString &);
@@ -100,7 +101,6 @@ public:
// Protocol interaction.
void updateValue(const GdbMi &item);
void updateChildCount(const GdbMi &mi);
void updateAddress(const GdbMi &addressMi);
void updateType(const GdbMi &item);
void updateDisplayedType(const GdbMi &item);
@@ -112,7 +112,7 @@ public:
QString name; // Displayed name
QString value; // Displayed value
QByteArray editvalue; // Displayed value
qint32 editformat; // Format of displayed value
DebuggerDisplay editformat; // Format of displayed value
QByteArray type; // Type for further processing
QString displayedType; // Displayed type (optional)
quint64 address; // Displayed address of the actual object
@@ -124,16 +124,9 @@ public:
bool wantsChildren;
bool valueEnabled; // Value will be enabled or not
bool valueEditable; // Value will be editable
bool error;
qint32 sortId;
QByteArray dumperFlags;
Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::WatchHandler)
public:
// FIXME: this is engine specific data that should be mapped internally
QByteArray variable; // Name of internal Gdb variable if created
qint32 source; // Originated from dumper or symbol evaluation? (CDB only)
};
void decodeArrayData(std::function<void(const WatchData &)> itemHandler,

View File

@@ -49,6 +49,7 @@
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
#include <utils/checkablemessagebox.h>
#include <utils/theme/theme.h>
#include <QDebug>
#include <QFile>
@@ -199,6 +200,7 @@ public:
class WatchModel : public WatchModelBase
{
Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::WatchModel)
public:
WatchModel(WatchHandler *handler, DebuggerEngine *engine);
@@ -711,19 +713,19 @@ QString WatchItem::displayType() const
QColor WatchItem::valueColor() const
{
static const QColor red(200, 0, 0);
static const QColor gray(140, 140, 140);
using Utils::Theme;
Theme *theme = Utils::creatorTheme();
if (watchModel()) {
if (!valueEnabled)
return gray;
return theme->color(Theme::Debugger_WatchItem_ValueInvalid);
if (!watchModel()->m_contentsValid && !isInspect())
return gray;
return theme->color(Theme::Debugger_WatchItem_ValueInvalid);
if (value.isEmpty()) // This might still show 0x...
return gray;
return theme->color(Theme::Debugger_WatchItem_ValueInvalid);
if (value != watchModel()->m_valueCache.value(iname))
return red;
return theme->color(Theme::Debugger_WatchItem_ValueChanged);
}
return QColor();
return theme->color(Theme::Debugger_WatchItem_ValueNormal);
}
QVariant WatchItem::data(int column, int role) const
@@ -1175,6 +1177,8 @@ void WatchModel::insertItem(WatchItem *item)
QTC_ASSERT(parent, return);
const int row = findInsertPosition(parent->children(), item);
parent->insertChild(row, item);
item->walkTree([this](TreeItem *sub) { showEditValue(*static_cast<WatchItem *>(sub)); });
}
void WatchModel::reexpandItems()

View File

@@ -15,6 +15,10 @@ QtcPlugin {
Depends { name: "ProjectExplorer" }
Depends { name: "QtSupport" }
pluginTestDepends: [
"CppEditor",
]
cpp.defines: base.concat(["CPP_ENABLED"])
cpp.includePaths: base.concat([
sharedSources.prefix

View File

@@ -10,3 +10,5 @@ QTC_PLUGIN_DEPENDS += \
qtsupport \
texteditor \
coreplugin
QTC_TEST_DEPENDS += \
cppeditor

View File

@@ -10,6 +10,11 @@ QtcPlugin {
Depends { name: "Core" }
Depends { name: "TextEditor" }
pluginTestDepends: [
"CppEditor",
"CppTools",
]
files: [
"fakevim.qrc",
"fakevimactions.cpp",

View File

@@ -6,3 +6,6 @@ QTC_LIB_DEPENDS += \
QTC_PLUGIN_DEPENDS += \
coreplugin \
texteditor
QTC_TEST_DEPENDS += \
cppeditor \
cpptools

View File

@@ -963,6 +963,12 @@ void FakeVimPlugin::test_vim_delete()
KEYS("dd", "");
INTEGRITY(false);
// delete character / word / line in insert mode
data.setText("123" N "456 789");
KEYS("A<C-h>", "12" N "456 789");
KEYS("<C-u>", "" N "456 789");
KEYS("<Esc>jA<C-w>", "" N "456 ");
data.setText("void main()");
KEYS("dt(", "()");
INTEGRITY(false);
@@ -2510,6 +2516,16 @@ void FakeVimPlugin::test_vim_copy_paste()
KEYS("j\"yyy", "abc" N "abc" N X "def" N "ghi");
KEYS("gg\"yP", X "def" N "abc" N "abc" N "def" N "ghi");
KEYS("\"xP", X "abc" N "def" N "abc" N "abc" N "def" N "ghi");
// delete to black hole register
data.setText("aaa bbb ccc");
KEYS("yiww\"_diwP", "aaa aaa ccc");
data.setText("aaa bbb ccc");
KEYS("yiwwdiwP", "aaa bbb ccc");
// yank register is only used for y{motion} commands
data.setText("aaa bbb ccc");
KEYS("yiwwdiw\"0P", "aaa aaa ccc");
}
void FakeVimPlugin::test_vim_undo_redo()

View File

@@ -2416,6 +2416,9 @@ void FakeVimHandler::Private::enterFakeVim()
{
QTC_ASSERT(!m_inFakeVim, qDebug() << "enterFakeVim() shouldn't be called recursively!"; return);
if (!m_buffer->currentHandler)
m_buffer->currentHandler = this;
pullOrCreateBufferData();
m_inFakeVim = true;
@@ -4953,7 +4956,8 @@ void FakeVimHandler::Private::handleInsertMode(const Input &input)
endEditBlock();
}
} else if (input.isBackspace()) {
if (!handleInsertInEditor(input)) {
// pass C-h as backspace, too
if (!handleInsertInEditor(Input(Qt::Key_Backspace, Qt::NoModifier))) {
joinPreviousEditBlock();
if (!m_buffer->lastInsertion.isEmpty()
|| hasConfig(ConfigBackspace, "start")

View File

@@ -13,6 +13,10 @@ QtcPlugin {
Depends { name: "ProjectExplorer" }
Depends { name: "QtSupport" }
pluginTestDepends: [
"CppEditor",
]
files: [
"filesselectionwizardpage.cpp",
"filesselectionwizardpage.h",

View File

@@ -8,3 +8,5 @@ QTC_PLUGIN_DEPENDS += \
cpptools \
texteditor \
qtsupport
QTC_TEST_DEPENDS += \
cppeditor

View File

@@ -221,7 +221,7 @@ QString DefaultDeployConfigurationFactory::displayNameForId(Core::Id id) const
{
if (id == Constants::DEFAULT_DEPLOYCONFIGURATION_ID)
//: Display name of the default deploy configuration
return tr("Deploy Configuration");
return DeployConfigurationFactory::tr("Deploy Configuration");
return QString();
}

View File

@@ -93,9 +93,9 @@ public:
LineEditValidator(MacroExpander *expander, const QRegularExpression &pattern, QObject *parent) :
QRegularExpressionValidator(pattern, parent)
{
m_expander.setDisplayName(tr("Line Edit Validator Expander"));
m_expander.setDisplayName(JsonFieldPage::tr("Line Edit Validator Expander"));
m_expander.setAccumulating(true);
m_expander.registerVariable("INPUT", tr("The text edit input to fix up."),
m_expander.registerVariable("INPUT", JsonFieldPage::tr("The text edit input to fix up."),
[this]() { return m_currentInput; });
m_expander.registerSubProvider([expander]() -> MacroExpander * { return expander; });
}

View File

@@ -172,11 +172,35 @@ void TargetSelector::setCurrentIndex(int index)
m_currentTargetIndex = index;
if (isVisible())
ensureCurrentIndexVisible();
update();
emit currentChanged(m_currentTargetIndex,
m_currentTargetIndex >= 0 ? m_targets.at(m_currentTargetIndex).currentSubIndex : -1);
}
void TargetSelector::showEvent(QShowEvent *event)
{
QWidget::showEvent(event);
ensureCurrentIndexVisible();
}
void TargetSelector::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
ensureCurrentIndexVisible();
}
void TargetSelector::ensureCurrentIndexVisible()
{
if (m_currentTargetIndex < m_startIndex)
m_startIndex = m_currentTargetIndex;
const int lastIndex = m_startIndex + maxVisibleTargets() - 1;
if (m_currentTargetIndex > lastIndex)
m_startIndex = m_currentTargetIndex - maxVisibleTargets() + 1;
}
void TargetSelector::setCurrentSubIndex(int subindex)
{
if (subindex < 0 ||

View File

@@ -89,6 +89,8 @@ protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void leaveEvent(QEvent *event);
void showEvent(QShowEvent *event);
void resizeEvent(QResizeEvent *event);
bool event(QEvent *e);
private slots:
@@ -99,6 +101,7 @@ private slots:
private:
void getControlAt(int x, int y, int *buttonIndex, int *targetIndex, int *targetSubIndex);
int maxVisibleTargets() const;
void ensureCurrentIndexVisible();
const QImage m_unselected;
const QImage m_runselected;

View File

@@ -117,9 +117,9 @@ public:
m_factories = ExtensionSystem::PluginManager::getObjects<ToolChainFactory>(
[](ToolChainFactory *factory) { return factory->canCreate();});
m_model.setHeader(QStringList() << tr("Name") << tr("Type"));
m_autoRoot = new TreeItem(QStringList() << tr("Auto-detected") << QString());
m_manualRoot = new TreeItem(QStringList() << tr("Manual") << QString());
m_model.setHeader(QStringList() << ToolChainOptionsPage::tr("Name") << ToolChainOptionsPage::tr("Type"));
m_autoRoot = new TreeItem(QStringList() << ToolChainOptionsPage::tr("Auto-detected") << QString());
m_manualRoot = new TreeItem(QStringList() << ToolChainOptionsPage::tr("Manual") << QString());
m_model.rootItem()->appendChild(m_autoRoot);
m_model.rootItem()->appendChild(m_manualRoot);
foreach (ToolChain *tc, ToolChainManager::toolChains()) {
@@ -137,7 +137,7 @@ public:
m_toolChainView->header()->setSectionResizeMode(1, QHeaderView::Stretch);
m_toolChainView->expandAll();
m_addButton = new QPushButton(tr("Add"), this);
m_addButton = new QPushButton(ToolChainOptionsPage::tr("Add"), this);
auto addMenu = new QMenu;
foreach (ToolChainFactory *factory, m_factories) {
QAction *action = new QAction(addMenu);
@@ -147,10 +147,10 @@ public:
}
m_addButton->setMenu(addMenu);
m_cloneButton = new QPushButton(tr("Clone"), this);
m_cloneButton = new QPushButton(ToolChainOptionsPage::tr("Clone"), this);
connect(m_cloneButton, &QAbstractButton::clicked, [this] { createToolChain(0); });
m_delButton = new QPushButton(tr("Remove"), this);
m_delButton = new QPushButton(ToolChainOptionsPage::tr("Remove"), this);
m_container = new DetailsWidget(this);
m_container->setState(DetailsWidget::NoSummary);
@@ -317,16 +317,16 @@ void ToolChainOptionsWidget::apply()
if (removedTcs.count() == 1) {
QMessageBox::warning(Core::ICore::dialogParent(),
tr("Duplicate Compilers Detected"),
tr("The following compiler was already configured:<br>"
ToolChainOptionsPage::tr("Duplicate Compilers Detected"),
ToolChainOptionsPage::tr("The following compiler was already configured:<br>"
"&nbsp;%1<br>"
"It was not configured again.")
.arg(removedTcs.at(0)));
} else if (!removedTcs.isEmpty()) {
QMessageBox::warning(Core::ICore::dialogParent(),
tr("Duplicate Compilers Detected"),
tr("The following compilers were already configured:<br>"
ToolChainOptionsPage::tr("Duplicate Compilers Detected"),
ToolChainOptionsPage::tr("The following compilers were already configured:<br>"
"&nbsp;%1<br>"
"They were not configured again.")
.arg(removedTcs.join(QLatin1String(",<br>&nbsp;"))));

View File

@@ -79,7 +79,7 @@ QbsProfilesSettingsPage::QbsProfilesSettingsPage(QObject *parent)
: Core::IOptionsPage(parent), m_widget(0)
{
setId("AA.QbsProfiles");
setDisplayName(tr("Profiles"));
setDisplayName(QCoreApplication::translate("QbsProjectManager", "Profiles"));
setCategory(Constants::QBS_SETTINGS_CATEGORY);
setDisplayCategory(QCoreApplication::translate("QbsProjectManager",
Constants::QBS_SETTINGS_TR_CATEGORY));

View File

@@ -171,18 +171,12 @@ bool QmlProfilerTraceView::hasValidSelection() const
qint64 QmlProfilerTraceView::selectionStart() const
{
QQuickItem *rootObject = d->m_mainView->rootObject();
if (rootObject)
return rootObject->property("selectionRangeStart").toLongLong();
return 0;
return d->m_zoomControl->selectionStart();
}
qint64 QmlProfilerTraceView::selectionEnd() const
{
QQuickItem *rootObject = d->m_mainView->rootObject();
if (rootObject)
return rootObject->property("selectionRangeEnd").toLongLong();
return 0;
return d->m_zoomControl->selectionEnd();
}
void QmlProfilerTraceView::clear()

View File

@@ -657,7 +657,7 @@ void TextEditorWidgetPrivate::ctor(const QSharedPointer<TextDocument> &doc)
// (void) new QShortcut(tr("F11"), this, SLOT(slotToggleBlockVisible()));
#ifdef DO_FOO
(void) new QShortcut(tr("CTRL+D"), this, SLOT(doFoo()));
(void) new QShortcut(TextEditorWidget::tr("CTRL+D"), this, SLOT(doFoo()));
#endif
// parentheses matcher
@@ -6779,10 +6779,10 @@ void TextEditorWidgetPrivate::updateCursorPosition()
const int line = block.blockNumber() + 1;
const int column = cursor.position() - block.position();
m_cursorPositionLabel->show();
m_cursorPositionLabel->setText(tr("Line: %1, Col: %2").arg(line)
m_cursorPositionLabel->setText(TextEditorWidget::tr("Line: %1, Col: %2").arg(line)
.arg(q->textDocument()->tabSettings().columnAt(block.text(),
column)+1),
tr("Line: 9999, Col: 999"));
TextEditorWidget::tr("Line: 9999, Col: 999"));
m_contextHelpId.clear();
if (!block.isVisible())

View File

@@ -56,6 +56,7 @@ namespace Internal {
class TextEditorActionHandlerPrivate : public QObject
{
Q_DECLARE_TR_FUNCTIONS(TextEditor::Internal::TextEditorActionHandler)
public:
TextEditorActionHandlerPrivate(TextEditorActionHandler *parent,
Core::Id contextId,

View File

@@ -97,14 +97,15 @@ RunControl *WinRtDebugSupport::createDebugRunControl(WinRtRunConfiguration *runC
if (!errorMessage->isEmpty())
return 0;
QLocalServer server;
server.listen(QLatin1String("QtCreatorWinRtDebugPIDPipe"));
runner->debug(debuggerHelper.absoluteFilePath());
if (!runner->waitForStarted()) {
*errorMessage = tr("Cannot start the WinRT Runner Tool.");
return 0;
}
QLocalServer server;
server.listen(QLatin1String("QtCreatorWinRtDebugPIDPipe"));
if (!server.waitForNewConnection(10000)) {
*errorMessage = tr("Cannot establish connection to the WinRT debugging helper.");
return 0;

View File

@@ -83,7 +83,17 @@ void tst_offsets::offsets_data()
QFilePrivate *p = 0;
QTestData &data = QTest::newRow("QFilePrivate::fileName")
<< int((char *)&p->fileName - (char *)p);
if (qtVersion >= 0x50400)
if (qtVersion >= 0x50500)
#ifdef Q_OS_WIN
# ifdef Q_CC_MSVC
data << 176 << 248;
# else // MinGW
data << 164 << 248;
# endif
#else
data << 156 << 248;
#endif
else if (qtVersion >= 0x50400)
#ifdef Q_OS_WIN
# ifdef Q_CC_MSVC
data << 196 << 272;

View File

@@ -38,6 +38,14 @@
using namespace Timeline;
void renderMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message)
{
if (type > QtDebugMsg)
QTest::qFail(message.toLatin1().constData(), context.file, context.line);
else
QTest::qWarn(message.toLatin1().constData(), context.file, context.line);
}
void runSceneGraph(QSGNode *node)
{
QSurfaceFormat format;
@@ -62,7 +70,9 @@ void runSceneGraph(QSGNode *node)
QSGAbstractRenderer *renderer = engine.createRenderer();
QVERIFY(renderer != 0);
renderer->setRootNode(&root);
QtMessageHandler originalHandler = qInstallMessageHandler(renderMessageHandler);
renderer->renderScene();
qInstallMessageHandler(originalHandler);
delete renderer;
// Unfortunately we cannot check the results of the rendering. But at least we know the shaders

View File

@@ -89,12 +89,6 @@ def main():
clickButton(waitForObject(":Close Debugging Session.Yes_QPushButton", 2000))
except:
pass
if platform.system() == 'Darwin' and JIRA.isBugStillOpen(11595):
try:
expectedBreakpointsOrder.remove({os.path.join(workingDir, projectName, "main.cpp"):10})
test.warning("Removed cpp file after first run. (QTCREATORBUG-11595)")
except:
pass
else:
test.fatal("Setting breakpoints failed - leaving without testing.")
invokeMenuItem("File", "Exit")