Merge remote-tracking branch 'origin/2.8' into HEAD

Conflicts:
	qtcreator.pri
	qtcreator.qbs

Change-Id: I5d2018d3437b99bcdffa92bf1a212f42923c4fad
This commit is contained in:
Eike Ziller
2013-07-03 16:55:27 +02:00
61 changed files with 1036 additions and 363 deletions

2
README
View File

@@ -7,7 +7,7 @@ Supported Platforms
The standalone binary packages support the following platforms:
Windows XP SP2 or later
(K)Ubuntu Linux 10.04 (32-bit and 64-bit) or later
(K)Ubuntu Linux 11.10 (32-bit and 64-bit) or later
Mac OS 10.6 or later
Building the sources requires Qt 4.8.0 or later.

View File

@@ -29,12 +29,6 @@ def directBaseClass(typeobj, index = 0):
# FIXME: Check it's really a base.
return typeobj.fields()[index]
def createPointerValue(context, address, pointeeType):
return gdb.Value(address).cast(pointeeType.pointer())
def createReferenceValue(context, address, referencedType):
return gdb.Value(address).cast(referencedType.pointer()).dereference()
def savePrint(output):
try:
print(output)
@@ -358,6 +352,9 @@ qqDumpers = {}
# This is a cache of all dumpers that support writing.
qqEditable = {}
# This is an approximation of the Qt Version found
qqVersion = None
def registerDumper(function):
global qqDumpers, qqFormats, qqEditable
try:
@@ -1134,7 +1131,7 @@ def qtNamespace():
if not qqNs is None:
return qqNs
try:
str = catchCliOutput("ptype QString::Null")[0]
str = gdb.execute("ptype QString::Null", to_string=True)
# The result looks like:
# "type = const struct myns::QString::Null {"
# " <no data fields>"
@@ -1323,6 +1320,7 @@ class Dumper:
self.formats = {}
self.useDynamicType = True
self.expandedINames = {}
self.childEventAddress = None
def __init__(self, args):
self.defaultInit()
@@ -1539,15 +1537,73 @@ class Dumper:
def charPtrType(self):
return self.lookupType('char*')
def intPtrType(self):
return self.lookupType('int*')
def voidPtrType(self):
return self.lookupType('void*')
def voidPtrSize(self):
return self.voidPtrType().sizeof
def addressOf(self, value):
return long(value.address)
def createPointerValue(self, address, pointeeType):
return gdb.Value(address).cast(pointeeType.pointer())
def intSize(self):
return 4
def ptrSize(self):
return self.lookupType('void*').sizeof
def is32bit(self):
return self.lookupType('void*').sizeof == 4
def createValue(self, address, referencedType):
return gdb.Value(address).cast(referencedType.pointer()).dereference()
def dereference(self, addr):
return long(gdb.Value(addr).cast(self.voidPtrType().pointer()).dereference())
def extractInt(self, addr):
return long(gdb.Value(addr).cast(self.intPtrType()).dereference())
# Do not use value.address here as this might not have one,
# i.e. be the result of an inferior call
def dereferenceValue(self, value):
return value.cast(self.voidPtrType())
def isQObject(self, value):
try:
#if True:
vtable = self.dereference(long(value.address)) # + ptrSize
metaObjectEntry = self.dereference(vtable) # It's the first entry.
#warn("MO: 0x%x " % metaObjectEntry)
s = gdb.execute("info symbol 0x%x" % metaObjectEntry, to_string=True)
#warn("S: %s " % s)
#return s.find("::metaObject() const") > 0
return s.find("::metaObject() const") > 0 or s.find("10metaObjectEv") > 0
#return str(metaObjectEntry).find("::metaObject() const") > 0
except:
return False
def isQObject_B(self, value):
# Alternative: Check for specific values, like targeting the
# 'childEvent' member which is typically not overwritten, slot 8.
# ~"Symbol \"Myns::QObject::childEvent(Myns::QChildEvent*)\" is a
# function at address 0xb70f691a.\n"
if self.childEventAddress == None:
try:
loc = gdb.execute("info address ::QObject::childEvent", to_string=True)
self.childEventAddress = long(loc[loc.rfind(' '):-2], 16)
except:
self.childEventAddress = 0
try:
vtable = self.dereference(long(value.address))
return self.childEventAddress == self.dereference(vtable + 8 * self.ptrSize())
except:
return False
def put(self, value):
self.output.append(value)
@@ -1559,6 +1615,18 @@ class Dumper:
return xrange(0, self.currentNumChild)
return xrange(min(self.currentMaxNumChild, self.currentNumChild))
def qtVersion(self):
global qqVersion
if not qqVersion is None:
return qqVersion
try:
# This will fail on Qt 5
gdb.execute("ptype QString::shared_empty", to_string=True)
qqVersion = 0x040800
except:
qqVersion = 0x050000
return qqVersion
# Convenience function.
def putItemCount(self, count, maximum = 1000000000):
# This needs to override the default value, so don't use 'put' directly.
@@ -2118,7 +2186,8 @@ class Dumper:
#warn("INAME: %s " % self.currentIName)
#warn("INAMES: %s " % self.expandedINames)
#warn("EXPANDED: %s " % (self.currentIName in self.expandedINames))
self.tryPutObjectNameValue(value) # Is this too expensive?
if self.isQObject(value):
self.putQObjectNameValue(value) # Is this too expensive?
self.putType(typeName)
self.putEmptyValue()
self.putNumChild(fieldCount(type))

View File

@@ -84,12 +84,12 @@ def isSimpleType(typeobj):
def call2(value, func, args):
# args is a tuple.
arg = ','.join(args)
warn("CALL: %s -> %s(%s)" % (value, func, arg))
#warn("CALL: %s -> %s(%s)" % (value, func, arg))
type = value.type.name
exp = "((%s*)%s)->%s(%s)" % (type, value.address, func, arg)
warn("CALL: %s" % exp)
#warn("CALL: %s" % exp)
result = value.CreateValueFromExpression('$tmp', exp)
warn(" -> %s" % result)
#warn(" -> %s" % result)
return result
def call(value, func, *args):
@@ -252,14 +252,6 @@ Value = lldb.SBValue
def pointerValue(value):
return value.GetValueAsUnsigned()
def createPointerValue(context, address, pointeeType):
addr = int(address) & 0xFFFFFFFFFFFFFFFF
return context.CreateValueFromAddress(None, addr, pointeeType).AddressOf()
def createReferenceValue(context, address, referencedType):
addr = int(address) & 0xFFFFFFFFFFFFFFFF
return context.CreateValueFromAddress(None, addr, referencedType)
def impl_SBValue__add__(self, offset):
if self.GetType().IsPointerType():
if isinstance(offset, int) or isinstance(offset, long):
@@ -269,7 +261,12 @@ def impl_SBValue__add__(self, offset):
itemsize = self.GetType().GetPointeeType().GetByteSize()
address = self.GetValueAsUnsigned() + offset * itemsize
address = address & 0xFFFFFFFFFFFFFFFF # Force unsigned
return createPointerValue(self, address, self.GetType().GetPointeeType())
# We don't have a dumper object
#return createPointerValue(self, address, self.GetType().GetPointeeType())
addr = int(address) & 0xFFFFFFFFFFFFFFFF
return self.CreateValueFromAddress(None, addr, self.GetType().GetPointeeType()).AddressOf()
raise RuntimeError("SBValue.__add__ not implemented: %s" % self.GetType())
return NotImplemented
@@ -565,7 +562,7 @@ class Dumper:
self.intType_ = None
self.sizetType_ = None
self.charPtrType_ = None
self.voidType_ = None
self.voidPtrType_ = None
self.isShuttingDown_ = False
self.isInterrupting_ = False
self.dummyValue = None
@@ -609,6 +606,15 @@ class Dumper:
inner = self.extractTemplateArgument(typeobj.GetName(), index)
return int(inner)
def qtVersion(self):
return 0x050000
def is32bit(self):
return False
def intSize(self):
return 4
def intType(self):
if self.intType_ is None:
self.intType_ = self.target.FindFirstType('int')
@@ -625,11 +631,11 @@ class Dumper:
return self.charPtrType_
def voidPtrType(self):
return None
return self.charPtrType() # FIXME
if self.voidPtrType_ is None:
self.voidPtrType_ = self.target.FindFirstType('void').GetPointerType()
return self.voidPtrType_
def voidPtrSize(self):
return None
def ptrSize(self):
return self.charPtrType().GetByteSize()
def sizetType(self):
@@ -640,6 +646,15 @@ class Dumper:
def addressOf(self, value):
return int(value.GetLoadAddress())
def dereferenceValue(self, value):
return long(value.Cast(self.voidPtrType()))
def dereference(self, address):
return long(self.createValue(address, self.voidPtrType()))
def extractInt(self, address):
return int(self.createValue(address, self.intType()))
def handleCommand(self, command):
result = lldb.SBCommandReturnObject()
self.debugger.GetCommandInterpreter().HandleCommand(command, result)
@@ -748,6 +763,14 @@ class Dumper:
def parseAndEvalute(self, expr):
return expr
def createPointerValue(self, address, pointeeType):
addr = int(address) & 0xFFFFFFFFFFFFFFFF
return self.context.CreateValueFromAddress(None, addr, pointeeType).AddressOf()
def createValue(self, address, referencedType):
addr = int(address) & 0xFFFFFFFFFFFFFFFF
return self.context.CreateValueFromAddress(None, addr, referencedType)
def putCallItem(self, name, value, func, *args):
result = call2(value, func, args)
with SubItem(self, name):
@@ -858,7 +881,7 @@ class Dumper:
def firstUsableFrame(self):
thread = self.currentThread()
for i in xrange(4):
for i in xrange(10):
frame = thread.GetFrameAtIndex(i)
lineEntry = frame.GetLineEntry()
line = lineEntry.GetLine()
@@ -875,8 +898,6 @@ class Dumper:
result += ',current-thread="%s"' % thread.GetThreadID()
result += ',frames=['
n = thread.GetNumFrames()
if n > 4:
n = 4
for i in xrange(n):
frame = thread.GetFrameAtIndex(i)
lineEntry = frame.GetLineEntry()
@@ -1007,7 +1028,8 @@ class Dumper:
if value.GetType().IsReferenceType():
origType = value.GetTypeName();
type = value.GetType().GetDereferencedType()
self.putItem(createReferenceValue(value, value.GetAddress(), type))
addr = int(value.GetAddress()) & 0xFFFFFFFFFFFFFFFF
self.putItem(value.CreateValueFromAddress(None, addr, type))
self.putBetterType(origType)
return
@@ -1039,6 +1061,7 @@ class Dumper:
#warn("DUMPABLE: %s" % (stripped in qqDumpers))
if stripped in qqDumpers:
self.putType(typeName)
self.context = value
qqDumpers[stripped](self, value)
return

View File

@@ -18,6 +18,7 @@ movableTypes = set([
"QXmlStreamNotationDeclaration", "QXmlStreamEntityDeclaration"
])
def checkSimpleRef(ref):
count = int(ref["_q_value"])
check(count > 0)
@@ -34,24 +35,30 @@ def checkRef(ref):
check(count >= minimum)
check(count < 1000000)
def qByteArrayData(d, addr):
if d.qtVersion() >= 0x050000:
# QTypedArray:
# - QtPrivate::RefCount ref
# - int size
# - uint alloc : 31, capacityReserved : 1
# - qptrdiff offset
size = d.extractInt(addr + 4)
alloc = d.extractInt(addr + 8) & 0x7ffffff
data = addr + d.dereference(addr + 8 + d.ptrSize())
else:
# Data:
# - QBasicAtomicInt ref;
# - int alloc, size;
# - [padding]
# - char *data;
alloc = d.extractInt(addr + 4)
size = d.extractInt(addr + 8)
data = d.dereference(addr + 8 + d.ptrSize())
return data, size, alloc
def qByteArrayDataData(d, value):
checkRef(value['ref'])
size = int(value['size'])
alloc = int(value['alloc'])
try:
# Qt 5. Will fail on Qt 4 due to the missing 'offset' member.
addr = d.addressOf(value) + int(value['offset'])
except:
# Qt 4:
addr = value['data']
return createPointerValue(value, addr, d.charType()), size, alloc
def qByteArrayData(d, value):
return d.byteArrayDataData(value['d'].dereference())
def qEncodeByteArray(d, value, limit = None):
data, size, alloc = d.byteArrayData(value)
def qEncodeByteArray(d, addr, limit = None):
data, size, alloc = qByteArrayData(d, addr)
if alloc != 0:
check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
limit = d.computeLimit(size, limit)
@@ -60,8 +67,9 @@ def qEncodeByteArray(d, value, limit = None):
s += "2e2e2e"
return s
def qEncodeString(d, value, limit = 0):
data, size, alloc = d.stringData(value)
# addr is the begin of a QByteArrayData structure
def qEncodeString(d, addr, limit = 0):
data, size, alloc = qByteArrayData(d, addr)
if alloc != 0:
check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
limit = d.computeLimit(size, limit)
@@ -70,6 +78,24 @@ def qEncodeString(d, value, limit = 0):
s += "2e002e002e00"
return s
def qPutStringValueByAddress(d, addr):
d.putValue(qEncodeString(d, d.dereference(addr)), Hex4EncodedLittleEndian)
Dumper.encodeByteArray = \
lambda d, value: qEncodeByteArray(d, d.dereferenceValue(value))
Dumper.byteArrayData = \
lambda d, value: qByteArrayData(d, d.dereferenceValue(value))
Dumper.putByteArrayValue = \
lambda d, value: d.putValue(d.encodeByteArray(value), Hex2EncodedLatin1)
Dumper.encodeString = \
lambda d, value: qEncodeString(d, d.dereferenceValue(value))
Dumper.stringData = \
lambda d, value: qByteArrayData(d, d.dereferenceValue(value))
Dumper.putStringValue = \
lambda d, value: d.putValue(d.encodeString(value), Hex4EncodedLittleEndian)
def mapForms():
return "Normal,Compact"
@@ -96,49 +122,68 @@ def qPutMapName(d, value):
else:
d.put('name="%s",' % value)
Dumper.encodeByteArray = qEncodeByteArray
Dumper.byteArrayData = qByteArrayData
Dumper.byteArrayDataData = qByteArrayDataData
Dumper.putByteArrayValue = \
lambda d, value: d.putValue(d.encodeByteArray(value), Hex2EncodedLatin1)
Dumper.putStringValue = \
lambda d, value: d.putValue(d.encodeString(value), Hex4EncodedLittleEndian)
Dumper.encodeString = qEncodeString
Dumper.stringData = Dumper.byteArrayData
Dumper.putMapName = qPutMapName
Dumper.isMapCompact = \
lambda d, keyType, valueType: qMapCompact(d.currentItemFormat(), keyType, valueType)
# Returns True when it encounters a QObject or derived class.
def tryPutObjectNameValue(d, value):
def qPutQObjectNameValue(d, value):
try:
# Is this derived from QObject?
dd = value["d_ptr"]["d"]
privateType = d.lookupType(d.ns + "QObjectPrivate")
staticMetaObject = value["staticMetaObject"]
d_ptr = dd.cast(privateType.pointer()).dereference()
objectName = None
try:
objectName = d_ptr["objectName"]
except: # Qt 5
p = d_ptr["extraData"]
if not isNull(p):
objectName = p.dereference()["objectName"]
if not objectName is None:
data, size, alloc = d.stringData(objectName)
intSize = d.intSize()
ptrSize = d.ptrSize()
# dd = value["d_ptr"]["d"] is just behind the vtable.
dd = d.dereference(d.addressOf(value) + ptrSize)
if d.qtVersion() < 0x050000:
# Size of QObjectData: 5 pointer + 2 int
# - vtable
# - QObject *q_ptr;
# - QObject *parent;
# - QObjectList children;
# - uint isWidget : 1; etc..
# - int postedEvents;
# - QMetaObject *metaObject;
# Offset of objectName in QObjectPrivate: 5 pointer + 2 int
# - [QObjectData base]
# - QString objectName
objectName = d.dereference(dd + 5 * ptrSize + 2 * intSize)
else:
# Size of QObjectData: 5 pointer + 2 int
# - vtable
# - QObject *q_ptr;
# - QObject *parent;
# - QObjectList children;
# - uint isWidget : 1; etc...
# - int postedEvents;
# - QDynamicMetaObjectData *metaObject;
extra = d.dereference(dd + 5 * ptrSize + 2 * intSize)
if extra == 0:
return
# Offset of objectName in ExtraData: 6 pointer
# - QVector<QObjectUserData *> userData; only #ifndef QT_NO_USERDATA
# - QList<QByteArray> propertyNames;
# - QList<QVariant> propertyValues;
# - QVector<int> runningTimers;
# - QList<QPointer<QObject> > eventFilters;
# - QString objectName
objectName = d.dereference(extra + 5 * ptrSize)
data, size, alloc = qByteArrayData(d, objectName)
if size > 0:
str = d.readRawMemory(data, 2 * size)
d.putValue(str, Hex4EncodedLittleEndian, 1)
return True
except:
return False
pass
Dumper.tryPutObjectNameValue = tryPutObjectNameValue
Dumper.putQObjectNameValue = qPutQObjectNameValue
############################################################################################
###################################################################################
def qdump__QAtomicInt(d, value):
@@ -161,13 +206,6 @@ def qdump__QBasicAtomicPointer(d, value):
with Children(d):
d.putItem(value["_q_value"])
def qdump__QByteArrayData(d, value):
data, size, alloc = d.byteArrayDataData(value)
d.putValue(d.readRawMemory(data, size), Hex2EncodedLatin1)
d.putNumChild(size)
if d.isExpanded():
d.putArrayData(d.charType(), data, size)
def qform__QByteArray():
return "Inline,As Latin1 in Separate Window,As UTF-8 in Separate Window"
@@ -358,12 +396,20 @@ def qdump__QTime(d, value):
# This relies on the Qt4/Qt5 internal structure layout:
# {sharedref(4), date(8), time(4+x)}
def qdump__QDateTime(d, value):
intType = d.lookupType("int")
intPtrType = intType.pointer()
base = pointerValue(value.cast(intPtrType))
mds = int(createReferenceValue(value, base + intPtrType.sizeof + 8, intType))
base = d.dereferenceValue(value)
# QDateTimePrivate:
# - QAtomicInt ref; (padded on 64 bit)
# - [QDate date;]
# - - uint jd in Qt 4, qint64 in Qt 5; padded on 64 bit
# - [QTime time;]
# - - uint mds;
# - Spec spec;
dateSize = 4 if d.qtVersion() < 0x050000 and d.is32bit() else 8
dateBase = base + d.ptrSize() # Only QAtomicInt, but will be padded.
timeBase = dateBase + dateSize
mds = d.extractInt(timeBase)
if mds >= 0:
jd = int(createReferenceValue(value, base + intPtrType.sizeof, intType))
jd = d.extractInt(dateBase)
d.putValue("%s/%s" % (jd, mds), JulianDateAndMillisecondsSinceMidnight)
d.putNumChild(1)
if d.isExpanded():
@@ -388,31 +434,54 @@ def qdump__QDateTime(d, value):
def qdump__QDir(d, value):
d.putNumChild(1)
data = value["d_ptr"]["d"].dereference()
try:
# Up to Qt 4.7
d.putStringValue(data["path"])
except:
# Qt 4.8 and later.
d.putStringValue(data["dirEntry"]["m_filePath"])
privAddress = d.dereferenceValue(value)
bit32 = d.is32bit()
qt5 = d.qtVersion() >= 0x050000
# value.d_ptr.d.dirEntry.m_filePath - value.d_ptr.d
offset = (32 if bit32 else 56) if qt5 else 36
filePathAddress = privAddress + offset
#try:
# # Up to Qt 4.7
# d.putStringValue(data["path"])
#except:
# # Qt 4.8 and later.
# d.putStringValue(data["dirEntry"]["m_filePath"])
qPutStringValueByAddress(d, filePathAddress)
if d.isExpanded():
with Children(d):
qdir = d.ns + "QDir::"
d.putCallItem("absolutePath", value, "absolutePath")
d.putCallItem("canonicalPath", value, "canonicalPath")
d.putSubItem("entryList", data["files"])
d.putSubItem("entryInfoList", data["fileInfos"])
call(value, "count") # Fill cache.
#d.putCallItem("absolutePath", value, "absolutePath")
#d.putCallItem("canonicalPath", value, "canonicalPath")
with SubItem(d, "absolutePath"):
# value.d_ptr.d.absoluteDirEntry.m_filePath - value.d_ptr.d
offset = (48 if bit32 else 80) if qt5 else 36
typ = d.lookupType(d.ns + "QString")
d.putItem(d.createValue(privAddress + offset, typ))
with SubItem(d, "entryInfoList"):
# value.d_ptr.d.fileInfos - value.d_ptr.d
offset = (28 if bit32 else 48) if qt5 else 32
typ = d.lookupType(d.ns + "QList<" + d.ns + "QFileInfo>")
d.putItem(d.createValue(privAddress + offset, typ))
with SubItem(d, "entryList"):
# d.ptr.d.files - value.d_ptr.d
offset = (24 if bit32 else 40) if qt5 else 28
typ = d.lookupType(d.ns + "QStringList")
d.putItem(d.createValue(privAddress + offset, typ))
def qdump__QFile(d, value):
try:
# Try using debug info first.
ptype = d.lookupType(d.ns + "QFilePrivate").pointer()
d_ptr = value["d_ptr"]["d"]
d.putStringValue(d_ptr.cast(ptype).dereference()["fileName"])
except:
d.putPlainChildren(value)
return
fileNameAddress = d.addressOf(d_ptr.cast(ptype).dereference()["fileName"])
d.putNumChild(1)
except:
# 176 is the best guess.
privAddress = d.dereference(d.addressOf(value) + d.ptrSize())
fileNameAddress = privAddress + 176 # Qt 5, 32 bit
d.putNumChild(0)
qPutStringValueByAddress(d, fileNameAddress)
if d.isExpanded():
with Children(d):
base = fieldAt(value.type, 0).type
@@ -421,11 +490,16 @@ def qdump__QFile(d, value):
def qdump__QFileInfo(d, value):
try:
d.putStringValue(value["d_ptr"]["d"].dereference()["fileNames"][3])
except:
d.putPlainChildren(value)
return
privAddress = d.dereferenceValue(value)
#bit32 = d.is32bit()
#qt5 = d.qtVersion() >= 0x050000
#try:
# d.putStringValue(value["d_ptr"]["d"].dereference()["fileNames"][3])
#except:
# d.putPlainChildren(value)
# return
filePathAddress = privAddress + d.ptrSize()
qPutStringValueByAddress(d, filePathAddress)
d.putNumChild(1)
if d.isExpanded():
with Children(d, childType=d.lookupType(d.ns + "QString")):
@@ -650,11 +724,16 @@ def qdump__QHash__iterator(d, value):
def qdump__QHostAddress(d, value):
data = value["d"]["d"].dereference()
if int(data["ipString"]["d"]["size"]):
d.putStringValue(data["ipString"])
privAddress = d.dereferenceValue(value)
isQt5 = d.qtVersion() >= 0x050000
ipStringAddress = privAddress + (0 if isQt5 else 24)
# value.d.d->ipString
ipString = qEncodeString(d, d.dereference(ipStringAddress))
if len(ipString) > 0:
d.putValue(ipString, Hex4EncodedLittleEndian)
else:
a = int(data["a"])
# value.d.d->a
a = d.extractInt(privAddress + (2 * d.ptrSize() if isQt5 else 0))
a, n4 = divmod(a, 256)
a, n3 = divmod(a, 256)
a, n2 = divmod(a, 256)
@@ -663,7 +742,7 @@ def qdump__QHostAddress(d, value):
d.putNumChild(1)
if d.isExpanded():
with Children(d):
d.putFields(data)
d.putFields(value["d"]["d"].dereference())
def qdump__QList(d, value):
dptr = childAt(value, 0)["d"]
@@ -692,15 +771,15 @@ def qdump__QList(d, value):
addr = d.addressOf(array) + begin * stepSize
if isInternal:
if innerSize == stepSize:
p = createPointerValue(value, addr, innerType)
p = d.createPointerValue(addr, innerType)
d.putArrayData(innerType, p, size)
else:
with Children(d, size, childType=innerType):
for i in d.childRange():
p = createPointerValue(value, addr + i * stepSize, innerType)
d.putSubItem(i, p.dereference())
p = d.createValue(addr + i * stepSize, innerType)
d.putSubItem(i, p)
else:
p = createPointerValue(value, addr, innerType.pointer())
p = d.createPointerValue(addr, innerType.pointer())
# about 0.5s / 1000 items
with Children(d, size, maxNumChild=2000, childType=innerType):
for i in d.childRange():
@@ -711,49 +790,57 @@ def qform__QImage():
return "Normal,Displayed"
def qdump__QImage(d, value):
# This relies on current QImage layout
intPtrType = d.lookupType("int").pointer()
base = createReferenceValue(value, d.addressOf(value) + 3 * intPtrType.sizeof, intPtrType)
width = int(base[1])
height = int(base[2])
# This relies on current QImage layout:
# QImageData:
# - QAtomicInt ref
# - int width, height, depth, nbytes
# - qreal devicePixelRatio (+20) # Assume qreal == double, Qt 5 only
# - QVector<QRgb> colortable (+20 + gap)
# - uchar *data (+20 + gap + ptr)
# [- uchar **jumptable jumptable with Qt 3 suppor]
# - enum format (+20 + gap + 2 * ptr)
ptrSize = d.ptrSize()
isQt5 = d.qtVersion() >= 0x050000
offset = (3 if isQt5 else 2) * ptrSize
base = d.dereference(d.addressOf(value) + offset)
width = d.extractInt(base + 4)
height = d.extractInt(base + 8)
nbytes = d.extractInt(base + 16)
pixelRatioSize = 8 if isQt5 else 0
jumpTableSize = ptrSize if not isQt5 else 0 # FIXME: Assumes Qt3 Support
bits = d.dereference(base + 20 + pixelRatioSize + ptrSize)
iformat = d.extractInt(base + 20 + pixelRatioSize + jumpTableSize + 2 * ptrSize)
d.putValue("(%dx%d)" % (width, height))
d.putNumChild(0)
#d.putNumChild(1)
d.putNumChild(1)
if d.isExpanded():
with Children(d):
d.putIntItem("width", width)
d.putIntItem("height", height)
d.putIntItem("nbytes", nbytes)
d.putIntItem("format", iformat)
with SubItem(d, "data"):
d.putNoType()
d.putValue("0x%x" % bits)
d.putNumChild(0)
d.putValue("size: %s bytes" % nbytes);
d.putType("void *")
format = d.currentItemFormat()
if format == 1:
d.putDisplay(StopDisplay)
elif format == 2:
d_ptr = value["d"]
bits = d_ptr["data"]
nbytes = d_ptr["nbytes"]
if False:
# Take four bytes at a time, this is critical for performance.
# In fact, even four at a time is too slow beyond 100x100 or so.
# This is critical for performance. Writing to an external
# file using the following is faster when using GDB.
# file = tempfile.mkstemp(prefix="gdbpy_")
# filename = file[1].replace("\\", "\\\\")
# gdb.execute("dump binary memory %s %s %s" %
# (filename, bits, bits + nbytes))
# d.putDisplay(DisplayImageFile, " %d %d %d %d %s"
# % (width, height, nbytes, iformat, filename))
d.putField("editformat", DisplayImageData)
d.put('%s="' % name)
d.put("%08x" % width)
d.put("%08x" % height)
d.put("%08x" % int(d_ptr["format"]))
p = bits.cast(d.intType().pointer())
for i in xrange(nbytes / 4):
d.put("%08x" % int(p.dereference()))
p += 1
d.put('editvalue="')
d.put('%08x%08x%08x%08x' % (width, height, nbytes, iformat))
d.put(d.readRawMemory(bits, nbytes))
d.put('",')
else:
# Write to an external file. Much faster ;-(
file = tempfile.mkstemp(prefix="gdbpy_")
filename = file[1].replace("\\", "\\\\")
p = bits.cast(d.charType().pointer())
gdb.execute("dump binary memory %s %s %s" %
(filename, cleanAddress(p), cleanAddress(p + nbytes)))
d.putDisplay(DisplayImageFile, " %d %d %d %s"
% (width, height, d_ptr["format"], filename))
def qdump__QLinkedList(d, value):
@@ -960,8 +1047,7 @@ def extractCString(table, offset):
def qdump__QObject(d, value):
#warn("OBJECT: %s " % value)
d.tryPutObjectNameValue(value)
d.putQObjectNameValue(value)
try:
privateTypeName = d.ns + "QObjectPrivate"
@@ -1391,14 +1477,11 @@ def qdump__QObject(d, value):
# }
def qdump__QPixmap(d, value):
painters = int(value["painters"])
check(0 <= painters and painters < 1000)
d_ptr = value["data"]["d"]
if isNull(d_ptr):
d.putValue("(null)")
else:
checkSimpleRef(d_ptr["ref"])
d.putValue("(%dx%d)" % (d_ptr["w"], d_ptr["h"]))
offset = (3 if d.qtVersion() >= 0x050000 else 2) * d.ptrSize()
base = d.dereference(d.addressOf(value) + offset)
width = d.extractInt(base + 4)
height = d.extractInt(base + 8)
d.putValue("(%dx%d)" % (width, height))
d.putNumChild(0)
@@ -1460,16 +1543,35 @@ def qdump__QRectF(d, value):
def qdump__QRegExp(d, value):
d.putStringValue(value["priv"]["engineKey"]["pattern"])
# value.priv.engineKey.pattern
privAddress = d.dereferenceValue(value)
engineKeyAddress = privAddress + d.ptrSize()
patternAddress = engineKeyAddress
qPutStringValueByAddress(d, patternAddress)
d.putNumChild(1)
if d.isExpanded():
with Children(d):
# FIXME: Remove need to call
# QRegExpPrivate:
# - QRegExpEngine *eng (+0)
# - QRegExpEngineKey: (+1ptr)
# - QString pattern; (+1ptr)
# - QRegExp::PatternSyntax patternSyntax; (+2ptr)
# - Qt::CaseSensitivity cs; (+2ptr +1enum +pad?)
# - bool minimal (+2ptr +2enum +2pad?)
# - QString t (+2ptr +2enum +1bool +3pad?)
# - QStringList captures (+3ptr +2enum +1bool +3pad?)
# FIXME: Remove need to call. Needed to warm up cache.
call(value, "capturedTexts") # create cache
with SubItem(d, "syntax"):
d.putItem(value["priv"]["engineKey"]["patternSyntax"])
# value["priv"]["engineKey"["capturedCache"]
address = engineKeyAddress + d.ptrSize()
typ = d.lookupType(d.ns + "QRegExp::PatternSyntax")
d.putItem(d.createValue(address, typ))
with SubItem(d, "captures"):
d.putItem(value["priv"]["capturedCache"])
# value["priv"]["capturedCache"]
address = privAddress + 3 * d.ptrSize() + 12
typ = d.lookupType(d.ns + "QStringList")
d.putItem(d.createValue(address, typ))
def qdump__QRegion(d, value):
@@ -1644,7 +1746,7 @@ def qdump__QStringRef(d, value):
s = value["m_string"].dereference()
data, size, alloc = d.stringData(s)
data += 2 * int(value["m_position"])
size = value["m_size"]
size = int(value["m_size"])
s = d.readRawMemory(data, 2 * size)
d.putValue(s, Hex4EncodedLittleEndian)
d.putNumChild(3)
@@ -1674,22 +1776,19 @@ def qdump__QTextCodec(d, value):
def qdump__QTextCursor(d, value):
dd = value["d"]["d"]
if isNull(dd):
privAddress = d.dereferenceValue(value)
if privAddress == 0:
d.putValue("(invalid)")
d.putNumChild(0)
else:
try:
p = dd.dereference()
d.putValue(p["position"])
except:
d.putPlainChildren(value)
return
positionAddress = privAddress + 2 * d.ptrSize() + 8
d.putValue(d.extractInt(positionAddress))
d.putNumChild(1)
if d.isExpanded():
with Children(d):
d.putIntItem("position", p["position"])
d.putIntItem("anchor", p["anchor"])
positionAddress = privAddress + 2 * d.ptrSize() + 8
d.putIntItem("position", d.extractInt(positionAddress))
d.putIntItem("anchor", d.extractInt(positionAddress + intSize))
d.putCallItem("selected", value, "selectedText")
@@ -1706,22 +1805,31 @@ def qdump__QTextDocument(d, value):
def qdump__QUrl(d, value):
try:
# Qt 4
if d.qtVersion() < 0x050000:
data = value["d"].dereference()
d.putByteArrayValue(data["encodedOriginal"])
except:
try:
# Qt 5
data = value["d"].dereference()
str = d.encodeString(data["scheme"])
else:
# QUrlPrivate:
# - QAtomicInt ref;
# - int port;
# - QString scheme;
# - QString userName;
# - QString password;
# - QString host;
# - QString path;
# - QString query;
# - QString fragment;
schemeAddr = d.dereferenceValue(value) + 2 * d.intSize()
scheme = d.dereference(schemeAddr)
host = d.dereference(schemeAddr + 3 * d.ptrSize())
path = d.dereference(schemeAddr + 4 * d.ptrSize())
str = qEncodeString(d, scheme)
str += "3a002f002f00"
str += d.encodeString(data["host"])
str += d.encodeString(data["path"])
str += qEncodeString(d, host)
str += qEncodeString(d, path)
d.putValue(str, Hex4EncodedLittleEndian)
except:
d.putPlainChildren(value)
return
d.putNumChild(1)
if d.isExpanded():
with Children(d):

View File

@@ -13,12 +13,10 @@ TEMPLATE = app
SOURCES += main.cpp \
qmlstreamwriter.cpp
OTHER_FILES += Info.plist.in
macx {
info.input = Info.plist.in
info.output = $$DESTDIR/$${TARGET}.app/Contents/Info.plist
QMAKE_SUBSTITUTES += info
}
# generation of Info.plist from Info.plist.in is handled by static.pro
# compiling this project directly from the Qt Creator source tree does not work
OTHER_FILES += Info.plist
macx:QMAKE_INFO_PLIST = Info.plist
HEADERS += \
qmlstreamwriter.h

View File

@@ -60,12 +60,13 @@ symbian {
LIBS += -lavkon -lcone
}
}
OTHER_FILES+=Info.plist.in
# generation of Info.plist from Info.plist.in is handled by static.pro
# compiling this project directly from the Qt Creator source tree does not work
OTHER_FILES+=Info.plist
mac {
QMAKE_INFO_PLIST=Info.plist
TARGET=QMLObserver
info.input = Info.plist.in
info.output = $$DESTDIR/$${TARGET}.app/Contents/Info.plist
QMAKE_SUBSTITUTES += info
ICON=qml.icns
} else {
TARGET=qmlobserver

View File

@@ -29,9 +29,18 @@ DEFINES -= QT_NO_CAST_FROM_ASCII
OTHER_FILES += Info.plist.in
macx {
isEmpty(QTCREATOR_PRI_INCLUDED) {
# So this .pri file is used by
# compiling the sources that were deployed to Qt Creator,
# and the Info.plist was generated by static.pro at build time
QMAKE_INFO_PLIST = $$PWD/Info.plist
} else {
# So this .pri file is used from Qt Creator source tree,
# and we need to generate the Info.plist
info.input = $$PWD/Info.plist.in
info.output = $$DESTDIR/$${TARGET}.app/Contents/Info.plist
QMAKE_SUBSTITUTES += info
}
} else {
target.path = $$QTC_PREFIX/bin
INSTALLS += target

View File

@@ -23,9 +23,18 @@ DEFINES -= QT_NO_CAST_FROM_ASCII
OTHER_FILES += Info.plist.in
macx {
isEmpty(QTCREATOR_PRI_INCLUDED) {
# So this .pri file is used by
# compiling the sources that were deployed to Qt Creator,
# and the Info.plist was generated by static.pro at build time
QMAKE_INFO_PLIST = $$PWD/Info.plist
} else {
# So this .pri file is used from Qt Creator source tree,
# and we need to generate the Info.plist
info.input = $$PWD/Info.plist.in
info.output = $$DESTDIR/$${TARGET}.app/Contents/Info.plist
QMAKE_SUBSTITUTES += info
}
} else {
target.path = $$QTC_PREFIX/bin
INSTALLS += target

View File

@@ -44,6 +44,7 @@ macx: DATA_DIRS += scripts
for(data_dir, DATA_DIRS) {
files = $$files($$PWD/$$data_dir/*, true)
win32:files ~= s|\\\\|/|g
# Info.plist.in are handled below
for(file, files):!contains(file, ".*/Info\\.plist\\.in$"):!exists($$file/*):FILES += $$file
}
OTHER_FILES += $$FILES
@@ -74,6 +75,12 @@ OTHER_FILES += $$FILES
observerinfo.input = qml/qmlobserver/Info.plist.in
observerinfo.output = $$IDE_DATA_PATH/qml/qmlobserver/Info.plist
QMAKE_SUBSTITUTES += observerinfo
puppetinfo.input = qml/qmlpuppet/qmlpuppet/Info.plist.in
puppetinfo.output = $$IDE_DATA_PATH/qml/qmlpuppet/qmlpuppet/Info.plist
QMAKE_SUBSTITUES += puppetinfo
puppet2info.input = qml/qmlpuppet/qml2puppet/Info.plist.in
puppet2info.output = $$IDE_DATA_PATH/qml/qmlpuppet/qml2puppet/Info.plist
QMAKE_SUBSTITUES += puppetinfo
}
SRCRESOURCEDIR = $$IDE_SOURCE_TREE/src/share/qtcreator/

View File

@@ -45,7 +45,7 @@
<style name="JsScopeVar" foreground="#8888ff" italic="true"/>
<style name="JsImportVar" foreground="#8888ff" italic="true"/>
<style name="JsGlobalVar" foreground="#8888ff" italic="true"/>
<style name="DillFileLine" foreground="#000000" background="#d7d700"/>
<style name="DiffFileLine" foreground="#000000" background="#d7d700"/>
<style name="DiffContextLine" foreground="#000000" background="#8aaab6"/>
<style name="DiffSourceLine" background="#8c2d2d"/>
<style name="DiffSourceChar" foreground="#000000" background="#c34141"/>

View File

@@ -5,7 +5,7 @@
<style name="CurrentLine" foreground="#000000" background="#f2f2f2"/>
<style name="DiffFile"/>
<style name="DiffLocation"/>
<style name="DillFileLine" foreground="#ffffff" background="#000000"/>
<style name="DiffFileLine" foreground="#ffffff" background="#000000"/>
<style name="DiffContextLine" foreground="#ffffff" background="#7f7f7f"/>
<style name="DiffSourceLine" background="#d7d7d7"/>
<style name="DiffSourceChar" background="#afafaf"/>

View File

@@ -53,7 +53,7 @@
<style name="JsScopeVar" foreground="#8888ff" italic="true"/>
<style name="JsImportVar" foreground="#8888ff" italic="true"/>
<style name="JsGlobalVar" foreground="#8888ff" italic="true"/>
<style name="DillFileLine" foreground="#404040" background="#dcb178"/>
<style name="DiffFileLine" foreground="#404040" background="#dcb178"/>
<style name="DiffContextLine" foreground="#404040" background="#97bac7"/>
<style name="DiffSourceLine" background="#8c2d2d"/>
<style name="DiffSourceChar" background="#c34141"/>

View File

@@ -1,6 +1,6 @@
let $prefix := string("QT_TRANSLATE_NOOP(&quot;QmlProjectManager::QmlApplicationWizardDialog&quot;, &quot;")
let $prefix := string("QT_TRANSLATE_NOOP(&quot;QmlProjectManager::QmlApplicationWizard&quot;, &quot;")
let $suffix := concat("&quot;)", codepoints-to-string(10))
for $file in tokenize($files, string("\|"))
let $doc := doc($file)
for $text in ($doc/*:template/*:description, $doc/*:wizard/*:displayname)
for $text in ($doc/*:template/*:description, $doc/*:template/*:displayname)
return fn:concat($prefix, data($text), $suffix)

View File

@@ -14439,10 +14439,6 @@ Verwenden Sie die Eigenschaft importPaths, um Importpfade zu qmlproject-basierte
<source>Plain C++ Project (CMake Build)</source>
<translation>C++-Projekt (CMake)</translation>
</message>
<message>
<source>Creates a C++ plugin to load extensions dynamically into applications using the QDeclarativeEngine class.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Requires &amp;lt;b&amp;gt;Qt 4.7.0&amp;lt;/b&amp;gt; or newer.</source>
<translation>Erstellt ein C++-Plugin zum dynamischen Laden von Erweiterungen in Anwendungen mittels der Klasse QDeclarativeEngine.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Erfordert &amp;lt;b&amp;gt;Qt 4.7.0&amp;lt;/b&amp;gt; oder neuer.</translation>
</message>
<message>
<source>Custom QML Extension Plugin Parameters</source>
<oldsource>QML Runtime Plug-in Parameters</oldsource>
@@ -14610,18 +14606,22 @@ Verwenden Sie die Eigenschaft importPaths, um Importpfade zu qmlproject-basierte
<source>Local user settings</source>
<translation>Lokale Benutzer-Einstellungen</translation>
</message>
<message>
<source>Creates a C++ plugin to load extensions dynamically into applications using the QDeclarativeEngine class. Requires Qt 4.7.0 or newer.</source>
<translation>Erstellt ein C++-Plugin zum dynamischen Laden von Erweiterungen in Anwendungen mittels der Klasse QDeclarativeEngine. Erfordert Qt 4.7.0 oder neuer.</translation>
</message>
<message>
<source>Object class-name:</source>
<translation>Klassenname des Objektes:</translation>
</message>
<message>
<source>Creates a C++ plugin to load extensions dynamically into applications using the QQmlEngine class.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Requires &amp;lt;b&amp;gt;Qt 5.0&amp;lt;/b&amp;gt; or newer.</source>
<translation>Erstellt ein C++-Plugin zum dynamischen Laden von Erweiterungen in Anwendungen mittels der Klasse QQmlEngine.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Erfordert &amp;lt;b&amp;gt;Qt 5.0&amp;lt;/b&amp;gt; oder neuer.</translation>
</message>
<message>
<source>Qt Quick 1 Extension Plugin</source>
<translation>Plugin zur Erweiterung von QtQuick 1</translation>
</message>
<message>
<source>Creates a C++ plugin to load extensions dynamically into applications using the QQmlEngine class. Requires Qt 5.0 or newer.</source>
<translation>Erstellt ein C++-Plugin zum dynamischen Laden von Erweiterungen in Anwendungen mittels der Klasse QQmlEngine. Erfordert Qt 5.0 oder neuer.</translation>
</message>
<message>
<source>Qt Quick 2 Extension Plugin</source>
<translation>Plugin zur Erweiterung von QtQuick 2</translation>
@@ -18795,7 +18795,7 @@ Sie können diese Anwendung erstellen und sowohl auf Desktop- als auch auf mobil
</message>
<message>
<source>Creates a qmake-based subdirs project. This allows you to group your projects in a tree structure.</source>
<translation>Erstellt qmake-basiertes Projekt vom Typ subdirs. Dies ermöglicht es Ihnen, Ihre Projekte in einer Baumstruktur zu gruppieren.</translation>
<translation>Erstellt ein qmake-basiertes Projekt vom Typ subdirs. Dies ermöglicht es Ihnen, Ihre Projekte in einer Baumstruktur zu gruppieren.</translation>
</message>
<message>
<source>Done &amp;&amp; Add Subproject</source>
@@ -30823,22 +30823,11 @@ Möchten Sie, dass Qt Creator sie für Ihr Projekt anlegt?</translation>
</context>
<context>
<name>Qnx::Internal::BlackBerryRunConfiguration</name>
<message>
<source>%1 on BlackBerry device</source>
<translation>%1 auf BlackBerry-Gerät</translation>
</message>
<message>
<source>Run on BlackBerry device</source>
<translation>Ausführung auf BlackBerry-Gerät</translation>
</message>
</context>
<context>
<name>Qnx::Internal::BlackBerryRunConfigurationFactory</name>
<message>
<source>%1 on BlackBerry Device</source>
<translation>%1 auf BlackBerry-Gerät</translation>
</message>
</context>
<context>
<name>Qnx::Internal::BlackBerryRunControlFactory</name>
<message>
@@ -31266,6 +31255,10 @@ Qt Creator know about a likely URI.</source>
<source>List of Processes</source>
<translation>Liste der Prozesse</translation>
</message>
<message>
<source>&amp;Attach to Process</source>
<translation>&amp;An Prozess anhängen</translation>
</message>
</context>
<context>
<name>ProjectExplorer::DeviceProcessList</name>
@@ -32011,13 +32004,6 @@ Fehlerausgabe: %1</translation>
<translation>&amp;Letzte:</translation>
</message>
</context>
<context>
<name>DeviceProcessesDialog</name>
<message>
<source>&amp;Attach to Process</source>
<translation>&amp;An Prozess anhängen</translation>
</message>
</context>
<context>
<name>Debugger::Internal::DebuggerCore</name>
<message>
@@ -35711,21 +35697,6 @@ Kurznamen können verwendet werden, sofern sie eindeutig sind.</translation>
<translation>Refaktorisierung konnte nicht angewandt werden.</translation>
</message>
</context>
<context>
<name>QmlProjectManager::QmlApplicationWizardDialog</name>
<message>
<source>Creates a Qt Quick 1 UI project with a single QML file that contains the main view.&amp;lt;br/&amp;gt;You can review Qt Quick 1 UI projects in the QML Viewer and you need not build them. You do not need to have the development environment installed on your computer to create and run this type of projects.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Requires &amp;lt;b&amp;gt;Qt 4.8&amp;lt;/b&amp;gt; or newer.</source>
<translation>Erstellt ein Qt Quick 1-UI-Projekt mit einer einzigen QML-Datei, die die Hauptansicht enthält.&amp;lt;br/&amp;gt;Sie können Qt Quick 1-UI-Projekte mit dem QML-Viewer ohne Erstellung betrachten. Sie benötigen keine Entwicklungsumgebung auf Ihrem Computer, um solche Projekte zu erstellen und auszuführen.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Erfordert &amp;lt;b&amp;gt;Qt 4.8&amp;lt;/b&amp;gt; oder neuer.</translation>
</message>
<message>
<source>Creates a Qt Quick 2 UI project with a single QML file that contains the main view.&amp;lt;br/&amp;gt;You can review Qt Quick 2 UI projects in the QML Scene and you need not build them. You do not need to have the development environment installed on your computer to create and run this type of projects.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Requires &amp;lt;b&amp;gt;Qt 5.0&amp;lt;/b&amp;gt; or newer.</source>
<translation>Erstellt ein Qt Quick 2-UI-Projekt mit einer einzigen QML-Datei, die die Hauptansicht enthält.&amp;lt;br/&amp;gt;Sie können Qt Quick 2-UI-Projekte mit QML-Scene ohne Erstellung betrachten. Sie benötigen keine Entwicklungsumgebung auf Ihrem Computer, um solche Projekte zu erstellen und auszuführen.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Erfordert &amp;lt;b&amp;gt;Qt 5.0&amp;lt;/b&amp;gt; oder neuer.</translation>
</message>
<message>
<source>Creates a Qt Quick 2 UI project with a single QML file that contains the main view and uses Qt Quick Controls.&amp;lt;br/&amp;gt;You can review Qt Quick 2 UI projects in the QML Scene and you need not build them. This project requires that you have installed Qt Quick Controls for your Qt version.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Requires &amp;lt;b&amp;gt;Qt 5.1&amp;lt;/b&amp;gt; or newer.</source>
<translation>Erstellt ein Qt Quick 2-UI-Projekt mit einer einzigen QML-Datei, die die Hauptansicht enthält und Qt Quick Controls verwendet.&amp;lt;br/&amp;gt;Sie können Qt Quick 2-UI-Projekte mit QML-Scene ohne Erstellung betrachten. Dieses Projekt erfordert, dass die Qt Quick Controls für die Qt-Version installiert sind.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Erfordert &amp;lt;b&amp;gt;Qt 5.1&amp;lt;/b&amp;gt; oder neuer.</translation>
</message>
</context>
<context>
<name>CppEditor::QuickFix</name>
<message>
@@ -37058,4 +37029,31 @@ Dieser Wizard führt Sie durch die essentiellen Schritte, die zum Deployment ein
<translation>Beschreibung der Änderung einblenden</translation>
</message>
</context>
<context>
<name>QmlProjectManager::QmlApplicationWizard</name>
<message>
<source>Creates a Qt Quick 1 UI project with a single QML file that contains the main view. You can review Qt Quick 1 UI projects in the QML Viewer and you need not build them. You do not need to have the development environment installed on your computer to create and run this type of projects. Requires Qt 4.8 or newer.</source>
<translation>Erstellt ein Qt Quick 1-UI-Projekt mit einer einzigen QML-Datei, die die Hauptansicht enthält. Sie können Qt Quick 1-UI-Projekte mit dem QML-Viewer ohne Erstellung betrachten. Sie benötigen keine Entwicklungsumgebung auf Ihrem Computer, um solche Projekte zu erstellen und auszuführen. Erfordert Qt 4.8 oder neuer.</translation>
</message>
<message>
<source>Qt Quick 1 UI</source>
<translation>Qt Quick 1-UI</translation>
</message>
<message>
<source>Creates a Qt Quick 2 UI project with a single QML file that contains the main view. You can review Qt Quick 2 UI projects in the QML Scene and you need not build them. You do not need to have the development environment installed on your computer to create and run this type of projects. Requires Qt 5.0 or newer.</source>
<translation>Erstellt ein Qt Quick 2-UI-Projekt mit einer einzigen QML-Datei, die die Hauptansicht enthält. Sie können Qt Quick 2-UI-Projekte mit QML-Scene ohne Erstellung betrachten. Sie benötigen keine Entwicklungsumgebung auf Ihrem Computer, um solche Projekte zu erstellen und auszuführen. Erfordert Qt 5.0 oder neuer.</translation>
</message>
<message>
<source>Qt Quick 2 UI</source>
<translation>Qt Quick 2-UI</translation>
</message>
<message>
<source>Creates a Qt Quick 2 UI project with a single QML file that contains the main view and uses Qt Quick Controls. You can review Qt Quick 2 UI projects in the QML Scene and you need not build them. This project requires that you have installed Qt Quick Controls for your Qt version. Requires Qt 5.1 or newer.</source>
<translation>Erstellt ein Qt Quick 2-UI-Projekt mit einer einzigen QML-Datei, die die Hauptansicht enthält und Qt Quick Controls verwendet. Sie können Qt Quick 2-UI-Projekte mit QML-Scene ohne Erstellung betrachten. Dieses Projekt erfordert, dass die Qt Quick Controls für die Qt-Version installiert sind. Erfordert Qt 5.1 oder neuer.</translation>
</message>
<message>
<source>Qt Quick 2 UI with Controls</source>
<translation>Qt Quick 2-UI mit Controls</translation>
</message>
</context>
</TS>

View File

@@ -212,6 +212,7 @@ bool FindCdbBreakpoint::visit(SwitchStatementAST *ast)
bool FindCdbBreakpoint::visit(TryBlockStatementAST *ast)
{
accept(ast->statement);
accept(ast->catch_clause_list);
return false;
}

View File

@@ -943,6 +943,12 @@ static inline AbstractSymbolGroupNodePtrVector qMap5Nodes(const SymbolGroupValue
SymbolGroupValue root = head["left"];
if (!root)
return AbstractSymbolGroupNodePtrVector();
const std::string nodeType = qHashNodeType(v, "Node");
const std::string nodePtrType = nodeType + " *";
if (SymbolGroupValue::verbose)
DebugPrint() << v.type() << "," << nodeType;
RedBlackTreeNode *nodeTree =
RedBlackTreeNode::buildMapRecursion(root, head.address(), 0, "left", "right");
if (!nodeTree)
@@ -951,10 +957,6 @@ static inline AbstractSymbolGroupNodePtrVector qMap5Nodes(const SymbolGroupValue
nodeTree->debug(DebugPrint(), debugQMap5Node);
VectorIndexType i = 0;
// Finally convert them into real nodes 'QHashNode<K,V> (potentially expensive)
const std::string nodeType = qHashNodeType(v, "Node");
const std::string nodePtrType = nodeType + " *";
if (SymbolGroupValue::verbose)
DebugPrint() << v.type() << "," << nodeType;
AbstractSymbolGroupNodePtrVector result;
result.reserve(count);
for (const RedBlackTreeNode *n = nodeTree->begin() ; n && i < count; n = RedBlackTreeNode::next(n), i++) {

View File

@@ -19,7 +19,6 @@ Product {
}
return name;
}
moduleSearchPaths: "../../../qbs" // TODO: Should get inherited from project, but doesn't.
Depends { name: "ExtensionSystem" }
Depends { name: "pluginspec" }

View File

@@ -690,9 +690,9 @@ bool AndroidPackageCreationStep::createPackage()
buildProc->setProcessEnvironment(m_environment.toProcessEnvironment());
connect(buildProc, SIGNAL(readyReadStandardOutput()), this,
SLOT(handleBuildStdOutOutput()));
SLOT(handleBuildStdOutOutput()), Qt::DirectConnection);
connect(buildProc, SIGNAL(readyReadStandardError()), this,
SLOT(handleBuildStdErrOutput()));
SLOT(handleBuildStdErrOutput()), Qt::DirectConnection);
buildProc->setWorkingDirectory(m_androidDir.toString());

View File

@@ -144,6 +144,7 @@ void OutputPanePlaceHolder::ensureSizeHintAsMinimum()
if (idx < 0)
return;
d->m_splitter->refresh();
QList<int> sizes = d->m_splitter->sizes();
Internal::OutputPaneManager *om = Internal::OutputPaneManager::instance();
int minimum = (d->m_splitter->orientation() == Qt::Vertical

View File

@@ -556,23 +556,31 @@ void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo)
return;
ProjectExplorer::Project *project = pinfo.project().data();
m_projects.insert(project, pinfo);
m_dirty = true;
m_srcToProjectPart.clear();
foreach (const ProjectInfo &projectInfo, m_projects) {
foreach (const ProjectPart::Ptr &projectPart, projectInfo.projectParts()) {
ProjectInfo oldProjectInfo = m_projects.value(project);
if (oldProjectInfo.isValid()) {
foreach (const ProjectPart::Ptr &projectPart, oldProjectInfo.projectParts()) {
foreach (const ProjectFile &cxxFile, projectPart->files) {
m_srcToProjectPart[cxxFile.path].append(projectPart);
foreach (const QString &fileName, m_snapshot.allIncludesForDocument(cxxFile.path))
foreach (const QString &fileName,
m_snapshot.allIncludesForDocument(cxxFile.path)) {
m_snapshot.remove(fileName);
}
m_snapshot.remove(cxxFile.path);
}
}
}
m_snapshot.remove(configurationFileName());
m_projects.insert(project, pinfo);
m_dirty = true;
m_srcToProjectPart.clear();
foreach (const ProjectInfo &projectInfo, m_projects) {
foreach (const ProjectPart::Ptr &projectPart, projectInfo.projectParts()) {
foreach (const ProjectFile &cxxFile, projectPart->files) {
m_srcToProjectPart[cxxFile.path].append(projectPart);
}
}
}
}
if (!qgetenv("QTCREATOR_DUMP_PROJECT_INFO").isEmpty())
@@ -607,9 +615,14 @@ void CppModelManager::deleteEditorSupport(TextEditor::BaseTextEditor *textEditor
if (!isCppEditor(textEditor))
return;
CppEditorSupport *editorSupport;
{ // only lock the operations on m_editorSupport
QMutexLocker locker(&m_editorSupportMutex);
CppEditorSupport *editorSupport = m_editorSupport.value(textEditor, 0);
editorSupport = m_editorSupport.value(textEditor, 0);
m_editorSupport.remove(textEditor);
}
delete editorSupport;
}

View File

@@ -32,6 +32,9 @@
#include "cpppreprocessor.h"
#include "modelmanagertesthelper.h"
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h>
#include <QDebug>
#include <QFileInfo>
#include <QtTest>
@@ -96,6 +99,42 @@ private:
const QString m_testDataDirectory;
};
// TODO: When possible, use this helper class in all tests
class ProjectCreator
{
public:
ProjectCreator(ModelManagerTestHelper *modelManagerTestHelper)
: modelManagerTestHelper(modelManagerTestHelper)
{}
/// 'files' is expected to be a list of file names that reside in 'dir'.
void create(const QString &name, const QString &dir, const QStringList files)
{
const TestDataDirectory projectDir(dir);
foreach (const QString &file, files)
projectFiles << projectDir.file(file);
Project *project = modelManagerTestHelper->createProject(name);
projectInfo = CppModelManager::instance()->projectInfo(project);
QCOMPARE(projectInfo.project().data(), project);
ProjectPart::Ptr part(new ProjectPart);
projectInfo.appendProjectPart(part);
part->cxxVersion = ProjectPart::CXX98;
part->qtVersion = ProjectPart::Qt5;
foreach (const QString &file, projectFiles) {
ProjectFile projectFile(file, ProjectFile::classify(file));
part->files.append(projectFile);
}
}
ModelManagerTestHelper *modelManagerTestHelper;
ProjectInfo projectInfo;
QStringList projectFiles;
};
} // anonymous namespace
void CppToolsPlugin::test_modelmanager_paths()
@@ -278,3 +317,99 @@ void CppToolsPlugin::test_modelmanager_refresh_2()
QVERIFY(document->diagnosticMessages().isEmpty());
}
}
void CppToolsPlugin::test_modelmanager_snapshot_after_two_projects()
{
QStringList refreshedFiles;
ModelManagerTestHelper helper;
ProjectCreator project1(&helper);
ProjectCreator project2(&helper);
CppModelManager *mm = CppModelManager::instance();
// Project 1
project1.create(QLatin1String("snapshot_after_two_projects.1"),
QLatin1String("testdata_project1"),
QStringList() << QLatin1String("foo.h")
<< QLatin1String("foo.cpp")
<< QLatin1String("main.cpp"));
mm->updateProjectInfo(project1.projectInfo);
mm->updateSourceFiles(project1.projectFiles);
refreshedFiles = helper.waitForRefreshedSourceFiles();
QCOMPARE(refreshedFiles.toSet(), project1.projectFiles.toSet());
const int snapshotSizeAfterProject1 = mm->snapshot().size();
foreach (const QString &file, project1.projectFiles)
QVERIFY(mm->snapshot().contains(file));
// Project 2
project2.create(QLatin1String("snapshot_after_two_projects.2"),
QLatin1String("testdata_project2"),
QStringList() << QLatin1String("bar.h")
<< QLatin1String("bar.cpp")
<< QLatin1String("main.cpp"));
mm->updateProjectInfo(project2.projectInfo);
mm->updateSourceFiles(project2.projectFiles);
refreshedFiles = helper.waitForRefreshedSourceFiles();
QCOMPARE(refreshedFiles.toSet(), project2.projectFiles.toSet());
const int snapshotSizeAfterProject2 = mm->snapshot().size();
QVERIFY(snapshotSizeAfterProject2 > snapshotSizeAfterProject1);
QVERIFY(snapshotSizeAfterProject2 >= snapshotSizeAfterProject1 + project2.projectFiles.size());
foreach (const QString &file, project1.projectFiles)
QVERIFY(mm->snapshot().contains(file));
foreach (const QString &file, project2.projectFiles)
QVERIFY(mm->snapshot().contains(file));
}
void CppToolsPlugin::test_modelmanager_extraeditorsupport_uiFiles()
{
TestDataDirectory testDataDirectory(QLatin1String("testdata_guiproject1"));
const QString projectFile = testDataDirectory.file(QLatin1String("testdata_guiproject1.pro"));
// Open project with *.ui file
ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance();
QString errorOpeningProject;
Project *project = pe->openProject(projectFile, &errorOpeningProject);
QVERIFY(errorOpeningProject.isEmpty());
project->configureAsExampleProject(QStringList());
// Check working copy.
// An AbstractEditorSupport object should have been added for the ui_* file.
CppModelManagerInterface *mm = CppModelManagerInterface::instance();
CppModelManagerInterface::WorkingCopy workingCopy = mm->workingCopy();
QCOMPARE(workingCopy.size(), 2); // mm->configurationFileName() and "ui_*.h"
QStringList fileNamesInWorkinCopy;
QHashIterator<QString, QPair<QString, unsigned> > it = workingCopy.iterator();
while (it.hasNext()) {
it.next();
fileNamesInWorkinCopy << QFileInfo(it.key()).fileName();
}
fileNamesInWorkinCopy.sort();
const QString expectedUiHeaderFileName = QLatin1String("ui_mainwindow.h");
QCOMPARE(fileNamesInWorkinCopy.at(0), mm->configurationFileName());
QCOMPARE(fileNamesInWorkinCopy.at(1), expectedUiHeaderFileName);
// Check CppPreprocessor / includes.
// The CppPreprocessor is expected to find the ui_* file in the working copy.
const QString fileIncludingTheUiFile = testDataDirectory.file(QLatin1String("mainwindow.cpp"));
while (!mm->snapshot().document(fileIncludingTheUiFile))
QCoreApplication::processEvents();
const CPlusPlus::Snapshot snapshot = mm->snapshot();
const Document::Ptr document = snapshot.document(fileIncludingTheUiFile);
QVERIFY(document);
const QStringList includedFiles = document->includedFiles();
QCOMPARE(includedFiles.size(), 2);
QCOMPARE(QFileInfo(includedFiles.at(0)).fileName(), QLatin1String("mainwindow.h"));
QCOMPARE(QFileInfo(includedFiles.at(1)).fileName(), QLatin1String("ui_mainwindow.h"));
// Close Project
ProjectExplorer::SessionManager *sm = pe->session();
sm->removeProject(project);
ModelManagerTestHelper::verifyClean();
}

View File

@@ -233,7 +233,7 @@ QString CppPreprocessor::resolveFile_helper(const QString &fileName, IncludeType
foreach (const QString &includePath, m_includePaths) {
QString path = includePath + fileName;
if (checkFile(path))
if (m_workingCopy.contains(path) || checkFile(path))
return path;
}

View File

@@ -171,6 +171,8 @@ private slots:
void test_modelmanager_framework_headers();
void test_modelmanager_refresh_1();
void test_modelmanager_refresh_2();
void test_modelmanager_snapshot_after_two_projects();
void test_modelmanager_extraeditorsupport_uiFiles();
private:
void test_completion();

View File

@@ -79,7 +79,7 @@ public:
~ModelManagerTestHelper();
void cleanup();
void verifyClean();
static void verifyClean();
Project *createProject(const QString &name);

View File

@@ -156,7 +156,7 @@ equals(TEST, 1):!isEmpty(copydata) {
else: OUTPUT_DIR = $$IDE_BUILD_TREE/$$TEST_DIR
testfile.target = $$OUTPUT_DIR/$$basename(INPUT_FILE)
testfile.depends = $$INPUT_FILE
win32 {
win32:isEmpty(QMAKE_SH) {
INPUT_FILE ~= s,/,\\\\,g
OUTPUT_DIR ~= s,/,\\\\,g
} else {

View File

@@ -1678,7 +1678,7 @@ void DebuggerPluginPrivate::attachToProcess(bool startServerOnly)
DebuggerKitChooser::RemoteDebugging : DebuggerKitChooser::LocalDebugging;
DebuggerKitChooser *kitChooser = new DebuggerKitChooser(mode);
DeviceProcessesDialog *dlg = new DeviceProcessesDialog(kitChooser, mainWindow());
dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
dlg->addAcceptButton(ProjectExplorer::DeviceProcessesDialog::tr("&Attach to Process"));
dlg->showAllDevices();
if (dlg->exec() == QDialog::Rejected) {
delete dlg;

View File

@@ -69,6 +69,7 @@ void ImageWidget::setImage(const QImage &image)
{
setFixedSize(image.size() + QSize(2, 2));
m_image = image;
update();
}
void ImageWidget::mousePressEvent(QMouseEvent *ev)

View File

@@ -1679,28 +1679,37 @@ void WatchHandler::showEditValue(const WatchData &data)
showSeparateWidget(l);
m_model->m_editHandlers[key] = l;
}
int width = 0, height = 0, format = 0;
int width = 0, height = 0, nbytes = 0, format = 0;
QByteArray ba;
uchar *bits = 0;
if (data.editformat == DisplayImageData) {
ba = QByteArray::fromHex(data.editvalue);
QTC_ASSERT(ba.size() > 16, return);
const int *header = (int *)(ba.data());
if (!ba.at(0) && !ba.at(1)) // Check on 'width' for Python dumpers returning 4-byte swapped-data.
swapEndian(ba.data(), ba.size());
bits = 12 + (uchar *)(ba.data());
swapEndian(ba.data(), 16);
bits = 16 + (uchar *)(ba.data());
width = header[0];
height = header[1];
format = header[2];
nbytes = header[2];
format = header[3];
} else if (data.editformat == DisplayImageFile) {
QTextStream ts(data.editvalue);
QString fileName;
ts >> width >> height >> format >> fileName;
ts >> width >> height >> nbytes >> format >> fileName;
QFile f(fileName);
f.open(QIODevice::ReadOnly);
ba = f.readAll();
bits = (uchar*)ba.data();
nbytes = width * height;
}
l->setImage(QImage(bits, width, height, QImage::Format(format)));
QTC_ASSERT(0 < width && width < 10000, return);
QTC_ASSERT(0 < height && height < 10000, return);
QTC_ASSERT(0 < nbytes && nbytes < 10000 * 10000, return);
QTC_ASSERT(0 < format && format < 32, return);
QImage im(width, height, QImage::Format(format));
qMemCopy(im.bits(), bits, nbytes);
l->setImage(im);
showSeparateWidget(l);
}
break;

View File

@@ -418,6 +418,8 @@ void DiffViewEditorWidget::mouseDoubleClickEvent(QMouseEvent *e)
if (e->button() == Qt::LeftButton && !(e->modifiers() & Qt::ShiftModifier)) {
QTextCursor cursor = cursorForPosition(e->pos());
jumpToOriginalFile(cursor);
e->accept();
return;
}
SnippetEditorWidget::mouseDoubleClickEvent(e);
}

View File

@@ -76,7 +76,8 @@
static const char GIT_DIRECTORY[] = ".git";
static const char graphLogFormatC[] = "%h %d %an %s %ci";
static const char HEAD[] = "HEAD";
static const char noColorOption[] = "--no-color";
static const char decorateOption[] = "--decorate";
namespace Git {
namespace Internal {
@@ -118,8 +119,8 @@ public:
// index -> working tree
void diffFile(const QString &fileName);
// stagedFileNames - files in index, diff will compare the state in HEAD to the one in the index
// unstagedFileNames - diff will compare the state in the index to the one in the working tree
// stagedFileNames: HEAD -> index
// unstagedFileNames: index -> working tree
void diffFiles(const QStringList &stagedFileNames, const QStringList &unstagedFileNames);
// index -> working tree
void diffProjects(const QStringList &projectPaths);
@@ -191,7 +192,7 @@ GitDiffHandler::GitDiffHandler(DiffEditor::DiffEditor *editor,
void GitDiffHandler::diffFile(const QString &fileName)
{
m_requestedRevisionRange = RevisionRange(
Revision(Other, QLatin1String(HEAD)),
Revision(Index),
Revision(WorkingTree));
collectFilesList(QStringList() << QLatin1String("--") << fileName);
@@ -201,7 +202,7 @@ void GitDiffHandler::diffFiles(const QStringList &stagedFileNames, const QString
{
RevisionRange stagedRange = RevisionRange(
Revision(Other, QLatin1String(HEAD)),
Revision(WorkingTree));
Revision(Index));
RevisionRange unstagedRange = RevisionRange(
Revision(Index),
Revision(WorkingTree));
@@ -219,7 +220,7 @@ void GitDiffHandler::diffFiles(const QStringList &stagedFileNames, const QString
void GitDiffHandler::diffProjects(const QStringList &projectPaths)
{
m_requestedRevisionRange = RevisionRange(
Revision(Other, QLatin1String(HEAD)),
Revision(Index),
Revision(WorkingTree));
collectFilesList(QStringList() << QLatin1String("--") << projectPaths);
@@ -228,7 +229,7 @@ void GitDiffHandler::diffProjects(const QStringList &projectPaths)
void GitDiffHandler::diffRepository()
{
m_requestedRevisionRange = RevisionRange(
Revision(Other, QLatin1String(HEAD)),
Revision(Index),
Revision(WorkingTree));
collectFilesList(QStringList());
@@ -254,23 +255,27 @@ void GitDiffHandler::show(const QString &id)
void GitDiffHandler::collectShowDescription(const QString &id)
{
if (m_editor.isNull())
return;
m_editor->clear(m_waitMessage);
VcsBase::Command *command = new VcsBase::Command(m_gitPath, m_workingDirectory, m_processEnvironment);
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(slotShowDescriptionReceived(QByteArray)));
QStringList arguments;
arguments << QLatin1String("show") << QLatin1String("-s") << QLatin1String("--format=fuller") << id;
arguments << QLatin1String("show") << QLatin1String("-s") << QLatin1String("--format=fuller")
<< QLatin1String(noColorOption) << QLatin1String(decorateOption) << id;
command->addJob(arguments, m_timeout);
command->execute();
}
void GitDiffHandler::slotShowDescriptionReceived(const QByteArray &data)
{
if (m_editor.isNull())
return;
const QString description = m_editor->editorWidget()->codec()->toUnicode(data).remove(QLatin1Char('\r'));
DiffEditor::DiffShowEditor *editor = qobject_cast<DiffEditor::DiffShowEditor *>(m_editor);
if (editor) {
if (editor)
editor->setDescription(description);
}
collectFilesList(QStringList()
<< m_requestedRevisionRange.begin.id
@@ -279,6 +284,8 @@ void GitDiffHandler::slotShowDescriptionReceived(const QByteArray &data)
void GitDiffHandler::collectFilesList(const QStringList &additionalArguments)
{
if (m_editor.isNull())
return;
m_editor->clear(m_waitMessage);
VcsBase::Command *command = new VcsBase::Command(m_gitPath, m_workingDirectory, m_processEnvironment);
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(slotFileListReceived(QByteArray)));
@@ -632,6 +639,7 @@ public:
m_enableAnnotationContextMenu(enableAnnotationContextMenu),
m_fileNames(fileNames)
{
QTC_ASSERT(!directory.isEmpty(), return);
QToolButton *diffButton = addToggleButton(QLatin1String("--patch"), tr("Show Diff"),
tr("Show difference."));
mapSetting(diffButton, m_client->settings()->boolPointer(GitSettings::logDiffKey));
@@ -790,9 +798,6 @@ GitClient::~GitClient()
{
}
const char *GitClient::noColorOption = "--no-color";
const char *GitClient::decorateOption = "--decorate";
QString GitClient::findRepositoryForDirectory(const QString &dir)
{
if (dir.isEmpty() || dir.endsWith(QLatin1String("/.git"))
@@ -1307,7 +1312,7 @@ bool GitClient::synchronousLog(const QString &workingDirectory, const QStringLis
QByteArray outputText;
QByteArray errorText;
QStringList allArguments;
allArguments << QLatin1String("log") << QLatin1String(GitClient::noColorOption);
allArguments << QLatin1String("log") << QLatin1String(noColorOption);
allArguments.append(arguments);
const bool rc = fullySynchronousGit(workingDirectory, allArguments, &outputText, &errorText);
if (rc) {
@@ -1785,7 +1790,7 @@ QString GitClient::synchronousShortDescription(const QString &workingDirectory,
QByteArray outputTextData;
QByteArray errorText;
QStringList arguments;
arguments << QLatin1String("log") << QLatin1String(GitClient::noColorOption)
arguments << QLatin1String("log") << QLatin1String(noColorOption)
<< (QLatin1String("--pretty=format:") + format)
<< QLatin1String("--max-count=1") << revision;
const bool rc = fullySynchronousGit(workingDirectory, arguments, &outputTextData, &errorText);
@@ -2685,8 +2690,11 @@ bool GitClient::getCommitData(const QString &workingDirectory,
QString templateFilename = gitDirectory.absoluteFilePath(QLatin1String("MERGE_MSG"));
if (!QFile::exists(templateFilename))
templateFilename = gitDirectory.absoluteFilePath(QLatin1String("SQUASH_MSG"));
if (!QFile::exists(templateFilename))
templateFilename = readConfigValue(workingDirectory, QLatin1String("commit.template"));
if (!QFile::exists(templateFilename)) {
Utils::FileName templateName = Utils::FileName::fromUserInput(
readConfigValue(workingDirectory, QLatin1String("commit.template")));
templateFilename = templateName.toString();
}
if (!templateFilename.isEmpty()) {
// Make relative to repository
const QFileInfo templateFileInfo(templateFilename);

View File

@@ -313,9 +313,6 @@ public:
static QString msgNoChangedFiles();
static QString msgNoCommits(bool includeRemote);
static const char *noColorOption;
static const char *decorateOption;
public slots:
void show(const QString &source, const QString &id,
const QStringList &args = QStringList(), const QString &name = QString());

View File

@@ -66,7 +66,9 @@ PerforceEditor::PerforceEditor(const VcsBase::VcsBaseEditorParameters *type,
// Diff format:
// 1) "==== //depot/.../mainwindow.cpp#2 - /depot/.../mainwindow.cpp ====" (created by p4 diff)
// 2) "==== //depot/.../mainwindow.cpp#15 (text) ====" (created by p4 describe)
setDiffFilePattern(QRegExp(QLatin1String("^==== (.+)#\\d")));
// 3) --- //depot/XXX/closingkit/trunk/source/cui/src/cui_core.cpp<tab>2012-02-08 13:54:01.000000000 0100
// +++ P:/XXX\closingkit\trunk\source\cui\src\cui_core.cpp<tab>2012-02-08 13:54:01.000000000 0100
setDiffFilePattern(QRegExp(QLatin1String("^(?:={4}|\\+{3}) (.+)(?:\\t|#\\d)")));
setLogEntryPattern(QRegExp(QLatin1String("^... #\\d change (\\d+) ")));
setAnnotateRevisionTextFormat(tr("Annotate change list \"%1\""));
if (Perforce::Constants::debug)

View File

@@ -734,7 +734,7 @@ void SettingsAccessor::backupUserFile() const
// Do we need to do a backup?
const QString origName = oldSettings.fileName().toString();
QString backupName = origName;
if (oldSettings.environmentId() != creatorId())
if (!oldSettings.environmentId().isEmpty() && oldSettings.environmentId() != creatorId())
backupName += QLatin1String(".") + QString::fromLatin1(oldSettings.environmentId()).mid(1, 7);
if (oldSettings.version() != currentVersion()) {
if (m_handlers.contains(oldSettings.version()))
@@ -774,7 +774,7 @@ SettingsAccessor::SettingsData SettingsAccessor::readUserSettings() const
"<p>All settings files were either too new or too "
"old to be read.</p>"),
QMessageBox::Ok);
} else if (result.environmentId() != creatorId()) {
} else if (!result.environmentId().isEmpty() && result.environmentId() != creatorId()) {
// Wrong environment!
QMessageBox msgBox(
QMessageBox::Question,
@@ -873,7 +873,7 @@ SettingsAccessor::SettingsData SettingsAccessor::findBestSettings(const QStringL
continue;
}
if (!tmp.environmentId().isEmpty() && tmp.environmentId() == creatorId()) {
if (tmp.environmentId().isEmpty() || tmp.environmentId() == creatorId()) {
if (tmp.version() > newestMatching.version())
newestMatching = tmp;
} else {

View File

@@ -1096,15 +1096,21 @@ QString PropertyEditor::locateQmlFile(const NodeMetaInfo &info, const QString &r
const QString relativePathWithVersion = relativePathWithoutEnding + versionString + QLatin1String(".qml");
//Check for qml files with versions first
const QString withoutDirWithVersion = relativePathWithVersion.split(QLatin1String("/")).last();
if (importDir.exists(relativePathWithVersion))
return importDir.absoluteFilePath(relativePathWithVersion);
if (importDir.exists(withoutDirWithVersion)) //Since we are in a subfolder of the import we do not require the directory
return importDir.absoluteFilePath(withoutDirWithVersion);
if (fileSystemDir.exists(relativePathWithVersion))
return fileSystemDir.absoluteFilePath(relativePathWithVersion);
if (resourcesDir.exists(relativePathWithVersion))
return resourcesDir.absoluteFilePath(relativePathWithVersion);
const QString withoutDir = relativePath.split(QLatin1String("/")).last();
if (importDir.exists(relativePath))
return importDir.absoluteFilePath(relativePath);
if (importDir.exists(withoutDir)) //Since we are in a subfolder of the import we do not require the directory
return importDir.absoluteFilePath(withoutDir);
if (fileSystemDir.exists(relativePath))
return fileSystemDir.absoluteFilePath(relativePath);
if (resourcesDir.exists(relativePath))

View File

@@ -39,7 +39,7 @@ namespace Internal {
typedef QSharedPointer<InternalNodeAbstractProperty> InternalNodeAbstractPropertyPointer;
}
class NodeAbstractProperty : public AbstractProperty
class QMLDESIGNERCORE_EXPORT NodeAbstractProperty : public AbstractProperty
{
friend class QmlDesigner::ModelNode;
friend class QmlDesigner::Internal::ModelPrivate;

View File

@@ -195,7 +195,7 @@ QmlJS::Document::Language QmlJSTools::languageOfFile(const QString &fileName)
Core::MimeType qbsSourceTy = db->findByType(QLatin1String(Constants::QBS_MIMETYPE));
mergeSuffixes(qbsSuffixes, qbsSourceTy.suffixes());
Core::MimeType qmlProjectSourceTy = db->findByType(QLatin1String(Constants::QMLPROJECT_MIMETYPE));
mergeSuffixes(qbsSuffixes, qmlProjectSourceTy.suffixes());
mergeSuffixes(qmlProjectSuffixes, qmlProjectSourceTy.suffixes());
Core::MimeType jsonSourceTy = db->findByType(QLatin1String(Constants::JSON_MIMETYPE));
mergeSuffixes(jsonSuffixes, jsonSourceTy.suffixes());
}
@@ -243,6 +243,11 @@ ModelManager::ModelManager(QObject *parent):
m_updateCppQmlTypesTimer->setSingleShot(true);
connect(m_updateCppQmlTypesTimer, SIGNAL(timeout()), SLOT(startCppQmlTypeUpdate()));
m_asyncResetTimer = new QTimer(this);
m_asyncResetTimer->setInterval(1000);
m_asyncResetTimer->setSingleShot(true);
connect(m_asyncResetTimer, SIGNAL(timeout()), SLOT(resetCodeModel()));
qRegisterMetaType<QmlJS::Document::Ptr>("QmlJS::Document::Ptr");
qRegisterMetaType<QmlJS::LibraryInfo>("QmlJS::LibraryInfo");
qRegisterMetaType<QmlJSTools::SemanticInfo>("QmlJSTools::SemanticInfo");
@@ -1056,6 +1061,11 @@ void ModelManager::startCppQmlTypeUpdate()
m_queuedCppDocuments.clear();
}
void ModelManager::asyncReset()
{
m_asyncResetTimer->start();
}
void ModelManager::updateCppQmlTypes(QFutureInterface<void> &interface,
ModelManager *qmlModelManager,
CPlusPlus::Snapshot snapshot,
@@ -1100,7 +1110,7 @@ void ModelManager::updateCppQmlTypes(QFutureInterface<void> &interface,
qmlModelManager->m_cppDataHash = newData;
if (hasNewInfo)
// one could get away with re-linking the cpp types...
QMetaObject::invokeMethod(qmlModelManager, "resetCodeModel");
QMetaObject::invokeMethod(qmlModelManager, "asyncReset");
}
ModelManager::CppDataHash ModelManager::cppData() const

View File

@@ -141,6 +141,7 @@ private slots:
void maybeQueueCppQmlTypeUpdate(const CPlusPlus::Document::Ptr &doc);
void queueCppQmlTypeUpdate(const CPlusPlus::Document::Ptr &doc, bool scan);
void startCppQmlTypeUpdate();
void asyncReset();
private:
static bool matchesMimeType(const Core::MimeType &fileMimeType, const Core::MimeType &knownMimeType);
@@ -160,6 +161,7 @@ private:
QFutureSynchronizer<void> m_synchronizer;
QTimer *m_updateCppQmlTypesTimer;
QTimer *m_asyncResetTimer;
QHash<QString, QPair<CPlusPlus::Document::Ptr, bool> > m_queuedCppDocuments;
QFuture<void> m_cppQmlTypesUpdater;
QmlJS::QrcCache m_qrcCache;

View File

@@ -557,7 +557,7 @@ QStringList Qt4PriFileNode::fullVPaths(const QStringList &baseVPaths, QtSupport:
return vPaths;
}
static QSet<Utils::FileName> recursiveEnumerate(const QString &folder)
QSet<Utils::FileName> Qt4PriFileNode::recursiveEnumerate(const QString &folder)
{
QSet<Utils::FileName> result;
QFileInfo fi(folder);
@@ -718,10 +718,66 @@ void Qt4PriFileNode::watchFolders(const QSet<QString> &folders)
m_watchedFolders = folders;
}
void Qt4PriFileNode::folderChanged(const QString &changedFolder)
bool Qt4PriFileNode::folderChanged(const QString &changedFolder, const QSet<Utils::FileName> &newFiles)
{
Q_UNUSED(changedFolder);
scheduleUpdate();
//qDebug()<<"########## Qt4PriFileNode::folderChanged";
// So, we need to figure out which files changed.
QSet<Utils::FileName> addedFiles = newFiles;
addedFiles.subtract(m_recursiveEnumerateFiles);
QSet<Utils::FileName> removedFiles = m_recursiveEnumerateFiles;
removedFiles.subtract(newFiles);
foreach (const Utils::FileName &file, removedFiles) {
if (!file.isChildOf(Utils::FileName::fromString(changedFolder)))
removedFiles.remove(file);
}
if (addedFiles.isEmpty() && removedFiles.isEmpty())
return false;
m_recursiveEnumerateFiles = newFiles;
// Apply the differences
// per file type
const QVector<Qt4NodeStaticData::FileTypeData> &fileTypes = qt4NodeStaticData()->fileTypeData;
for (int i = 0; i < fileTypes.size(); ++i) {
FileType type = fileTypes.at(i).type;
QSet<Utils::FileName> add = filterFilesRecursiveEnumerata(type, addedFiles);
QSet<Utils::FileName> remove = filterFilesRecursiveEnumerata(type, removedFiles);
if (!add.isEmpty() || !remove.isEmpty()) {
// Scream :)
// qDebug()<<"For type"<<fileTypes.at(i).typeName<<"\n"
// <<"added files"<<add<<"\n"
// <<"removed files"<<remove;
m_files[type].unite(add);
m_files[type].subtract(remove);
}
}
// Now apply stuff
InternalNode contents;
for (int i = 0; i < fileTypes.size(); ++i) {
FileType type = fileTypes.at(i).type;
if (!m_files[type].isEmpty()) {
InternalNode *subfolder = new InternalNode;
subfolder->type = type;
subfolder->icon = fileTypes.at(i).icon;
subfolder->fullPath = m_projectDir;
subfolder->typeName = fileTypes.at(i).typeName;
subfolder->priority = -i;
subfolder->displayName = fileTypes.at(i).typeName;
contents.virtualfolders.append(subfolder);
// create the hierarchy with subdirectories
subfolder->create(m_projectDir, m_files[type], type);
}
}
contents.updateSubFolders(this, this);
return true;
}
bool Qt4PriFileNode::deploysFolder(const QString &folder) const

View File

@@ -162,7 +162,7 @@ public:
bool renameFile(const FileType fileType,
const QString &filePath, const QString &newFilePath);
void folderChanged(const QString &changedFolder);
bool folderChanged(const QString &changedFolder, const QSet<Utils::FileName> &newFiles);
bool deploysFolder(const QString &folder) const;
QList<ProjectExplorer::RunConfiguration *> runConfigurationsFor(Node *node);
@@ -172,6 +172,7 @@ public:
// Set by parent
bool includedInExactParse() const;
static QSet<Utils::FileName> recursiveEnumerate(const QString &folder);
protected:
void setIncludedInExactParse(bool b);
static QStringList varNames(FileType type);

View File

@@ -146,7 +146,7 @@ class CentralizedFolderWatcher : public QObject
{
Q_OBJECT
public:
CentralizedFolderWatcher(QObject *parent);
CentralizedFolderWatcher(Qt4Project *parent);
~CentralizedFolderWatcher();
void watchFolders(const QList<QString> &folders, Qt4ProjectManager::Qt4PriFileNode *node);
void unwatchFolders(const QList<QString> &folders, Qt4ProjectManager::Qt4PriFileNode *node);
@@ -157,6 +157,7 @@ private slots:
void delayedFolderChanged(const QString &folder);
private:
Qt4Project *m_project;
QSet<QString> recursiveDirs(const QString &folder);
QFileSystemWatcher m_watcher;
QMultiMap<QString, Qt4ProjectManager::Qt4PriFileNode *> m_map;
@@ -1215,7 +1216,8 @@ namespace {
bool debugCFW = false;
}
CentralizedFolderWatcher::CentralizedFolderWatcher(QObject *parent) : QObject(parent)
CentralizedFolderWatcher::CentralizedFolderWatcher(Qt4Project *parent)
: QObject(parent), m_project(parent)
{
m_compressTimer.setSingleShot(true);
m_compressTimer.setInterval(200);
@@ -1337,12 +1339,19 @@ void CentralizedFolderWatcher::delayedFolderChanged(const QString &folder)
QString dir = folder;
const QChar slash = QLatin1Char('/');
bool newOrRemovedFiles = false;
while (true) {
if (!dir.endsWith(slash))
dir.append(slash);
QList<Qt4ProjectManager::Qt4PriFileNode *> nodes = m_map.values(dir);
if (!nodes.isEmpty()) {
// Collect all the files
QSet<Utils::FileName> newFiles;
newFiles += Qt4PriFileNode::recursiveEnumerate(folder);
foreach (Qt4ProjectManager::Qt4PriFileNode *node, nodes) {
node->folderChanged(folder);
newOrRemovedFiles = newOrRemovedFiles
|| node->folderChanged(folder, newFiles);
}
}
// Chop off last part, and break if there's nothing to chop off
@@ -1357,7 +1366,6 @@ void CentralizedFolderWatcher::delayedFolderChanged(const QString &folder)
dir.truncate(index + 1);
}
QString folderWithSlash = folder;
if (!folder.endsWith(slash))
folderWithSlash.append(slash);
@@ -1374,6 +1382,11 @@ void CentralizedFolderWatcher::delayedFolderChanged(const QString &folder)
m_watcher.addPaths(tmp.toList());
m_recursiveWatchedFolders += tmp;
}
if (newOrRemovedFiles) {
m_project->updateFileList();
m_project->updateCodeModels();
}
}
bool Qt4Project::needsConfiguration() const

View File

@@ -64,10 +64,13 @@ QList<FilterEntry> LineNumberFilter::matchesFor(QFutureInterface<Locator::Filter
int sectionCount = lineAndColumn.size();
int line = 0;
int column = 0;
bool ok;
if (sectionCount > 0)
line = lineAndColumn.at(0).toInt();
if (sectionCount > 1)
column = lineAndColumn.at(1).toInt();
line = lineAndColumn.at(0).toInt(&ok);
if (ok && sectionCount > 1)
column = lineAndColumn.at(1).toInt(&ok);
if (!ok)
return value;
if (currentTextEditor() && (line > 0 || column > 0)) {
LineColumn data;
data.first = line;

View File

@@ -87,7 +87,7 @@ const char *nameForStyle(TextStyle style)
case C_DIFF_FILE: return "DiffFile";
case C_DIFF_LOCATION: return "DiffLocation";
case C_DIFF_FILE_LINE: return "DillFileLine";
case C_DIFF_FILE_LINE: return "DiffFileLine";
case C_DIFF_CONTEXT_LINE: return "DiffContextLine";
case C_DIFF_SOURCE_LINE: return "DiffSourceLine";
case C_DIFF_SOURCE_CHAR: return "DiffSourceChar";

View File

@@ -98,9 +98,11 @@ bool DiffChunk::isValid() const
return !fileName.isEmpty() && !chunk.isEmpty();
}
QByteArray DiffChunk::asPatch() const
QByteArray DiffChunk::asPatch(const QString &workingDirectory) const
{
const QByteArray fileNameBA = QFile::encodeName(fileName);
QString relativeFile = workingDirectory.isEmpty() ?
fileName : QDir(workingDirectory).relativeFilePath(fileName);
const QByteArray fileNameBA = QFile::encodeName(relativeFile);
QByteArray rc = "--- ";
rc += fileNameBA;
rc += "\n+++ ";
@@ -1466,7 +1468,8 @@ bool VcsBaseEditorWidget::canApplyDiffChunk(const DiffChunk &dc) const
// (passing '-R' for revert), assuming we got absolute paths from the VCS plugins.
bool VcsBaseEditorWidget::applyDiffChunk(const DiffChunk &dc, bool revert) const
{
return VcsBasePlugin::runPatch(dc.asPatch(), QString(), 0, revert);
return VcsBasePlugin::runPatch(dc.asPatch(d->m_diffBaseDirectory),
d->m_diffBaseDirectory, 0, revert);
}
QString VcsBaseEditorWidget::fileNameFromDiffSpecification(const QTextBlock &inBlock) const

View File

@@ -78,7 +78,7 @@ class VCSBASE_EXPORT DiffChunk
{
public:
bool isValid() const;
QByteArray asPatch() const;
QByteArray asPatch(const QString &workingDirectory) const;
QString fileName;
QByteArray chunk;

View File

@@ -1056,7 +1056,7 @@ bool VcsBasePlugin::runPatch(const QByteArray &input, const QString &workingDire
QStringList args(QLatin1String("-p") + QString::number(strip));
if (reverse)
args << QLatin1String("-R");
ow->appendCommand(QString(), patch, args);
ow->appendCommand(workingDirectory, patch, args);
patchProcess.start(patch, args);
if (!patchProcess.waitForStarted()) {
ow->appendError(tr("Unable to launch '%1': %2").arg(patch, patchProcess.errorString()));

View File

@@ -1026,7 +1026,7 @@ void QMakeEvaluator::loadDefaults()
# endif
#elif defined(Q_OS_UNIX)
struct utsname name;
if (!uname(&name)) {
if (uname(&name) != -1) {
vars[ProKey("QMAKE_HOST.os")] << ProString(name.sysname);
vars[ProKey("QMAKE_HOST.name")] << ProString(QString::fromLocal8Bit(name.nodename));
vars[ProKey("QMAKE_HOST.version")] << ProString(name.release);

View File

@@ -46,6 +46,7 @@ private slots:
void findBreakpoints();
void findBreakpoints2();
void findBreakpoints3();
};
void tst_Misc::diagnosticClient_error()
@@ -155,7 +156,7 @@ void tst_Misc::findBreakpoints2()
" }\n"
"}\n"
);
Document::Ptr doc = Document::create("findContstructorBreakpoint");
Document::Ptr doc = Document::create("findSwitchBreakpoint");
QVERIFY(!doc.isNull());
doc->setUtf8Source(src);
bool success = doc->parse();
@@ -173,5 +174,32 @@ void tst_Misc::findBreakpoints2()
QCOMPARE(findBreakpoint(7), 7U);
}
void tst_Misc::findBreakpoints3()
{
const QByteArray src("\n" // line 0
"int foo() {\n"
" try {\n" // line 2
" bar();\n" // line 3
" } catch (Mooze &m) {\n" // line 4
" wooze();\n" // line 5
" }\n"
" return 0;\n" // line 7
"}\n"
);
Document::Ptr doc = Document::create("findCatchBreakpoint");
QVERIFY(!doc.isNull());
doc->setUtf8Source(src);
bool success = doc->parse();
QVERIFY(success);
QCOMPARE(doc->diagnosticMessages().size(), 0);
FindCdbBreakpoint findBreakpoint(doc->translationUnit());
QCOMPARE(findBreakpoint(2), 3U);
QCOMPARE(findBreakpoint(3), 3U);
QCOMPARE(findBreakpoint(4), 5U);
QCOMPARE(findBreakpoint(5), 5U);
QCOMPARE(findBreakpoint(7), 7U);
}
QTEST_MAIN(tst_Misc)
#include "tst_misc.moc"

View File

@@ -545,9 +545,9 @@ private:
void tst_Dumpers::initTestCase()
{
m_debuggerBinary = qgetenv("QTC_DEBUGGER_PATH_FOR_TEST");
if (m_debuggerBinary.isEmpty())
m_debuggerBinary = "gdb";
qDebug() << "Debugger : " << m_debuggerBinary.constData();
m_debuggerEngine = DumpTestGdbEngine;
if (m_debuggerBinary.endsWith("cdb.exe"))
@@ -559,6 +559,7 @@ void tst_Dumpers::initTestCase()
m_qmakeBinary = qgetenv("QTC_QMAKE_PATH_FOR_TEST");
if (m_qmakeBinary.isEmpty())
m_qmakeBinary = "qmake";
qDebug() << "QMake : " << m_qmakeBinary.constData();
Environment utilsEnv = Environment::systemEnvironment();
utilsEnv.appendOrSet(QLatin1String("QT_HASH_SEED"), QLatin1String("0"));
@@ -574,7 +575,7 @@ void tst_Dumpers::initTestCase()
QByteArray output = debugger.readAllStandardOutput();
//qDebug() << "stdout: " << output;
m_usePython = !output.contains("Python scripting is not supported in this copy of GDB");
qDebug() << (m_usePython ? "Python is available" : "Python is not available");
qDebug() << "Python : " << (m_usePython ? "ok" : "*** not ok ***");
qDebug() << "Dumper dir : " << DUMPERDIR;
QString version = QString::fromLocal8Bit(output);
@@ -587,7 +588,7 @@ void tst_Dumpers::initTestCase()
version = version.mid(pos1, pos2 - pos1);
extractGdbVersion(version, &m_gdbVersion,
&m_gdbBuildVersion, &m_isMacGdb, &m_isQnxGdb);
qDebug() << "Gdb version " << m_gdbVersion;
qDebug() << "Gdb version : " << m_gdbVersion;
} else if (m_debuggerEngine == DumpTestCdbEngine) {
QByteArray envBat = qgetenv("QTC_MSVC_ENV_BAT");
QMap <QString, QString> envPairs;
@@ -776,7 +777,7 @@ void tst_Dumpers::dumper()
"run " + nograb + "\n"
"up\n"
"python print('@%sS@%s@' % ('N', qtNamespace()))\n"
"bb options:fancy,autoderef,dyntype vars: expanded:" + expanded + " typeformats:\n";
"bb options:fancy,autoderef,dyntype,pe vars: expanded:" + expanded + " typeformats:\n";
} else {
cmds += "run\n";
foreach (const Check &check, data.checks) {
@@ -1123,13 +1124,15 @@ void tst_Dumpers::dumper_data()
QTest::newRow("QDateTime0")
<< Data("#include <QDateTime>\n",
"QDateTime date;\n")
"QDateTime date;\n"
"unused(&date);\n")
% CoreProfile()
% Check("date", "(invalid)", "@QDateTime");
QTest::newRow("QDateTime1")
<< Data("#include <QDateTime>\n",
"QDateTime date(QDate(1980, 1, 1), QTime(13, 15, 32), Qt::UTC);\n")
"QDateTime date(QDate(1980, 1, 1), QTime(13, 15, 32), Qt::UTC);\n"
"unused(&date);\n")
% CoreProfile()
% Check("date", "Tue Jan 1 13:15:32 1980", "@QDateTime")
% Check("date.(ISO)", "\"1980-01-01T13:15:32Z\"", "@QString")
@@ -1147,11 +1150,12 @@ void tst_Dumpers::dumper_data()
<< Data("#include <QDir>\n",
"QDir dir(" + tempDir + ");\n"
"QString s = dir.absolutePath();\n"
"unused(&dir, &s);\n")
"QFileInfoList fi = dir.entryInfoList();\n"
"unused(&dir, &s, &fi);\n")
% CoreProfile()
% Check("dir", tempDir, "@QDir")
% Check("dir.absolutePath", tempDir, "@QString")
% Check("dir.canonicalPath", tempDir, "@QString");
% Check("dir.absolutePath", tempDir, "@QString");
// % Check("dir.canonicalPath", tempDir, "@QString");
QTest::newRow("QFileInfo")
#ifdef Q_OS_WIN
@@ -2745,6 +2749,7 @@ void tst_Dumpers::dumper_data()
"v.push_back(str);\n"
"l.push_back(str);\n"
"l.push_back(str);\n")
% CoreProfile()
% Check("l0", "<0 items>", "@QList<std::string>")
% Check("l", "<2 items>", "@QList<std::string>")
% Check("str", "\"foo\"", "std::string")
@@ -3118,7 +3123,7 @@ void tst_Dumpers::dumper_data()
% Check("anc", "1", "int");
QTest::newRow("QThread1")
<< Data("#include <QThread>\n",
<< Data("#include <QThread>\n"
"struct Thread : QThread\n"
"{\n"
" void run()\n"
@@ -3127,7 +3132,7 @@ void tst_Dumpers::dumper_data()
" breakHere();\n"
" }\n"
" int m_id;\n"
"};\n"
"};\n",
"const int N = 14;\n"
"Thread thread[N];\n"
"for (int i = 0; i != N; ++i) {\n"
@@ -3135,6 +3140,7 @@ void tst_Dumpers::dumper_data()
" thread[i].setObjectName(\"This is thread #\" + QString::number(i));\n"
" thread[i].start();\n"
"}\n")
% CoreProfile()
% CheckType("this", "Thread")
% Check("this.@1", "[@QThread]", "\"This is thread #3\"", "@QThread")
% Check("this.@1.@1", "[@QObject]", "\"This is thread #3\"", "@QObject");
@@ -3256,6 +3262,7 @@ void tst_Dumpers::dumper_data()
"QVariant var;\n"
"var.setValue(my);\n"
"breakHere();\n")
% CoreProfile()
% Check("my", "<2 items>", "MyType")
% Check("my.0", "[0]", "", "@QMapNode<unsigned int, @QStringList>")
% Check("my.0.key", "1", "unsigned int")
@@ -3304,6 +3311,7 @@ void tst_Dumpers::dumper_data()
"vl.append(QVariant(21));\n"
"vl.append(QVariant(22));\n"
"vl.append(QVariant(\"2Some String\"));\n")
% CoreProfile()
% Check("vl", "<6 items>", "@QVariantList")
% CheckType("vl.0", "[0]", "@QVariant (int)")
% CheckType("vl.2", "[2]", "@QVariant (QString)");
@@ -3317,6 +3325,7 @@ void tst_Dumpers::dumper_data()
"vm[\"d\"] = QVariant(21);\n"
"vm[\"e\"] = QVariant(22);\n"
"vm[\"f\"] = QVariant(\"2Some String\");\n")
% CoreProfile()
% Check("vm", "<6 items>", "@QVariantMap")
% Check("vm.0", "[0]", "", "@QMapNode<@QString, @QVariant>")
% Check("vm.0.key", Value4("\"a\""), "@QString")
@@ -3325,15 +3334,16 @@ void tst_Dumpers::dumper_data()
% Check("vm.0.value", Value5("2"), "@QVariant (int)")
% Check("vm.5", "[5]", "", "@QMapNode<@QString, @QVariant>")
% Check("vm.5.key", Value4("\"f\""), "@QString")
% Check("vm.5.value", Value4("\"2Some String\""), "@QVariant (@QString)")
% Check("vm.5.value", Value4("\"2Some String\""), "@QVariant (QString)")
% Check("vm.5.key", Value5("\"f\""), "@QString")
% Check("vm.5.value", Value5("\"2Some String\""), "@QVariant (@QString)");
% Check("vm.5.value", Value5("\"2Some String\""), "@QVariant (QString)");
QTest::newRow("QVectorIntBig")
<< Data("#include <QVector>\n",
"QVector<int> vec(10000);\n"
"for (int i = 0; i != vec.size(); ++i)\n"
" vec[i] = i * i;\n")
% CoreProfile()
% Check("vec", "<10000 items>", "@QVector<int>")
% Check("vec.0", "[0]", "0", "int")
% Check("vec.1999", "[1999]", "3996001", "int");
@@ -3343,6 +3353,7 @@ void tst_Dumpers::dumper_data()
"QVector<Foo> vec;\n"
"vec.append(1);\n"
"vec.append(2);\n")
% CoreProfile()
% Check("vec", "<2 items>", "@QVector<Foo>")
% Check("vec.0", "[0]", "", "Foo")
% Check("vec.0.a", "1", "int")
@@ -3355,7 +3366,8 @@ void tst_Dumpers::dumper_data()
"FooVector vec;\n"
"vec.append(1);\n"
"vec.append(2);\n")
% Check("vec", "<2 items>", "@FooVector")
% CoreProfile()
% Check("vec", "<2 items>", "FooVector")
% Check("vec.0", "[0]", "", "Foo")
% Check("vec.0.a", "1", "int")
% Check("vec.1", "[1]", "", "Foo")
@@ -4032,7 +4044,7 @@ void tst_Dumpers::dumper_data()
"boost::optional<QStringList> sl0, sl;\n"
"sl = (QStringList() << \"xxx\" << \"yyy\");\n"
"sl.get().append(\"zzz\");\n")
% Check("sl", "<3 items>", "boost::optional<QStringList>");
% Check("sl", "<3 items>", "boost::optional<@QStringList>");
QTest::newRow("BoostSharedPtr")
<< Data("#include <QStringList>\n"

View File

@@ -0,0 +1,13 @@
// Copyright license
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

View File

@@ -0,0 +1,16 @@
// Copyright license
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}

View File

@@ -0,0 +1,24 @@
// Copyright license
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

View File

@@ -0,0 +1,24 @@
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle" >
<string>MainWindow</string>
</property>
<widget class="QMenuBar" name="menuBar" />
<widget class="QToolBar" name="mainToolBar" />
<widget class="QWidget" name="centralWidget" />
<widget class="QStatusBar" name="statusBar" />
</widget>
<layoutDefault spacing="6" margin="11" />
<pixmapfunction></pixmapfunction>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,9 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = testdata_guiproject1
TEMPLATE = app
SOURCES += main.cpp mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui

View File

@@ -0,0 +1,7 @@
// Copyright header
#include "foo.h"
Foo::Foo()
{
}

View File

@@ -0,0 +1,12 @@
// Copyright header
#ifndef FOO_H
#define FOO_H
class Foo
{
public:
Foo();
};
#endif // FOO_H

View File

@@ -0,0 +1,9 @@
// Copyright header
#include "foo.h"
int main()
{
Foo foo;
return 1;
}

View File

@@ -0,0 +1,7 @@
// Copyright header
#include "bar.h"
Bar::Bar()
{
}

View File

@@ -0,0 +1,12 @@
// Copyright header
#ifndef BAR_H
#define BAR_H
class Bar
{
public:
Bar();
};
#endif // BAR_H

View File

@@ -0,0 +1,9 @@
// Copyright header
#include "bar.h"
int main()
{
Bar bar;
return 1;
}

View File

@@ -349,6 +349,9 @@ def __configureFW__(workingDir, projectName, isReleaseBuild, addToFW=True):
mode = "delete"
enable = ""
projectName = ""
# Needs admin privileges on Windows 7
# Using the deprecated "netsh firewall" because the newer
# "netsh advfirewall" would need admin privileges on Windows Vista, too.
return subprocess.call('netsh firewall %s allowedprogram "%s.exe" %s %s' % (mode, path, projectName, enable))
# helper to check whether win firewall is running or not