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: The standalone binary packages support the following platforms:
Windows XP SP2 or later 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 Mac OS 10.6 or later
Building the sources requires Qt 4.8.0 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. # FIXME: Check it's really a base.
return typeobj.fields()[index] 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): def savePrint(output):
try: try:
print(output) print(output)
@@ -358,6 +352,9 @@ qqDumpers = {}
# This is a cache of all dumpers that support writing. # This is a cache of all dumpers that support writing.
qqEditable = {} qqEditable = {}
# This is an approximation of the Qt Version found
qqVersion = None
def registerDumper(function): def registerDumper(function):
global qqDumpers, qqFormats, qqEditable global qqDumpers, qqFormats, qqEditable
try: try:
@@ -1134,7 +1131,7 @@ def qtNamespace():
if not qqNs is None: if not qqNs is None:
return qqNs return qqNs
try: try:
str = catchCliOutput("ptype QString::Null")[0] str = gdb.execute("ptype QString::Null", to_string=True)
# The result looks like: # The result looks like:
# "type = const struct myns::QString::Null {" # "type = const struct myns::QString::Null {"
# " <no data fields>" # " <no data fields>"
@@ -1323,6 +1320,7 @@ class Dumper:
self.formats = {} self.formats = {}
self.useDynamicType = True self.useDynamicType = True
self.expandedINames = {} self.expandedINames = {}
self.childEventAddress = None
def __init__(self, args): def __init__(self, args):
self.defaultInit() self.defaultInit()
@@ -1539,15 +1537,73 @@ class Dumper:
def charPtrType(self): def charPtrType(self):
return self.lookupType('char*') return self.lookupType('char*')
def intPtrType(self):
return self.lookupType('int*')
def voidPtrType(self): def voidPtrType(self):
return self.lookupType('void*') return self.lookupType('void*')
def voidPtrSize(self):
return self.voidPtrType().sizeof
def addressOf(self, value): def addressOf(self, value):
return long(value.address) 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): def put(self, value):
self.output.append(value) self.output.append(value)
@@ -1559,6 +1615,18 @@ class Dumper:
return xrange(0, self.currentNumChild) return xrange(0, self.currentNumChild)
return xrange(min(self.currentMaxNumChild, 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. # Convenience function.
def putItemCount(self, count, maximum = 1000000000): def putItemCount(self, count, maximum = 1000000000):
# This needs to override the default value, so don't use 'put' directly. # 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("INAME: %s " % self.currentIName)
#warn("INAMES: %s " % self.expandedINames) #warn("INAMES: %s " % self.expandedINames)
#warn("EXPANDED: %s " % (self.currentIName in 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.putType(typeName)
self.putEmptyValue() self.putEmptyValue()
self.putNumChild(fieldCount(type)) self.putNumChild(fieldCount(type))

View File

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

View File

@@ -18,6 +18,7 @@ movableTypes = set([
"QXmlStreamNotationDeclaration", "QXmlStreamEntityDeclaration" "QXmlStreamNotationDeclaration", "QXmlStreamEntityDeclaration"
]) ])
def checkSimpleRef(ref): def checkSimpleRef(ref):
count = int(ref["_q_value"]) count = int(ref["_q_value"])
check(count > 0) check(count > 0)
@@ -34,24 +35,30 @@ def checkRef(ref):
check(count >= minimum) check(count >= minimum)
check(count < 1000000) 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): def qEncodeByteArray(d, addr, limit = None):
return d.byteArrayDataData(value['d'].dereference()) data, size, alloc = qByteArrayData(d, addr)
def qEncodeByteArray(d, value, limit = None):
data, size, alloc = d.byteArrayData(value)
if alloc != 0: if alloc != 0:
check(0 <= size and size <= alloc and alloc <= 100*1000*1000) check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
limit = d.computeLimit(size, limit) limit = d.computeLimit(size, limit)
@@ -60,8 +67,9 @@ def qEncodeByteArray(d, value, limit = None):
s += "2e2e2e" s += "2e2e2e"
return s return s
def qEncodeString(d, value, limit = 0): # addr is the begin of a QByteArrayData structure
data, size, alloc = d.stringData(value) def qEncodeString(d, addr, limit = 0):
data, size, alloc = qByteArrayData(d, addr)
if alloc != 0: if alloc != 0:
check(0 <= size and size <= alloc and alloc <= 100*1000*1000) check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
limit = d.computeLimit(size, limit) limit = d.computeLimit(size, limit)
@@ -70,6 +78,24 @@ def qEncodeString(d, value, limit = 0):
s += "2e002e002e00" s += "2e002e002e00"
return s 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(): def mapForms():
return "Normal,Compact" return "Normal,Compact"
@@ -96,49 +122,68 @@ def qPutMapName(d, value):
else: else:
d.put('name="%s",' % value) 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.putMapName = qPutMapName
Dumper.isMapCompact = \ Dumper.isMapCompact = \
lambda d, keyType, valueType: qMapCompact(d.currentItemFormat(), keyType, valueType) lambda d, keyType, valueType: qMapCompact(d.currentItemFormat(), keyType, valueType)
# Returns True when it encounters a QObject or derived class. def qPutQObjectNameValue(d, value):
def tryPutObjectNameValue(d, value):
try: try:
# Is this derived from QObject? intSize = d.intSize()
dd = value["d_ptr"]["d"] ptrSize = d.ptrSize()
privateType = d.lookupType(d.ns + "QObjectPrivate") # dd = value["d_ptr"]["d"] is just behind the vtable.
staticMetaObject = value["staticMetaObject"] dd = d.dereference(d.addressOf(value) + ptrSize)
d_ptr = dd.cast(privateType.pointer()).dereference()
objectName = None if d.qtVersion() < 0x050000:
try: # Size of QObjectData: 5 pointer + 2 int
objectName = d_ptr["objectName"] # - vtable
except: # Qt 5 # - QObject *q_ptr;
p = d_ptr["extraData"] # - QObject *parent;
if not isNull(p): # - QObjectList children;
objectName = p.dereference()["objectName"] # - uint isWidget : 1; etc..
if not objectName is None: # - int postedEvents;
data, size, alloc = d.stringData(objectName) # - 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: if size > 0:
str = d.readRawMemory(data, 2 * size) str = d.readRawMemory(data, 2 * size)
d.putValue(str, Hex4EncodedLittleEndian, 1) d.putValue(str, Hex4EncodedLittleEndian, 1)
return True
except: except:
return False pass
Dumper.tryPutObjectNameValue = tryPutObjectNameValue Dumper.putQObjectNameValue = qPutQObjectNameValue
############################################################################################ ###################################################################################
def qdump__QAtomicInt(d, value): def qdump__QAtomicInt(d, value):
@@ -161,13 +206,6 @@ def qdump__QBasicAtomicPointer(d, value):
with Children(d): with Children(d):
d.putItem(value["_q_value"]) 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(): def qform__QByteArray():
return "Inline,As Latin1 in Separate Window,As UTF-8 in Separate Window" 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: # This relies on the Qt4/Qt5 internal structure layout:
# {sharedref(4), date(8), time(4+x)} # {sharedref(4), date(8), time(4+x)}
def qdump__QDateTime(d, value): def qdump__QDateTime(d, value):
intType = d.lookupType("int") base = d.dereferenceValue(value)
intPtrType = intType.pointer() # QDateTimePrivate:
base = pointerValue(value.cast(intPtrType)) # - QAtomicInt ref; (padded on 64 bit)
mds = int(createReferenceValue(value, base + intPtrType.sizeof + 8, intType)) # - [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: if mds >= 0:
jd = int(createReferenceValue(value, base + intPtrType.sizeof, intType)) jd = d.extractInt(dateBase)
d.putValue("%s/%s" % (jd, mds), JulianDateAndMillisecondsSinceMidnight) d.putValue("%s/%s" % (jd, mds), JulianDateAndMillisecondsSinceMidnight)
d.putNumChild(1) d.putNumChild(1)
if d.isExpanded(): if d.isExpanded():
@@ -388,31 +434,54 @@ def qdump__QDateTime(d, value):
def qdump__QDir(d, value): def qdump__QDir(d, value):
d.putNumChild(1) d.putNumChild(1)
data = value["d_ptr"]["d"].dereference() privAddress = d.dereferenceValue(value)
try: bit32 = d.is32bit()
# Up to Qt 4.7 qt5 = d.qtVersion() >= 0x050000
d.putStringValue(data["path"]) # value.d_ptr.d.dirEntry.m_filePath - value.d_ptr.d
except: offset = (32 if bit32 else 56) if qt5 else 36
# Qt 4.8 and later. filePathAddress = privAddress + offset
d.putStringValue(data["dirEntry"]["m_filePath"]) #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(): if d.isExpanded():
with Children(d): with Children(d):
qdir = d.ns + "QDir::" call(value, "count") # Fill cache.
d.putCallItem("absolutePath", value, "absolutePath") #d.putCallItem("absolutePath", value, "absolutePath")
d.putCallItem("canonicalPath", value, "canonicalPath") #d.putCallItem("canonicalPath", value, "canonicalPath")
d.putSubItem("entryList", data["files"]) with SubItem(d, "absolutePath"):
d.putSubItem("entryInfoList", data["fileInfos"]) # 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): def qdump__QFile(d, value):
try: try:
# Try using debug info first.
ptype = d.lookupType(d.ns + "QFilePrivate").pointer() ptype = d.lookupType(d.ns + "QFilePrivate").pointer()
d_ptr = value["d_ptr"]["d"] d_ptr = value["d_ptr"]["d"]
d.putStringValue(d_ptr.cast(ptype).dereference()["fileName"]) fileNameAddress = d.addressOf(d_ptr.cast(ptype).dereference()["fileName"])
except:
d.putPlainChildren(value)
return
d.putNumChild(1) 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(): if d.isExpanded():
with Children(d): with Children(d):
base = fieldAt(value.type, 0).type base = fieldAt(value.type, 0).type
@@ -421,11 +490,16 @@ def qdump__QFile(d, value):
def qdump__QFileInfo(d, value): def qdump__QFileInfo(d, value):
try: privAddress = d.dereferenceValue(value)
d.putStringValue(value["d_ptr"]["d"].dereference()["fileNames"][3]) #bit32 = d.is32bit()
except: #qt5 = d.qtVersion() >= 0x050000
d.putPlainChildren(value) #try:
return # d.putStringValue(value["d_ptr"]["d"].dereference()["fileNames"][3])
#except:
# d.putPlainChildren(value)
# return
filePathAddress = privAddress + d.ptrSize()
qPutStringValueByAddress(d, filePathAddress)
d.putNumChild(1) d.putNumChild(1)
if d.isExpanded(): if d.isExpanded():
with Children(d, childType=d.lookupType(d.ns + "QString")): with Children(d, childType=d.lookupType(d.ns + "QString")):
@@ -650,11 +724,16 @@ def qdump__QHash__iterator(d, value):
def qdump__QHostAddress(d, value): def qdump__QHostAddress(d, value):
data = value["d"]["d"].dereference() privAddress = d.dereferenceValue(value)
if int(data["ipString"]["d"]["size"]): isQt5 = d.qtVersion() >= 0x050000
d.putStringValue(data["ipString"]) 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: 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, n4 = divmod(a, 256)
a, n3 = divmod(a, 256) a, n3 = divmod(a, 256)
a, n2 = divmod(a, 256) a, n2 = divmod(a, 256)
@@ -663,7 +742,7 @@ def qdump__QHostAddress(d, value):
d.putNumChild(1) d.putNumChild(1)
if d.isExpanded(): if d.isExpanded():
with Children(d): with Children(d):
d.putFields(data) d.putFields(value["d"]["d"].dereference())
def qdump__QList(d, value): def qdump__QList(d, value):
dptr = childAt(value, 0)["d"] dptr = childAt(value, 0)["d"]
@@ -692,15 +771,15 @@ def qdump__QList(d, value):
addr = d.addressOf(array) + begin * stepSize addr = d.addressOf(array) + begin * stepSize
if isInternal: if isInternal:
if innerSize == stepSize: if innerSize == stepSize:
p = createPointerValue(value, addr, innerType) p = d.createPointerValue(addr, innerType)
d.putArrayData(innerType, p, size) d.putArrayData(innerType, p, size)
else: else:
with Children(d, size, childType=innerType): with Children(d, size, childType=innerType):
for i in d.childRange(): for i in d.childRange():
p = createPointerValue(value, addr + i * stepSize, innerType) p = d.createValue(addr + i * stepSize, innerType)
d.putSubItem(i, p.dereference()) d.putSubItem(i, p)
else: else:
p = createPointerValue(value, addr, innerType.pointer()) p = d.createPointerValue(addr, innerType.pointer())
# about 0.5s / 1000 items # about 0.5s / 1000 items
with Children(d, size, maxNumChild=2000, childType=innerType): with Children(d, size, maxNumChild=2000, childType=innerType):
for i in d.childRange(): for i in d.childRange():
@@ -711,49 +790,57 @@ def qform__QImage():
return "Normal,Displayed" return "Normal,Displayed"
def qdump__QImage(d, value): def qdump__QImage(d, value):
# This relies on current QImage layout # This relies on current QImage layout:
intPtrType = d.lookupType("int").pointer() # QImageData:
base = createReferenceValue(value, d.addressOf(value) + 3 * intPtrType.sizeof, intPtrType) # - QAtomicInt ref
width = int(base[1]) # - int width, height, depth, nbytes
height = int(base[2]) # - 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.putValue("(%dx%d)" % (width, height))
d.putNumChild(0) d.putNumChild(1)
#d.putNumChild(1)
if d.isExpanded(): if d.isExpanded():
with Children(d): with Children(d):
d.putIntItem("width", width)
d.putIntItem("height", height)
d.putIntItem("nbytes", nbytes)
d.putIntItem("format", iformat)
with SubItem(d, "data"): with SubItem(d, "data"):
d.putNoType() d.putValue("0x%x" % bits)
d.putNumChild(0) d.putNumChild(0)
d.putValue("size: %s bytes" % nbytes); d.putType("void *")
format = d.currentItemFormat() format = d.currentItemFormat()
if format == 1: if format == 1:
d.putDisplay(StopDisplay) d.putDisplay(StopDisplay)
elif format == 2: elif format == 2:
d_ptr = value["d"] # This is critical for performance. Writing to an external
bits = d_ptr["data"] # file using the following is faster when using GDB.
nbytes = d_ptr["nbytes"] # file = tempfile.mkstemp(prefix="gdbpy_")
if False: # filename = file[1].replace("\\", "\\\\")
# Take four bytes at a time, this is critical for performance. # gdb.execute("dump binary memory %s %s %s" %
# In fact, even four at a time is too slow beyond 100x100 or so. # (filename, bits, bits + nbytes))
# d.putDisplay(DisplayImageFile, " %d %d %d %d %s"
# % (width, height, nbytes, iformat, filename))
d.putField("editformat", DisplayImageData) d.putField("editformat", DisplayImageData)
d.put('%s="' % name) d.put('editvalue="')
d.put("%08x" % width) d.put('%08x%08x%08x%08x' % (width, height, nbytes, iformat))
d.put("%08x" % height) d.put(d.readRawMemory(bits, nbytes))
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('",') 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): def qdump__QLinkedList(d, value):
@@ -960,8 +1047,7 @@ def extractCString(table, offset):
def qdump__QObject(d, value): def qdump__QObject(d, value):
#warn("OBJECT: %s " % value) d.putQObjectNameValue(value)
d.tryPutObjectNameValue(value)
try: try:
privateTypeName = d.ns + "QObjectPrivate" privateTypeName = d.ns + "QObjectPrivate"
@@ -1391,14 +1477,11 @@ def qdump__QObject(d, value):
# } # }
def qdump__QPixmap(d, value): def qdump__QPixmap(d, value):
painters = int(value["painters"]) offset = (3 if d.qtVersion() >= 0x050000 else 2) * d.ptrSize()
check(0 <= painters and painters < 1000) base = d.dereference(d.addressOf(value) + offset)
d_ptr = value["data"]["d"] width = d.extractInt(base + 4)
if isNull(d_ptr): height = d.extractInt(base + 8)
d.putValue("(null)") d.putValue("(%dx%d)" % (width, height))
else:
checkSimpleRef(d_ptr["ref"])
d.putValue("(%dx%d)" % (d_ptr["w"], d_ptr["h"]))
d.putNumChild(0) d.putNumChild(0)
@@ -1460,16 +1543,35 @@ def qdump__QRectF(d, value):
def qdump__QRegExp(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) d.putNumChild(1)
if d.isExpanded(): if d.isExpanded():
with Children(d): 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 call(value, "capturedTexts") # create cache
with SubItem(d, "syntax"): 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"): 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): def qdump__QRegion(d, value):
@@ -1644,7 +1746,7 @@ def qdump__QStringRef(d, value):
s = value["m_string"].dereference() s = value["m_string"].dereference()
data, size, alloc = d.stringData(s) data, size, alloc = d.stringData(s)
data += 2 * int(value["m_position"]) data += 2 * int(value["m_position"])
size = value["m_size"] size = int(value["m_size"])
s = d.readRawMemory(data, 2 * size) s = d.readRawMemory(data, 2 * size)
d.putValue(s, Hex4EncodedLittleEndian) d.putValue(s, Hex4EncodedLittleEndian)
d.putNumChild(3) d.putNumChild(3)
@@ -1674,22 +1776,19 @@ def qdump__QTextCodec(d, value):
def qdump__QTextCursor(d, value): def qdump__QTextCursor(d, value):
dd = value["d"]["d"] privAddress = d.dereferenceValue(value)
if isNull(dd): if privAddress == 0:
d.putValue("(invalid)") d.putValue("(invalid)")
d.putNumChild(0) d.putNumChild(0)
else: else:
try: positionAddress = privAddress + 2 * d.ptrSize() + 8
p = dd.dereference() d.putValue(d.extractInt(positionAddress))
d.putValue(p["position"])
except:
d.putPlainChildren(value)
return
d.putNumChild(1) d.putNumChild(1)
if d.isExpanded(): if d.isExpanded():
with Children(d): with Children(d):
d.putIntItem("position", p["position"]) positionAddress = privAddress + 2 * d.ptrSize() + 8
d.putIntItem("anchor", p["anchor"]) d.putIntItem("position", d.extractInt(positionAddress))
d.putIntItem("anchor", d.extractInt(positionAddress + intSize))
d.putCallItem("selected", value, "selectedText") d.putCallItem("selected", value, "selectedText")
@@ -1706,22 +1805,31 @@ def qdump__QTextDocument(d, value):
def qdump__QUrl(d, value): def qdump__QUrl(d, value):
try: if d.qtVersion() < 0x050000:
# Qt 4
data = value["d"].dereference() data = value["d"].dereference()
d.putByteArrayValue(data["encodedOriginal"]) d.putByteArrayValue(data["encodedOriginal"])
except: else:
try: # QUrlPrivate:
# Qt 5 # - QAtomicInt ref;
data = value["d"].dereference() # - int port;
str = d.encodeString(data["scheme"]) # - 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 += "3a002f002f00"
str += d.encodeString(data["host"]) str += qEncodeString(d, host)
str += d.encodeString(data["path"]) str += qEncodeString(d, path)
d.putValue(str, Hex4EncodedLittleEndian) d.putValue(str, Hex4EncodedLittleEndian)
except:
d.putPlainChildren(value)
return
d.putNumChild(1) d.putNumChild(1)
if d.isExpanded(): if d.isExpanded():
with Children(d): with Children(d):

View File

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

View File

@@ -60,12 +60,13 @@ symbian {
LIBS += -lavkon -lcone 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 { mac {
QMAKE_INFO_PLIST=Info.plist
TARGET=QMLObserver TARGET=QMLObserver
info.input = Info.plist.in
info.output = $$DESTDIR/$${TARGET}.app/Contents/Info.plist
QMAKE_SUBSTITUTES += info
ICON=qml.icns ICON=qml.icns
} else { } else {
TARGET=qmlobserver TARGET=qmlobserver

View File

@@ -29,9 +29,18 @@ DEFINES -= QT_NO_CAST_FROM_ASCII
OTHER_FILES += Info.plist.in OTHER_FILES += Info.plist.in
macx { 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.input = $$PWD/Info.plist.in
info.output = $$DESTDIR/$${TARGET}.app/Contents/Info.plist info.output = $$DESTDIR/$${TARGET}.app/Contents/Info.plist
QMAKE_SUBSTITUTES += info QMAKE_SUBSTITUTES += info
}
} else { } else {
target.path = $$QTC_PREFIX/bin target.path = $$QTC_PREFIX/bin
INSTALLS += target INSTALLS += target

View File

@@ -23,9 +23,18 @@ DEFINES -= QT_NO_CAST_FROM_ASCII
OTHER_FILES += Info.plist.in OTHER_FILES += Info.plist.in
macx { 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.input = $$PWD/Info.plist.in
info.output = $$DESTDIR/$${TARGET}.app/Contents/Info.plist info.output = $$DESTDIR/$${TARGET}.app/Contents/Info.plist
QMAKE_SUBSTITUTES += info QMAKE_SUBSTITUTES += info
}
} else { } else {
target.path = $$QTC_PREFIX/bin target.path = $$QTC_PREFIX/bin
INSTALLS += target INSTALLS += target

View File

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

View File

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

View File

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

View File

@@ -53,7 +53,7 @@
<style name="JsScopeVar" foreground="#8888ff" italic="true"/> <style name="JsScopeVar" foreground="#8888ff" italic="true"/>
<style name="JsImportVar" foreground="#8888ff" italic="true"/> <style name="JsImportVar" foreground="#8888ff" italic="true"/>
<style name="JsGlobalVar" 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="DiffContextLine" foreground="#404040" background="#97bac7"/>
<style name="DiffSourceLine" background="#8c2d2d"/> <style name="DiffSourceLine" background="#8c2d2d"/>
<style name="DiffSourceChar" background="#c34141"/> <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)) let $suffix := concat("&quot;)", codepoints-to-string(10))
for $file in tokenize($files, string("\|")) for $file in tokenize($files, string("\|"))
let $doc := doc($file) 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) 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> <source>Plain C++ Project (CMake Build)</source>
<translation>C++-Projekt (CMake)</translation> <translation>C++-Projekt (CMake)</translation>
</message> </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> <message>
<source>Custom QML Extension Plugin Parameters</source> <source>Custom QML Extension Plugin Parameters</source>
<oldsource>QML Runtime Plug-in Parameters</oldsource> <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> <source>Local user settings</source>
<translation>Lokale Benutzer-Einstellungen</translation> <translation>Lokale Benutzer-Einstellungen</translation>
</message> </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> <message>
<source>Object class-name:</source> <source>Object class-name:</source>
<translation>Klassenname des Objektes:</translation> <translation>Klassenname des Objektes:</translation>
</message> </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> <message>
<source>Qt Quick 1 Extension Plugin</source> <source>Qt Quick 1 Extension Plugin</source>
<translation>Plugin zur Erweiterung von QtQuick 1</translation> <translation>Plugin zur Erweiterung von QtQuick 1</translation>
</message> </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> <message>
<source>Qt Quick 2 Extension Plugin</source> <source>Qt Quick 2 Extension Plugin</source>
<translation>Plugin zur Erweiterung von QtQuick 2</translation> <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>
<message> <message>
<source>Creates a qmake-based subdirs project. This allows you to group your projects in a tree structure.</source> <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>
<message> <message>
<source>Done &amp;&amp; Add Subproject</source> <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>
<context> <context>
<name>Qnx::Internal::BlackBerryRunConfiguration</name> <name>Qnx::Internal::BlackBerryRunConfiguration</name>
<message>
<source>%1 on BlackBerry device</source>
<translation>%1 auf BlackBerry-Gerät</translation>
</message>
<message> <message>
<source>Run on BlackBerry device</source> <source>Run on BlackBerry device</source>
<translation>Ausführung auf BlackBerry-Gerät</translation> <translation>Ausführung auf BlackBerry-Gerät</translation>
</message> </message>
</context> </context>
<context>
<name>Qnx::Internal::BlackBerryRunConfigurationFactory</name>
<message>
<source>%1 on BlackBerry Device</source>
<translation>%1 auf BlackBerry-Gerät</translation>
</message>
</context>
<context> <context>
<name>Qnx::Internal::BlackBerryRunControlFactory</name> <name>Qnx::Internal::BlackBerryRunControlFactory</name>
<message> <message>
@@ -31266,6 +31255,10 @@ Qt Creator know about a likely URI.</source>
<source>List of Processes</source> <source>List of Processes</source>
<translation>Liste der Prozesse</translation> <translation>Liste der Prozesse</translation>
</message> </message>
<message>
<source>&amp;Attach to Process</source>
<translation>&amp;An Prozess anhängen</translation>
</message>
</context> </context>
<context> <context>
<name>ProjectExplorer::DeviceProcessList</name> <name>ProjectExplorer::DeviceProcessList</name>
@@ -32011,13 +32004,6 @@ Fehlerausgabe: %1</translation>
<translation>&amp;Letzte:</translation> <translation>&amp;Letzte:</translation>
</message> </message>
</context> </context>
<context>
<name>DeviceProcessesDialog</name>
<message>
<source>&amp;Attach to Process</source>
<translation>&amp;An Prozess anhängen</translation>
</message>
</context>
<context> <context>
<name>Debugger::Internal::DebuggerCore</name> <name>Debugger::Internal::DebuggerCore</name>
<message> <message>
@@ -35711,21 +35697,6 @@ Kurznamen können verwendet werden, sofern sie eindeutig sind.</translation>
<translation>Refaktorisierung konnte nicht angewandt werden.</translation> <translation>Refaktorisierung konnte nicht angewandt werden.</translation>
</message> </message>
</context> </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> <context>
<name>CppEditor::QuickFix</name> <name>CppEditor::QuickFix</name>
<message> <message>
@@ -37058,4 +37029,31 @@ Dieser Wizard führt Sie durch die essentiellen Schritte, die zum Deployment ein
<translation>Beschreibung der Änderung einblenden</translation> <translation>Beschreibung der Änderung einblenden</translation>
</message> </message>
</context> </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> </TS>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -32,6 +32,9 @@
#include "cpppreprocessor.h" #include "cpppreprocessor.h"
#include "modelmanagertesthelper.h" #include "modelmanagertesthelper.h"
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h>
#include <QDebug> #include <QDebug>
#include <QFileInfo> #include <QFileInfo>
#include <QtTest> #include <QtTest>
@@ -96,6 +99,42 @@ private:
const QString m_testDataDirectory; 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 } // anonymous namespace
void CppToolsPlugin::test_modelmanager_paths() void CppToolsPlugin::test_modelmanager_paths()
@@ -278,3 +317,99 @@ void CppToolsPlugin::test_modelmanager_refresh_2()
QVERIFY(document->diagnosticMessages().isEmpty()); 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) { foreach (const QString &includePath, m_includePaths) {
QString path = includePath + fileName; QString path = includePath + fileName;
if (checkFile(path)) if (m_workingCopy.contains(path) || checkFile(path))
return path; return path;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -66,7 +66,9 @@ PerforceEditor::PerforceEditor(const VcsBase::VcsBaseEditorParameters *type,
// Diff format: // Diff format:
// 1) "==== //depot/.../mainwindow.cpp#2 - /depot/.../mainwindow.cpp ====" (created by p4 diff) // 1) "==== //depot/.../mainwindow.cpp#2 - /depot/.../mainwindow.cpp ====" (created by p4 diff)
// 2) "==== //depot/.../mainwindow.cpp#15 (text) ====" (created by p4 describe) // 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+) "))); setLogEntryPattern(QRegExp(QLatin1String("^... #\\d change (\\d+) ")));
setAnnotateRevisionTextFormat(tr("Annotate change list \"%1\"")); setAnnotateRevisionTextFormat(tr("Annotate change list \"%1\""));
if (Perforce::Constants::debug) if (Perforce::Constants::debug)

View File

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

View File

@@ -1096,15 +1096,21 @@ QString PropertyEditor::locateQmlFile(const NodeMetaInfo &info, const QString &r
const QString relativePathWithVersion = relativePathWithoutEnding + versionString + QLatin1String(".qml"); const QString relativePathWithVersion = relativePathWithoutEnding + versionString + QLatin1String(".qml");
//Check for qml files with versions first //Check for qml files with versions first
const QString withoutDirWithVersion = relativePathWithVersion.split(QLatin1String("/")).last();
if (importDir.exists(relativePathWithVersion)) if (importDir.exists(relativePathWithVersion))
return importDir.absoluteFilePath(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)) if (fileSystemDir.exists(relativePathWithVersion))
return fileSystemDir.absoluteFilePath(relativePathWithVersion); return fileSystemDir.absoluteFilePath(relativePathWithVersion);
if (resourcesDir.exists(relativePathWithVersion)) if (resourcesDir.exists(relativePathWithVersion))
return resourcesDir.absoluteFilePath(relativePathWithVersion); return resourcesDir.absoluteFilePath(relativePathWithVersion);
const QString withoutDir = relativePath.split(QLatin1String("/")).last();
if (importDir.exists(relativePath)) if (importDir.exists(relativePath))
return importDir.absoluteFilePath(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)) if (fileSystemDir.exists(relativePath))
return fileSystemDir.absoluteFilePath(relativePath); return fileSystemDir.absoluteFilePath(relativePath);
if (resourcesDir.exists(relativePath)) if (resourcesDir.exists(relativePath))

View File

@@ -39,7 +39,7 @@ namespace Internal {
typedef QSharedPointer<InternalNodeAbstractProperty> InternalNodeAbstractPropertyPointer; typedef QSharedPointer<InternalNodeAbstractProperty> InternalNodeAbstractPropertyPointer;
} }
class NodeAbstractProperty : public AbstractProperty class QMLDESIGNERCORE_EXPORT NodeAbstractProperty : public AbstractProperty
{ {
friend class QmlDesigner::ModelNode; friend class QmlDesigner::ModelNode;
friend class QmlDesigner::Internal::ModelPrivate; 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)); Core::MimeType qbsSourceTy = db->findByType(QLatin1String(Constants::QBS_MIMETYPE));
mergeSuffixes(qbsSuffixes, qbsSourceTy.suffixes()); mergeSuffixes(qbsSuffixes, qbsSourceTy.suffixes());
Core::MimeType qmlProjectSourceTy = db->findByType(QLatin1String(Constants::QMLPROJECT_MIMETYPE)); 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)); Core::MimeType jsonSourceTy = db->findByType(QLatin1String(Constants::JSON_MIMETYPE));
mergeSuffixes(jsonSuffixes, jsonSourceTy.suffixes()); mergeSuffixes(jsonSuffixes, jsonSourceTy.suffixes());
} }
@@ -243,6 +243,11 @@ ModelManager::ModelManager(QObject *parent):
m_updateCppQmlTypesTimer->setSingleShot(true); m_updateCppQmlTypesTimer->setSingleShot(true);
connect(m_updateCppQmlTypesTimer, SIGNAL(timeout()), SLOT(startCppQmlTypeUpdate())); 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::Document::Ptr>("QmlJS::Document::Ptr");
qRegisterMetaType<QmlJS::LibraryInfo>("QmlJS::LibraryInfo"); qRegisterMetaType<QmlJS::LibraryInfo>("QmlJS::LibraryInfo");
qRegisterMetaType<QmlJSTools::SemanticInfo>("QmlJSTools::SemanticInfo"); qRegisterMetaType<QmlJSTools::SemanticInfo>("QmlJSTools::SemanticInfo");
@@ -1056,6 +1061,11 @@ void ModelManager::startCppQmlTypeUpdate()
m_queuedCppDocuments.clear(); m_queuedCppDocuments.clear();
} }
void ModelManager::asyncReset()
{
m_asyncResetTimer->start();
}
void ModelManager::updateCppQmlTypes(QFutureInterface<void> &interface, void ModelManager::updateCppQmlTypes(QFutureInterface<void> &interface,
ModelManager *qmlModelManager, ModelManager *qmlModelManager,
CPlusPlus::Snapshot snapshot, CPlusPlus::Snapshot snapshot,
@@ -1100,7 +1110,7 @@ void ModelManager::updateCppQmlTypes(QFutureInterface<void> &interface,
qmlModelManager->m_cppDataHash = newData; qmlModelManager->m_cppDataHash = newData;
if (hasNewInfo) if (hasNewInfo)
// one could get away with re-linking the cpp types... // one could get away with re-linking the cpp types...
QMetaObject::invokeMethod(qmlModelManager, "resetCodeModel"); QMetaObject::invokeMethod(qmlModelManager, "asyncReset");
} }
ModelManager::CppDataHash ModelManager::cppData() const ModelManager::CppDataHash ModelManager::cppData() const

View File

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

View File

@@ -557,7 +557,7 @@ QStringList Qt4PriFileNode::fullVPaths(const QStringList &baseVPaths, QtSupport:
return vPaths; return vPaths;
} }
static QSet<Utils::FileName> recursiveEnumerate(const QString &folder) QSet<Utils::FileName> Qt4PriFileNode::recursiveEnumerate(const QString &folder)
{ {
QSet<Utils::FileName> result; QSet<Utils::FileName> result;
QFileInfo fi(folder); QFileInfo fi(folder);
@@ -718,10 +718,66 @@ void Qt4PriFileNode::watchFolders(const QSet<QString> &folders)
m_watchedFolders = folders; m_watchedFolders = folders;
} }
void Qt4PriFileNode::folderChanged(const QString &changedFolder) bool Qt4PriFileNode::folderChanged(const QString &changedFolder, const QSet<Utils::FileName> &newFiles)
{ {
Q_UNUSED(changedFolder); //qDebug()<<"########## Qt4PriFileNode::folderChanged";
scheduleUpdate(); // 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 bool Qt4PriFileNode::deploysFolder(const QString &folder) const

View File

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

View File

@@ -146,7 +146,7 @@ class CentralizedFolderWatcher : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
CentralizedFolderWatcher(QObject *parent); CentralizedFolderWatcher(Qt4Project *parent);
~CentralizedFolderWatcher(); ~CentralizedFolderWatcher();
void watchFolders(const QList<QString> &folders, Qt4ProjectManager::Qt4PriFileNode *node); void watchFolders(const QList<QString> &folders, Qt4ProjectManager::Qt4PriFileNode *node);
void unwatchFolders(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); void delayedFolderChanged(const QString &folder);
private: private:
Qt4Project *m_project;
QSet<QString> recursiveDirs(const QString &folder); QSet<QString> recursiveDirs(const QString &folder);
QFileSystemWatcher m_watcher; QFileSystemWatcher m_watcher;
QMultiMap<QString, Qt4ProjectManager::Qt4PriFileNode *> m_map; QMultiMap<QString, Qt4ProjectManager::Qt4PriFileNode *> m_map;
@@ -1215,7 +1216,8 @@ namespace {
bool debugCFW = false; bool debugCFW = false;
} }
CentralizedFolderWatcher::CentralizedFolderWatcher(QObject *parent) : QObject(parent) CentralizedFolderWatcher::CentralizedFolderWatcher(Qt4Project *parent)
: QObject(parent), m_project(parent)
{ {
m_compressTimer.setSingleShot(true); m_compressTimer.setSingleShot(true);
m_compressTimer.setInterval(200); m_compressTimer.setInterval(200);
@@ -1337,12 +1339,19 @@ void CentralizedFolderWatcher::delayedFolderChanged(const QString &folder)
QString dir = folder; QString dir = folder;
const QChar slash = QLatin1Char('/'); const QChar slash = QLatin1Char('/');
bool newOrRemovedFiles = false;
while (true) { while (true) {
if (!dir.endsWith(slash)) if (!dir.endsWith(slash))
dir.append(slash); dir.append(slash);
QList<Qt4ProjectManager::Qt4PriFileNode *> nodes = m_map.values(dir); 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) { 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 // 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); dir.truncate(index + 1);
} }
QString folderWithSlash = folder; QString folderWithSlash = folder;
if (!folder.endsWith(slash)) if (!folder.endsWith(slash))
folderWithSlash.append(slash); folderWithSlash.append(slash);
@@ -1374,6 +1382,11 @@ void CentralizedFolderWatcher::delayedFolderChanged(const QString &folder)
m_watcher.addPaths(tmp.toList()); m_watcher.addPaths(tmp.toList());
m_recursiveWatchedFolders += tmp; m_recursiveWatchedFolders += tmp;
} }
if (newOrRemovedFiles) {
m_project->updateFileList();
m_project->updateCodeModels();
}
} }
bool Qt4Project::needsConfiguration() const bool Qt4Project::needsConfiguration() const

View File

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

View File

@@ -87,7 +87,7 @@ const char *nameForStyle(TextStyle style)
case C_DIFF_FILE: return "DiffFile"; case C_DIFF_FILE: return "DiffFile";
case C_DIFF_LOCATION: return "DiffLocation"; 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_CONTEXT_LINE: return "DiffContextLine";
case C_DIFF_SOURCE_LINE: return "DiffSourceLine"; case C_DIFF_SOURCE_LINE: return "DiffSourceLine";
case C_DIFF_SOURCE_CHAR: return "DiffSourceChar"; case C_DIFF_SOURCE_CHAR: return "DiffSourceChar";

View File

@@ -98,9 +98,11 @@ bool DiffChunk::isValid() const
return !fileName.isEmpty() && !chunk.isEmpty(); 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 = "--- "; QByteArray rc = "--- ";
rc += fileNameBA; rc += fileNameBA;
rc += "\n+++ "; 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. // (passing '-R' for revert), assuming we got absolute paths from the VCS plugins.
bool VcsBaseEditorWidget::applyDiffChunk(const DiffChunk &dc, bool revert) const 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 QString VcsBaseEditorWidget::fileNameFromDiffSpecification(const QTextBlock &inBlock) const

View File

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

View File

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

View File

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

View File

@@ -46,6 +46,7 @@ private slots:
void findBreakpoints(); void findBreakpoints();
void findBreakpoints2(); void findBreakpoints2();
void findBreakpoints3();
}; };
void tst_Misc::diagnosticClient_error() void tst_Misc::diagnosticClient_error()
@@ -155,7 +156,7 @@ void tst_Misc::findBreakpoints2()
" }\n" " }\n"
"}\n" "}\n"
); );
Document::Ptr doc = Document::create("findContstructorBreakpoint"); Document::Ptr doc = Document::create("findSwitchBreakpoint");
QVERIFY(!doc.isNull()); QVERIFY(!doc.isNull());
doc->setUtf8Source(src); doc->setUtf8Source(src);
bool success = doc->parse(); bool success = doc->parse();
@@ -173,5 +174,32 @@ void tst_Misc::findBreakpoints2()
QCOMPARE(findBreakpoint(7), 7U); 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) QTEST_MAIN(tst_Misc)
#include "tst_misc.moc" #include "tst_misc.moc"

View File

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