Merge remote-tracking branch 'origin/4.2'
Conflicts: qbs/modules/qtc/qtc.qbs qtcreator.pri Change-Id: I245212bd45104636b1c9737b36d3db3e4af23092
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
BIN
doc/images/qmldesigner-binding-editor.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 22 KiB |
@@ -346,11 +346,11 @@
|
||||
\li Some versions of Perf will not start recording unless given a
|
||||
certain minimum sampling frequency. Try with a
|
||||
\uicontrol {Sampling Frequency} of 1000.
|
||||
\li On some devices, for example Boundary Devices i.MX6 Boards, the
|
||||
Perf support is not very stable and the Linux kernel may randomly
|
||||
fail to record data after some time. Perf can use different types
|
||||
of events to trigger samples. You can get a list of available event
|
||||
types by running \c {perf list} on the device and add
|
||||
\li On some devices, in particular various i.MX6 Boards, the hardware
|
||||
performance counters are dysfunctional and the Linux kernel may
|
||||
randomly fail to record data after some time. Perf can use different
|
||||
types of events to trigger samples. You can get a list of available
|
||||
event types by running \c {perf list} on the device and add
|
||||
\c {-e <event type>} to the \uicontrol {Additional arguments} field
|
||||
to change the event type to be used. The choice of event type
|
||||
affects the performance and stability of the sampling.
|
||||
|
||||
@@ -171,23 +171,25 @@
|
||||
recorded. Move the cursor on an event on a row to see how long it takes and
|
||||
where in the source it is being called. To display the information only when
|
||||
an event is selected, disable the \uicontrol {View Event Information on Mouseover}
|
||||
button (5).
|
||||
button (4).
|
||||
|
||||
The outline (10) summarizes the period for which data was collected. Drag
|
||||
the zoom range (8) or click the outline to move on the outline. You can
|
||||
also move between events by selecting the \uicontrol {Jump to Previous Event} (1)
|
||||
and \uicontrol {Jump to Next Event} (2) buttons.
|
||||
also move between events by selecting the \uicontrol {Jump to Previous Event}
|
||||
and \uicontrol {Jump to Next Event} buttons (1).
|
||||
|
||||
Select the \uicontrol {Show Zoom Slider} button (3) to open a slider that you can
|
||||
Select the \uicontrol {Show Zoom Slider} button (2) to open a slider that you can
|
||||
use to set the zoom level. You can also drag the zoom handles (9). To reset
|
||||
the default zoom level, right-click the timeline to open the context menu,
|
||||
and select \uicontrol {Reset Zoom}.
|
||||
|
||||
Click the time ruler to add vertical orientation lines (5) to the timeline.
|
||||
|
||||
\section2 Selecting Event Ranges
|
||||
|
||||
You can select an event range (7) to view the frame rate of events and to
|
||||
compare it with the frame rate of similar events. Select the
|
||||
\uicontrol {Select Range} button (4) to activate the selection tool. Then click in
|
||||
\uicontrol {Select Range} button (3) to activate the selection tool. Then click in
|
||||
the timeline to specify the beginning of the event range. Drag the selection
|
||||
handle to define the end of the range. The length of the range indicates the
|
||||
frame rate of the event.
|
||||
@@ -557,14 +559,26 @@
|
||||
\section2 Visualizing Statistics as Flame Graphs
|
||||
|
||||
The \uicontrol {Flame Graph} view shows a more concise statistical overview
|
||||
of QML and JavaScript execution. The horizontal bars show the amount of
|
||||
of QML and JavaScript execution. In the \uicontrol {Visualize Total Time}
|
||||
view, the horizontal bars show the amount of
|
||||
time all invocations of a certain function took together, relative to the
|
||||
total runtime of all JavaScript and QML events. The nesting shows which
|
||||
functions were called by which other ones. Mind that, unlike the
|
||||
functions were called by which other ones.
|
||||
|
||||
\image qml-profiler-flamegraph.png "Flame Graph View"
|
||||
|
||||
To view the total amount of memory allocated by the functions in the
|
||||
\uicontrol {Visualize Memory} view, select \uicontrol Memory in the
|
||||
drop-down menu (1).
|
||||
|
||||
To view the the number of memory allocations performed by the functions in
|
||||
the \uicontrol {Visualize Allocations} view, select \uicontrol Allocations
|
||||
in the drop-down menu.
|
||||
|
||||
Unlike the
|
||||
\uicontrol Timeline view, the \uicontrol {Flame Graph} view does not show the
|
||||
time spans when no QML or JavaScript is running at all. Thus, it is not
|
||||
suitable for analyzing per frame execution times. However, it is very easy
|
||||
to see the total impact of the various QML and JavaScript events there.
|
||||
|
||||
\image qml-profiler-flamegraph.png "Flame Graph View"
|
||||
*/
|
||||
|
||||
@@ -37,22 +37,32 @@
|
||||
|
||||
\title Comparing Files
|
||||
|
||||
You can use a diff editor from \QC to compare two text files. They can be
|
||||
either versions of the same file or arbitrary files.
|
||||
You can use a diff editor to display unsaved changed in the current file or
|
||||
all open files or to compare any two text files that can be either versions
|
||||
of the same file or arbitrary files.
|
||||
|
||||
\image creator-diff-editor.png "Diff editor output in the Edit mode"
|
||||
To view unsaved changes in the current file, select \uicontrol Tools >
|
||||
\uicontrol Diff > \uicontrol {Diff Current File}.
|
||||
|
||||
To compare files:
|
||||
To view unsaved changes in all open files, select \uicontrol Tools >
|
||||
\uicontrol Diff > \uicontrol {Diff Open Files}.
|
||||
|
||||
To compare two files:
|
||||
|
||||
\list 1
|
||||
|
||||
\li Select \uicontrol Tools > \uicontrol Diff.
|
||||
\li Select \uicontrol Tools > \uicontrol Diff >
|
||||
\uicontrol {Diff External Files}.
|
||||
|
||||
\li Select two files to compare.
|
||||
|
||||
\endlist
|
||||
|
||||
The differences are output in the \uicontrol Edit mode. Color coding is used
|
||||
\section1 Viewing the Changes
|
||||
|
||||
\image creator-diff-editor.png "Diff editor output in the Edit mode"
|
||||
|
||||
The changes are displayed in the \uicontrol Edit mode. Color coding is used
|
||||
to mark changed lines. By default, light red indicates lines that contain
|
||||
removed text (painted a darker red) in the left pane and light green
|
||||
indicates lines that contain added text (painted a darker green) in the
|
||||
@@ -70,6 +80,26 @@
|
||||
\inlineimage sidebysidediff.png
|
||||
(\uicontrol {Switch to Side by Side Diff Editor}).
|
||||
|
||||
To only show text changes, select \uicontrol {Ignore Whitespace}.
|
||||
|
||||
To expand the context for the changes, set the number of unchanged lines to
|
||||
show in \uicontrol {Context lines}. Set the value to -1 to show the whole
|
||||
file.
|
||||
|
||||
By default, the horizontal scroll bars in the left and right pane are
|
||||
synchronized. To use them independently of each other, select the
|
||||
\inlineimage linkicon.png
|
||||
(\uicontrol {Synchronize Horizontal Scroll Bars}) button.
|
||||
|
||||
If the files change outside \QC, select \inlineimage reload_gray.png
|
||||
(\uicontrol {Reload Editor}) to compare them again and to show the results.
|
||||
|
||||
To send a chunk of changes to a \l{Pasting and Fetching Code Snippets}
|
||||
{code pasting service}, select \uicontrol {Send Chunk to CodePaster} in the
|
||||
context menu.
|
||||
|
||||
\section1 Changing the Colors
|
||||
|
||||
To change the default colors, select \uicontrol Tools > \uicontrol Options >
|
||||
\uicontrol {Text Editor} > \uicontrol {Font & Colors}. Create your own color
|
||||
scheme and select new colors for the following options:
|
||||
@@ -95,22 +125,4 @@
|
||||
indicates added characters.
|
||||
|
||||
\endlist
|
||||
|
||||
To only show text changes, select \uicontrol {Ignore Whitespace}.
|
||||
|
||||
To expand the context for the changes, set the number of unchanged lines to
|
||||
show in \uicontrol {Context lines}. Set the value to -1 to show the whole
|
||||
file.
|
||||
|
||||
By default, the horizontal scroll bars in the left and right pane are
|
||||
synchronized. To use them independently of each other, select the
|
||||
\inlineimage linkicon.png
|
||||
(\uicontrol {Synchronize Horizontal Scroll Bars}) button.
|
||||
|
||||
If the files change outside \QC, select \inlineimage reload_gray.png
|
||||
(\uicontrol {Reload Editor}) to compare them again and to show the results.
|
||||
|
||||
To send a chunk of changes to a \l{Pasting and Fetching Code Snippets}
|
||||
{code pasting service}, select \uicontrol {Send Chunk to CodePaster} in the
|
||||
context menu.
|
||||
*/
|
||||
|
||||
@@ -915,6 +915,9 @@
|
||||
|
||||
\li C++ code snippets, which specify C++ code constructs
|
||||
|
||||
\li CMake code snippets that you can use when editing \c CMakeLists.txt
|
||||
files in the CMake editor
|
||||
|
||||
\li QML code snippets, which specify QML code constructs
|
||||
|
||||
\li Nim code snippets, which specify Nim code constructs
|
||||
|
||||
@@ -161,6 +161,8 @@
|
||||
|
||||
\li Keyword completion
|
||||
|
||||
\li Code completion
|
||||
|
||||
\li Auto-indentation
|
||||
|
||||
\li Matching parentheses and quotes
|
||||
|
||||
@@ -428,6 +428,10 @@
|
||||
you can change the position of an object on the canvas and then add animation
|
||||
to the change between the states.
|
||||
|
||||
To determine when the state should be applied, select
|
||||
\uicontrol {Set when Condition} in the context menu and specify a
|
||||
\l [QtQuick]{State::when}{when} property for the state.
|
||||
|
||||
You can preview the states in the \uicontrol State pane and click them to switch
|
||||
between states on the canvas.
|
||||
|
||||
|
||||
@@ -133,12 +133,23 @@
|
||||
|
||||
\image qmldesigner-set-expression.png "Type properties context menu"
|
||||
|
||||
The \uicontrol {Binding Editor} supports code completion. Start typing a
|
||||
string and press \key Ctrl+Space to display a list of properties, IDs, and
|
||||
code snippets. When you enter a period (.) after a property name, a list of
|
||||
available values is displayed. Press \key Enter to accept the first
|
||||
suggestion in the list and to complete the code.
|
||||
|
||||
\image qmldesigner-binding-editor.png "Binding Editor"
|
||||
|
||||
To remove bindings, select \uicontrol Reset in the context menu.
|
||||
|
||||
You can set bindings also in the \uicontrol Connections view. For more
|
||||
information, see \l {Adding Bindings Between Properties}.
|
||||
|
||||
For more information on the JavaScript environment provided by QML, see
|
||||
\l{Integrating QML and JavaScript}.
|
||||
|
||||
\QMLD cannot show bindings and using them might have a negative impact on
|
||||
Bindings are a black box for \QMLD and using them might have a negative impact on
|
||||
performance, so consider setting anchors and margins for items, instead.
|
||||
For example, instead of setting \c {parent.width} for an item, you could
|
||||
anchor the item to its sibling items on the left and the right.
|
||||
|
||||
@@ -78,7 +78,7 @@ def package_repos(repos, combined_prefix, target_file_base):
|
||||
print('Creating .tar.gz...')
|
||||
createTarGz(archive_path(crlf=False), target_file_base + '.tar.gz')
|
||||
print('Creating .tar.xz...')
|
||||
createTarGz(archive_path(crlf=False), target_file_base + '.tar.xz')
|
||||
createTarXz(archive_path(crlf=False), target_file_base + '.tar.xz')
|
||||
print('Creating .zip with CRLF...')
|
||||
createZip(archive_path(crlf=True), target_file_base + '.zip')
|
||||
print('Removing temporary directory...')
|
||||
|
||||
@@ -117,25 +117,25 @@ def qdump__boost__unordered__unordered_set(d, value):
|
||||
innerType = value.type[0]
|
||||
bucketCount = d.extractInt(base + ptrSize)
|
||||
#warn("A BUCKET COUNT: %s" % bucketCount)
|
||||
#warn("X BUCKET COUNT: %s" % d.parseAndEvaluate("s1.table_.bucket_count_"))
|
||||
#warn("X BUCKET COUNT: %s" % d.parseAndEvaluate("s1.table_.bucket_count_").value())
|
||||
try:
|
||||
# boost 1.58
|
||||
table = value["table_"]
|
||||
bucketsAddr = table["buckets_"].integer()
|
||||
#warn("A BUCKETS: 0x%x" % bucketsAddr)
|
||||
#warn("X BUCKETS: %s" % d.parseAndEvaluate("s1.table_.buckets_"))
|
||||
#warn("X BUCKETS: 0x%x" % d.parseAndEvaluate("s1.table_.buckets_").pointer())
|
||||
lastBucketAddr = bucketsAddr + bucketCount * ptrSize
|
||||
#warn("A LAST BUCKET: 0x%x" % lastBucketAddr)
|
||||
#warn("X LAST BUCKET: %s" % d.parseAndEvaluate("s1.table_.get_bucket(s1.table_.bucket_count_)"))
|
||||
#warn("X LAST BUCKET: 0x%x" % d.parseAndEvaluate("s1.table_.get_bucket(s1.table_.bucket_count_)").pointer())
|
||||
previousStartAddr = lastBucketAddr
|
||||
#warn("A PREVIOUS START: 0x%x" % previousStartAddr)
|
||||
#warn("X PREVIOUS START: %s" % d.parseAndEvaluate("s1.table_.get_previous_start()"))
|
||||
#warn("X PREVIOUS START: 0x%x" % d.parseAndEvaluate("s1.table_.get_previous_start()").pointer())
|
||||
item = d.extractPointer(previousStartAddr)
|
||||
#warn("A KEY ADDR: 0x%x" % item)
|
||||
#warn("X KEY ADDR: %s" % d.parseAndEvaluate("s1.table_.get_previous_start()->next_"))
|
||||
#warn("X KEY ADDR: 0x%x" % d.parseAndEvaluate("s1.table_.get_previous_start()->next_").pointer())
|
||||
item = d.extractPointer(previousStartAddr)
|
||||
#warn("A VALUE: %x" % d.extractInt(item + ptrSize))
|
||||
#warn("X VALUE: %s" % d.parseAndEvaluate("*(int*)(s1.table_.get_previous_start()->next_ + 1)"))
|
||||
#warn("X VALUE: %x" % d.parseAndEvaluate("*(int*)(s1.table_.get_previous_start()->next_ + 1)").integer())
|
||||
with Children(d, size, maxNumChild=10000):
|
||||
for j in d.childRange():
|
||||
d.putSubItem(j, d.createValue(item + 2 * ptrSize, innerType))
|
||||
|
||||
@@ -205,17 +205,46 @@ class Dumper(DumperBase):
|
||||
self.output = []
|
||||
self.setVariableFetchingOptions(args)
|
||||
|
||||
def fromNativeDowncastableValue(self, nativeValue):
|
||||
def fromFrameValue(self, nativeValue):
|
||||
val = nativeValue
|
||||
if self.useDynamicType:
|
||||
try:
|
||||
return self.fromNativeValue(nativeValue.cast(nativeValue.dynamic_type))
|
||||
val = nativeValue.cast(nativeValue.dynamic_type)
|
||||
except:
|
||||
pass
|
||||
return self.fromNativeValue(nativeValue)
|
||||
return self.fromNativeValue(val)
|
||||
|
||||
def fromNativeValue(self, nativeValue):
|
||||
#self.check(isinstance(nativeValue, gdb.Value))
|
||||
#warn("FROM NATIVE VALUE: %s" % nativeValue)
|
||||
self.check(isinstance(nativeValue, gdb.Value))
|
||||
nativeType = nativeValue.type
|
||||
code = nativeType.code
|
||||
if code == gdb.TYPE_CODE_REF:
|
||||
targetType = self.fromNativeType(nativeType.target().unqualified())
|
||||
val = self.createReferenceValue(toInteger(nativeValue.address), targetType)
|
||||
#warn("CREATED REF: %s" % val)
|
||||
return val
|
||||
if code == gdb.TYPE_CODE_PTR:
|
||||
targetType = self.fromNativeType(nativeType.target().unqualified())
|
||||
val = self.createPointerValue(toInteger(nativeValue), targetType)
|
||||
#warn("CREATED PTR 1: %s" % val)
|
||||
if not nativeValue.address is None:
|
||||
val.laddress = toInteger(nativeValue.address)
|
||||
#warn("CREATED PTR 2: %s" % val)
|
||||
return val
|
||||
if code == gdb.TYPE_CODE_TYPEDEF:
|
||||
targetType = nativeType.strip_typedefs().unqualified()
|
||||
#warn("TARGET TYPE: %s" % targetType)
|
||||
if targetType.code == gdb.TYPE_CODE_ARRAY:
|
||||
val = self.Value(self)
|
||||
val.laddress = toInteger(nativeValue.address)
|
||||
else:
|
||||
# Cast may fail (e.g for arrays, see test for Bug5799)
|
||||
val = self.fromNativeValue(nativeValue.cast(targetType))
|
||||
val.type = self.fromNativeType(nativeType)
|
||||
#warn("CREATED TYPEDEF: %s" % val)
|
||||
return val
|
||||
|
||||
val = self.Value(self)
|
||||
if not nativeValue.address is None:
|
||||
val.laddress = toInteger(nativeValue.address)
|
||||
@@ -238,82 +267,131 @@ class Dumper(DumperBase):
|
||||
val.ldisplay += ' (%s)' % intval
|
||||
elif code == gdb.TYPE_CODE_COMPLEX:
|
||||
val.ldisplay = str(nativeValue)
|
||||
elif code == gdb.TYPE_CODE_ARRAY:
|
||||
val.type.ltarget = nativeValue[0].type.unqualified()
|
||||
#elif code == gdb.TYPE_CODE_ARRAY:
|
||||
# val.type.ltarget = nativeValue[0].type.unqualified()
|
||||
return val
|
||||
|
||||
def ptrSize(self):
|
||||
result = gdb.lookup_type('void').pointer().sizeof
|
||||
self.ptrSize = lambda: result
|
||||
return result
|
||||
|
||||
def fromNativeType(self, nativeType):
|
||||
self.check(isinstance(nativeType, gdb.Type))
|
||||
typeobj = self.Type(self)
|
||||
typeobj.nativeType = nativeType.unqualified()
|
||||
typeobj.name = str(typeobj.nativeType)
|
||||
typeobj.lbitsize = nativeType.sizeof * 8
|
||||
typeobj.code = {
|
||||
gdb.TYPE_CODE_TYPEDEF : TypeCodeTypedef,
|
||||
gdb.TYPE_CODE_METHOD : TypeCodeFunction,
|
||||
gdb.TYPE_CODE_VOID : TypeCodeVoid,
|
||||
gdb.TYPE_CODE_FUNC : TypeCodeFunction,
|
||||
gdb.TYPE_CODE_METHODPTR : TypeCodeFunction,
|
||||
gdb.TYPE_CODE_MEMBERPTR : TypeCodeFunction,
|
||||
gdb.TYPE_CODE_PTR : TypeCodePointer,
|
||||
gdb.TYPE_CODE_REF : TypeCodeReference,
|
||||
gdb.TYPE_CODE_BOOL : TypeCodeIntegral,
|
||||
gdb.TYPE_CODE_CHAR : TypeCodeIntegral,
|
||||
gdb.TYPE_CODE_INT : TypeCodeIntegral,
|
||||
gdb.TYPE_CODE_FLT : TypeCodeFloat,
|
||||
gdb.TYPE_CODE_ENUM : TypeCodeEnum,
|
||||
gdb.TYPE_CODE_ARRAY : TypeCodeArray,
|
||||
gdb.TYPE_CODE_STRUCT : TypeCodeStruct,
|
||||
gdb.TYPE_CODE_UNION : TypeCodeStruct,
|
||||
gdb.TYPE_CODE_COMPLEX : TypeCodeComplex,
|
||||
gdb.TYPE_CODE_STRING : TypeCodeFortranString,
|
||||
}[nativeType.code]
|
||||
return typeobj
|
||||
code = nativeType.code
|
||||
#warn('FROM NATIVE TYPE: %s' % nativeType)
|
||||
#nativeType = nativeType.unqualified()
|
||||
|
||||
def nativeTypeDereference(self, nativeType):
|
||||
return self.fromNativeType(nativeType.strip_typedefs().target())
|
||||
if code == gdb.TYPE_CODE_PTR:
|
||||
#warn('PTR')
|
||||
targetType = self.fromNativeType(nativeType.target().unqualified())
|
||||
return self.createPointerType(targetType)
|
||||
|
||||
def nativeTypeUnqualified(self, nativeType):
|
||||
return self.fromNativeType(nativeType.unqualified())
|
||||
if code == gdb.TYPE_CODE_REF:
|
||||
#warn('REF')
|
||||
targetType = self.fromNativeType(nativeType.target().unqualified())
|
||||
return self.createReferenceType(targetType)
|
||||
|
||||
def nativeTypePointer(self, nativeType):
|
||||
return self.fromNativeType(nativeType.pointer())
|
||||
if code == gdb.TYPE_CODE_ARRAY:
|
||||
#warn('ARRAY')
|
||||
nativeTargetType = nativeType.target().unqualified()
|
||||
targetType = self.fromNativeType(nativeTargetType)
|
||||
count = nativeType.sizeof // nativeTargetType.sizeof
|
||||
return self.createArrayType(targetType, count)
|
||||
|
||||
def nativeTypeTarget(self, nativeType):
|
||||
while nativeType.code == gdb.TYPE_CODE_TYPEDEF:
|
||||
nativeType = nativeType.strip_typedefs().unqualified()
|
||||
return self.fromNativeType(nativeType.target())
|
||||
if code == gdb.TYPE_CODE_TYPEDEF:
|
||||
#warn('TYPEDEF')
|
||||
nativeTargetType = nativeType.unqualified()
|
||||
while nativeTargetType.code == gdb.TYPE_CODE_TYPEDEF:
|
||||
nativeTargetType = nativeTargetType.strip_typedefs().unqualified()
|
||||
targetType = self.fromNativeType(nativeTargetType)
|
||||
return self.createTypedefedType(targetType, str(nativeType))
|
||||
|
||||
def nativeTypeFirstBase(self, nativeType):
|
||||
nativeFields = nativeType.fields()
|
||||
if len(nativeFields) and nativeFields[0].is_base_class:
|
||||
return self.fromNativeType(nativeFields[0].type)
|
||||
if code == gdb.TYPE_CODE_ERROR:
|
||||
warn('Type error: %s' % nativeType)
|
||||
return self.Type(self, '')
|
||||
|
||||
typeId = self.nativeTypeId(nativeType)
|
||||
res = self.typeData.get(typeId, None)
|
||||
if res is None:
|
||||
tdata = self.TypeData(self)
|
||||
tdata.name = str(nativeType)
|
||||
tdata.typeId = typeId
|
||||
tdata.lbitsize = nativeType.sizeof * 8
|
||||
tdata.code = {
|
||||
#gdb.TYPE_CODE_TYPEDEF : TypeCodeTypedef, # Handled above.
|
||||
gdb.TYPE_CODE_METHOD : TypeCodeFunction,
|
||||
gdb.TYPE_CODE_VOID : TypeCodeVoid,
|
||||
gdb.TYPE_CODE_FUNC : TypeCodeFunction,
|
||||
gdb.TYPE_CODE_METHODPTR : TypeCodeFunction,
|
||||
gdb.TYPE_CODE_MEMBERPTR : TypeCodeFunction,
|
||||
#gdb.TYPE_CODE_PTR : TypeCodePointer, # Handled above.
|
||||
#gdb.TYPE_CODE_REF : TypeCodeReference, # Handled above.
|
||||
gdb.TYPE_CODE_BOOL : TypeCodeIntegral,
|
||||
gdb.TYPE_CODE_CHAR : TypeCodeIntegral,
|
||||
gdb.TYPE_CODE_INT : TypeCodeIntegral,
|
||||
gdb.TYPE_CODE_FLT : TypeCodeFloat,
|
||||
gdb.TYPE_CODE_ENUM : TypeCodeEnum,
|
||||
#gdb.TYPE_CODE_ARRAY : TypeCodeArray,
|
||||
gdb.TYPE_CODE_STRUCT : TypeCodeStruct,
|
||||
gdb.TYPE_CODE_UNION : TypeCodeStruct,
|
||||
gdb.TYPE_CODE_COMPLEX : TypeCodeComplex,
|
||||
gdb.TYPE_CODE_STRING : TypeCodeFortranString,
|
||||
}[code]
|
||||
if tdata.code == TypeCodeEnum:
|
||||
tdata.enumDisplay = lambda intval: self.nativeTypeEnumDisplay(nativeType, intval)
|
||||
self.registerType(typeId, tdata) # Prevent recursion in fields.
|
||||
tdata.lfields = self.listFields(nativeType, self.Type(self, typeId))
|
||||
tdata.templateArguments = self.listTemplateParameters(nativeType)
|
||||
self.registerType(typeId, tdata) # Fix up fields and template args
|
||||
# warn('CREATE TYPE: %s' % typeId)
|
||||
#else:
|
||||
# warn('REUSE TYPE: %s' % typeId)
|
||||
return self.Type(self, typeId)
|
||||
|
||||
def listTemplateParameters(self, nativeType):
|
||||
targs = []
|
||||
pos = 0
|
||||
while True:
|
||||
try:
|
||||
targ = nativeType.template_argument(pos)
|
||||
except:
|
||||
break
|
||||
if isinstance(targ, gdb.Type):
|
||||
targs.append(self.fromNativeType(targ.unqualified()))
|
||||
elif isinstance(targ, gdb.Value):
|
||||
#targs.append(self.fromNativeValue(targ))
|
||||
targs.append(self.fromNativeValue(targ).value())
|
||||
else:
|
||||
error('CRAP')
|
||||
pos += 1
|
||||
return targs
|
||||
|
||||
def nativeTypeEnumDisplay(self, nativeType, intval):
|
||||
try:
|
||||
val = gdb.parse_and_eval("(%s)%d" % (nativeType, intval))
|
||||
return "%s (%d)" % (val, intval)
|
||||
val = gdb.parse_and_eval('(%s)%d' % (nativeType, intval))
|
||||
return '%s (%d)' % (val, intval)
|
||||
except:
|
||||
return "%d" % intval
|
||||
return '%d' % intval
|
||||
|
||||
def nativeTypeFields(self, nativeType):
|
||||
if nativeType.code == gdb.TYPE_CODE_TYPEDEF:
|
||||
return self.nativeTypeFields(nativeType.strip_typedefs())
|
||||
def nativeTypeId(self, nativeType):
|
||||
name = str(nativeType)
|
||||
if len(name) == 0:
|
||||
c = '0'
|
||||
elif name == 'struct {...}':
|
||||
c = 's'
|
||||
elif name == 'union {...}':
|
||||
c = 'u'
|
||||
else:
|
||||
return name
|
||||
typeId = c + ''.join(['{%s:%s}' % (f.name, self.nativeTypeId(f.type)) for f in nativeType.fields()])
|
||||
return typeId
|
||||
|
||||
def listFields(self, nativeType, parentType):
|
||||
#if nativeType.code == gdb.TYPE_CODE_TYPEDEF:
|
||||
# return self.listFields(nativeType.strip_typedefs(), parentType)
|
||||
|
||||
fields = []
|
||||
if nativeType.code == gdb.TYPE_CODE_ARRAY:
|
||||
# An array.
|
||||
typeobj = nativeType.strip_typedefs()
|
||||
innerType = typeobj.target()
|
||||
for i in xrange(int(typeobj.sizeof / innerType.sizeof)):
|
||||
field = self.Field(self)
|
||||
field.ltype = self.fromNativeType(innerType)
|
||||
field.parentType = self.fromNativeType(nativeType)
|
||||
field.isBaseClass = False
|
||||
field.lbitsize = innerType.sizeof
|
||||
field.lbitpos = i * innerType.sizeof * 8
|
||||
fields.append(field)
|
||||
return fields
|
||||
|
||||
if not nativeType.code in (gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION):
|
||||
return fields
|
||||
@@ -321,18 +399,20 @@ class Dumper(DumperBase):
|
||||
nativeIndex = 0
|
||||
baseIndex = 0
|
||||
nativeFields = nativeType.fields()
|
||||
#warn("NATIVE FIELDS: %s" % nativeFields)
|
||||
#warn('NATIVE FIELDS: %s' % nativeFields)
|
||||
anonNumber = 0
|
||||
for nativeField in nativeFields:
|
||||
#warn("FIELD: %s" % nativeField)
|
||||
#warn(" DIR: %s" % dir(nativeField))
|
||||
#warn(" BITSIZE: %s" % nativeField.bitsize)
|
||||
#warn(" ARTIFICIAL: %s" % nativeField.artificial)
|
||||
#warn("FIELD NAME: %s" % nativeField.name)
|
||||
#warn("FIELD TYPE: %s" % nativeField.type)
|
||||
#warn('FIELD: %s' % nativeField)
|
||||
#warn(' DIR: %s' % dir(nativeField))
|
||||
#warn(' BITSIZE: %s' % nativeField.bitsize)
|
||||
#warn(' ARTIFICIAL: %s' % nativeField.artificial)
|
||||
#warn('FIELD NAME: %s' % nativeField.name)
|
||||
#warn('FIELD TYPE: %s' % nativeField.type)
|
||||
#warn('FIELD TYPE ID: %s' % self.nativeTypeId(nativeField.type))
|
||||
#self.check(isinstance(nativeField, gdb.Field))
|
||||
field = self.Field(self)
|
||||
field.ltype = self.fromNativeType(nativeField.type)
|
||||
field.parentType = self.fromNativeType(nativeType)
|
||||
field.ltype = self.fromNativeType(nativeField.type.unqualified())
|
||||
field.parentType = parentType
|
||||
field.name = nativeField.name
|
||||
field.isBaseClass = nativeField.is_base_class
|
||||
if hasattr(nativeField, 'bitpos'):
|
||||
@@ -356,36 +436,31 @@ class Dumper(DumperBase):
|
||||
# Something without a name.
|
||||
# Anonymous union? We need a dummy name to distinguish
|
||||
# multiple anonymous unions in the struct.
|
||||
self.anonNumber += 1
|
||||
field.name = "#%s" % self.anonNumber
|
||||
anonNumber += 1
|
||||
field.name = '#%s' % anonNumber
|
||||
else:
|
||||
# Normal named field.
|
||||
field.name = nativeField.name
|
||||
|
||||
field.nativeIndex = nativeIndex
|
||||
#warn('FIELD RESULT: %s' % field)
|
||||
fields.append(field)
|
||||
nativeIndex += 1
|
||||
|
||||
#warn("FIELDS: %s" % fields)
|
||||
#warn('FIELDS: %s' % fields)
|
||||
return fields
|
||||
|
||||
def nativeTypeStripTypedefs(self, typeobj):
|
||||
typeobj = typeobj.unqualified()
|
||||
while typeobj.code == gdb.TYPE_CODE_TYPEDEF:
|
||||
typeobj = typeobj.strip_typedefs().unqualified()
|
||||
return self.fromNativeType(typeobj)
|
||||
|
||||
def listOfLocals(self, partialVar):
|
||||
frame = gdb.selected_frame()
|
||||
|
||||
try:
|
||||
block = frame.block()
|
||||
#warn("BLOCK: %s " % block)
|
||||
#warn('BLOCK: %s ' % block)
|
||||
except RuntimeError as error:
|
||||
#warn("BLOCK IN FRAME NOT ACCESSIBLE: %s" % error)
|
||||
#warn('BLOCK IN FRAME NOT ACCESSIBLE: %s' % error)
|
||||
return []
|
||||
except:
|
||||
warn("BLOCK NOT ACCESSIBLE FOR UNKNOWN REASONS")
|
||||
warn('BLOCK NOT ACCESSIBLE FOR UNKNOWN REASONS')
|
||||
return []
|
||||
|
||||
items = []
|
||||
@@ -409,10 +484,18 @@ class Dumper(DumperBase):
|
||||
# "NotImplementedError: Symbol type not yet supported in
|
||||
# Python scripts."
|
||||
#warn("SYMBOL %s (%s, %s)): " % (symbol, name, symbol.name))
|
||||
try:
|
||||
value = self.fromNativeDowncastableValue(frame.read_var(name, block))
|
||||
#warn("READ 1: %s" % value)
|
||||
if False and self.passExceptions:
|
||||
value = self.fromFrameValue(frame.read_var(name, block))
|
||||
value.name = name
|
||||
#warn("READ 1: %s" % value.stringify())
|
||||
items.append(value)
|
||||
continue
|
||||
|
||||
try:
|
||||
# Same as above, but for production.
|
||||
value = self.fromFrameValue(frame.read_var(name, block))
|
||||
value.name = name
|
||||
#warn("READ 1: %s" % value.stringify())
|
||||
items.append(value)
|
||||
continue
|
||||
except:
|
||||
@@ -420,7 +503,7 @@ class Dumper(DumperBase):
|
||||
|
||||
try:
|
||||
#warn("READ 2: %s" % item.value)
|
||||
value = self.fromNativeDowncastableValue(frame.read_var(name))
|
||||
value = self.fromFrameValue(frame.read_var(name))
|
||||
value.name = name
|
||||
items.append(value)
|
||||
continue
|
||||
@@ -435,7 +518,8 @@ class Dumper(DumperBase):
|
||||
try:
|
||||
#warn("READ 3: %s %s" % (name, item.value))
|
||||
#warn("ITEM 3: %s" % item.value)
|
||||
value = self.fromNativeDowncastableValue(gdb.parse_and_eval(name))
|
||||
value = self.fromFrameValue(gdb.parse_and_eval(name))
|
||||
value.name = name
|
||||
items.append(value)
|
||||
except:
|
||||
# Can happen in inlined code (see last line of
|
||||
@@ -550,10 +634,11 @@ class Dumper(DumperBase):
|
||||
exp = "((%s*)0x%x)->%s(%s)" % (typeName, addr, function, arg)
|
||||
#warn("CALL: %s" % exp)
|
||||
result = gdb.parse_and_eval(exp)
|
||||
#warn(" -> %s" % result)
|
||||
warn(" -> %s" % result)
|
||||
res = self.fromNativeValue(result)
|
||||
if not value.address():
|
||||
gdb.parse_and_eval("free((void*)0x%x)" % addr)
|
||||
return self.fromNativeValue(result)
|
||||
return res
|
||||
|
||||
def makeExpression(self, value):
|
||||
typename = "::" + value.type.name
|
||||
@@ -573,13 +658,6 @@ class Dumper(DumperBase):
|
||||
#warn(" VALUE: %s" % value)
|
||||
return value
|
||||
|
||||
def nativeTypeTemplateArgument(self, nativeType, position, numeric):
|
||||
#warn("NATIVE TYPE: %s" % dir(nativeType))
|
||||
arg = nativeType.template_argument(position)
|
||||
if numeric:
|
||||
return int(str(arg))
|
||||
return self.fromNativeType(arg)
|
||||
|
||||
def pokeValue(self, value):
|
||||
# Allocates inferior memory and copies the contents of value.
|
||||
# Returns a pointer to the copy.
|
||||
@@ -885,9 +963,6 @@ class Dumper(DumperBase):
|
||||
def enumExpression(self, enumType, enumValue):
|
||||
return self.qtNamespace() + "Qt::" + enumValue
|
||||
|
||||
def lookupType(self, typeName):
|
||||
return self.fromNativeType(self.lookupNativeType(typeName))
|
||||
|
||||
def lookupNativeType(self, typeName):
|
||||
nativeType = self.lookupNativeTypeHelper(typeName)
|
||||
if not nativeType is None:
|
||||
@@ -1154,7 +1229,7 @@ class CliDumper(Dumper):
|
||||
def putNumChild(self, numchild):
|
||||
pass
|
||||
|
||||
def putOriginalAddress(self, value):
|
||||
def putOriginalAddress(self, address):
|
||||
pass
|
||||
|
||||
def fetchVariables(self, args):
|
||||
@@ -1205,4 +1280,4 @@ class InterpreterMessageBreakpoint(gdb.Breakpoint):
|
||||
print("Interpreter event received.")
|
||||
return theDumper.handleInterpreterMessage()
|
||||
|
||||
InterpreterMessageBreakpoint()
|
||||
#InterpreterMessageBreakpoint()
|
||||
|
||||
@@ -121,7 +121,7 @@ def qdump__Eigen__Matrix(d, value):
|
||||
storage = value['m_storage']
|
||||
nrows = storage['m_rows'].integer() if argRow == -1 else argRow
|
||||
ncols = storage['m_cols'].integer() if argCol == -1 else argCol
|
||||
p = storage['m_data'].integer()
|
||||
p = storage['m_data'].pointer()
|
||||
innerSize = innerType.size()
|
||||
d.putValue('(%s x %s), %s' % (nrows, ncols, ['ColumnMajor', 'RowMajor'][rowMajor]))
|
||||
d.putField('keeporder', '1')
|
||||
|
||||
@@ -152,7 +152,7 @@ def qdump_X_QModelIndex(d, value):
|
||||
except:
|
||||
p = value['i']
|
||||
m = value['m']
|
||||
if m.integer() == 0 or r < 0 or c < 0:
|
||||
if m.pointer() == 0 or r < 0 or c < 0:
|
||||
d.putValue('(invalid)')
|
||||
d.putPlainChildren(value)
|
||||
return
|
||||
@@ -196,7 +196,7 @@ def qdump_X_QModelIndex(d, value):
|
||||
|
||||
|
||||
def qdump__QDate(d, value):
|
||||
jd = value.integer()
|
||||
jd = value.pointer()
|
||||
if jd:
|
||||
d.putValue(jd, 'juliandate')
|
||||
d.putNumChild(1)
|
||||
@@ -332,6 +332,7 @@ def qdump__QDateTime(d, value):
|
||||
d.putNumChild(0)
|
||||
return
|
||||
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
ns = d.qtNamespace()
|
||||
@@ -1120,7 +1121,7 @@ def qdump__QRegion(d, value):
|
||||
|
||||
|
||||
def qdump__QScopedPointer(d, value):
|
||||
if value.integer() == 0:
|
||||
if value.pointer() == 0:
|
||||
d.putValue('(null)')
|
||||
d.putNumChild(0)
|
||||
else:
|
||||
@@ -1187,13 +1188,13 @@ def qdump__QSet(d, value):
|
||||
|
||||
|
||||
def qdump__QSharedData(d, value):
|
||||
d.putValue('ref: %s' % d.extractInt(value['ref'].address))
|
||||
d.putValue('ref: %s' % value.to('i'))
|
||||
d.putNumChild(0)
|
||||
|
||||
|
||||
def qdump__QSharedDataPointer(d, value):
|
||||
d_ptr = value['d']
|
||||
if d_ptr.integer() == 0:
|
||||
if d_ptr.pointer() == 0:
|
||||
d.putValue('(null)')
|
||||
d.putNumChild(0)
|
||||
else:
|
||||
@@ -1206,7 +1207,7 @@ def qdump__QSharedDataPointer(d, value):
|
||||
d.putPlainChildren(value)
|
||||
return
|
||||
d.putBetterType(d.currentType)
|
||||
d.putItem(d_ptr.cast(innerType.pointer()).dereference())
|
||||
d.putItem(d_ptr.dereference())
|
||||
|
||||
|
||||
|
||||
@@ -1404,6 +1405,7 @@ def qdump__QUrl(d, value):
|
||||
if displayFormat == SeparateFormat:
|
||||
d.putDisplay('utf16:separate', url)
|
||||
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
d.putIntItem('port', port)
|
||||
@@ -1684,12 +1686,12 @@ def qdump__QVariant(d, value):
|
||||
ptr = p.pointer()
|
||||
(elided, blob) = d.encodeCArray(ptr, 1, 100)
|
||||
typeName = d.hexdecode(blob)
|
||||
base = data.extractPointer()
|
||||
# Prefer namespaced version.
|
||||
if len(ns) > 0:
|
||||
if not d.lookupNativeType(ns + typeName) is None:
|
||||
typeName = ns + typeName
|
||||
d.putSubItem('data', d.createValue(base, d.createType(typeName)))
|
||||
data.type = d.createType(typeName + ' *')
|
||||
d.putSubItem('data', data)
|
||||
if not typeName is None:
|
||||
d.putBetterType('%sQVariant (%s)' % (ns, typeName))
|
||||
return None
|
||||
@@ -1706,7 +1708,7 @@ def qedit__QVector(d, value, data):
|
||||
base = value['d'].address() + offset
|
||||
except:
|
||||
# Qt 4.
|
||||
base = value['p']['array'].integer()
|
||||
base = value['p']['array'].pointer()
|
||||
d.setValues(base, innerType, values)
|
||||
|
||||
|
||||
@@ -1766,6 +1768,7 @@ def qdump_QWeakPointerHelper(d, value, isWeak):
|
||||
|
||||
def qdump__QXmlAttributes__Attribute(d, value):
|
||||
d.putEmptyValue()
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
(qname, uri, localname, val) = value.split('{QString}' * 4)
|
||||
@@ -2345,7 +2348,7 @@ def qdump__QScriptValue(d, value):
|
||||
#d.putEmptyValue()
|
||||
dd = value['d_ptr']['d']
|
||||
ns = d.qtNamespace()
|
||||
if dd.integer() == 0:
|
||||
if dd.pointer() == 0:
|
||||
d.putValue('(invalid)')
|
||||
d.putNumChild(0)
|
||||
return
|
||||
@@ -2621,9 +2624,9 @@ def qdump__QJsonValue(d, value):
|
||||
|
||||
|
||||
def qdump__QJsonArray(d, value):
|
||||
qdumpHelper_QJsonArray(d, value['d'].integer(), value['a'].integer())
|
||||
qdumpHelper_QJsonArray(d, value['d'].pointer(), value['a'].pointer())
|
||||
|
||||
|
||||
def qdump__QJsonObject(d, value):
|
||||
qdumpHelper_QJsonObject(d, value['d'].integer(), value['o'].integer())
|
||||
qdumpHelper_QJsonObject(d, value['d'].pointer(), value['o'].pointer())
|
||||
|
||||
|
||||
@@ -76,17 +76,17 @@ def qdump__std__deque(d, value):
|
||||
impl = value["_M_impl"]
|
||||
start = impl["_M_start"]
|
||||
finish = impl["_M_finish"]
|
||||
size = bufsize * int((finish["_M_node"].integer() - start["_M_node"].integer()) / d.ptrSize() - 1)
|
||||
size += int((finish["_M_cur"].integer() - finish["_M_first"].integer()) / innerSize)
|
||||
size += int((start["_M_last"].integer() - start["_M_cur"].integer()) / innerSize)
|
||||
size = bufsize * ((finish["_M_node"].pointer() - start["_M_node"].pointer()) // d.ptrSize() - 1)
|
||||
size += ((finish["_M_cur"].pointer() - finish["_M_first"].pointer()) // innerSize)
|
||||
size += ((start["_M_last"].pointer() - start["_M_cur"].pointer()) // innerSize)
|
||||
|
||||
d.check(0 <= size and size <= 1000 * 1000 * 1000)
|
||||
d.putItemCount(size)
|
||||
if d.isExpanded():
|
||||
with Children(d, size, maxNumChild=2000, childType=innerType):
|
||||
pcur = start["_M_cur"].integer()
|
||||
pcur = start["_M_cur"].pointer()
|
||||
pfirst = start["_M_first"]
|
||||
plast = start["_M_last"].integer()
|
||||
plast = start["_M_last"].pointer()
|
||||
pnode = start["_M_node"]
|
||||
for i in d.childRange():
|
||||
d.putSubItem(i, d.createValue(pcur, innerType))
|
||||
@@ -99,7 +99,7 @@ def qdump__std__deque(d, value):
|
||||
#warn("NEWNODE: 0x%x %s" % (newnode.pointer(), newnode))
|
||||
pnode = newnode
|
||||
#warn("PNODE 2: 0x%x %s" % (pnode.pointer(), pnode))
|
||||
pfirst = newnode.dereference().integer()
|
||||
pfirst = newnode.dereference().pointer()
|
||||
plast = pfirst + bufsize * d.ptrSize()
|
||||
pcur = pfirst
|
||||
|
||||
@@ -237,7 +237,6 @@ def qdump__std__map(d, value):
|
||||
|
||||
if d.isExpanded():
|
||||
pairType = value.type[3][0]
|
||||
pairPointer = pairType.pointer()
|
||||
with PairedChildren(d, size, pairType=pairType, maxNumChild=1000):
|
||||
node = value["_M_t"]["_M_impl"]["_M_header"]["_M_left"]
|
||||
nodeSize = node.dereference().type.size()
|
||||
@@ -245,10 +244,10 @@ def qdump__std__map(d, value):
|
||||
for i in d.childRange():
|
||||
(pad1, key, pad2, value) = d.split(typeCode, node.pointer() + nodeSize)
|
||||
d.putPairItem(i, (key, value))
|
||||
if node["_M_right"].integer() == 0:
|
||||
if node["_M_right"].pointer() == 0:
|
||||
parent = node["_M_parent"]
|
||||
while True:
|
||||
if node.integer() != parent["_M_right"].integer():
|
||||
if node.pointer() != parent["_M_right"].pointer():
|
||||
break
|
||||
node = parent
|
||||
parent = parent["_M_parent"]
|
||||
@@ -257,7 +256,7 @@ def qdump__std__map(d, value):
|
||||
else:
|
||||
node = node["_M_right"]
|
||||
while True:
|
||||
if node["_M_left"].integer() == 0:
|
||||
if node["_M_left"].pointer() == 0:
|
||||
break
|
||||
node = node["_M_left"]
|
||||
|
||||
@@ -271,13 +270,13 @@ def qdump_std__map__helper(d, size, value):
|
||||
for i in d.childRange():
|
||||
pair = node.cast(nodeType).dereference()['_Myval']
|
||||
d.putPairItem(i, pair)
|
||||
if node['_Right']['_Isnil'].integer() == 0:
|
||||
if node['_Right']['_Isnil'].pointer() == 0:
|
||||
node = node['_Right']
|
||||
while node['_Left']['_Isnil'].integer() == 0:
|
||||
while node['_Left']['_Isnil'].pointer() == 0:
|
||||
node = node['_Left']
|
||||
else:
|
||||
parent = node['_Parent']
|
||||
while node and parent['_Right']['_Isnil'].integer() == 0:
|
||||
while node and parent['_Right']['_Isnil'].pointer() == 0:
|
||||
node = parent
|
||||
parent = parent['_Parent']
|
||||
if node['_Right'] != parent:
|
||||
@@ -377,7 +376,7 @@ def qdump__std__set(d, value):
|
||||
for i in d.childRange():
|
||||
(pad, val) = d.split(typeCode, node.pointer() + nodeSize)
|
||||
d.putSubItem(i, val)
|
||||
if node["_M_right"].integer() == 0:
|
||||
if node["_M_right"].pointer() == 0:
|
||||
parent = node["_M_parent"]
|
||||
while node == parent["_M_right"]:
|
||||
node = parent
|
||||
@@ -386,7 +385,7 @@ def qdump__std__set(d, value):
|
||||
node = parent
|
||||
else:
|
||||
node = node["_M_right"]
|
||||
while node["_M_left"].integer() != 0:
|
||||
while node["_M_left"].pointer() != 0:
|
||||
node = node["_M_left"]
|
||||
|
||||
def qdump__std__set__QNX(d, value):
|
||||
@@ -419,7 +418,7 @@ def std1TreeMin(d, node):
|
||||
# return __x;
|
||||
#
|
||||
left = node['__left_']
|
||||
if left.integer():
|
||||
if left.pointer():
|
||||
node = left
|
||||
return node
|
||||
|
||||
@@ -428,7 +427,7 @@ def std1TreeIsLeftChild(d, node):
|
||||
# return __x == __x->__parent_->__left_;
|
||||
#
|
||||
other = node['__parent_']['__left_']
|
||||
return node.integer() == other.integer()
|
||||
return node.pointer() == other.pointer()
|
||||
|
||||
|
||||
def std1TreeNext(d, node):
|
||||
@@ -440,7 +439,7 @@ def std1TreeNext(d, node):
|
||||
# return __x->__parent_;
|
||||
#
|
||||
right = node['__right_']
|
||||
if right.integer():
|
||||
if right.pointer():
|
||||
return std1TreeMin(d, right)
|
||||
while not std1TreeIsLeftChild(d, node):
|
||||
node = node['__parent_']
|
||||
@@ -612,18 +611,18 @@ def qdump__std____1__wstring(d, value):
|
||||
|
||||
|
||||
def qdump__std__shared_ptr(d, value):
|
||||
if d.isMsvcTarget:
|
||||
if d.isMsvcTarget():
|
||||
i = value["_Ptr"]
|
||||
else:
|
||||
i = value["_M_ptr"]
|
||||
|
||||
if i.integer() == 0:
|
||||
if i.pointer() == 0:
|
||||
d.putValue("(null)")
|
||||
d.putNumChild(0)
|
||||
return
|
||||
with Children(d):
|
||||
short = d.putSubItem("data", i)
|
||||
if d.isMsvcTarget:
|
||||
short = d.putSubItem("data", i.dereference())
|
||||
if d.isMsvcTarget():
|
||||
refcount = value["_Rep"]
|
||||
d.putIntItem("usecount", refcount["_Uses"])
|
||||
d.putIntItem("weakcount", refcount["_Weaks"])
|
||||
@@ -635,7 +634,7 @@ def qdump__std__shared_ptr(d, value):
|
||||
|
||||
def qdump__std____1__shared_ptr(d, value):
|
||||
i = value["__ptr_"]
|
||||
if i.integer() == 0:
|
||||
if i.pointer() == 0:
|
||||
d.putValue("(null)")
|
||||
d.putNumChild(0)
|
||||
return
|
||||
@@ -660,6 +659,17 @@ def qdump__std____1__unique_ptr(d, value):
|
||||
qdump__std__unique_ptr(d, value)
|
||||
|
||||
|
||||
def qdump__std__pair(d, value):
|
||||
typeCode = '{%s}@{%s}' % (value.type[0].name, value.type[1].name)
|
||||
first, pad, second = value.split(typeCode)
|
||||
with Children(d):
|
||||
key = d.putSubItem('first', first)
|
||||
value = d.putSubItem('second', second)
|
||||
d.putField('key', key.value)
|
||||
if key.encoding is not None:
|
||||
d.putField('keyencoded', key.encoding)
|
||||
d.putValue(value.value, value.encoding)
|
||||
|
||||
def qform__std__unordered_map():
|
||||
return mapForms()
|
||||
|
||||
@@ -733,7 +743,7 @@ def qdump__std__unordered_set(d, value):
|
||||
|
||||
d.putItemCount(size)
|
||||
if d.isExpanded():
|
||||
p = start.integer()
|
||||
p = start.pointer()
|
||||
valueType = value.type[0]
|
||||
with Children(d, size, childType=valueType):
|
||||
ptrSize = d.ptrSize()
|
||||
@@ -974,10 +984,10 @@ def qdump____gnu_cxx__hash_set(d, value):
|
||||
bucketFinish = buckets["_M_finish"]
|
||||
p = bucketStart
|
||||
itemCount = 0
|
||||
for i in xrange(int((bucketFinish.integer() - bucketStart.integer()) / d.ptrSize())):
|
||||
if p.dereference().integer():
|
||||
for i in xrange((bucketFinish.pointer() - bucketStart.pointer()) // d.ptrSize()):
|
||||
if p.dereference().pointer():
|
||||
cur = p.dereference()
|
||||
while cur.integer():
|
||||
while cur.pointer():
|
||||
d.putSubItem(itemCount, cur["_M_val"])
|
||||
cur = cur["_M_next"]
|
||||
itemCount += 1
|
||||
|
||||
@@ -605,7 +605,33 @@ ObjectNodeInstance::Pointer ObjectNodeInstance::create(QObject *object)
|
||||
|
||||
QObject *ObjectNodeInstance::createPrimitive(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context)
|
||||
{
|
||||
return QmlPrivateGate::createPrimitive(typeName, majorNumber, minorNumber, context);
|
||||
QObject *object = QmlPrivateGate::createPrimitive(typeName, majorNumber, minorNumber, context);
|
||||
|
||||
/* Let's try to create the primitive from source, since with incomplete meta info this might be a pure
|
||||
* QML type. This is the case for example if a C++ type is mocked up with a QML file.
|
||||
*/
|
||||
|
||||
if (!object)
|
||||
object = createPrimitiveFromSource(typeName, majorNumber, minorNumber, context);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
QObject *ObjectNodeInstance::createPrimitiveFromSource(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context)
|
||||
{
|
||||
if (typeName.isEmpty())
|
||||
return 0;
|
||||
|
||||
QStringList parts = typeName.split("/");
|
||||
const QString unqualifiedTypeName = parts.last();
|
||||
parts.removeLast();
|
||||
|
||||
if (parts.isEmpty())
|
||||
return 0;
|
||||
|
||||
const QString importString = parts.join(".") + " " + QString::number(majorNumber) + "." + QString::number(minorNumber);
|
||||
QString source = "import " + importString + "\n" + unqualifiedTypeName + " {\n" + "}\n";
|
||||
return createCustomParserObject(source, "", context);
|
||||
}
|
||||
|
||||
QObject *ObjectNodeInstance::createComponentWrap(const QString &nodeSource, const QByteArray &importCode, QQmlContext *context)
|
||||
|
||||
@@ -67,6 +67,7 @@ public:
|
||||
|
||||
static Pointer create(QObject *objectToBeWrapped);
|
||||
static QObject *createPrimitive(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context);
|
||||
static QObject *createPrimitiveFromSource(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context);
|
||||
static QObject *createCustomParserObject(const QString &nodeSource, const QByteArray &importCode, QQmlContext *context);
|
||||
static QObject *createComponent(const QString &componentPath, QQmlContext *context);
|
||||
static QObject *createComponent(const QUrl &componentUrl, QQmlContext *context);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
project(%{ProjectName})
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
aux_source_directory(. SRC_LIST)
|
||||
add_executable(${PROJECT_NAME} ${SRC_LIST})
|
||||
|
||||
project(%{ProjectName})
|
||||
add_executable(${PROJECT_NAME} "%{CFileName}")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
project(%{ProjectName})
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
aux_source_directory(. SRC_LIST)
|
||||
add_executable(${PROJECT_NAME} ${SRC_LIST})
|
||||
|
||||
project(%{ProjectName})
|
||||
add_executable(${PROJECT_NAME} "%{CppFileName}")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
TEMPLATE = lib
|
||||
TARGET = %ProjectName%
|
||||
QT += qml quick
|
||||
CONFIG += qt plugin c++11
|
||||
CONFIG += plugin c++11
|
||||
|
||||
TARGET = $$qtLibraryTarget($$TARGET)
|
||||
uri = %Uri%
|
||||
|
||||
@@ -242,5 +242,5 @@ IconOverlayCppSource=:/cppeditor/images/dark_qt_cpp.png
|
||||
IconOverlayPrf=:/qtsupport/images/dark_qt_project.png
|
||||
IconOverlayPri=:/qtsupport/images/dark_qt_project.png
|
||||
IconOverlayPro=:/qtsupport/images/dark_qt_project.png
|
||||
StandardPixmapFileIcon=:/core/images/dark_fileicon.png
|
||||
StandardPixmapDirIcon=:/core/images/dark_foldericon.png
|
||||
StandardPixmapFileIcon=:/utils/images/dark_fileicon.png
|
||||
StandardPixmapDirIcon=:/utils/images/dark_foldericon.png
|
||||
|
||||
@@ -19865,6 +19865,38 @@ Ids must begin with a lowercase letter.</source>
|
||||
<source>iOS tool Error %1</source>
|
||||
<translation>Ошибка %1 утилиты iOS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Application install on Simulator failed. %1</source>
|
||||
<translation>Не удалось установить приложение на эмулятор. %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Application install on Simulator failed. Simulator not running.</source>
|
||||
<translation>Не удалось установить приложение на эмулятор. Он не запущен.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Application launch on Simulator failed. Invalid Bundle path %1</source>
|
||||
<translation>Запуск приложения на эмуляторе не удался. Неверный путь пакета %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Spawning the Application process on Simulator failed.</source>
|
||||
<translation>Не удалось породить процесс приложения на эмуляторе.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Application launch on Simulator failed. Simulator not running.</source>
|
||||
<translation>Не удалось запустить приложение на эмуляторе. Он не запущен.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Application launch on Simulator failed. %1</source>
|
||||
<translation>Запуск приложения на эмуляторе не удался. %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Spawning the Application process on Simulator failed. Spawning timed out.</source>
|
||||
<translation>Не удалось породить процесс приложения на эмуляторе. Время порождения истекло.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Simulator application process error %1</source>
|
||||
<translation>Приложение из эмулятора вернуло ошибку %1</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>IosDeployStepWidget</name>
|
||||
@@ -21336,14 +21368,14 @@ Ids must begin with a lowercase letter.</source>
|
||||
<name>Nim::NimCompilerBuildStepFactory</name>
|
||||
<message>
|
||||
<source>Nim Compiler Build Step</source>
|
||||
<translation type="unfinished">Этап сборки компилятора Nim</translation>
|
||||
<translation>Этап сборки компилятора Nim</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Nim::NimCompilerCleanStep</name>
|
||||
<message>
|
||||
<source>Nim Clean Step</source>
|
||||
<translation type="unfinished">Этап очистки компилятора Nim</translation>
|
||||
<translation>Этап очистки компилятора Nim</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Build directory "%1" does not exist.</source>
|
||||
@@ -21432,28 +21464,28 @@ Ids must begin with a lowercase letter.</source>
|
||||
<name>NimCompilerBuildStep</name>
|
||||
<message>
|
||||
<source>Nim Compiler Build Step</source>
|
||||
<translation type="unfinished">Этап сборки компилятора Nim</translation>
|
||||
<translation>Этап сборки компилятора Nim</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>NimCompilerBuildStepConfigWidget</name>
|
||||
<message>
|
||||
<source>Nim build step</source>
|
||||
<translation type="unfinished">Этап сборки Nim</translation>
|
||||
<translation>Этап сборки Nim</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>NimCompilerCleanStepFactory</name>
|
||||
<message>
|
||||
<source>Nim Compiler Clean Step</source>
|
||||
<translation type="unfinished">Этап очистки компилятора Nim</translation>
|
||||
<translation>Этап очистки компилятора Nim</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>NimCompilerCleanStepWidget</name>
|
||||
<message>
|
||||
<source>Nim clean step</source>
|
||||
<translation type="unfinished">Этап очистки Nim</translation>
|
||||
<translation>Этап очистки Nim</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -36642,11 +36674,11 @@ In addition, Shift+Enter inserts an escape character at the cursor position and
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove the automatically inserted character if the trigger is deleted by backspace after the completion.</source>
|
||||
<translation type="unfinished">Удалять автоматически вставленный символ, если флаг удалён бекспейсом после дополнения.</translation>
|
||||
<translation>Удалять автоматически вставленный символ, если флаг удалён бекспейсом после дополнения.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove automatically inserted text on backspace</source>
|
||||
<translation type="unfinished">Удалять автоматически вставленный текст по бекспейсу</translation>
|
||||
<translation>Удалять автоматически вставленный текст по бекспейсу</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Documentation Comments</source>
|
||||
|
||||
@@ -66,9 +66,9 @@ Item {
|
||||
anchors.leftMargin: 18
|
||||
anchors.rightMargin: 20
|
||||
anchors.right: parent.right
|
||||
|
||||
text: examplesModel.searchString
|
||||
placeholderText: qsTr("Search in Examples...")
|
||||
onTextChanged: examplesModel.parseSearchString(text)
|
||||
onTextChanged: examplesModel.setSearchString(text)
|
||||
}
|
||||
|
||||
CustomizedGridView {
|
||||
|
||||
@@ -39,9 +39,9 @@ Item {
|
||||
anchors.rightMargin: 20
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 30
|
||||
|
||||
text: tutorialsModel.searchString
|
||||
placeholderText: qsTr("Search in Tutorials...")
|
||||
onTextChanged: tutorialsModel.parseSearchString(text)
|
||||
onTextChanged: tutorialsModel.setSearchString(text)
|
||||
}
|
||||
|
||||
CustomizedGridView {
|
||||
|
||||
@@ -1252,7 +1252,12 @@ bool Check::visit(BinaryExpression *ast)
|
||||
|
||||
bool Check::visit(Block *ast)
|
||||
{
|
||||
addMessage(ErrBlocksNotSupportedInQmlUi, locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation()));
|
||||
|
||||
bool isDirectInConnectionsScope =
|
||||
(!m_typeStack.isEmpty() && m_typeStack.last() == QLatin1String("Connections"));
|
||||
|
||||
if (!isDirectInConnectionsScope)
|
||||
addMessage(ErrBlocksNotSupportedInQmlUi, locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation()));
|
||||
|
||||
if (Node *p = parent()) {
|
||||
if (!cast<UiScriptBinding *>(p)
|
||||
|
||||
@@ -1300,7 +1300,7 @@ void ModelManagerInterface::updateCppQmlTypes(QFutureInterface<void> &interface,
|
||||
interface.setProgressValue(0);
|
||||
|
||||
CppDataHash newData;
|
||||
QHash<QString, QStringList> newDeclarations;
|
||||
QHash<QString, QList<CPlusPlus::Document::Ptr> > newDeclarations;
|
||||
{
|
||||
QMutexLocker locker(&qmlModelManager->m_cppDataMutex);
|
||||
newData = qmlModelManager->m_cppDataHash;
|
||||
@@ -1321,33 +1321,36 @@ void ModelManagerInterface::updateCppQmlTypes(QFutureInterface<void> &interface,
|
||||
const QString fileName = doc->fileName();
|
||||
if (!scan) {
|
||||
hasNewInfo = newData.remove(fileName) > 0 || hasNewInfo;
|
||||
foreach (const QString &file, newDeclarations[fileName]) {
|
||||
CPlusPlus::Document::Ptr doc = snapshot.document(file);
|
||||
if (doc.isNull())
|
||||
continue;
|
||||
finder(doc);
|
||||
hasNewInfo = rescanExports(file, finder, newData) || hasNewInfo;
|
||||
foreach (const CPlusPlus::Document::Ptr &savedDoc, newDeclarations.value(fileName)) {
|
||||
finder(savedDoc);
|
||||
hasNewInfo = rescanExports(savedDoc->fileName(), finder, newData) || hasNewInfo;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto it = newDeclarations.begin(), end = newDeclarations.end(); it != end;) {
|
||||
if (it->removeOne(fileName)) {
|
||||
doc->releaseSourceAndAST();
|
||||
if (it->isEmpty()) {
|
||||
it = newDeclarations.erase(it);
|
||||
continue;
|
||||
for (auto docIt = it->begin(), endDocIt = it->end(); docIt != endDocIt;) {
|
||||
CPlusPlus::Document::Ptr &savedDoc = *docIt;
|
||||
if (savedDoc->fileName() == fileName) {
|
||||
savedDoc->releaseSourceAndAST();
|
||||
it->erase(docIt);
|
||||
break;
|
||||
} else {
|
||||
++docIt;
|
||||
}
|
||||
}
|
||||
++it;
|
||||
if (it->isEmpty())
|
||||
it = newDeclarations.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
foreach (const QString &declarationFile, finder(doc)) {
|
||||
newDeclarations[declarationFile].append(fileName);
|
||||
newDeclarations[declarationFile].append(doc);
|
||||
doc->keepSourceAndAST(); // keep for later reparsing when dependent doc changes
|
||||
}
|
||||
|
||||
hasNewInfo = rescanExports(doc->fileName(), finder, newData) || hasNewInfo;
|
||||
hasNewInfo = rescanExports(fileName, finder, newData) || hasNewInfo;
|
||||
doc->releaseSourceAndAST();
|
||||
}
|
||||
|
||||
|
||||
@@ -275,7 +275,7 @@ private:
|
||||
QrcCache m_qrcCache;
|
||||
|
||||
CppDataHash m_cppDataHash;
|
||||
QHash<QString, QStringList> m_cppDeclarationFiles;
|
||||
QHash<QString, QList<CPlusPlus::Document::Ptr> > m_cppDeclarationFiles;
|
||||
mutable QMutex m_cppDataMutex;
|
||||
|
||||
// project integration
|
||||
|
||||
@@ -14,9 +14,9 @@ msvc {
|
||||
# Starting from Windows SDK 8, the headers and libs are under 'ProgramFiles (x86)'.
|
||||
# The libraries are under 'ProgramFiles'as well, so, check for existence of 'inc'.
|
||||
# 32bit qmake:
|
||||
!exists($$CDB_PATH):CDB_PATH="$$(ProgramFiles)/Windows Kits/8.0/Debuggers"
|
||||
!exists($$CDB_PATH):CDB_PATH="$$(ProgramFiles)/Windows Kits/8.1/Debuggers"
|
||||
!exists($$CDB_PATH):CDB_PATH="$$(ProgramFiles)/Windows Kits/10/Debuggers"
|
||||
!exists($$CDB_PATH/inc):CDB_PATH="$$(ProgramFiles)/Windows Kits/8.0/Debuggers"
|
||||
!exists($$CDB_PATH/inc):CDB_PATH="$$(ProgramFiles)/Windows Kits/8.1/Debuggers"
|
||||
!exists($$CDB_PATH/inc):CDB_PATH="$$(ProgramFiles)/Windows Kits/10/Debuggers"
|
||||
# 64bit qmake:
|
||||
!exists($$CDB_PATH/inc):CDB_PATH="$$(ProgramFiles) (x86)/Windows Kits/8.0/Debuggers"
|
||||
!exists($$CDB_PATH/inc):CDB_PATH="$$(ProgramFiles) (x86)/Windows Kits/8.1/Debuggers"
|
||||
|
||||
@@ -166,11 +166,11 @@ QVariant SftpFileSystemModel::data(const QModelIndex &index, int role) const
|
||||
switch (node->fileInfo.type) {
|
||||
case FileTypeRegular:
|
||||
case FileTypeOther:
|
||||
return QIcon(QLatin1String(":/core/images/unknownfile.png"));
|
||||
return QIcon(":/utils/images/unknownfile.png");
|
||||
case FileTypeDirectory:
|
||||
return QIcon(QLatin1String(":/core/images/dir.png"));
|
||||
return QIcon(":/utils/images/dir.png");
|
||||
case FileTypeUnknown:
|
||||
return QIcon(QLatin1String(":/core/images/help.png")); // Shows a question mark.
|
||||
return QIcon(":/utils/images/help.png"); // Shows a question mark.
|
||||
}
|
||||
}
|
||||
if (index.column() == 1) {
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QFuture>
|
||||
#include <QFutureInterface>
|
||||
#include <QFutureWatcher>
|
||||
#include <QRunnable>
|
||||
#include <QThread>
|
||||
#include <QThreadPool>
|
||||
@@ -493,4 +494,58 @@ runAsync(QThreadPool *pool, Function &&function, Args&&... args)
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Adds a handler for when a result is ready.
|
||||
This creates a new QFutureWatcher. Do not use if you intend to react on multiple conditions
|
||||
or create a QFutureWatcher already for other reasons.
|
||||
*/
|
||||
template <typename R, typename T>
|
||||
const QFuture<T> &onResultReady(const QFuture<T> &future, R *receiver, void(R::*member)(const T &))
|
||||
{
|
||||
auto watcher = new QFutureWatcher<T>();
|
||||
watcher->setFuture(future);
|
||||
QObject::connect(watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater);
|
||||
QObject::connect(watcher, &QFutureWatcherBase::resultReadyAt, receiver,
|
||||
[receiver, member, watcher](int index) {
|
||||
(receiver->*member)(watcher->future().resultAt(index));
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds a handler for when a result is ready. The guard object determines the lifetime of
|
||||
the connection.
|
||||
This creates a new QFutureWatcher. Do not use if you intend to react on multiple conditions
|
||||
or create a QFutureWatcher already for other reasons.
|
||||
*/
|
||||
template <typename T, typename Function>
|
||||
const QFuture<T> &onResultReady(const QFuture<T> &future, QObject *guard, Function f)
|
||||
{
|
||||
auto watcher = new QFutureWatcher<T>();
|
||||
watcher->setFuture(future);
|
||||
QObject::connect(watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater);
|
||||
QObject::connect(watcher, &QFutureWatcherBase::resultReadyAt, guard, [f, watcher](int index) {
|
||||
f(watcher->future().resultAt(index));
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds a handler for when a result is ready.
|
||||
This creates a new QFutureWatcher. Do not use if you intend to react on multiple conditions
|
||||
or create a QFutureWatcher already for other reasons.
|
||||
*/
|
||||
template <typename T, typename Function>
|
||||
const QFuture<T> &onResultReady(const QFuture<T> &future, Function f)
|
||||
{
|
||||
auto watcher = new QFutureWatcher<T>();
|
||||
watcher->setFuture(future);
|
||||
QObject::connect(watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater);
|
||||
QObject::connect(watcher, &QFutureWatcherBase::resultReadyAt, [f, watcher](int index) {
|
||||
f(watcher->future().resultAt(index));
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
} // Utils
|
||||
|
||||
@@ -149,9 +149,7 @@ public:
|
||||
PaletteShadow,
|
||||
|
||||
PaletteWindowDisabled,
|
||||
PaletteBackgroundDisabled,
|
||||
PaletteWindowTextDisabled,
|
||||
PaletteForegroundDisabled,
|
||||
PaletteBaseDisabled,
|
||||
PaletteAlternateBaseDisabled,
|
||||
PaletteToolTipBaseDisabled,
|
||||
@@ -299,18 +297,9 @@ public:
|
||||
|
||||
enum Gradient {
|
||||
DetailsWidgetHeaderGradient,
|
||||
Welcome_Button_GradientNormal,
|
||||
Welcome_Button_GradientPressed
|
||||
};
|
||||
|
||||
enum ImageFile {
|
||||
ProjectExplorerHeader,
|
||||
ProjectExplorerSource,
|
||||
ProjectExplorerForm,
|
||||
ProjectExplorerResource,
|
||||
ProjectExplorerQML,
|
||||
ProjectExplorerOtherFiles,
|
||||
ProjectFileIcon,
|
||||
IconOverlayCSource,
|
||||
IconOverlayCppHeader,
|
||||
IconOverlayCppSource,
|
||||
|
||||
@@ -507,9 +507,12 @@ FileName AndroidConfig::toolPath(const Abi &abi, const QString &ndkToolChainVers
|
||||
.arg(toolsPrefix(abi)));
|
||||
}
|
||||
|
||||
FileName AndroidConfig::gccPath(const Abi &abi, const QString &ndkToolChainVersion) const
|
||||
FileName AndroidConfig::gccPath(const Abi &abi, ToolChain::Language lang,
|
||||
const QString &ndkToolChainVersion) const
|
||||
{
|
||||
return toolPath(abi, ndkToolChainVersion).appendString(QLatin1String("-gcc" QTC_HOST_EXE_SUFFIX));
|
||||
const QString tool
|
||||
= HostOsInfo::withExecutableSuffix(QString::fromLatin1(lang == ToolChain::Language::C ? "-gcc" : "-g++"));
|
||||
return toolPath(abi, ndkToolChainVersion).appendString(tool);
|
||||
}
|
||||
|
||||
FileName AndroidConfig::gdbPath(const Abi &abi, const QString &ndkToolChainVersion) const
|
||||
@@ -1198,24 +1201,32 @@ QString AndroidConfigurations::defaultDevice(Project *project, const QString &ab
|
||||
return map.value(abi);
|
||||
}
|
||||
|
||||
static bool equalKits(Kit *a, Kit *b)
|
||||
static bool matchToolChain(const ToolChain *atc, const ToolChain *btc)
|
||||
{
|
||||
if (atc == btc)
|
||||
return true;
|
||||
|
||||
if (!atc || !btc)
|
||||
return false;
|
||||
|
||||
if (atc->typeId() != Constants::ANDROID_TOOLCHAIN_ID || btc->typeId() != Constants::ANDROID_TOOLCHAIN_ID)
|
||||
return false;
|
||||
|
||||
auto aatc = static_cast<const AndroidToolChain *>(atc);
|
||||
auto abtc = static_cast<const AndroidToolChain *>(btc);
|
||||
return aatc->ndkToolChainVersion() == abtc->ndkToolChainVersion()
|
||||
&& aatc->targetAbi() == abtc->targetAbi();
|
||||
}
|
||||
|
||||
static bool matchKits(const Kit *a, const Kit *b)
|
||||
{
|
||||
if (QtSupport::QtKitInformation::qtVersion(a) != QtSupport::QtKitInformation::qtVersion(b))
|
||||
return false;
|
||||
ToolChain *atc = ToolChainKitInformation::toolChain(a, ToolChain::Language::Cxx);
|
||||
ToolChain *btc = ToolChainKitInformation::toolChain(b, ToolChain::Language::Cxx);
|
||||
if (atc == btc)
|
||||
return true;
|
||||
if (!atc || atc->typeId() != Constants::ANDROID_TOOLCHAIN_ID)
|
||||
return false;
|
||||
if (!btc || btc->typeId() != Constants::ANDROID_TOOLCHAIN_ID)
|
||||
return false;
|
||||
AndroidToolChain *aatc = static_cast<AndroidToolChain *>(atc);
|
||||
AndroidToolChain *bbtc = static_cast<AndroidToolChain *>(btc);
|
||||
if (aatc->ndkToolChainVersion() == bbtc->ndkToolChainVersion()
|
||||
&& aatc->targetAbi() == bbtc->targetAbi())
|
||||
return true;
|
||||
return false;
|
||||
|
||||
return matchToolChain(ToolChainKitInformation::toolChain(a, ToolChain::Language::Cxx),
|
||||
ToolChainKitInformation::toolChain(b, ToolChain::Language::Cxx))
|
||||
&& matchToolChain(ToolChainKitInformation::toolChain(a, ToolChain::Language::C),
|
||||
ToolChainKitInformation::toolChain(b, ToolChain::Language::C));
|
||||
}
|
||||
|
||||
void AndroidConfigurations::registerNewToolChains()
|
||||
@@ -1243,32 +1254,13 @@ void AndroidConfigurations::removeOldToolChains()
|
||||
|
||||
void AndroidConfigurations::updateAutomaticKitList()
|
||||
{
|
||||
QList<AndroidToolChain *> toolchains;
|
||||
if (AndroidConfigurations::currentConfig().automaticKitCreation()) {
|
||||
// having a empty toolchains list will remove all autodetected kits for android
|
||||
// exactly what we want in that case
|
||||
foreach (ToolChain *tc, ToolChainManager::toolChains()) {
|
||||
if (!tc->isAutoDetected())
|
||||
continue;
|
||||
if (tc->typeId() != Constants::ANDROID_TOOLCHAIN_ID)
|
||||
continue;
|
||||
if (!tc->isValid()) // going to be deleted
|
||||
continue;
|
||||
toolchains << static_cast<AndroidToolChain *>(tc);
|
||||
}
|
||||
}
|
||||
const QList<Kit *> existingKits = Utils::filtered(KitManager::kits(), [](const Kit *k) {
|
||||
return k->isAutoDetected() && !k->isSdkProvided()
|
||||
&& DeviceTypeKitInformation::deviceTypeId(k) == Core::Id(Constants::ANDROID_DEVICE_TYPE);
|
||||
});
|
||||
|
||||
QList<Kit *> existingKits;
|
||||
|
||||
foreach (Kit *k, KitManager::kits()) {
|
||||
if (DeviceTypeKitInformation::deviceTypeId(k) != Core::Id(Constants::ANDROID_DEVICE_TYPE))
|
||||
continue;
|
||||
if (!k->isAutoDetected())
|
||||
continue;
|
||||
if (k->isSdkProvided())
|
||||
continue;
|
||||
|
||||
// Update code for 3.0 beta, which shipped with a bug for the debugger settings
|
||||
// Update code for 3.0 beta, which shipped with a bug for the debugger settings
|
||||
for (Kit *k : existingKits) {
|
||||
ToolChain *tc = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx);
|
||||
if (tc && Debugger::DebuggerKitInformation::runnable(k).executable != tc->suggestedDebugger().toString()) {
|
||||
Debugger::DebuggerItem debugger;
|
||||
@@ -1281,14 +1273,15 @@ void AndroidConfigurations::updateAutomaticKitList()
|
||||
QVariant id = Debugger::DebuggerItemManager::registerDebugger(debugger);
|
||||
Debugger::DebuggerKitInformation::setDebugger(k, id);
|
||||
}
|
||||
existingKits << k;
|
||||
}
|
||||
|
||||
QHash<Abi, QList<QtSupport::BaseQtVersion *> > qtVersionsForArch;
|
||||
foreach (QtSupport::BaseQtVersion *qtVersion, QtSupport::QtVersionManager::unsortedVersions()) {
|
||||
if (qtVersion->type() != QLatin1String(Constants::ANDROIDQT))
|
||||
continue;
|
||||
QList<Abi> qtAbis = qtVersion->qtAbis();
|
||||
QHash<Abi, QList<const QtSupport::BaseQtVersion *> > qtVersionsForArch;
|
||||
const QList<QtSupport::BaseQtVersion *> qtVersions
|
||||
= Utils::filtered(QtSupport::QtVersionManager::unsortedVersions(), [](const QtSupport::BaseQtVersion *v) {
|
||||
return v->type() == Constants::ANDROIDQT;
|
||||
});
|
||||
for (const QtSupport::BaseQtVersion *qtVersion : qtVersions) {
|
||||
const QList<Abi> qtAbis = qtVersion->qtAbis();
|
||||
if (qtAbis.empty())
|
||||
continue;
|
||||
qtVersionsForArch[qtAbis.first()].append(qtVersion);
|
||||
@@ -1298,22 +1291,36 @@ void AndroidConfigurations::updateAutomaticKitList()
|
||||
IDevice::ConstPtr device = dm->find(Core::Id(Constants::ANDROID_DEVICE_ID));
|
||||
if (device.isNull()) {
|
||||
// no device, means no sdk path
|
||||
foreach (Kit *k, existingKits)
|
||||
for (Kit *k : existingKits)
|
||||
KitManager::deregisterKit(k);
|
||||
return;
|
||||
}
|
||||
|
||||
// register new kits
|
||||
QList<Kit *> newKits;
|
||||
foreach (AndroidToolChain *tc, toolchains) {
|
||||
if (tc->isSecondaryToolChain())
|
||||
const QList<ToolChain *> tmp = Utils::filtered(ToolChainManager::toolChains(), [](ToolChain *tc) {
|
||||
return tc->isAutoDetected()
|
||||
&& tc->isValid()
|
||||
&& tc->typeId() == Constants::ANDROID_TOOLCHAIN_ID
|
||||
&& !static_cast<AndroidToolChain *>(tc)->isSecondaryToolChain();
|
||||
});
|
||||
const QList<AndroidToolChain *> toolchains = Utils::transform(tmp, [](ToolChain *tc) {
|
||||
return static_cast<AndroidToolChain *>(tc);
|
||||
});
|
||||
for (AndroidToolChain *tc : toolchains) {
|
||||
if (tc->isSecondaryToolChain() || tc->language() != ToolChain::Language::Cxx)
|
||||
continue;
|
||||
QList<QtSupport::BaseQtVersion *> qtVersions = qtVersionsForArch.value(tc->targetAbi());
|
||||
foreach (QtSupport::BaseQtVersion *qt, qtVersions) {
|
||||
const QList<AndroidToolChain *> allLanguages = Utils::filtered(toolchains,
|
||||
[tc](AndroidToolChain *otherTc) {
|
||||
return tc->targetAbi() == otherTc->targetAbi();
|
||||
});
|
||||
for (const QtSupport::BaseQtVersion *qt : qtVersionsForArch.value(tc->targetAbi())) {
|
||||
Kit *newKit = new Kit;
|
||||
newKit->setAutoDetected(true);
|
||||
newKit->setAutoDetectionSource("AndroidConfiguration");
|
||||
DeviceTypeKitInformation::setDeviceTypeId(newKit, Core::Id(Constants::ANDROID_DEVICE_TYPE));
|
||||
ToolChainKitInformation::setToolChain(newKit, tc);
|
||||
for (AndroidToolChain *tc : allLanguages)
|
||||
ToolChainKitInformation::setToolChain(newKit, tc);
|
||||
QtSupport::QtKitInformation::setQtVersion(newKit, qt);
|
||||
DeviceKitInformation::setDevice(newKit, device);
|
||||
|
||||
@@ -1329,48 +1336,25 @@ void AndroidConfigurations::updateAutomaticKitList()
|
||||
|
||||
AndroidGdbServerKitInformation::setGdbSever(newKit, tc->suggestedGdbServer());
|
||||
newKit->makeSticky();
|
||||
newKit->setUnexpandedDisplayName(tr("Android for %1 (GCC %2, Qt %3)")
|
||||
.arg(static_cast<const AndroidQtVersion *>(qt)->targetArch())
|
||||
.arg(tc->ndkToolChainVersion())
|
||||
.arg(qt->qtVersionString()));
|
||||
newKits << newKit;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = existingKits.count() - 1; i >= 0; --i) {
|
||||
Kit *existingKit = existingKits.at(i);
|
||||
for (int j = 0; j < newKits.count(); ++j) {
|
||||
Kit *newKit = newKits.at(j);
|
||||
if (equalKits(existingKit, newKit)) {
|
||||
// Kit is already registered, nothing to do
|
||||
newKits.removeAt(j);
|
||||
existingKits.at(i)->makeSticky();
|
||||
existingKits.removeAt(i);
|
||||
ToolChainKitInformation::setToolChain(existingKit, ToolChainKitInformation::toolChain(newKit, ToolChain::Language::Cxx));
|
||||
KitManager::deleteKit(newKit);
|
||||
j = newKits.count();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Kit *k, existingKits) {
|
||||
ToolChain *tc = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx);
|
||||
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k);
|
||||
if (tc && tc->typeId() == Constants::ANDROID_TOOLCHAIN_ID
|
||||
&& tc->isValid()
|
||||
&& qtVersion && qtVersion->type() == QLatin1String(Constants::ANDROIDQT)) {
|
||||
k->makeUnSticky();
|
||||
k->setAutoDetected(false);
|
||||
QSet<const Kit *> rediscoveredExistingKits;
|
||||
for (Kit *newKit : newKits) {
|
||||
Kit *existingKit = Utils::findOrDefault(existingKits, [newKit](const Kit *k) { return matchKits(newKit, k); });
|
||||
if (existingKit) {
|
||||
existingKit->copyFrom(newKit);
|
||||
KitManager::deleteKit(newKit);
|
||||
rediscoveredExistingKits.insert(existingKit);
|
||||
} else {
|
||||
KitManager::deregisterKit(k);
|
||||
KitManager::registerKit(newKit);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Kit *kit, newKits) {
|
||||
AndroidToolChain *tc = static_cast<AndroidToolChain *>(ToolChainKitInformation::toolChain(kit, ToolChain::Language::Cxx));
|
||||
AndroidQtVersion *qt = static_cast<AndroidQtVersion *>(QtSupport::QtKitInformation::qtVersion(kit));
|
||||
kit->setUnexpandedDisplayName(tr("Android for %1 (GCC %2, Qt %3)")
|
||||
.arg(qt->targetArch())
|
||||
.arg(tc->ndkToolChainVersion())
|
||||
.arg(qt->qtVersionString()));
|
||||
KitManager::registerKit(kit);
|
||||
}
|
||||
}
|
||||
|
||||
bool AndroidConfigurations::force32bitEmulator()
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "android_global.h"
|
||||
|
||||
#include <projectexplorer/toolchain.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
@@ -126,7 +128,9 @@ public:
|
||||
Utils::FileName emulatorToolPath() const;
|
||||
|
||||
|
||||
Utils::FileName gccPath(const ProjectExplorer::Abi &abi, const QString &ndkToolChainVersion) const;
|
||||
Utils::FileName gccPath(const ProjectExplorer::Abi &abi,
|
||||
ProjectExplorer::ToolChain::Language lang,
|
||||
const QString &ndkToolChainVersion) const;
|
||||
Utils::FileName gdbPath(const ProjectExplorer::Abi &abi, const QString &ndkToolChainVersion) const;
|
||||
|
||||
Utils::FileName keytoolPath() const;
|
||||
|
||||
@@ -314,6 +314,8 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
|
||||
// Check for a gdb with a broken python
|
||||
QStringList gdbPaths;
|
||||
foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths) {
|
||||
if (ati.language == ProjectExplorer::ToolChain::Language::C)
|
||||
continue;
|
||||
// we only check the arm gdbs, that's indicative enough
|
||||
if (ati.abi.architecture() != ProjectExplorer::Abi::ArmArchitecture)
|
||||
continue;
|
||||
@@ -329,8 +331,10 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
|
||||
|
||||
// See if we have qt versions for those toolchains
|
||||
QSet<ProjectExplorer::Abi> toolchainsForAbi;
|
||||
foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths)
|
||||
toolchainsForAbi.insert(ati.abi);
|
||||
foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths) {
|
||||
if (ati.language == ProjectExplorer::ToolChain::Language::Cxx)
|
||||
toolchainsForAbi.insert(ati.abi);
|
||||
}
|
||||
|
||||
QSet<ProjectExplorer::Abi> qtVersionsForAbi;
|
||||
foreach (QtSupport::BaseQtVersion *qtVersion, QtSupport::QtVersionManager::unsortedVersions()) {
|
||||
@@ -496,16 +500,6 @@ void AndroidSettingsWidget::saveSettings()
|
||||
AndroidConfigurations::setConfig(m_androidConfig);
|
||||
}
|
||||
|
||||
int indexOf(const QList<AndroidToolChainFactory::AndroidToolChainInformation> &list, const Utils::FileName &f)
|
||||
{
|
||||
int end = list.count();
|
||||
for (int i = 0; i < end; ++i) {
|
||||
if (list.at(i).compilerCommand == f)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::sdkLocationEditingFinished()
|
||||
{
|
||||
m_androidConfig.setSdkLocation(Utils::FileName::fromUserInput(m_ui->SDKLocationPathChooser->rawPath()));
|
||||
|
||||
@@ -302,16 +302,17 @@ QList<AndroidToolChainFactory::AndroidToolChainInformation> AndroidToolChainFact
|
||||
int idx = versionRegExp.indexIn(fileName);
|
||||
if (idx == -1)
|
||||
continue;
|
||||
AndroidToolChainInformation ati;
|
||||
ati.version = fileName.mid(idx + 1);
|
||||
QString platform = fileName.left(idx);
|
||||
ati.abi = AndroidConfig::abiForToolChainPrefix(platform);
|
||||
if (ati.abi.architecture() == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
|
||||
continue;
|
||||
// AndroidToolChain *tc = new AndroidToolChain(arch, version, true);
|
||||
ati.compilerCommand = AndroidConfigurations::currentConfig().gccPath(ati.abi, ati.version);
|
||||
// tc->setCompilerCommand(compilerPath);
|
||||
result.append(ati);
|
||||
for (const ToolChain::Language lang : { ToolChain::Language::Cxx, ToolChain::Language::C }) {
|
||||
AndroidToolChainInformation ati;
|
||||
ati.language = lang;
|
||||
ati.version = fileName.mid(idx + 1);
|
||||
QString platform = fileName.left(idx);
|
||||
ati.abi = AndroidConfig::abiForToolChainPrefix(platform);
|
||||
if (ati.abi.architecture() == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
|
||||
continue;
|
||||
ati.compilerCommand = AndroidConfigurations::currentConfig().gccPath(ati.abi, lang, ati.version);
|
||||
result.append(ati);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -353,19 +354,22 @@ bool AndroidToolChainFactory::versionCompareLess(const QList<int> &a, const QLis
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AndroidToolChainFactory::versionCompareLess(AndroidToolChain *atc, AndroidToolChain *btc)
|
||||
bool AndroidToolChainFactory::versionCompareLess(QList<AndroidToolChain *> atc,
|
||||
QList<AndroidToolChain *> btc)
|
||||
{
|
||||
QList<int> a = versionNumberFromString(atc->ndkToolChainVersion());
|
||||
QList<int> b = versionNumberFromString(btc->ndkToolChainVersion());
|
||||
const QList<int> a = versionNumberFromString(atc.at(0)->ndkToolChainVersion());
|
||||
const QList<int> b = versionNumberFromString(btc.at(0)->ndkToolChainVersion());
|
||||
|
||||
return versionCompareLess(a, b);
|
||||
}
|
||||
|
||||
static AndroidToolChain *findToolChain(Utils::FileName &compilerPath, const QList<ToolChain *> &alreadyKnown)
|
||||
static AndroidToolChain *findToolChain(Utils::FileName &compilerPath, ToolChain::Language lang,
|
||||
const QList<ToolChain *> &alreadyKnown)
|
||||
{
|
||||
return static_cast<AndroidToolChain *>(
|
||||
Utils::findOrDefault(alreadyKnown, [compilerPath](ToolChain *tc) {
|
||||
Utils::findOrDefault(alreadyKnown, [compilerPath, lang](ToolChain *tc) {
|
||||
return tc->typeId() == Constants::ANDROID_TOOLCHAIN_ID
|
||||
&& tc->language() == lang
|
||||
&& tc->compilerCommand() == compilerPath;
|
||||
}));
|
||||
}
|
||||
@@ -382,7 +386,7 @@ AndroidToolChainFactory::autodetectToolChainsForNdk(const FileName &ndkPath,
|
||||
FileName path = ndkPath;
|
||||
QDirIterator it(path.appendPath(QLatin1String("toolchains")).toString(),
|
||||
QStringList() << QLatin1String("*"), QDir::Dirs);
|
||||
QHash<Abi, AndroidToolChain *> newestToolChainForArch;
|
||||
QHash<Abi, QList<AndroidToolChain *>> newestToolChainForArch;
|
||||
|
||||
while (it.hasNext()) {
|
||||
const QString &fileName = FileName::fromString(it.next()).fileName();
|
||||
@@ -394,26 +398,30 @@ AndroidToolChainFactory::autodetectToolChainsForNdk(const FileName &ndkPath,
|
||||
Abi abi = AndroidConfig::abiForToolChainPrefix(platform);
|
||||
if (abi.architecture() == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
|
||||
continue;
|
||||
FileName compilerPath = AndroidConfigurations::currentConfig().gccPath(abi, version);
|
||||
QList<AndroidToolChain *> toolChainBundle;
|
||||
for (ToolChain::Language lang : { ToolChain::Language::Cxx, ToolChain::Language::C }) {
|
||||
FileName compilerPath = AndroidConfigurations::currentConfig().gccPath(abi, lang, version);
|
||||
|
||||
AndroidToolChain *tc = findToolChain(compilerPath, alreadyKnown);
|
||||
if (!tc) {
|
||||
tc = new AndroidToolChain(abi, version, ToolChain::Language::Cxx,
|
||||
ToolChain::AutoDetection);
|
||||
tc->resetToolChain(compilerPath);
|
||||
AndroidToolChain *tc = findToolChain(compilerPath, lang, alreadyKnown);
|
||||
if (!tc) {
|
||||
tc = new AndroidToolChain(abi, version, lang,
|
||||
ToolChain::AutoDetection);
|
||||
tc->resetToolChain(compilerPath);
|
||||
}
|
||||
result.append(tc);
|
||||
toolChainBundle.append(tc);
|
||||
}
|
||||
result.append(tc);
|
||||
|
||||
auto it = newestToolChainForArch.constFind(abi);
|
||||
if (it == newestToolChainForArch.constEnd())
|
||||
newestToolChainForArch.insert(abi, tc);
|
||||
else if (versionCompareLess(it.value(), tc))
|
||||
newestToolChainForArch[abi] = tc;
|
||||
newestToolChainForArch.insert(abi, toolChainBundle);
|
||||
else if (versionCompareLess(it.value(), toolChainBundle))
|
||||
newestToolChainForArch[abi] = toolChainBundle;
|
||||
}
|
||||
|
||||
foreach (ToolChain *tc, result) {
|
||||
AndroidToolChain *atc = static_cast<AndroidToolChain *>(tc);
|
||||
atc->setSecondaryToolChain(newestToolChainForArch.value(atc->targetAbi()) != atc);
|
||||
atc->setSecondaryToolChain(!newestToolChainForArch.value(atc->targetAbi()).contains(atc));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -104,6 +104,7 @@ public:
|
||||
class AndroidToolChainInformation
|
||||
{
|
||||
public:
|
||||
ProjectExplorer::ToolChain::Language language;
|
||||
Utils::FileName compilerCommand;
|
||||
ProjectExplorer::Abi abi;
|
||||
QString version;
|
||||
@@ -116,7 +117,8 @@ public:
|
||||
|
||||
static QList<int> versionNumberFromString(const QString &version);
|
||||
static bool versionCompareLess(const QList<int> &a, const QList<int> &b);
|
||||
static bool versionCompareLess(AndroidToolChain *atc, AndroidToolChain *btc);
|
||||
static bool versionCompareLess(QList<AndroidToolChain *> atc,
|
||||
QList<AndroidToolChain *> btc);
|
||||
static QList<int> newestToolChainVersionForArch(const ProjectExplorer::Abi &abi);
|
||||
private:
|
||||
static QHash<ProjectExplorer::Abi, QList<int> > m_newestVersionForAbi;
|
||||
|
||||
@@ -129,6 +129,8 @@ void AppManagerProject::populateProject()
|
||||
foreach (ProjectExplorer::Target *target, targets())
|
||||
targetUpdateDeployableFiles(target, files);
|
||||
}
|
||||
|
||||
emit parsingFinished();
|
||||
}
|
||||
|
||||
void AppManagerProject::recursiveScanDirectory(const QDir &dir, QSet<QString> &container)
|
||||
|
||||
@@ -231,6 +231,8 @@ void AutotoolsProject::makefileParsingFinished()
|
||||
|
||||
m_makefileParserThread->deleteLater();
|
||||
m_makefileParserThread = 0;
|
||||
|
||||
emit parsingFinished();
|
||||
}
|
||||
|
||||
void AutotoolsProject::onFileChanged(const QString &file)
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "clangstaticanalyzertool.h"
|
||||
#include "clangstaticanalyzerutils.h"
|
||||
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
#include <cpptools/projectinfo.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/kitmanager.h>
|
||||
@@ -44,6 +43,7 @@
|
||||
#include <QSignalSpy>
|
||||
#include <QTimer>
|
||||
#include <QtTest>
|
||||
#include <QVariant>
|
||||
|
||||
#include <functional>
|
||||
|
||||
@@ -66,6 +66,35 @@ static bool processEventsUntil(const std::function<bool()> condition, int timeOu
|
||||
}
|
||||
}
|
||||
|
||||
class WaitForParsedProjects : public QObject
|
||||
{
|
||||
public:
|
||||
WaitForParsedProjects(ProjectExplorer::SessionManager &sessionManager,
|
||||
const QStringList &projects)
|
||||
: m_sessionManager(sessionManager)
|
||||
, m_projectsToWaitFor(projects)
|
||||
{
|
||||
connect(&m_sessionManager, &ProjectExplorer::SessionManager::projectFinishedParsing,
|
||||
this, &WaitForParsedProjects::onProjectFinishedParsing);
|
||||
}
|
||||
|
||||
void onProjectFinishedParsing(ProjectExplorer::Project *project)
|
||||
{
|
||||
m_projectsToWaitFor.removeOne(project->projectFilePath().toString());
|
||||
}
|
||||
|
||||
bool wait()
|
||||
{
|
||||
return processEventsUntil([this]() {
|
||||
return m_projectsToWaitFor.isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
ProjectExplorer::SessionManager &m_sessionManager;
|
||||
QStringList m_projectsToWaitFor;
|
||||
};
|
||||
|
||||
namespace ClangStaticAnalyzer {
|
||||
namespace Internal {
|
||||
|
||||
@@ -84,16 +113,14 @@ void ClangStaticAnalyzerPreconfiguredSessionTests::initTestCase()
|
||||
if (!m_sessionManager.sessions().contains(preconfiguredSessionName))
|
||||
QSKIP("Manually preconfigured session 'ClangStaticAnalyzerPreconfiguredSession' needed.");
|
||||
|
||||
// Load session
|
||||
if (m_sessionManager.activeSession() != preconfiguredSessionName)
|
||||
QVERIFY(m_sessionManager.loadSession(preconfiguredSessionName));
|
||||
if (m_sessionManager.activeSession() == preconfiguredSessionName)
|
||||
QSKIP("Session must not be already active.");
|
||||
|
||||
// Wait until all projects are loaded.
|
||||
const int sessionManagerProjects = m_sessionManager.projects().size();
|
||||
const auto allProjectsLoaded = [sessionManagerProjects]() {
|
||||
return CppModelManager::instance()->projectInfos().size() == sessionManagerProjects;
|
||||
};
|
||||
QVERIFY(processEventsUntil(allProjectsLoaded));
|
||||
// Load session
|
||||
const QStringList projects = m_sessionManager.projectsForSessionName(preconfiguredSessionName);
|
||||
WaitForParsedProjects waitForParsedProjects(m_sessionManager, projects);
|
||||
QVERIFY(m_sessionManager.loadSession(preconfiguredSessionName));
|
||||
QVERIFY(waitForParsedProjects.wait());
|
||||
}
|
||||
|
||||
void ClangStaticAnalyzerPreconfiguredSessionTests::testPreconfiguredSession()
|
||||
@@ -201,15 +228,15 @@ bool ClangStaticAnalyzerPreconfiguredSessionTests::switchToProjectAndTarget(Proj
|
||||
m_sessionManager.setStartupProject(project);
|
||||
|
||||
if (target != project->activeTarget()) {
|
||||
QSignalSpy waitUntilProjectUpdated(CppModelManager::instance(),
|
||||
&CppModelManager::projectPartsUpdated);
|
||||
QSignalSpy spyFinishedParsing(ProjectExplorer::SessionManager::instance(),
|
||||
&ProjectExplorer::SessionManager::projectFinishedParsing);
|
||||
m_sessionManager.setActiveTarget(project, target, ProjectExplorer::SetActive::NoCascade);
|
||||
QTC_ASSERT(spyFinishedParsing.wait(30000), return false);
|
||||
|
||||
const bool waitResult = waitUntilProjectUpdated.wait(30000);
|
||||
if (!waitResult) {
|
||||
qWarning() << "waitUntilProjectUpdated() failed";
|
||||
return false;
|
||||
}
|
||||
const QVariant projectArgument = spyFinishedParsing.takeFirst().takeFirst();
|
||||
QTC_ASSERT(projectArgument.canConvert<ProjectExplorer::Project *>(), return false);
|
||||
|
||||
return projectArgument.value<ProjectExplorer::Project *>() == project;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -145,6 +145,8 @@ void CMakeProject::updateProjectData()
|
||||
emit fileListChanged();
|
||||
|
||||
emit cmakeBc->emitBuildTypeChanged();
|
||||
|
||||
emit parsingFinished();
|
||||
}
|
||||
|
||||
void CMakeProject::updateQmlJSCodeModel()
|
||||
|
||||
@@ -44,17 +44,12 @@ ConfigModel::ConfigModel(QObject *parent) : QAbstractTableModel(parent)
|
||||
|
||||
int ConfigModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
QTC_ASSERT(parent.model() == nullptr || parent.model() == this, return 0);
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
return m_configuration.count();
|
||||
return parent.isValid() ? 0 : m_configuration.count();
|
||||
}
|
||||
|
||||
int ConfigModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
QTC_ASSERT(!parent.isValid(), return 0);
|
||||
QTC_ASSERT(parent.model() == nullptr, return 0);
|
||||
return 3;
|
||||
return parent.isValid() ? 0 : 3;
|
||||
}
|
||||
|
||||
Qt::ItemFlags ConfigModel::flags(const QModelIndex &index) const
|
||||
|
||||
@@ -340,9 +340,8 @@ QIcon ManhattanStyle::standardIcon(StandardPixmap standardIcon, const QStyleOpti
|
||||
if (standardIcon == QStyle::SP_ComputerIcon) {
|
||||
// Ubuntu has in some versions a 16x16 icon, see QTCREATORBUG-12832
|
||||
const QList<QSize> &sizes = icon.availableSizes();
|
||||
if (Utils::allOf(sizes, [](const QSize &size) { return size.width() < 32;})) {
|
||||
icon = QIcon(QLatin1String(":/core/images/Desktop.png"));
|
||||
}
|
||||
if (Utils::allOf(sizes, [](const QSize &size) { return size.width() < 32;}))
|
||||
icon = QIcon(":/utils/images/Desktop.png");
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
<string>?</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="core.qrc">
|
||||
<normaloff>:/core/images/help.png</normaloff>:/core/images/help.png</iconset>
|
||||
<iconset resource="../../libs/utils/utils.qrc">
|
||||
<normaloff>:/utils/images/help.png</normaloff>:/utils/images/help.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -390,7 +390,7 @@
|
||||
<tabstop>bigFilesLimitSpinBox</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="core.qrc"/>
|
||||
<include location="../../libs/utils/utils.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
@@ -771,6 +771,66 @@ void CppEditorPlugin::test_quickfix_data()
|
||||
"}\n"
|
||||
);
|
||||
|
||||
// Checks: No special treatment for reference to non const.
|
||||
QTest::newRow("GenerateGetterSetter_referenceToNonConst")
|
||||
<< CppQuickFixFactoryPtr(new GenerateGetterSetter) << _(
|
||||
"\n"
|
||||
"class Something\n"
|
||||
"{\n"
|
||||
" int &it@;\n"
|
||||
"};\n"
|
||||
) << _(
|
||||
"\n"
|
||||
"class Something\n"
|
||||
"{\n"
|
||||
" int ⁢\n"
|
||||
"\n"
|
||||
"public:\n"
|
||||
" int &getIt() const;\n"
|
||||
" void setIt(const int &value);\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"int &Something::getIt() const\n"
|
||||
"{\n"
|
||||
" return it;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void Something::setIt(const int &value)\n"
|
||||
"{\n"
|
||||
" it = value;\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
// Checks: No special treatment for reference to const.
|
||||
QTest::newRow("GenerateGetterSetter_referenceToConst")
|
||||
<< CppQuickFixFactoryPtr(new GenerateGetterSetter) << _(
|
||||
"\n"
|
||||
"class Something\n"
|
||||
"{\n"
|
||||
" const int &it@;\n"
|
||||
"};\n"
|
||||
) << _(
|
||||
"\n"
|
||||
"class Something\n"
|
||||
"{\n"
|
||||
" const int ⁢\n"
|
||||
"\n"
|
||||
"public:\n"
|
||||
" const int &getIt() const;\n"
|
||||
" void setIt(const int &value);\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"const int &Something::getIt() const\n"
|
||||
"{\n"
|
||||
" return it;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void Something::setIt(const int &value)\n"
|
||||
"{\n"
|
||||
" it = value;\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
// Checks:
|
||||
// 1. Setter: Setter is a static function.
|
||||
// 2. Getter: Getter is a static, non const function.
|
||||
|
||||
@@ -3018,10 +3018,12 @@ public:
|
||||
if (passByValue) {
|
||||
paramString = oo.prettyType(fullySpecifiedType, paramName);
|
||||
} else {
|
||||
FullySpecifiedType constParamType(fullySpecifiedType);
|
||||
const ReferenceType *refType = type->asReferenceType();
|
||||
FullySpecifiedType constParamType(refType ? refType->elementType()
|
||||
: fullySpecifiedType);
|
||||
constParamType.setConst(true);
|
||||
QScopedPointer<ReferenceType> referenceType(new ReferenceType(constParamType, false));
|
||||
FullySpecifiedType referenceToConstParamType(referenceType.data());
|
||||
const FullySpecifiedType referenceToConstParamType(referenceType.data());
|
||||
paramString = oo.prettyType(referenceToConstParamType, paramName);
|
||||
}
|
||||
|
||||
|
||||
@@ -286,6 +286,7 @@ void GenericProject::refresh(RefreshOptions options)
|
||||
}
|
||||
|
||||
refreshCppCodeModel();
|
||||
emit parsingFinished();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -102,8 +102,10 @@ void IosAnalyzeSupport::handleRemoteOutput(const QString &output)
|
||||
|
||||
void IosAnalyzeSupport::handleRemoteErrorOutput(const QString &output)
|
||||
{
|
||||
if (m_runControl)
|
||||
if (m_runControl) {
|
||||
m_runControl->appendMessage(output, Utils::StdErrFormat);
|
||||
m_outputParser.processOutput(output);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -64,6 +64,16 @@ static bool checkForTimeout(const std::chrono::time_point< std::chrono::high_res
|
||||
return timedOut;
|
||||
}
|
||||
|
||||
static QByteArray runSimCtlCommand(QStringList args)
|
||||
{
|
||||
QProcess simCtlProcess;
|
||||
args.prepend(QStringLiteral("simctl"));
|
||||
simCtlProcess.start(QStringLiteral("xcrun"), args, QProcess::ReadOnly);
|
||||
if (!simCtlProcess.waitForFinished())
|
||||
qCDebug(simulatorLog) << "simctl command failed." << simCtlProcess.errorString();
|
||||
return simCtlProcess.readAll();
|
||||
}
|
||||
|
||||
class SimulatorControlPrivate :QObject {
|
||||
Q_OBJECT
|
||||
private:
|
||||
@@ -79,7 +89,6 @@ private:
|
||||
|
||||
SimulatorControlPrivate(QObject *parent = nullptr);
|
||||
~SimulatorControlPrivate();
|
||||
QByteArray runSimCtlCommand(QStringList args) const;
|
||||
SimDeviceInfo deviceInfo(const QString &simUdid) const;
|
||||
bool runCommand(QString command, const QStringList &args, QByteArray *output = nullptr);
|
||||
|
||||
@@ -105,7 +114,7 @@ QList<Ios::Internal::IosDeviceType> SimulatorControl::availableSimulators()
|
||||
|
||||
void SimulatorControl::updateAvailableSimulators()
|
||||
{
|
||||
const QByteArray output = d->runSimCtlCommand({QLatin1String("list"), QLatin1String("-j"), QLatin1String("devices")});
|
||||
const QByteArray output = runSimCtlCommand({QLatin1String("list"), QLatin1String("-j"), QLatin1String("devices")});
|
||||
QJsonDocument doc = QJsonDocument::fromJson(output);
|
||||
if (!doc.isNull()) {
|
||||
QList<IosDeviceType> availableDevices;
|
||||
@@ -185,7 +194,7 @@ bool SimulatorControl::installApp(const QString &simUdid, const Utils::FileName
|
||||
{
|
||||
bool installed = false;
|
||||
if (isSimulatorRunning(simUdid)) {
|
||||
commandOutput = d->runSimCtlCommand(QStringList() << QStringLiteral("install") << simUdid << bundlePath.toString());
|
||||
commandOutput = runSimCtlCommand(QStringList() << QStringLiteral("install") << simUdid << bundlePath.toString());
|
||||
installed = commandOutput.isEmpty();
|
||||
} else {
|
||||
commandOutput = "Simulator device not running.";
|
||||
@@ -199,7 +208,7 @@ qint64 SimulatorControl::launchApp(const QString &simUdid, const QString &bundle
|
||||
pId = -1;
|
||||
if (!bundleIdentifier.isEmpty() && isSimulatorRunning(simUdid)) {
|
||||
const QStringList args({QStringLiteral("launch"), simUdid , bundleIdentifier});
|
||||
const QByteArray output = d->runSimCtlCommand(args);
|
||||
const QByteArray output = runSimCtlCommand(args);
|
||||
const QByteArray pIdStr = output.trimmed().split(' ').last().trimmed();
|
||||
bool validInt = false;
|
||||
pId = pIdStr.toLongLong(&validInt);
|
||||
@@ -264,16 +273,6 @@ SimulatorControlPrivate::~SimulatorControlPrivate()
|
||||
|
||||
}
|
||||
|
||||
QByteArray SimulatorControlPrivate::runSimCtlCommand(QStringList args) const
|
||||
{
|
||||
QProcess simCtlProcess;
|
||||
args.prepend(QStringLiteral("simctl"));
|
||||
simCtlProcess.start(QStringLiteral("xcrun"), args, QProcess::ReadOnly);
|
||||
if (!simCtlProcess.waitForFinished())
|
||||
qCDebug(simulatorLog) << "simctl command failed." << simCtlProcess.errorString();
|
||||
return simCtlProcess.readAll();
|
||||
}
|
||||
|
||||
// The simctl spawns the process and returns the pId but the application process might not have started, at least in a state where you can interrupt it.
|
||||
// Use SimulatorControl::waitForProcessSpawn to be sure.
|
||||
QProcess *SimulatorControl::spawnAppProcess(const QString &simUdid, const Utils::FileName &bundlePath, qint64 &pId, bool waitForDebugger, const QStringList &extraArgs)
|
||||
@@ -282,7 +281,7 @@ QProcess *SimulatorControl::spawnAppProcess(const QString &simUdid, const Utils:
|
||||
if (isSimulatorRunning(simUdid)) {
|
||||
QString bundleId = bundleIdentifier(bundlePath);
|
||||
QString executableName = bundleExecutable(bundlePath);
|
||||
QByteArray appPath = d->runSimCtlCommand(QStringList() << QStringLiteral("get_app_container") << simUdid << bundleId).trimmed();
|
||||
QByteArray appPath = runSimCtlCommand(QStringList() << QStringLiteral("get_app_container") << simUdid << bundleId).trimmed();
|
||||
if (!appPath.isEmpty() && !executableName.isEmpty()) {
|
||||
// Spawn the app. The spawned app is started in suspended mode.
|
||||
appPath.append('/' + executableName.toLocal8Bit());
|
||||
|
||||
@@ -140,6 +140,8 @@ void NimProject::updateProject()
|
||||
rootProjectNode()->buildTree(fileNodes);
|
||||
|
||||
emit fileListChanged();
|
||||
|
||||
emit parsingFinished();
|
||||
}
|
||||
|
||||
bool NimProject::supportsKit(Kit *k, QString *) const
|
||||
|
||||
@@ -304,9 +304,6 @@ void JsonFieldPage::Field::setIsCompleteExpando(const QVariant &v, const QString
|
||||
// LabelFieldData:
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
LabelField::LabelField() : m_wordWrap(false)
|
||||
{ }
|
||||
|
||||
bool LabelField::parseData(const QVariant &data, QString *errorMessage)
|
||||
{
|
||||
if (data.type() != QVariant::Map) {
|
||||
@@ -343,9 +340,6 @@ QWidget *LabelField::createWidget(const QString &displayName, JsonFieldPage *pag
|
||||
// SpacerFieldData:
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
SpacerField::SpacerField() : m_factor(1)
|
||||
{ }
|
||||
|
||||
bool SpacerField::parseData(const QVariant &data, QString *errorMessage)
|
||||
{
|
||||
if (data.isNull())
|
||||
@@ -388,9 +382,6 @@ QWidget *SpacerField::createWidget(const QString &displayName, JsonFieldPage *pa
|
||||
// LineEditFieldData:
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
LineEditField::LineEditField() : m_isModified(false), m_isValidating(false)
|
||||
{ }
|
||||
|
||||
bool LineEditField::parseData(const QVariant &data, QString *errorMessage)
|
||||
{
|
||||
if (data.isNull())
|
||||
@@ -502,9 +493,6 @@ void LineEditField::initializeData(MacroExpander *expander)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
|
||||
TextEditField::TextEditField() : m_acceptRichText(false)
|
||||
{ }
|
||||
|
||||
bool TextEditField::parseData(const QVariant &data, QString *errorMessage)
|
||||
{
|
||||
if (data.isNull())
|
||||
@@ -570,9 +558,6 @@ void TextEditField::initializeData(MacroExpander *expander)
|
||||
// PathChooserFieldData:
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
PathChooserField::PathChooserField() : m_kind(PathChooser::ExistingDirectory)
|
||||
{ }
|
||||
|
||||
bool PathChooserField::parseData(const QVariant &data, QString *errorMessage)
|
||||
{
|
||||
if (data.isNull())
|
||||
@@ -668,11 +653,6 @@ void PathChooserField::initializeData(MacroExpander *expander)
|
||||
// CheckBoxFieldData:
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
CheckBoxField::CheckBoxField() :
|
||||
m_checkedValue(QLatin1String("0")),
|
||||
m_uncheckedValue(QLatin1String("1"))
|
||||
{ }
|
||||
|
||||
bool CheckBoxField::parseData(const QVariant &data, QString *errorMessage)
|
||||
{
|
||||
if (data.isNull())
|
||||
|
||||
@@ -63,36 +63,28 @@ public:
|
||||
|
||||
class LabelField : public JsonFieldPage::Field
|
||||
{
|
||||
public:
|
||||
LabelField();
|
||||
|
||||
private:
|
||||
QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override;
|
||||
bool parseData(const QVariant &data, QString *errorMessage) override;
|
||||
|
||||
bool m_wordWrap;
|
||||
bool m_wordWrap = false;
|
||||
QString m_text;
|
||||
};
|
||||
|
||||
class SpacerField : public JsonFieldPage::Field
|
||||
{
|
||||
public:
|
||||
SpacerField();
|
||||
|
||||
bool suppressName() const override { return true; }
|
||||
|
||||
private:
|
||||
bool parseData(const QVariant &data, QString *errorMessage) override;
|
||||
QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override;
|
||||
|
||||
int m_factor;
|
||||
int m_factor = 1;
|
||||
};
|
||||
|
||||
class LineEditField : public JsonFieldPage::Field
|
||||
{
|
||||
public:
|
||||
LineEditField();
|
||||
|
||||
private:
|
||||
bool parseData(const QVariant &data, QString *errorMessage) override;
|
||||
QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override;
|
||||
@@ -102,10 +94,10 @@ private:
|
||||
bool validate(Utils::MacroExpander *expander, QString *message) override;
|
||||
void initializeData(Utils::MacroExpander *expander) override;
|
||||
|
||||
bool m_isModified;
|
||||
bool m_isValidating;
|
||||
bool m_restoreLastHistoryItem;
|
||||
bool m_isPassword;
|
||||
bool m_isModified = false;
|
||||
bool m_isValidating = false;
|
||||
bool m_restoreLastHistoryItem = false;
|
||||
bool m_isPassword = false;
|
||||
QString m_placeholderText;
|
||||
QString m_defaultText;
|
||||
QString m_disabledText;
|
||||
@@ -117,9 +109,6 @@ private:
|
||||
|
||||
class TextEditField : public JsonFieldPage::Field
|
||||
{
|
||||
public:
|
||||
TextEditField();
|
||||
|
||||
private:
|
||||
bool parseData(const QVariant &data, QString *errorMessage) override;
|
||||
QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override;
|
||||
@@ -130,7 +119,7 @@ private:
|
||||
void initializeData(Utils::MacroExpander *expander) override;
|
||||
|
||||
QString m_defaultText;
|
||||
bool m_acceptRichText;
|
||||
bool m_acceptRichText = false;
|
||||
QString m_disabledText;
|
||||
|
||||
mutable QString m_currentText;
|
||||
@@ -138,9 +127,6 @@ private:
|
||||
|
||||
class PathChooserField : public JsonFieldPage::Field
|
||||
{
|
||||
public:
|
||||
PathChooserField();
|
||||
|
||||
private:
|
||||
bool parseData(const QVariant &data, QString *errorMessage) override;
|
||||
|
||||
@@ -155,7 +141,7 @@ private:
|
||||
QString m_path;
|
||||
QString m_basePath;
|
||||
QString m_historyId;
|
||||
Utils::PathChooser::Kind m_kind;
|
||||
Utils::PathChooser::Kind m_kind = Utils::PathChooser::ExistingDirectory;
|
||||
|
||||
QString m_currentPath;
|
||||
};
|
||||
@@ -163,8 +149,6 @@ private:
|
||||
class CheckBoxField : public JsonFieldPage::Field
|
||||
{
|
||||
public:
|
||||
CheckBoxField();
|
||||
|
||||
bool suppressName() const override { return true; }
|
||||
|
||||
private:
|
||||
@@ -177,8 +161,8 @@ private:
|
||||
bool validate(Utils::MacroExpander *expander, QString *message) override;
|
||||
void initializeData(Utils::MacroExpander *expander) override;
|
||||
|
||||
QString m_checkedValue;
|
||||
QString m_uncheckedValue;
|
||||
QString m_checkedValue = QString("0");
|
||||
QString m_uncheckedValue = QString("1");
|
||||
QVariant m_checkedExpression;
|
||||
|
||||
bool m_isModified = false;
|
||||
@@ -186,9 +170,6 @@ private:
|
||||
|
||||
class ComboBoxField : public JsonFieldPage::Field
|
||||
{
|
||||
public:
|
||||
ComboBoxField() = default;
|
||||
|
||||
private:
|
||||
bool parseData(const QVariant &data, QString *errorMessage) override;
|
||||
|
||||
|
||||
@@ -573,7 +573,7 @@ MsvcToolChainFactory::MsvcToolChainFactory()
|
||||
|
||||
QSet<ToolChain::Language> MsvcToolChainFactory::supportedLanguages() const
|
||||
{
|
||||
return { ProjectExplorer::ToolChain::Language::Cxx };
|
||||
return { ToolChain::Language::C, ToolChain::Language::Cxx };
|
||||
}
|
||||
|
||||
bool MsvcToolChainFactory::checkForVisualStudioInstallation(const QString &vsName)
|
||||
@@ -617,24 +617,32 @@ QString MsvcToolChainFactory::vcVarsBatFor(const QString &basePath, MsvcToolChai
|
||||
return QString();
|
||||
}
|
||||
|
||||
static ToolChain *findOrCreateToolChain(const QList<ToolChain *> &alreadyKnown,
|
||||
const QString &name, const Abi &abi,
|
||||
const QString &varsBat, const QString &varsBatArg,
|
||||
ToolChain::Detection d = ToolChain::ManualDetection)
|
||||
static QList<ToolChain *> findOrCreateToolChain(
|
||||
const QList<ToolChain *> &alreadyKnown,
|
||||
const QString &name, const Abi &abi,
|
||||
const QString &varsBat, const QString &varsBatArg,
|
||||
ToolChain::Detection d = ToolChain::ManualDetection)
|
||||
{
|
||||
ToolChain *tc = Utils::findOrDefault(alreadyKnown,
|
||||
[&varsBat, &varsBatArg, &abi](ToolChain *tc) -> bool {
|
||||
if (tc->typeId() != Constants::MSVC_TOOLCHAIN_TYPEID)
|
||||
return false;
|
||||
if (tc->targetAbi() != abi)
|
||||
return false;
|
||||
auto mtc = static_cast<MsvcToolChain *>(tc);
|
||||
return mtc->varsBat() == varsBat
|
||||
&& mtc->varsBatArg() == varsBatArg;
|
||||
});
|
||||
if (!tc)
|
||||
tc = new MsvcToolChain(name, abi, varsBat, varsBatArg, ToolChain::Language::Cxx, d);
|
||||
return tc;
|
||||
QList<ToolChain *> res;
|
||||
for (auto language: {ToolChain::Language::C, ToolChain::Language::Cxx}) {
|
||||
ToolChain *tc = Utils::findOrDefault(
|
||||
alreadyKnown,
|
||||
[&varsBat, &varsBatArg, &abi, &language](ToolChain *tc) -> bool {
|
||||
if (tc->typeId() != Constants::MSVC_TOOLCHAIN_TYPEID)
|
||||
return false;
|
||||
if (tc->targetAbi() != abi)
|
||||
return false;
|
||||
if (tc->language() != language)
|
||||
return false;
|
||||
auto mtc = static_cast<MsvcToolChain *>(tc);
|
||||
return mtc->varsBat() == varsBat
|
||||
&& mtc->varsBatArg() == varsBatArg;
|
||||
});
|
||||
if (!tc)
|
||||
tc = new MsvcToolChain(name, abi, varsBat, varsBatArg, language, d);
|
||||
res << tc;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// Detect build tools introduced with MSVC2015
|
||||
@@ -670,10 +678,11 @@ static void detectCppBuildTools(QList<ToolChain *> *list)
|
||||
const Entry &e = entries[i];
|
||||
const Abi abi(e.architecture, Abi::WindowsOS, Abi::WindowsMsvc2015Flavor,
|
||||
e.format, e.wordSize);
|
||||
list->append(new MsvcToolChain(name + QLatin1String(e.postFix), abi,
|
||||
vcVarsBat, QLatin1String(e.varsBatArg),
|
||||
ToolChain::Language::Cxx,
|
||||
ToolChain::AutoDetection));
|
||||
for (auto language: {ToolChain::Language::C, ToolChain::Language::Cxx}) {
|
||||
list->append(new MsvcToolChain(name + QLatin1String(e.postFix), abi,
|
||||
vcVarsBat, QLatin1String(e.varsBatArg),
|
||||
language, ToolChain::AutoDetection));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -743,19 +752,18 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al
|
||||
continue;
|
||||
|
||||
QList<ToolChain *> tmp;
|
||||
tmp.append(findOrCreateToolChain(alreadyKnown,
|
||||
generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86),
|
||||
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86, sdkKey),
|
||||
fi.absoluteFilePath(), QLatin1String("/x86"), ToolChain::AutoDetection));
|
||||
// Add all platforms, cross-compiler is automatically selected by SetEnv.cmd if needed
|
||||
tmp.append(findOrCreateToolChain(alreadyKnown,
|
||||
generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::amd64),
|
||||
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::amd64, sdkKey),
|
||||
fi.absoluteFilePath(), QLatin1String("/x64"), ToolChain::AutoDetection));
|
||||
tmp.append(findOrCreateToolChain(alreadyKnown,
|
||||
generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::ia64),
|
||||
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::ia64, sdkKey),
|
||||
fi.absoluteFilePath(), QLatin1String("/ia64"), ToolChain::AutoDetection));
|
||||
const QVector<QPair<MsvcToolChain::Platform, QString> > platforms = {
|
||||
{MsvcToolChain::x86, "x86"},
|
||||
{MsvcToolChain::amd64, "x64"},
|
||||
{MsvcToolChain::ia64, "ia64"},
|
||||
};
|
||||
for (auto platform: platforms) {
|
||||
tmp.append(findOrCreateToolChain(
|
||||
alreadyKnown,
|
||||
generateDisplayName(name, MsvcToolChain::WindowsSDK, platform.first),
|
||||
findAbiOfMsvc(MsvcToolChain::WindowsSDK, platform.first, sdkKey),
|
||||
fi.absoluteFilePath(), "/" + platform.second, ToolChain::AutoDetection));
|
||||
}
|
||||
// Make sure the default is front.
|
||||
if (folder == defaultSdkPath)
|
||||
results = tmp + results;
|
||||
@@ -786,14 +794,16 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al
|
||||
const int version = vsName.leftRef(dotPos).toInt();
|
||||
const QString vcvarsAllbat = path + QLatin1String("/vcvarsall.bat");
|
||||
if (QFileInfo(vcvarsAllbat).isFile()) {
|
||||
QList<MsvcToolChain::Platform> platforms; // prioritized list
|
||||
// prioritized list.
|
||||
// x86_arm was put before amd64_arm as a workaround for auto detected windows phone
|
||||
// toolchains. As soon as windows phone builds support x64 cross builds, this change
|
||||
// can be reverted.
|
||||
platforms << MsvcToolChain::x86 << MsvcToolChain::amd64_x86
|
||||
<< MsvcToolChain::amd64 << MsvcToolChain::x86_amd64
|
||||
<< MsvcToolChain::arm << MsvcToolChain::x86_arm << MsvcToolChain::amd64_arm
|
||||
<< MsvcToolChain::ia64 << MsvcToolChain::x86_ia64;
|
||||
const QVector<MsvcToolChain::Platform> platforms = {
|
||||
MsvcToolChain::x86, MsvcToolChain::amd64_x86,
|
||||
MsvcToolChain::amd64, MsvcToolChain::x86_amd64,
|
||||
MsvcToolChain::arm, MsvcToolChain::x86_arm, MsvcToolChain::amd64_arm,
|
||||
MsvcToolChain::ia64, MsvcToolChain::x86_ia64
|
||||
};
|
||||
foreach (const MsvcToolChain::Platform &platform, platforms) {
|
||||
const bool toolchainInstalled = QFileInfo(vcVarsBatFor(path, platform)).isFile();
|
||||
if (hostSupportsPlatform(platform) && toolchainInstalled) {
|
||||
|
||||
@@ -168,6 +168,9 @@ signals:
|
||||
void projectContextUpdated();
|
||||
void projectLanguagesUpdated();
|
||||
|
||||
signals: // for tests only
|
||||
void parsingFinished();
|
||||
|
||||
protected:
|
||||
virtual RestoreResult fromMap(const QVariantMap &map, QString *errorMessage);
|
||||
virtual bool setupTarget(Target *t);
|
||||
|
||||
@@ -1689,6 +1689,9 @@ ProjectExplorerPlugin::OpenProjectResult ProjectExplorerPlugin::openProjects(con
|
||||
foundProjectManager = true;
|
||||
QString tmp;
|
||||
if (Project *pro = manager->openProject(filePath, &tmp)) {
|
||||
QObject::connect(pro, &Project::parsingFinished, [pro]() {
|
||||
emit SessionManager::instance()->projectFinishedParsing(pro);
|
||||
});
|
||||
QString restoreError;
|
||||
Project::RestoreResult restoreResult = pro->restoreSettings(&restoreError);
|
||||
if (restoreResult == Project::RestoreResult::Ok) {
|
||||
|
||||
@@ -138,6 +138,9 @@ signals:
|
||||
void aboutToSaveSession();
|
||||
void dependencyChanged(ProjectExplorer::Project *a, ProjectExplorer::Project *b);
|
||||
|
||||
signals: // for tests only
|
||||
void projectFinishedParsing(ProjectExplorer::Project *project);
|
||||
|
||||
private:
|
||||
static void saveActiveMode(Core::Id mode);
|
||||
void clearProjectFileCache();
|
||||
|
||||
@@ -202,7 +202,9 @@ bool ToolChain::operator == (const ToolChain &tc) const
|
||||
return true;
|
||||
|
||||
// We ignore displayname
|
||||
return typeId() == tc.typeId() && isAutoDetected() == tc.isAutoDetected();
|
||||
return typeId() == tc.typeId()
|
||||
&& isAutoDetected() == tc.isAutoDetected()
|
||||
&& language() == tc.language();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -619,6 +619,8 @@ void PythonProject::refresh()
|
||||
return new PythonFileNode(FileName::fromString(f), displayName);
|
||||
});
|
||||
rootProjectNode()->buildTree(fileNodes);
|
||||
|
||||
emit parsingFinished();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -503,6 +503,7 @@ void QbsProject::handleQbsParsingDone(bool success)
|
||||
if (dataChanged)
|
||||
updateAfterParse();
|
||||
emit projectParsingDone(success);
|
||||
emit parsingFinished();
|
||||
}
|
||||
|
||||
void QbsProject::handleRuleExecutionDone()
|
||||
|
||||
@@ -87,7 +87,8 @@ void QmakeKitInformation::setup(Kit *k)
|
||||
break;
|
||||
}
|
||||
}
|
||||
ToolChainKitInformation::setToolChain(k, possibleTc);
|
||||
if (possibleTc)
|
||||
ToolChainKitInformation::setToolChain(k, possibleTc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,26 +87,25 @@ using namespace Utils;
|
||||
|
||||
struct FileTypeDataStorage {
|
||||
FileType type;
|
||||
Theme::ImageFile themeImage;
|
||||
const char *typeName;
|
||||
const char *icon;
|
||||
const char *addFileFilter;
|
||||
};
|
||||
|
||||
static const FileTypeDataStorage fileTypeDataStorage[] = {
|
||||
{ HeaderType, Theme::ProjectExplorerHeader, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Headers"),
|
||||
{ HeaderType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Headers"),
|
||||
ProjectExplorer::Constants::FILEOVERLAY_H, "*.h; *.hh; *.hpp; *.hxx;"},
|
||||
{ SourceType, Theme::ProjectExplorerSource, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Sources"),
|
||||
{ SourceType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Sources"),
|
||||
ProjectExplorer::Constants::FILEOVERLAY_CPP, "*.c; *.cc; *.cpp; *.cp; *.cxx; *.c++;" },
|
||||
{ FormType, Theme::ProjectExplorerForm, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Forms"),
|
||||
{ FormType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Forms"),
|
||||
Constants::FILEOVERLAY_UI, "*.ui;" },
|
||||
{ StateChartType, Theme::ProjectExplorerForm, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "State charts"),
|
||||
{ StateChartType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "State charts"),
|
||||
ProjectExplorer::Constants::FILEOVERLAY_SCXML, "*.scxml;" },
|
||||
{ ResourceType, Theme::ProjectExplorerResource, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Resources"),
|
||||
{ ResourceType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Resources"),
|
||||
ProjectExplorer::Constants::FILEOVERLAY_QRC, "*.qrc;" },
|
||||
{ QMLType, Theme::ProjectExplorerQML, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "QML"),
|
||||
{ QMLType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "QML"),
|
||||
ProjectExplorer::Constants::FILEOVERLAY_QML, "*.qml;" },
|
||||
{ UnknownFileType, Theme::ProjectExplorerOtherFiles, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Other files"),
|
||||
{ UnknownFileType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Other files"),
|
||||
ProjectExplorer::Constants::FILEOVERLAY_UNKNOWN, "*;" }
|
||||
};
|
||||
|
||||
@@ -159,10 +158,7 @@ QmakeNodeStaticData::QmakeNodeStaticData()
|
||||
|
||||
const QPixmap dirPixmap = qApp->style()->standardIcon(QStyle::SP_DirIcon).pixmap(desiredSize);
|
||||
for (unsigned i = 0 ; i < count; ++i) {
|
||||
QIcon overlayIcon;
|
||||
const QString iconFile = creatorTheme()->imageFile(fileTypeDataStorage[i].themeImage,
|
||||
QString::fromLatin1(fileTypeDataStorage[i].icon));
|
||||
overlayIcon = QIcon(iconFile);
|
||||
const QIcon overlayIcon(QLatin1String(fileTypeDataStorage[i].icon));
|
||||
QIcon folderIcon;
|
||||
folderIcon.addPixmap(FileIconProvider::overlayIcon(dirPixmap, overlayIcon));
|
||||
const QString desc = QCoreApplication::translate("QmakeProjectManager::QmakePriFileNode", fileTypeDataStorage[i].typeName);
|
||||
@@ -171,9 +167,7 @@ QmakeNodeStaticData::QmakeNodeStaticData()
|
||||
desc, filter, folderIcon));
|
||||
}
|
||||
// Project icon
|
||||
const QString fileName = creatorTheme()->imageFile(Theme::ProjectFileIcon,
|
||||
QLatin1String(ProjectExplorer::Constants::FILEOVERLAY_QT));
|
||||
const QIcon projectBaseIcon(fileName);
|
||||
const QIcon projectBaseIcon(ProjectExplorer::Constants::FILEOVERLAY_QT);
|
||||
const QPixmap projectPixmap = FileIconProvider::overlayIcon(dirPixmap, projectBaseIcon);
|
||||
projectIcon.addPixmap(projectPixmap);
|
||||
|
||||
@@ -205,7 +199,6 @@ public:
|
||||
QtSupport::ProFileReader *readerCumulative;
|
||||
ProFileGlobals *qmakeGlobals;
|
||||
QMakeVfs *qmakeVfs;
|
||||
bool isQt5;
|
||||
};
|
||||
|
||||
class PriFileEvalResult
|
||||
@@ -244,7 +237,6 @@ public:
|
||||
TargetInformation targetInformation;
|
||||
InstallsList installsList;
|
||||
QHash<QmakeVariable, QStringList> newVarValues;
|
||||
bool isDeployable;
|
||||
QStringList errors;
|
||||
};
|
||||
|
||||
@@ -645,7 +637,7 @@ PriFileEvalResult QmakePriFileNode::extractValues(const EvalInput &input,
|
||||
// all the files from those folders and add watchers for them. That's too
|
||||
// dangerous if we get the folders wrong and enumerate the whole project
|
||||
// tree multiple times.
|
||||
QStringList dynamicVariables = dynamicVarNames(input.readerExact, input.isQt5);
|
||||
QStringList dynamicVariables = dynamicVarNames(input.readerExact);
|
||||
foreach (ProFile *includeFileExact, includeFilesExact)
|
||||
foreach (const QString &dynamicVar, dynamicVariables)
|
||||
result.folders += input.readerExact->values(dynamicVar, includeFileExact);
|
||||
@@ -1467,25 +1459,15 @@ QStringList QmakePriFileNode::varNamesForRemoving()
|
||||
return vars;
|
||||
}
|
||||
|
||||
QStringList QmakePriFileNode::dynamicVarNames(QtSupport::ProFileReader *readerExact,
|
||||
bool isQt5)
|
||||
QStringList QmakePriFileNode::dynamicVarNames(QtSupport::ProFileReader *reader)
|
||||
{
|
||||
QStringList result;
|
||||
|
||||
// Figure out DEPLOYMENT and INSTALLS
|
||||
const QString deployment = QLatin1String("DEPLOYMENT");
|
||||
const QString sources = QLatin1String(isQt5 ? ".files" : ".sources");
|
||||
QStringList listOfVars = readerExact->values(deployment);
|
||||
foreach (const QString &var, listOfVars) {
|
||||
result << (var + sources);
|
||||
}
|
||||
|
||||
// Figure out INSTALLS (and DEPLOYMENT, as it's aliased)
|
||||
const QString installs = QLatin1String("INSTALLS");
|
||||
const QString files = QLatin1String(".files");
|
||||
listOfVars = readerExact->values(installs);
|
||||
foreach (const QString &var, listOfVars) {
|
||||
foreach (const QString &var, reader->values(installs))
|
||||
result << (var + files);
|
||||
}
|
||||
result.removeDuplicates();
|
||||
return result;
|
||||
}
|
||||
@@ -1631,11 +1613,6 @@ QByteArray QmakeProFileNode::cxxDefines() const
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QmakeProFileNode::isDeployable() const
|
||||
{
|
||||
return m_isDeployable;
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QmakeProFileNode
|
||||
Implements abstract ProjectNode class
|
||||
@@ -1798,10 +1775,6 @@ EvalInput QmakeProFileNode::evalInput() const
|
||||
input.buildDirectory = buildDir();
|
||||
input.readerExact = m_readerExact;
|
||||
input.readerCumulative = m_readerCumulative;
|
||||
Target *t = m_project->activeTarget();
|
||||
Kit *k = t ? t->kit() : KitManager::defaultKit();
|
||||
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k);
|
||||
input.isQt5 = !qtVersion || qtVersion->qtVersion() >= QtSupport::QtVersionNumber(5,0,0);
|
||||
input.qmakeGlobals = m_project->qmakeGlobals();
|
||||
input.qmakeVfs = m_project->qmakeVfs();
|
||||
return input;
|
||||
@@ -2012,19 +1985,6 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
|
||||
result->newVarValues[QmakeCc] = input.readerExact->values("QMAKE_CC");
|
||||
result->newVarValues[QmakeCxx] = input.readerExact->values("QMAKE_CXX");
|
||||
|
||||
result->isDeployable = false;
|
||||
if (result->projectType == ApplicationTemplate) {
|
||||
result->isDeployable = true;
|
||||
} else {
|
||||
foreach (const QString &item, input.readerExact->values(QLatin1String("DEPLOYMENT"))) {
|
||||
if (!input.readerExact->values(item + QLatin1String(".sources")).isEmpty()) {
|
||||
result->isDeployable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (readerBuildPass && readerBuildPass != input.readerExact)
|
||||
delete readerBuildPass;
|
||||
}
|
||||
@@ -2274,7 +2234,6 @@ void QmakeProFileNode::applyEvaluate(EvalResult *evalResult)
|
||||
|
||||
m_subProjectsNotToDeploy = result->subProjectsNotToDeploy;
|
||||
m_installsList = result->installsList;
|
||||
m_isDeployable = result->isDeployable;
|
||||
|
||||
if (m_varValues != result->newVarValues)
|
||||
m_varValues = result->newVarValues;
|
||||
|
||||
@@ -180,7 +180,7 @@ protected:
|
||||
static QStringList varNames(ProjectExplorer::FileType type, QtSupport::ProFileReader *readerExact);
|
||||
static QStringList varNamesForRemoving();
|
||||
static QString varNameForAdding(const QString &mimeType);
|
||||
static QStringList dynamicVarNames(QtSupport::ProFileReader *readerExact, bool isQt5);
|
||||
static QStringList dynamicVarNames(QtSupport::ProFileReader *readerExact);
|
||||
static QSet<Utils::FileName> filterFilesProVariables(ProjectExplorer::FileType fileType, const QSet<Utils::FileName> &files);
|
||||
static QSet<Utils::FileName> filterFilesRecursiveEnumerata(ProjectExplorer::FileType fileType, const QSet<Utils::FileName> &files);
|
||||
|
||||
@@ -354,7 +354,6 @@ public:
|
||||
QString objectExtension() const;
|
||||
QString objectsDirectory() const;
|
||||
QByteArray cxxDefines() const;
|
||||
bool isDeployable() const;
|
||||
|
||||
enum AsyncUpdateDelay { ParseNow, ParseLater };
|
||||
void scheduleUpdate(AsyncUpdateDelay delay);
|
||||
@@ -401,8 +400,6 @@ private:
|
||||
static TargetInformation targetInformation(QtSupport::ProFileReader *reader, QtSupport::ProFileReader *readerBuildPass, const QString &buildDir, const QString &projectFilePath);
|
||||
static InstallsList installsList(const QtSupport::ProFileReader *reader, const QString &projectFilePath, const QString &projectDir);
|
||||
|
||||
bool m_isDeployable = false;
|
||||
|
||||
bool m_validParse = false;
|
||||
bool m_parseInProgress = true;
|
||||
|
||||
|
||||
@@ -753,6 +753,7 @@ void QmakeProject::decrementPendingEvaluateFutures()
|
||||
activeTarget()->updateDefaultDeployConfigurations();
|
||||
updateRunConfigurations();
|
||||
emit proFilesEvaluated();
|
||||
emit parsingFinished();
|
||||
if (debug)
|
||||
qDebug()<<" Setting state to Base";
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
|
||||
#include "componentview.h"
|
||||
#include "componentaction.h"
|
||||
|
||||
#include <nodemetainfo.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <nodeabstractproperty.h>
|
||||
@@ -193,7 +196,9 @@ void ComponentView::searchForComponentAndAddToList(const ModelNode &node)
|
||||
foreach (const ModelNode &node, node.allSubModelNodesAndThisNode()) {
|
||||
if (node.nodeSourceType() == ModelNode::NodeWithComponentSource
|
||||
|| (node.hasParentProperty()
|
||||
&& !node.parentProperty().isDefaultProperty())) {
|
||||
&& !node.parentProperty().isDefaultProperty()
|
||||
&& node.metaInfo().isValid()
|
||||
&& node.metaInfo().isGraphicalItem())) {
|
||||
if (masterNotAdded) {
|
||||
masterNotAdded = true;
|
||||
addMasterDocument();
|
||||
|
||||
@@ -223,7 +223,7 @@ static bool idContainsWrongLetter(const QString& id)
|
||||
|
||||
bool ModelNode::isValidId(const QString &id)
|
||||
{
|
||||
return id.isEmpty() || (!idContainsWrongLetter(id) && !idIsQmlKeyWord(id)) && !isIdToAvoid(id);
|
||||
return id.isEmpty() || (!idContainsWrongLetter(id) && !idIsQmlKeyWord(id) && !isIdToAvoid(id));
|
||||
}
|
||||
|
||||
bool ModelNode::hasId() const
|
||||
|
||||
@@ -198,6 +198,8 @@ void QmlProject::refresh(RefreshOptions options)
|
||||
QmlJS::Dialect::Qml);
|
||||
|
||||
modelManager()->updateProjectInfo(projectInfo, this);
|
||||
|
||||
emit parsingFinished();
|
||||
}
|
||||
|
||||
QStringList QmlProject::convertToAbsoluteFiles(const QStringList &paths) const
|
||||
|
||||
@@ -760,6 +760,14 @@ void ExamplesListModelFilter::updateFilter()
|
||||
}
|
||||
}
|
||||
|
||||
void ExamplesListModelFilter::setFilterStrings(const QStringList &arg)
|
||||
{
|
||||
if (m_filterStrings != arg) {
|
||||
m_filterStrings = arg;
|
||||
delayedUpdateFilter();
|
||||
}
|
||||
}
|
||||
|
||||
bool containsSubString(const QStringList &list, const QString &substr, Qt::CaseSensitivity cs)
|
||||
{
|
||||
return Utils::contains(list, [&substr, &cs](const QString &elem) {
|
||||
@@ -789,11 +797,11 @@ bool ExamplesListModelFilter::filterAcceptsRow(int sourceRow, const QModelIndex
|
||||
});
|
||||
}
|
||||
|
||||
if (!m_searchString.isEmpty()) {
|
||||
if (!m_filterStrings.isEmpty()) {
|
||||
const QString description = sourceModel()->index(sourceRow, 0, sourceParent).data(Description).toString();
|
||||
const QString name = sourceModel()->index(sourceRow, 0, sourceParent).data(Name).toString();
|
||||
|
||||
foreach (const QString &subString, m_searchString) {
|
||||
foreach (const QString &subString, m_filterStrings) {
|
||||
bool wordMatch = false;
|
||||
wordMatch |= (bool)name.contains(subString, Qt::CaseInsensitive);
|
||||
if (wordMatch)
|
||||
@@ -835,6 +843,14 @@ void ExamplesListModelFilter::filterForExampleSet(int index)
|
||||
m_sourceModel->selectExampleSet(index);
|
||||
}
|
||||
|
||||
void ExamplesListModelFilter::setFilterTags(const QStringList &arg)
|
||||
{
|
||||
if (m_filterTags != arg) {
|
||||
m_filterTags = arg;
|
||||
emit filterTagsChanged(arg);
|
||||
}
|
||||
}
|
||||
|
||||
void ExamplesListModelFilter::setShowTutorialsOnly(bool showTutorialsOnly)
|
||||
{
|
||||
m_showTutorialsOnly = showTutorialsOnly;
|
||||
@@ -984,8 +1000,13 @@ struct SearchStringLexer
|
||||
}
|
||||
};
|
||||
|
||||
void ExamplesListModelFilter::parseSearchString(const QString &arg)
|
||||
void ExamplesListModelFilter::setSearchString(const QString &arg)
|
||||
{
|
||||
if (m_searchString == arg)
|
||||
return;
|
||||
m_searchString = arg;
|
||||
emit searchStringChanged(m_searchString);
|
||||
// parse and update
|
||||
QStringList tags;
|
||||
QStringList searchTerms;
|
||||
SearchStringLexer lex(arg);
|
||||
@@ -1007,10 +1028,15 @@ void ExamplesListModelFilter::parseSearchString(const QString &arg)
|
||||
}
|
||||
}
|
||||
|
||||
setSearchStrings(searchTerms);
|
||||
setFilterStrings(searchTerms);
|
||||
setFilterTags(tags);
|
||||
delayedUpdateFilter();
|
||||
}
|
||||
|
||||
QString ExamplesListModelFilter::searchString() const
|
||||
{
|
||||
return m_searchString;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QtSupport
|
||||
|
||||
@@ -163,7 +163,7 @@ class ExamplesListModelFilter : public QSortFilterProxyModel
|
||||
public:
|
||||
Q_PROPERTY(bool showTutorialsOnly READ showTutorialsOnly WRITE setShowTutorialsOnly NOTIFY showTutorialsOnlyChanged)
|
||||
Q_PROPERTY(QStringList filterTags READ filterTags WRITE setFilterTags NOTIFY filterTagsChanged)
|
||||
Q_PROPERTY(QStringList searchStrings READ searchStrings WRITE setSearchStrings NOTIFY searchStrings)
|
||||
Q_PROPERTY(QString searchString READ searchString WRITE setSearchString NOTIFY searchStringChanged)
|
||||
|
||||
Q_PROPERTY(int exampleSetIndex READ exampleSetIndex NOTIFY exampleSetIndexChanged)
|
||||
|
||||
@@ -171,9 +171,11 @@ public:
|
||||
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
|
||||
|
||||
Q_INVOKABLE void setSearchString(const QString &arg);
|
||||
QString searchString() const;
|
||||
|
||||
bool showTutorialsOnly() { return m_showTutorialsOnly; }
|
||||
QStringList filterTags() const { return m_filterTags; }
|
||||
QStringList searchStrings() const { return m_searchString; }
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
@@ -182,35 +184,21 @@ public:
|
||||
Q_INVOKABLE void filterForExampleSet(int index);
|
||||
|
||||
public slots:
|
||||
void setFilterTags(const QStringList &arg)
|
||||
{
|
||||
if (m_filterTags != arg) {
|
||||
m_filterTags = arg;
|
||||
emit filterTagsChanged(arg);
|
||||
}
|
||||
}
|
||||
void setFilterTags(const QStringList &arg);
|
||||
void updateFilter();
|
||||
|
||||
void setSearchStrings(const QStringList &arg)
|
||||
{
|
||||
if (m_searchString != arg) {
|
||||
m_searchString = arg;
|
||||
emit searchStrings(arg);
|
||||
delayedUpdateFilter();
|
||||
}
|
||||
}
|
||||
|
||||
void parseSearchString(const QString &arg);
|
||||
void setShowTutorialsOnly(bool showTutorialsOnly);
|
||||
void handleQtVersionsChanged();
|
||||
|
||||
signals:
|
||||
void showTutorialsOnlyChanged();
|
||||
void filterTagsChanged(const QStringList &arg);
|
||||
void searchStrings(const QStringList &arg);
|
||||
void searchStringChanged(const QString &arg);
|
||||
void exampleSetIndexChanged();
|
||||
|
||||
private:
|
||||
void setFilterStrings(const QStringList &arg);
|
||||
|
||||
void qtVersionManagerLoaded();
|
||||
void helpManagerInitialized();
|
||||
|
||||
@@ -221,8 +209,9 @@ private:
|
||||
int exampleSetIndex() const;
|
||||
|
||||
bool m_showTutorialsOnly;
|
||||
QString m_searchString;
|
||||
QStringList m_filterTags;
|
||||
QStringList m_searchString;
|
||||
QStringList m_filterStrings;
|
||||
ExamplesListModel *m_sourceModel;
|
||||
int m_timerId;
|
||||
bool m_blockIndexUpdate;
|
||||
|
||||
@@ -685,11 +685,6 @@ void QtOptionsPageWidget::userChangedCurrentVersion()
|
||||
updateDescriptionLabel();
|
||||
}
|
||||
|
||||
void QtOptionsPageWidget::qtVersionChanged()
|
||||
{
|
||||
updateDescriptionLabel();
|
||||
}
|
||||
|
||||
void QtOptionsPageWidget::updateDescriptionLabel()
|
||||
{
|
||||
QtVersionItem *item = currentItem();
|
||||
@@ -736,7 +731,7 @@ void QtOptionsPageWidget::updateWidgets()
|
||||
m_versionUi->formLayout->addRow(m_configurationWidget);
|
||||
m_configurationWidget->setEnabled(!version->isAutodetected());
|
||||
connect(m_configurationWidget, &QtConfigWidget::changed,
|
||||
this, &QtOptionsPageWidget::qtVersionChanged);
|
||||
this, &QtOptionsPageWidget::updateDescriptionLabel);
|
||||
}
|
||||
} else {
|
||||
m_versionUi->nameEdit->clear();
|
||||
|
||||
@@ -85,7 +85,6 @@ private:
|
||||
|
||||
private:
|
||||
void updateQtVersions(const QList<int> &, const QList<int> &, const QList<int> &);
|
||||
void qtVersionChanged();
|
||||
void versionChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void addQtDir();
|
||||
void removeQtDir();
|
||||
|
||||
@@ -103,7 +103,7 @@ class RelayServer: public QObject
|
||||
public:
|
||||
RelayServer(IosTool *parent);
|
||||
~RelayServer();
|
||||
bool startServer(int port, bool ipv6);
|
||||
bool startServer(int port);
|
||||
void stopServer();
|
||||
quint16 serverPort();
|
||||
IosTool *iosTool();
|
||||
@@ -113,7 +113,8 @@ public:
|
||||
protected:
|
||||
virtual void newRelayConnection() = 0;
|
||||
|
||||
QTcpServer m_server;
|
||||
QTcpServer m_ipv4Server;
|
||||
QTcpServer m_ipv6Server;
|
||||
QList<Relayer *> m_connections;
|
||||
};
|
||||
|
||||
@@ -188,7 +189,6 @@ private:
|
||||
int maxProgress;
|
||||
int opLeft;
|
||||
bool debug;
|
||||
bool ipv6;
|
||||
bool inAppOutput;
|
||||
bool splitAppOutput; // as QXmlStreamReader reports the text attributes atomically it is better to split
|
||||
Ios::IosDeviceManager::AppOp appOp;
|
||||
@@ -404,31 +404,39 @@ RelayServer::~RelayServer()
|
||||
stopServer();
|
||||
}
|
||||
|
||||
bool RelayServer::startServer(int port, bool ipv6)
|
||||
bool RelayServer::startServer(int port)
|
||||
{
|
||||
QTC_CHECK(!m_server.isListening());
|
||||
m_server.setMaxPendingConnections(1);
|
||||
connect(&m_server, &QTcpServer::newConnection, this, &RelayServer::handleNewRelayConnection);
|
||||
QTC_CHECK(!m_ipv4Server.isListening());
|
||||
QTC_CHECK(!m_ipv6Server.isListening());
|
||||
connect(&m_ipv4Server, &QTcpServer::newConnection,
|
||||
this, &RelayServer::handleNewRelayConnection);
|
||||
connect(&m_ipv6Server, &QTcpServer::newConnection,
|
||||
this, &RelayServer::handleNewRelayConnection);
|
||||
quint16 portValue = static_cast<quint16>(port);
|
||||
if (port < 0 || port > 0xFFFF)
|
||||
return false;
|
||||
if (ipv6)
|
||||
return m_server.listen(QHostAddress(QHostAddress::LocalHostIPv6), portValue);
|
||||
else
|
||||
return m_server.listen(QHostAddress(QHostAddress::LocalHost), portValue);
|
||||
m_ipv4Server.listen(QHostAddress(QHostAddress::LocalHostIPv6), portValue);
|
||||
m_ipv6Server.listen(QHostAddress(QHostAddress::LocalHost), portValue);
|
||||
return m_ipv4Server.isListening() || m_ipv6Server.isListening();
|
||||
}
|
||||
|
||||
void RelayServer::stopServer()
|
||||
{
|
||||
foreach (Relayer *connection, m_connections)
|
||||
delete connection;
|
||||
if (m_server.isListening())
|
||||
m_server.close();
|
||||
if (m_ipv4Server.isListening())
|
||||
m_ipv4Server.close();
|
||||
if (m_ipv6Server.isListening())
|
||||
m_ipv6Server.close();
|
||||
}
|
||||
|
||||
quint16 RelayServer::serverPort()
|
||||
{
|
||||
return m_server.serverPort();
|
||||
if (m_ipv4Server.isListening())
|
||||
return m_ipv4Server.serverPort();
|
||||
if (m_ipv6Server.isListening())
|
||||
return m_ipv6Server.serverPort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
IosTool *RelayServer::iosTool()
|
||||
@@ -459,11 +467,12 @@ SingleRelayServer::SingleRelayServer(IosTool *parent,
|
||||
|
||||
void SingleRelayServer::newRelayConnection()
|
||||
{
|
||||
QTcpSocket *clientSocket = m_ipv4Server.hasPendingConnections()
|
||||
? m_ipv4Server.nextPendingConnection() : m_ipv6Server.nextPendingConnection();
|
||||
if (m_connections.size() > 0) {
|
||||
delete m_server.nextPendingConnection();
|
||||
delete clientSocket;
|
||||
return;
|
||||
}
|
||||
QTcpSocket *clientSocket = m_server.nextPendingConnection();
|
||||
if (clientSocket) {
|
||||
Relayer *newConnection = new Relayer(this, clientSocket);
|
||||
m_connections.append(newConnection);
|
||||
@@ -483,7 +492,8 @@ GenericRelayServer::GenericRelayServer(IosTool *parent, int remotePort,
|
||||
|
||||
void GenericRelayServer::newRelayConnection()
|
||||
{
|
||||
QTcpSocket *clientSocket = m_server.nextPendingConnection();
|
||||
QTcpSocket *clientSocket = m_ipv4Server.hasPendingConnections()
|
||||
? m_ipv4Server.nextPendingConnection() : m_ipv6Server.nextPendingConnection();
|
||||
if (clientSocket) {
|
||||
iosTool()->errorMsg(QString::fromLatin1("setting up relayer for new connection"));
|
||||
RemotePortRelayer *newConnection = new RemotePortRelayer(this, clientSocket);
|
||||
@@ -498,7 +508,6 @@ IosTool::IosTool(QObject *parent):
|
||||
maxProgress(0),
|
||||
opLeft(0),
|
||||
debug(false),
|
||||
ipv6(false),
|
||||
inAppOutput(false),
|
||||
splitAppOutput(true),
|
||||
appOp(Ios::IosDeviceManager::None),
|
||||
@@ -548,8 +557,6 @@ void IosTool::run(const QStringList &args)
|
||||
appOp = Ios::IosDeviceManager::AppOp(appOp | Ios::IosDeviceManager::Run);
|
||||
} else if (arg == QLatin1String("--noninteractive")) {
|
||||
// ignored for compatibility
|
||||
} else if (arg == QLatin1String("--ipv6")) {
|
||||
ipv6 = true;
|
||||
} else if (arg == QLatin1String("-v") || arg == QLatin1String("--verbose")) {
|
||||
echoRelays = true;
|
||||
} else if (arg == QLatin1String("-d") || arg == QLatin1String("--debug")) {
|
||||
@@ -721,12 +728,12 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId,
|
||||
int qmlPort = deviceSession->qmljsDebugPort();
|
||||
if (qmlPort) {
|
||||
qmlServer = new GenericRelayServer(this, qmlPort, deviceSession);
|
||||
qmlServer->startServer(0, ipv6);
|
||||
qmlServer->startServer(0);
|
||||
}
|
||||
}
|
||||
if (debug) {
|
||||
gdbServer = new SingleRelayServer(this, gdbFd);
|
||||
if (!gdbServer->startServer(0, ipv6)) {
|
||||
if (!gdbServer->startServer(0)) {
|
||||
doExit(-4);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1903,9 +1903,9 @@ void tst_Dumpers::dumper_data()
|
||||
+ Check("h1.2.value.1", "[1]", "2", "int")
|
||||
|
||||
+ Check("h2", "<3 items>", "@QHash<int, float>")
|
||||
+ Check("h2.0", "[0] 0", FloatValue("33"), "float")
|
||||
+ Check("h2.1", "[1] 22", FloatValue("22"), "float")
|
||||
+ Check("h2.2", "[2] 11", FloatValue("11"), "float")
|
||||
+ Check("h2.0", "[0] 0", FloatValue("33"), "")
|
||||
+ Check("h2.1", "[1] 22", FloatValue("22"), "")
|
||||
+ Check("h2.2", "[2] 11", FloatValue("11"), "")
|
||||
|
||||
+ Check("h3", "<1 items>", "@QHash<@QString, int>")
|
||||
+ Check("h3.0.key", "key", "\"22.0\"", "@QString")
|
||||
@@ -1934,7 +1934,7 @@ void tst_Dumpers::dumper_data()
|
||||
+ CheckType("h7.2.value", "@QPointer<@QObject>")
|
||||
|
||||
+ Check("h8", "<3 items>", "Hash")
|
||||
+ Check("h8.0", "[0] 22", FloatValue("22"), "float")
|
||||
+ Check("h8.0", "[0] 22", FloatValue("22"), "")
|
||||
+ Check("it1.key", "22", "int")
|
||||
+ Check("it1.value", FloatValue("22"), "float")
|
||||
+ Check("it3.key", "33", "int")
|
||||
@@ -2347,8 +2347,8 @@ void tst_Dumpers::dumper_data()
|
||||
+ Check("m1.1.value.0", "[0]", "\"22\"", "@QString")
|
||||
|
||||
+ Check("m2", "<2 items>", "@QMap<unsigned int, float>")
|
||||
+ Check("m2.0", "[0] 11", FloatValue("31.0"), "float")
|
||||
+ Check("m2.1", "[1] 22", FloatValue("32.0"), "float")
|
||||
+ Check("m2.0", "[0] 11", FloatValue("31.0"), "")
|
||||
+ Check("m2.1", "[1] 22", FloatValue("32.0"), "")
|
||||
|
||||
+ Check("m3", "<2 items>", "T")
|
||||
|
||||
@@ -2432,8 +2432,8 @@ void tst_Dumpers::dumper_data()
|
||||
+ Check("m0", "<0 items>", "@QMultiMap<int, int>")
|
||||
|
||||
+ Check("m1", "<6 items>", "@QMultiMap<unsigned int, float>")
|
||||
+ Check("m1.0", "[0] 11", FloatValue("11"), "float")
|
||||
+ Check("m1.5", "[5] 22", FloatValue("22"), "float")
|
||||
+ Check("m1.0", "[0] 11", FloatValue("11"), "")
|
||||
+ Check("m1.5", "[5] 22", FloatValue("22"), "")
|
||||
|
||||
+ Check("m2", "<1 items>", "@QMultiMap<@QString, float>")
|
||||
+ Check("m2.0.key", "\"22.0\"", "@QString")
|
||||
@@ -4120,23 +4120,23 @@ void tst_Dumpers::dumper_data()
|
||||
"map4.insert(std::pair<unsigned int, float>(22, 25.0));\n")
|
||||
|
||||
+ Check("map1", "<2 items>", "std::map<unsigned int, unsigned int>")
|
||||
+ Check("map1.0", "[0] 11", "1", "unsigned int")
|
||||
+ Check("map1.1", "[1] 22", "2", "unsigned int")
|
||||
+ Check("map1.0", "[0] 11", "1", "")
|
||||
+ Check("map1.1", "[1] 22", "2", "")
|
||||
|
||||
+ Check("map2", "<2 items>", "std::map<unsigned int, float>")
|
||||
+ Check("map2.0", "[0] 11", FloatValue("11"), "float")
|
||||
+ Check("map2.1", "[1] 22", FloatValue("22"), "float")
|
||||
+ Check("map2.0", "[0] 11", FloatValue("11"), "")
|
||||
+ Check("map2.1", "[1] 22", FloatValue("22"), "")
|
||||
|
||||
+ Check("map3", "<6 items>", "Map")
|
||||
+ Check("map3.0", "[0] 11", FloatValue("11"), "float")
|
||||
+ Check("map3.0", "[0] 11", FloatValue("11"), "")
|
||||
+ Check("it1.first", "11", "int")
|
||||
+ Check("it1.second", FloatValue("11"), "float")
|
||||
+ Check("it6.first", "66", "int")
|
||||
+ Check("it6.second", FloatValue("66"), "float")
|
||||
|
||||
+ Check("map4", "<5 items>", "std::multimap<unsigned int, float>")
|
||||
+ Check("map4.0", "[0] 11", FloatValue("11"), "float")
|
||||
+ Check("map4.4", "[4] 22", FloatValue("25"), "float");
|
||||
+ Check("map4.0", "[0] 11", FloatValue("11"), "")
|
||||
+ Check("map4.4", "[4] 22", FloatValue("25"), "");
|
||||
|
||||
|
||||
QTest::newRow("StdMapQt")
|
||||
@@ -4188,33 +4188,33 @@ void tst_Dumpers::dumper_data()
|
||||
+ CoreProfile()
|
||||
|
||||
+ Check("map1", "<3 items>", "std::map<@QString, Foo>")
|
||||
+ Check("map1.0", "[0] \"22.0\"", "", "std::pair<@QString const, Foo>")
|
||||
+ Check("map1.0", "[0] \"22.0\"", "", "")
|
||||
+ Check("map1.0.first", "\"22.0\"", "@QString")
|
||||
+ Check("map1.0.second", "", "Foo")
|
||||
+ Check("map1.0.second.a", "22", "int")
|
||||
+ Check("map1.1", "[1] \"33.0\"", "", "std::pair<@QString const, Foo>")
|
||||
+ Check("map1.1", "[1] \"33.0\"", "", "")
|
||||
+ Check("map1.2.first", "\"44.0\"", "@QString")
|
||||
+ Check("map1.2.second", "", "Foo")
|
||||
+ Check("map1.2.second.a", "44", "int")
|
||||
|
||||
+ Check("map2", "<2 items>", "std::map<char const*, Foo>")
|
||||
+ Check("map2.0", "[0] \"22.0\"", "", "std::pair<char const* const, Foo>")
|
||||
+ Check("map2.0", "[0] \"22.0\"", "", "")
|
||||
+ Check("map2.0.first", "\"22.0\"", "char *")
|
||||
+ Check("map2.0.first.0", "[0]", "50", "char")
|
||||
+ Check("map2.0.second", "", "Foo")
|
||||
+ Check("map2.0.second.a", "22", "int")
|
||||
+ Check("map2.1", "[1] \"33.0\"", "", "std::pair<char const* const, Foo>")
|
||||
+ Check("map2.1", "[1] \"33.0\"", "", "")
|
||||
+ Check("map2.1.first", "\"33.0\"", "char *")
|
||||
+ Check("map2.1.first.0", "[0]", "51", "char")
|
||||
+ Check("map2.1.second", "", "Foo")
|
||||
+ Check("map2.1.second.a", "33", "int")
|
||||
|
||||
+ Check("map3", "<2 items>", "std::map<unsigned int, @QStringList>")
|
||||
+ Check("map3.0", "[0] 11", "<1 items>", "std::pair<unsigned int const, @QStringList>")
|
||||
+ Check("map3.0", "[0] 11", "<1 items>", "")
|
||||
+ Check("map3.0.first", "11", "unsigned int")
|
||||
+ Check("map3.0.second", "<1 items>", "@QStringList")
|
||||
+ Check("map3.0.second.0", "[0]", "\"11\"", "@QString")
|
||||
+ Check("map3.1", "[1] 22", "<1 items>", "std::pair<unsigned int const, @QStringList>")
|
||||
+ Check("map3.1", "[1] 22", "<1 items>", "")
|
||||
+ Check("map3.1.first", "22", "unsigned int")
|
||||
+ Check("map3.1.second", "<1 items>", "@QStringList")
|
||||
+ Check("map3.1.second.0", "[0]", "\"22\"", "@QString")
|
||||
@@ -4222,26 +4222,25 @@ void tst_Dumpers::dumper_data()
|
||||
+ Check("map4.1.second.0", "[0]", "\"22\"", "@QString")
|
||||
|
||||
+ Check("map5", "<2 items>", "std::map<@QString, float>")
|
||||
+ Check("map5.0", "[0] \"11.0\"", FloatValue("11"), "std::pair<@QString const, float>")
|
||||
+ Check("map5.0", "[0] \"11.0\"", FloatValue("11"), "")
|
||||
+ Check("map5.0.first", "\"11.0\"", "@QString")
|
||||
+ Check("map5.0.second", FloatValue("11"), "float")
|
||||
+ Check("map5.1", "[1] \"22.0\"", FloatValue("22"), "std::pair<@QString const, float>")
|
||||
+ Check("map5.1", "[1] \"22.0\"", FloatValue("22"), "")
|
||||
+ Check("map5.1.first", "\"22.0\"", "@QString")
|
||||
+ Check("map5.1.second", FloatValue("22"), "float")
|
||||
|
||||
+ Check("map6", "<2 items>", "std::map<int, @QString>")
|
||||
+ Check("map6.0", "[0] 11", "\"11.0\"", "std::pair<int const, @QString>")
|
||||
+ Check("map6.0", "[0] 11", "\"11.0\"", "")
|
||||
+ Check("map6.0.first", "11", "int")
|
||||
+ Check("map6.0.second", "\"11.0\"", "@QString")
|
||||
+ Check("map6.1", "[1] 22", "\"22.0\"", "std::pair<int const, @QString>")
|
||||
+ Check("map6.1", "[1] 22", "\"22.0\"", "")
|
||||
+ Check("map6.1.first", "22", "int")
|
||||
+ Check("map6.1.second", "\"22.0\"", "@QString")
|
||||
|
||||
+ Check("map7", "<3 items>", "std::map<@QString, @QPointer<@QObject>>")
|
||||
+ Check("map7.0", "[0] \".\"", "", "std::pair<@QString const, @QPointer<@QObject>>")
|
||||
+ Check("map7.0", "[0] \".\"", "", "")
|
||||
+ Check("map7.0.first", "\".\"", "@QString")
|
||||
+ Check("map7.0.second", "", "@QPointer<@QObject>")
|
||||
+ Check("map7.2", "[2] \"Welt\"", "", "std::pair<@QString const, @QPointer<@QObject>>")
|
||||
+ Check("map7.2.first", "\"Welt\"", "@QString");
|
||||
|
||||
|
||||
@@ -4672,8 +4671,8 @@ void tst_Dumpers::dumper_data()
|
||||
+ Cxx11Profile()
|
||||
|
||||
+ Check("map1", "<2 items>", "std::unordered_map<unsigned int, unsigned int>")
|
||||
+ Check("map1.0", "[0] 22", "2", "unsigned int")
|
||||
+ Check("map1.1", "[1] 11", "1", "unsigned int")
|
||||
+ Check("map1.0", "[0] 22", "2", "")
|
||||
+ Check("map1.1", "[1] 11", "1", "")
|
||||
|
||||
+ Check("map2", "<2 items>", "std::unordered_map<std::string, float>")
|
||||
+ Check("map2.0", "[0] \"22.0\"", FloatValue("22.0"), "")
|
||||
@@ -5382,17 +5381,8 @@ void tst_Dumpers::dumper_data()
|
||||
+ Check("y2", "", "X")
|
||||
+ Check("y3", "", "X");
|
||||
|
||||
QTest::newRow("RValueReferenceLldb")
|
||||
QTest::newRow("RValueReference")
|
||||
<< Data(rvalueData)
|
||||
+ LldbEngine
|
||||
+ Check("x1", "", "X &&")
|
||||
+ Check("x2", "", "X &&")
|
||||
+ Check("x3", "", "X &&");
|
||||
|
||||
QTest::newRow("RValueReferenceGdb")
|
||||
<< Data(rvalueData)
|
||||
+ GdbEngine
|
||||
+ GccVersion(0, 40704)
|
||||
+ Check("x1", "", "X &")
|
||||
+ Check("x2", "", "X &")
|
||||
+ Check("x3", "", "X &");
|
||||
@@ -6231,6 +6221,7 @@ void tst_Dumpers::dumper_data()
|
||||
+ Check("v15", "\"utf16\"", "@QJSValue (QString)")
|
||||
+ Check("v15.1", "[1]", "116", "@QChar");
|
||||
|
||||
#if 0
|
||||
#ifdef Q_OS_LINUX
|
||||
// Hint: To open a failing test in Creator, do:
|
||||
// touch qt_tst_dumpers_Nim_.../dummy.nimproject
|
||||
@@ -6239,6 +6230,7 @@ void tst_Dumpers::dumper_data()
|
||||
nimData.configTest = "which nim";
|
||||
nimData.allProfile =
|
||||
"CONFIG -= qt\n"
|
||||
"SOURCES += main.nim\n"
|
||||
"# Prevents linking\n"
|
||||
"TARGET=\n"
|
||||
"# Overwrites qmake-generated 'all' target.\n"
|
||||
@@ -6253,8 +6245,10 @@ void tst_Dumpers::dumper_data()
|
||||
"proc mainProc =\n"
|
||||
" var name: string = \"Hello World\"\n"
|
||||
" var i: int = 43\n"
|
||||
" var j: int\n"
|
||||
" var x: seq[int]\n"
|
||||
" x = @[1, 2, 3, 4, 5, 6]\n\n"
|
||||
" j = i + name.len()\n"
|
||||
" # Crash it.\n"
|
||||
" var m1 = Mirror(tag:1)\n"
|
||||
" var m2 = Mirror(tag:2)\n"
|
||||
@@ -6278,6 +6272,7 @@ void tst_Dumpers::dumper_data()
|
||||
+ Check("x", "<6 items>", Pattern("TY.*NI.6..")) // Something like "TY95019 (NI[6])"
|
||||
+ Check("x.2", "[2]", "3", "NI");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
||||
@@ -44,6 +44,7 @@ private slots:
|
||||
void threadPriority();
|
||||
void runAsyncNoFutureInterface();
|
||||
void crefFunction();
|
||||
void onResultReady();
|
||||
};
|
||||
|
||||
void report3(QFutureInterface<int> &fi)
|
||||
@@ -557,6 +558,64 @@ void tst_RunExtensions::crefFunction()
|
||||
QCOMPARE(value, true);
|
||||
}
|
||||
|
||||
class ObjWithProperty : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public slots:
|
||||
void setValue(const QString &s)
|
||||
{
|
||||
value = s;
|
||||
}
|
||||
|
||||
public:
|
||||
QString value;
|
||||
};
|
||||
|
||||
void tst_RunExtensions::onResultReady()
|
||||
{
|
||||
{ // lambda
|
||||
QFuture<QString> f = Utils::runAsync([](QFutureInterface<QString> &fi) {
|
||||
fi.reportResult("Hi");
|
||||
fi.reportResult("there");
|
||||
});
|
||||
int count = 0;
|
||||
QString res;
|
||||
Utils::onResultReady(f, [&count, &res](const QString &s) {
|
||||
++count;
|
||||
res = s;
|
||||
});
|
||||
f.waitForFinished();
|
||||
QCoreApplication::processEvents();
|
||||
QCOMPARE(count, 2);
|
||||
QCOMPARE(res, QString("there"));
|
||||
}
|
||||
{ // lambda with guard
|
||||
QFuture<QString> f = Utils::runAsync([](QFutureInterface<QString> &fi) {
|
||||
fi.reportResult("Hi");
|
||||
fi.reportResult("there");
|
||||
});
|
||||
int count = 0;
|
||||
ObjWithProperty obj;
|
||||
Utils::onResultReady(f, &obj, [&count, &obj](const QString &s) {
|
||||
++count;
|
||||
obj.setValue(s);
|
||||
});
|
||||
f.waitForFinished();
|
||||
QCoreApplication::processEvents();
|
||||
QCOMPARE(count, 2);
|
||||
QCOMPARE(obj.value, QString("there"));
|
||||
}
|
||||
{ // member
|
||||
QFuture<QString> f = Utils::runAsync([]() { return QString("Hi"); });
|
||||
ObjWithProperty obj;
|
||||
Utils::onResultReady(f, &obj, &ObjWithProperty::setValue);
|
||||
f.waitForFinished();
|
||||
QCoreApplication::processEvents();
|
||||
QCOMPARE(obj.value, QString("Hi"));
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_RunExtensions)
|
||||
|
||||
#include "tst_runextensions.moc"
|
||||
|
||||