Commit 0a893fc6 authored by Eike Ziller's avatar Eike Ziller

Merge remote-tracking branch 'origin/3.0'

parents 7206a469 242cb179
......@@ -6,7 +6,7 @@
<Publisher>Qt Project</Publisher>
<ProductUrl>http://qt-project.org</ProductUrl>
<Icon>logo.png</Icon>
<InstallerWindowIcon>logo.png</InstallerWindowIcon>
<Watermark>watermark.png</Watermark>
<UninstallerName>QtCreatorUninstaller</UninstallerName>
<!-- @homeDir@ and @rootDir@ are some of the supported vars -->
......
......@@ -6,7 +6,7 @@
<Publisher>Qt Project</Publisher>
<ProductUrl>http://qt-project.org</ProductUrl>
<Icon>logo.png</Icon>
<InstallerWindowIcon>logo.png</InstallerWindowIcon>
<Watermark>watermark.png</Watermark>
<UninstallerName>Uninstall Qt Creator</UninstallerName>
<!-- @homeDir@ and @rootDir@ are some of the supported vars -->
......
......@@ -6,7 +6,7 @@
<Publisher>Qt Project</Publisher>
<ProductUrl>http://qt-project.org</ProductUrl>
<Icon>logo.png</Icon>
<InstallerWindowIcon>logo.png</InstallerWindowIcon>
<Watermark>watermark.png</Watermark>
<UninstallerName>QtCreatorUninst</UninstallerName>
<!-- @homeDir@ and @rootDir@ are some of the supported vars -->
......
......@@ -818,7 +818,7 @@ Hex2EncodedFloat4, \
Hex2EncodedFloat8, \
IPv6AddressAndHexScopeId, \
Hex2EncodedUtf8WithoutQuotes, \
MillisecondsSinceEpoch \
DateTimeInternal \
= range(30)
# Display modes. Keep that synchronized with DebuggerDisplay in watchutils.h
......
......@@ -681,7 +681,12 @@ class Dumper(DumperBase):
def firstStoppedThread(self):
for i in xrange(0, self.process.GetNumThreads()):
thread = self.process.GetThreadAtIndex(i)
if thread.GetStopReason() == lldb.eStopReasonBreakpoint:
reason = thread.GetStopReason()
if (reason == lldb.eStopReasonBreakpoint or
reason == lldb.eStopReasonException or
reason == lldb.eStopReasonPlanComplete or
reason == lldb.eStopReasonSignal or
reason == lldb.eStopReasonWatchpoint):
return thread
return None
......
......@@ -239,11 +239,25 @@ def qdump__QDateTime(d, value):
base = d.dereferenceValue(value)
if qtVersion >= 0x050200:
dateBase = base + d.ptrSize() # Only QAtomicInt, but will be padded.
ms = d.extractInt64(dateBase)
offset = d.extractInt(dateBase + 12)
isValid = ms > 0
if isValid:
d.putValue("%s" % (ms - offset * 1000), MillisecondsSinceEpoch)
# qint64 m_msecs
# Qt::TimeSpec m_spec
# int m_offsetFromUtc
# QTimeZone m_timeZone // only #ifndef QT_BOOTSTRAPPED
# StatusFlags m_status
status = d.extractInt(dateBase + 16 + d.ptrSize())
if int(status & 0x10): # ValidDateTime
isValid = True
msecs = d.extractInt64(dateBase)
spec = d.extractInt(dateBase + 8)
offset = d.extractInt(dateBase + 12)
tzp = d.dereference(dateBase + 16)
if tzp == 0:
tz = ""
else:
idBase = tzp + 2 * d.ptrSize() # [QSharedData] + [vptr]
tz = d.encodeByteArrayHelper(d.dereference(idBase))
d.putValue("%s/%s/%s/%s/%s" % (msecs, spec, offset, tz, status),
DateTimeInternal)
else:
# This relies on the Qt4/Qt5 internal structure layout:
# {sharedref(4), date(8), time(4+x)}
......@@ -1711,7 +1725,7 @@ def qdump__QTextCursor(d, value):
with Children(d):
positionAddress = privAddress + 2 * d.ptrSize() + 8
d.putIntItem("position", d.extractInt(positionAddress))
d.putIntItem("anchor", d.extractInt(positionAddress + intSize))
d.putIntItem("anchor", d.extractInt(positionAddress + d.intSize()))
d.putCallItem("selected", value, "selectedText")
......
......@@ -13,18 +13,6 @@
<description><![CDATA[This tutorial uses basic elements and illustrates basic concepts of Qt Quick.]]></description>
<tags>qt quick,qml,states,transitions,visual designer,qt creator</tags>
</tutorial>
<tutorial imageUrl="images/icons/qt_quick_1.png" difficulty="" projectPath="" name="Qt Quick Elements, Part 1" isVideo="true" videoUrl="http://youtu.be/vGIVWfLVZLM" videoLength="5:04">
<description><![CDATA[In this video Nigel Hietala describes how QML Elements are used. Nigel creates a new Qt Quick based application project using Qt SDK, shows how a basic UI is built using elements and is previewed in the Qt Quick viewer.]]></description>
<tags>qt quick,qml,qt sdk,qt creator</tags>
</tutorial>
<tutorial imageUrl="images/icons/qt_quick_2.png" difficulty="" projectPath="" name="Qt Quick Elements, Part 2" isVideo="true" videoUrl="http://youtu.be/fakxsSDBC-Q" videoLength="5:14">
<description><![CDATA[In this video Nigel Hietala describes how QML Components are created and used. Nigel shows how a reusable Qt Quick component is created by defining a separate QML file.]]></description>
<tags>qt quick,qml,qt sdk,qt creator</tags>
</tutorial>
<tutorial imageUrl="images/icons/qt_quick_3.png" difficulty="" projectPath="" name="Qt Quick Elements, Part 3" isVideo="true" videoUrl="http://youtu.be/UjjIk4e_6Q4" videoLength="5:50">
<description><![CDATA[In this video Nigel Hietala describes how to use the States and Transitions of Qt Quick. Nigel creates a simple application using a state to control the visibility of an image when a button is clicked.]]></description>
<tags>qt quick,qml,qt sdk,qt creator</tags>
</tutorial>
<tutorial imageUrl="images/icons/ddays09.png" difficulty="" projectPath="" name="Qt Creator Bootcamp" isVideo="true" videoUrl="http://developer.qt.nokia.com/videos/watch/qt_creator_bootcamp" videoLength="58:29">
<description><![CDATA[All you need to start with Qt Creator - a cross-platform IDE Are you developing cross-platform applications with Qt, but are missing a cross-platform development environment?]]></description>
<tags>qt sdk,qt creator</tags>
......
......@@ -72,6 +72,7 @@ enum KnownType
KT_QBasicAtomicInt = KT_Qt_Type + KT_HasSimpleDumper + 18,
KT_QAtomicInt = KT_Qt_Type + KT_HasSimpleDumper + 19,
KT_QStringRef = KT_Qt_Type + KT_HasSimpleDumper + 20,
KT_QTextCursor = KT_Qt_Type + KT_HasSimpleDumper + 21,
KT_QObject = KT_Qt_Type + KT_HasSimpleDumper + KT_HasComplexDumper + 20,
KT_QWindow = KT_Qt_Type + KT_HasSimpleDumper + KT_HasComplexDumper + 21,
KT_QWidget = KT_Qt_Type + KT_HasSimpleDumper + KT_HasComplexDumper + 22,
......
......@@ -1281,6 +1281,8 @@ static KnownType knownClassTypeHelper(const std::string &type,
return KT_QFixedPoint;
if (!type.compare(qPos, 11, "QScriptLine"))
return KT_QScriptLine;
if (!type.compare(qPos, 11, "QTextCursor"))
return KT_QTextCursor;
break;
case 12:
if (!type.compare(qPos, 12, "QKeySequence"))
......@@ -2383,6 +2385,18 @@ static inline bool dumpQWindow(const SymbolGroupValue &v, std::wostream &str, vo
return true;
}
//Dump a QTextCursor
static inline bool dumpQTextCursor(const SymbolGroupValue &v, std::wostream &str)
{
const unsigned offset = SymbolGroupValue::pointerSize() + SymbolGroupValue::sizeOf("double");
const ULONG64 posAddr = addressOfQPrivateMember(v, QPDM_qSharedDataPadded, offset);
if (!posAddr)
return false;
const int position = SymbolGroupValue::readIntValue(v.context().dataspaces, posAddr);
str << position;
return true;
}
// Dump a std::string.
static bool dumpStd_W_String(const SymbolGroupValue &v, int type, std::wostream &str,
MemoryHandle **memoryHandle = 0)
......@@ -2796,6 +2810,10 @@ unsigned dumpSimpleType(SymbolGroupNode *n, const SymbolGroupValueContext &ctx,
case KT_StdWString:
rc = dumpStd_W_String(v, kt, str, memoryHandleIn) ? SymbolGroupNode::SimpleDumperOk : SymbolGroupNode::SimpleDumperFailed;
break;
case KT_QTextCursor:
rc = dumpQTextCursor(v, str) ? SymbolGroupNode::SimpleDumperOk
: SymbolGroupNode::SimpleDumperFailed;
break;
default:
break;
}
......
......@@ -42,6 +42,7 @@
namespace Debugger {
class DebuggerItemManager;
namespace Internal {
class DebuggerItemConfigWidget;
class DebuggerItemModel;
......@@ -63,7 +64,6 @@ public:
QString engineTypeName() const;
QVariantMap toMap() const;
void reinitializeFromFile();
QVariant id() const { return m_id; }
......@@ -92,6 +92,7 @@ public:
private:
DebuggerItem(const QVariant &id);
void reinitializeFromFile();
QVariant m_id;
QString m_displayName;
......@@ -102,6 +103,7 @@ private:
friend class Internal::DebuggerItemConfigWidget;
friend class Internal::DebuggerItemModel;
friend class DebuggerItemManager;
};
} // namespace Debugger
......
......@@ -433,10 +433,18 @@ void DebuggerItemManager::setItemData(const QVariant &id, const QString &display
for (int i = 0, n = m_debuggers.size(); i != n; ++i) {
DebuggerItem &item = m_debuggers[i];
if (item.id() == id) {
item.setDisplayName(displayName);
item.setCommand(fileName);
item.reinitializeFromFile();
emit m_instance->debuggerUpdated(id);
bool changed = false;
if (item.displayName() != displayName) {
item.setDisplayName(displayName);
changed = true;
}
if (item.command() != fileName) {
item.setCommand(fileName);
item.reinitializeFromFile();
changed = true;
}
if (changed)
emit m_instance->debuggerUpdated(id);
break;
}
}
......
......@@ -152,8 +152,8 @@ bool DebuggerItemModel::updateDebuggerStandardItem(const DebuggerItem &item, boo
QTC_ASSERT(parent, return false);
// Do not mark items as changed if they actually are not:
DebuggerItem orig = debuggerItem(sitem);
if (orig == item && DebuggerItemManager::findById(orig.id()))
const DebuggerItem *orig = DebuggerItemManager::findById(item.id());
if (orig && *orig == item)
changed = false;
int row = sitem->row();
......
......@@ -39,6 +39,7 @@
#include <utils/qtcassert.h>
#include <utils/winutils.h>
#include <QFileInfo>
#include <QFormLayout>
#include <QHeaderView>
#include <QLabel>
......@@ -59,26 +60,6 @@ static const char debuggingToolsWikiLinkC[] = "http://qt-project.org/wiki/Qt_Cre
// DebuggerItemConfigWidget
// -----------------------------------------------------------------------
class DebuggerItemConfigWidget : public QWidget
{
Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::DebuggerItemConfigWidget)
public:
explicit DebuggerItemConfigWidget(DebuggerItemModel *model);
DebuggerItem store() const;
void setItem(const DebuggerItem &item);
void apply();
private:
QLineEdit *m_displayNameLineEdit;
QLabel *m_cdbLabel;
PathChooser *m_binaryChooser;
QLineEdit *m_abis;
DebuggerItemModel *m_model;
bool m_autodetected;
QVariant m_id;
};
DebuggerItemConfigWidget::DebuggerItemConfigWidget(DebuggerItemModel *model) :
m_model(model)
{
......@@ -90,6 +71,7 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget(DebuggerItemModel *model) :
m_binaryChooser->setExpectedKind(PathChooser::ExistingCommand);
m_binaryChooser->setMinimumWidth(400);
m_binaryChooser->setHistoryCompleter(QLatin1String("DebuggerPaths"));
connect(m_binaryChooser, SIGNAL(changed(QString)), this, SLOT(commandWasChanged()));
m_cdbLabel = new QLabel(this);
m_cdbLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
......@@ -107,7 +89,7 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget(DebuggerItemModel *model) :
formLayout->addRow(new QLabel(tr("ABIs:")), m_abis);
}
DebuggerItem DebuggerItemConfigWidget::store() const
DebuggerItem DebuggerItemConfigWidget::item() const
{
DebuggerItem item(m_id);
if (m_id.isNull())
......@@ -116,11 +98,28 @@ DebuggerItem DebuggerItemConfigWidget::store() const
item.setDisplayName(m_displayNameLineEdit->text());
item.setCommand(m_binaryChooser->fileName());
item.setAutoDetected(m_autodetected);
item.reinitializeFromFile();
m_model->updateDebugger(item);
QList<ProjectExplorer::Abi> abiList;
foreach (const QString &a, m_abis->text().split(QRegExp(QLatin1String("[^A-Za-z0-9-_]+")))) {
ProjectExplorer::Abi abi(a);
if (a.isNull())
continue;
abiList << a;
}
item.setAbis(abiList);
return item;
}
void DebuggerItemConfigWidget::store() const
{
m_model->updateDebugger(item());
}
void DebuggerItemConfigWidget::setAbis(const QStringList &abiNames)
{
m_abis->setText(abiNames.join(QLatin1String(", ")));
}
void DebuggerItemConfigWidget::setItem(const DebuggerItem &item)
{
store(); // store away the (changed) settings for future use
......@@ -157,17 +156,34 @@ void DebuggerItemConfigWidget::setItem(const DebuggerItem &item)
m_cdbLabel->setVisible(!text.isEmpty());
m_binaryChooser->setCommandVersionArguments(QStringList(versionCommand));
m_abis->setText(item.abiNames().join(QLatin1String(", ")));
setAbis(item.abiNames());
}
void DebuggerItemConfigWidget::apply()
{
DebuggerItem item = m_model->currentDebugger();
if (!item.isValid())
DebuggerItem current = m_model->currentDebugger();
if (!current.isValid())
return; // Nothing was selected here.
item = store();
setItem(item);
store();
setItem(item());
}
void DebuggerItemConfigWidget::commandWasChanged()
{
// Use DebuggerItemManager as a cache:
const DebuggerItem *existing
= DebuggerItemManager::findByCommand(m_binaryChooser->fileName());
if (existing) {
setAbis(existing->abiNames());
} else {
QFileInfo fi = QFileInfo(m_binaryChooser->path());
if (fi.isExecutable()) {
DebuggerItem tmp = item();
tmp.reinitializeFromFile();
setAbis(tmp.abiNames());
}
}
}
// --------------------------------------------------------------------------
......
......@@ -30,15 +30,23 @@
#ifndef DEBUGGER_DEBUGGEROPTIONSPAGE_H
#define DEBUGGER_DEBUGGEROPTIONSPAGE_H
#include "debuggeritem.h"
#include <coreplugin/dialogs/ioptionspage.h>
#include <QWidget>
QT_BEGIN_NAMESPACE
class QLabel;
class QLineEdit;
class QPushButton;
class QTreeView;
class QWidget;
QT_END_NAMESPACE
namespace Utils { class DetailsWidget; }
namespace Utils {
class DetailsWidget;
class PathChooser;
} // namespace Utils
namespace Debugger {
namespace Internal {
......@@ -47,6 +55,36 @@ class DebuggerItemModel;
class DebuggerItemConfigWidget;
class DebuggerKitConfigWidget;
// -----------------------------------------------------------------------
// DebuggerItemConfigWidget
// -----------------------------------------------------------------------
class DebuggerItemConfigWidget : public QWidget
{
Q_OBJECT
public:
explicit DebuggerItemConfigWidget(DebuggerItemModel *model);
void setItem(const DebuggerItem &item);
void apply();
private slots:
void commandWasChanged();
private:
DebuggerItem item() const;
void store() const;
void setAbis(const QStringList &abiNames);
QLineEdit *m_displayNameLineEdit;
QLabel *m_cdbLabel;
Utils::PathChooser *m_binaryChooser;
QLineEdit *m_abis;
DebuggerItemModel *m_model;
bool m_autodetected;
QVariant m_id;
};
// --------------------------------------------------------------------------
// DebuggerOptionsPage
// --------------------------------------------------------------------------
......
......@@ -33,6 +33,7 @@
#include <QDateTime>
#include <QDebug>
#include <QHostAddress>
#include <QTimeZone>
#include <ctype.h>
......@@ -503,6 +504,53 @@ static QTime timeFromData(int ms)
return ms == -1 ? QTime() : QTime(0, 0, 0, 0).addMSecs(ms);
}
// Stolen and adapted from qdatetime.cpp
static void getDateTime(qint64 msecs, int status, QDate *date, QTime *time)
{
enum {
SECS_PER_DAY = 86400,
MSECS_PER_DAY = 86400000,
SECS_PER_HOUR = 3600,
MSECS_PER_HOUR = 3600000,
SECS_PER_MIN = 60,
MSECS_PER_MIN = 60000,
TIME_T_MAX = 2145916799, // int maximum 2037-12-31T23:59:59 UTC
JULIAN_DAY_FOR_EPOCH = 2440588 // result of julianDayFromDate(1970, 1, 1)
};
// Status of date/time
enum StatusFlag {
NullDate = 0x01,
NullTime = 0x02,
ValidDate = 0x04,
ValidTime = 0x08,
ValidDateTime = 0x10,
TimeZoneCached = 0x20,
SetToStandardTime = 0x40,
SetToDaylightTime = 0x80
};
qint64 jd = JULIAN_DAY_FOR_EPOCH;
qint64 ds = 0;
if (qAbs(msecs) >= MSECS_PER_DAY) {
jd += (msecs / MSECS_PER_DAY);
msecs %= MSECS_PER_DAY;
}
if (msecs < 0) {
ds = MSECS_PER_DAY - msecs - 1;
jd -= ds / MSECS_PER_DAY;
ds = ds % MSECS_PER_DAY;
ds = MSECS_PER_DAY - ds - 1;
} else {
ds = msecs;
}
*date = (status & NullDate) ? QDate() : QDate::fromJulianDay(jd);
*time = (status & NullTime) ? QTime() : QTime::fromMSecsSinceStartOfDay(ds);
}
QString decodeData(const QByteArray &ba, int encoding)
{
switch (encoding) {
......@@ -629,15 +677,37 @@ QString decodeData(const QByteArray &ba, int encoding)
const QByteArray decodedBa = QByteArray::fromHex(ba);
return QString::fromUtf8(decodedBa);
}
case MillisecondsSinceEpoch: {
bool ok = false;
const qint64 ms = ba.toLongLong(&ok);
if (!ok)
return QLatin1String(ba);
QDateTime d;
d.setTimeSpec(Qt::UTC);
d.setMSecsSinceEpoch(ms);
return d.isValid() ? d.toString(Qt::TextDate) : QLatin1String("(invalid)");
case DateTimeInternal: { // 29, DateTimeInternal: msecs, spec, offset, tz, status
int p0 = ba.indexOf('/');
int p1 = ba.indexOf('/', p0 + 1);
int p2 = ba.indexOf('/', p1 + 1);
int p3 = ba.indexOf('/', p2 + 1);
qint64 msecs = ba.left(p0).toLongLong();
++p0;
Qt::TimeSpec spec = Qt::TimeSpec(ba.mid(p0, p1 - p0).toInt());
++p1;
qulonglong offset = ba.mid(p1, p2 - p1).toInt();
++p2;
QByteArray timeZoneId = QByteArray::fromHex(ba.mid(p2, p3 - p2));
++p3;
int status = ba.mid(p3).toInt();
QDate date;
QTime time;
getDateTime(msecs, status, &date, &time);
QDateTime dateTime;
if (spec == Qt::OffsetFromUTC) {
dateTime = QDateTime(date, time, spec, offset);
} else if (spec == Qt::TimeZone) {
if (!QTimeZone::isTimeZoneIdAvailable(timeZoneId))
return QLatin1String("<unavailable>");
dateTime = QDateTime(date, time, QTimeZone(timeZoneId));
} else {
dateTime = QDateTime(date, time, spec);
}
return dateTime.toString();
}
}
qDebug() << "ENCODING ERROR: " << encoding;
......
......@@ -205,7 +205,7 @@ enum DebuggerEncoding
Hex2EncodedFloat8 = 26,
IPv6AddressAndHexScopeId = 27,
Hex2EncodedUtf8WithoutQuotes = 28,
MillisecondsSinceEpoch = 29
DateTimeInternal = 29
};
// Keep in sync with dumper.py, symbolgroupvalue.cpp of CDB
......
......@@ -6512,10 +6512,19 @@ void FakeVimHandler::Private::scrollToLine(int line)
EDITOR(setTextCursor(tc2));
EDITOR(ensureCursorVisible());
int offset = 0;
const QTextBlock block = document()->findBlockByLineNumber(line);
const QTextLine textLine = block.isValid()
? block.layout()->lineAt(line - block.firstLineNumber()) : QTextLine();
tc2.setPosition(block.position() + (textLine.isValid() ? textLine.textStart() : 0));
if (block.isValid()) {
const int blockLineCount = block.layout()->lineCount();
const int lineInBlock = line - block.firstLineNumber();
if (0 <= lineInBlock && lineInBlock < blockLineCount) {
QTextLine textLine = block.layout()->lineAt(lineInBlock);
offset = textLine.textStart();
} else {
// QTC_CHECK(false);
}
}
tc2.setPosition(block.position() + offset);
EDITOR(setTextCursor(tc2));
EDITOR(ensureCursorVisible());
......
......@@ -46,6 +46,8 @@
#include <CoreFoundation/CoreFoundation.h>
#endif
#include <exception>
using namespace ProjectExplorer;
static bool debugDeviceDetection = false;
......@@ -364,62 +366,80 @@ io_iterator_t gRemovedIter;
extern "C" {
void deviceConnectedCallback(void *refCon, io_iterator_t iterator)
{
kern_return_t kr;
io_service_t usbDevice;
(void) refCon;
while ((usbDevice = IOIteratorNext(iterator))) {
io_name_t deviceName;
// Get the USB device's name.
kr = IORegistryEntryGetName(usbDevice, deviceName);
QString name;
if (KERN_SUCCESS == kr)
name = QString::fromLocal8Bit(deviceName);
if (debugDeviceDetection)
qDebug() << "ios device " << name << " in deviceAddedCallback";
CFStringRef cfUid = static_cast<CFStringRef>(IORegistryEntryCreateCFProperty(
usbDevice,
CFSTR(kUSBSerialNumberString),
kCFAllocatorDefault, 0));
QString uid = CFStringRef2QString(cfUid);
CFRelease(cfUid);
IosDeviceManager::instance()->deviceConnected(uid, name);
// Done with this USB device; release the reference added by IOIteratorNext
kr = IOObjectRelease(usbDevice);
}
}
void deviceDisconnectedCallback(void *refCon, io_iterator_t iterator)
{
kern_return_t kr;
io_service_t usbDevice;
(void) refCon;
while ((usbDevice = IOIteratorNext(iterator))) {
io_name_t deviceName;
// Get the USB device's name.
kr = IORegistryEntryGetName(usbDevice, deviceName);
if (KERN_SUCCESS != kr)
deviceName[0] = '\0';
if (debugDeviceDetection)
qDebug() << "ios device " << deviceName << " in deviceDisconnectedCallback";
try {
kern_return_t kr;
io_service_t usbDevice;
(void) refCon;