diff --git a/dist/changes-3.1.0 b/dist/changes-3.1.0
index e60625d25e5..dec584e72ba 100644
--- a/dist/changes-3.1.0
+++ b/dist/changes-3.1.0
@@ -26,6 +26,7 @@ Editing
Managing and Building Projects
* Re-added option to import existing builds even after project configuration (QTCREATORBUG-7836)
* Fixed that compiler output in issues list was not using monospace font (QTCREATORBUG-11345)
+ * Fixed crash when removing run configuration that was about to be run (QTCREATORBUG-11594)
QMake Projects
* Added context menu item "Add Existing Directory" that adds all
@@ -46,20 +47,24 @@ Debugging
* Removed support for GDB without Python
* Added context menu item for saving backtrace as tasks-file
* GDB, LLDB
- * Added pretty printer for std::unordered_set
+ * Added pretty printers for std::unordered_set and boost::container::list
* Fixed various pretty printers
* CDB
* Added pretty printer for std::complex and C++11 std::array
* LLDB
+ * Added support for debugging applications that run in terminal (QTCREATORBUG-9650)
+ * Added support for "Create Full Backtrace" (QTCREATORBUG-11642)
* Fixed that debugging was not possible with MallocScribble environment variable set
(QTCREATORBUG-11371)
* Fixed "Jump to Line", "Run to Line" and "Jump to Address"
+ * Fixed updating breakpoint locations while debugging (QTCREATORBUG-11564)
QML Profiler
* Improved performance (QTCREATORBUG-10950)
* Improved layout of details views
* Added JavaScript calls in Events view and Timeline view
* Fixed opening files from JavaScript profiling output (QTCREATORBUG-11094)
+ * Fixed hovering over narrow items in Timeline view (QTCREATORBUG-11692)
C++ Support
* Added code model inspector
@@ -72,6 +77,7 @@ C++ Support
* Fixed syntax highlighting of multiline strings and comments (QTCREATORBUG-662)
* Fixed that symbol dropdown was jumping to the wrong editor (QTCREATORBUG-11157)
* Fixed highlighting when #undef is used (QTCREATORBUG-10454)
+ * Fixed issue with follow symbol and overloaded functions (QTCREATORBUG-10295)
* Improved the Insert Virtual Functions refactoring action:
* Check only pure virtual functions by default
* Display all overrides of a function
@@ -131,6 +137,7 @@ QNX
* Added support for attaching debugger to running applications
* Fixed several issues with certificate password dialog in BlackBerry
options (QTCREATORBUG-10948)
+ * Fixed mkspec setting in the qmake build step (QTCREATORBUG-11674)
Android
* Made it possible to cancel waiting for an AVD to boot up
@@ -146,9 +153,14 @@ Android
* Fixed that Qt Creator restart was required after configuring Android SDK (QTCREATORBUG-10936)
iOS
+ * Enabled iOS support by default
+ * Added support for QML debugging
* Added check for already running application on device
* Added automatic detection that developer mode becomes activated on connected device
+WinRT
+ * Added experimental support
+
Credits for these changes go to:
Alessandro Portale
diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts
index f51cfaa01db..ca4b9657837 100644
--- a/share/qtcreator/translations/qtcreator_de.ts
+++ b/share/qtcreator/translations/qtcreator_de.ts
@@ -7213,7 +7213,7 @@ Add, modify, and remove document filters, which determine the documentation set
Error while building/deploying project %1 (kit: %2)
- Fehler beim Erstellen/Deployment des Projekts %1(Kit: %2)
+ Fehler beim Erstellen/Deployment des Projekts %1 (Kit: %2)
When executing step '%1'
diff --git a/share/qtcreator/welcomescreen/examples.qml b/share/qtcreator/welcomescreen/examples.qml
index 53d77a0d3bf..5dc5d53bde6 100644
--- a/share/qtcreator/welcomescreen/examples.qml
+++ b/share/qtcreator/welcomescreen/examples.qml
@@ -56,8 +56,13 @@ Rectangle {
anchors.right: parent.right
anchors.leftMargin: 18
+ text: examplesModel.readSearchStringsFromSettings()
+
placeholderText: qsTr("Search in Examples...")
- onTextChanged: examplesModel.parseSearchString(text)
+ onTextChanged: {
+ examplesModel.parseSearchString(text);
+ examplesModel.writeSearchStringToSettings(text);
+ }
}
ComboBox {
diff --git a/share/qtcreator/welcomescreen/widgets/SideBar.qml b/share/qtcreator/welcomescreen/widgets/SideBar.qml
index a3abe54fe72..5cb9b5e2a19 100644
--- a/share/qtcreator/welcomescreen/widgets/SideBar.qml
+++ b/share/qtcreator/welcomescreen/widgets/SideBar.qml
@@ -140,7 +140,7 @@ ColumnLayout {
IconAndLink {
iconSource: "images/icons/qt_cloud.png"
title: qsTr("Qt Cloud Services")
- openUrl: "https://developer.qtc.io?utm_source=qtcreator31"
+ openUrl: "https://developer.qtcloudservices.com?utm_source=qtcreator31"
}
IconAndLink {
iconSource: "images/icons/onlineCommunity.png"
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 89b52fde81d..e514199616e 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -1763,6 +1763,13 @@ void GdbEngine::handlePythonSetup(const GdbResponse &response)
showMessage(_("ENGINE SUCCESSFULLY STARTED"));
notifyEngineSetupOk();
} else {
+ QByteArray msg = response.data["msg"].data();
+ if (msg.contains("Python scripting is not supported in this copy of GDB.")) {
+ QString out1 = _("The selected build of GDB does not support Python scripting.");
+ QString out2 = _("It cannot be used in Qt Creator.");
+ showStatusMessage(out1 + QLatin1Char(' ') + out2);
+ showMessageBox(QMessageBox::Critical, tr("Execution Error"), out1 + _("
") + out2);
+ }
notifyEngineSetupFailed();
}
}
diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp
index 756121aeef2..1ec80f51079 100644
--- a/src/plugins/fakevim/fakevimplugin.cpp
+++ b/src/plugins/fakevim/fakevimplugin.cpp
@@ -2123,6 +2123,7 @@ void FakeVimPluginPrivate::showExtraInformation(const QString &text)
IEditor *iedit = EditorManager::openEditorWithContents(Id(), &title, text.toUtf8());
EditorManager::activateEditor(iedit);
FakeVimHandler *handler = m_editorToHandler.value(iedit, 0);
+ QTC_ASSERT(handler, return);
handler->handleCommand(_("0"));
}
diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
index f71c1892cc9..3964f8f8e07 100644
--- a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
@@ -243,17 +243,11 @@ bool AbstractMsvcToolChain::generateEnvironmentSettings(Utils::Environment &env,
const QString &batchArgs,
QMap &envPairs)
{
+ const QByteArray marker = "####################\r\n";
// Create a temporary file name for the output. Use a temporary file here
// as I don't know another way to do this in Qt...
// Note, can't just use a QTemporaryFile all the way through as it remains open
// internally so it can't be streamed to later.
- QString tempOutFile;
- QTemporaryFile* pVarsTempFile = new QTemporaryFile(QDir::tempPath() + QLatin1String("/XXXXXX.txt"));
- pVarsTempFile->setAutoRemove(false);
- pVarsTempFile->open();
- pVarsTempFile->close();
- tempOutFile = pVarsTempFile->fileName();
- delete pVarsTempFile;
// Create a batch file to create and save the env settings
Utils::TempFileSaver saver(QDir::tempPath() + QLatin1String("/XXXXXX.bat"));
@@ -265,10 +259,9 @@ bool AbstractMsvcToolChain::generateEnvironmentSettings(Utils::Environment &env,
call += batchArgs.toLocal8Bit();
}
saver.write(call + "\r\n");
-
- const QByteArray redirect = "set > " + Utils::QtcProcess::quoteArg(
- QDir::toNativeSeparators(tempOutFile)).toLocal8Bit() + "\r\n";
- saver.write(redirect);
+ saver.write("@echo " + marker);
+ saver.write("set\r\n");
+ saver.write("@echo " + marker);
if (!saver.finalize()) {
qWarning("%s: %s", Q_FUNC_INFO, qPrintable(saver.errorString()));
return false;
@@ -304,19 +297,31 @@ bool AbstractMsvcToolChain::generateEnvironmentSettings(Utils::Environment &env,
return false;
}
// The SDK/MSVC scripts do not return exit codes != 0. Check on stdout.
- const QByteArray stdOut = run.readAllStandardOutput();
+ QByteArray stdOut = run.readAllStandardOutput();
if (!stdOut.isEmpty() && (stdOut.contains("Unknown") || stdOut.contains("Error")))
qWarning("%s: '%s' reports:\n%s", Q_FUNC_INFO, call.constData(), stdOut.constData());
//
// Now parse the file to get the environment settings
- QFile varsFile(tempOutFile);
- if (!varsFile.open(QIODevice::ReadOnly))
+ int start = stdOut.indexOf(marker);
+ if (start == -1) {
+ qWarning("Could not find start marker in stdout output.");
return false;
+ }
+ stdOut = stdOut.mid(start + marker.size());
+
+ int end = stdOut.indexOf(marker);
+ if (end == -1) {
+ qWarning("Could not find end marker in stdout output.");
+ return false;
+ }
+
+ stdOut = stdOut.left(end);
+
+ QStringList lines = QString::fromLocal8Bit(stdOut).split(QLatin1String("\r\n"));
QRegExp regexp(QLatin1String("(\\w*)=(.*)"));
- while (!varsFile.atEnd()) {
- const QString line = QString::fromLocal8Bit(varsFile.readLine()).trimmed();
+ foreach (const QString &line, lines) {
if (regexp.exactMatch(line)) {
const QString varName = regexp.cap(1);
const QString varValue = regexp.cap(2);
@@ -326,10 +331,6 @@ bool AbstractMsvcToolChain::generateEnvironmentSettings(Utils::Environment &env,
}
}
- // Tidy up and remove the file
- varsFile.close();
- varsFile.remove();
-
return true;
}
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
index 5ef12e0db8d..81536e7096a 100644
--- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
@@ -990,6 +990,20 @@ QtSupport::ProFileReader *QmakeProject::createProFileReader(const QmakeProFileNo
m_qmakeGlobals->setCommandLineArguments(m_rootProjectNode->buildDir(), qmakeArgs);
QtSupport::ProFileCacheManager::instance()->incRefCount();
+
+ // On ios, qmake is called recursively, and the second call with a different
+ // spec.
+ // macx-ios-clang just creates supporting makefiles, and to avoid being
+ // slow does not evaluate everything, and contains misleading information
+ // (that is never used).
+ // macx-xcode correctly evaluates the variables and generates the xcodeproject
+ // that is actually used to build the application.
+ //
+ // It is important to override the spec file only for the creator evaluator,
+ // and not the qmake buildstep used to build the app (as we use the makefiles).
+ const char IOSQT[] = "Qt4ProjectManager.QtVersion.Ios"; // from Ios::Constants
+ if (qtVersion->type() == QLatin1String(IOSQT))
+ m_qmakeGlobals->xqmakespec = QLatin1String("macx-xcode");
}
++m_qmakeGlobalsRefCnt;
diff --git a/src/plugins/qmlprofiler/qml/MainView.qml b/src/plugins/qmlprofiler/qml/MainView.qml
index c97814e2ed2..3455e262a56 100644
--- a/src/plugins/qmlprofiler/qml/MainView.qml
+++ b/src/plugins/qmlprofiler/qml/MainView.qml
@@ -70,7 +70,12 @@ Rectangle {
mainviewTimePerPixel = Math.abs(endTime - startTime) / root.width;
backgroundMarks.updateMarks(startTime, endTime);
- view.updateFlickRange(startTime, endTime);
+ view.startTime = startTime;
+ view.endTime = endTime;
+ view.updateWindow();
+ }
+ onWindowChanged: {
+ view.updateWindow();
}
}
@@ -250,7 +255,7 @@ Rectangle {
onWidthChanged: {
var duration = Math.abs(zoomControl.endTime() - zoomControl.startTime());
if (duration > 0)
- contentWidth = qmlProfilerModelProxy.traceDuration() * width / duration;
+ contentWidth = zoomControl.windowLength() * width / duration;
}
// ***** child items
@@ -293,33 +298,29 @@ Rectangle {
return;
var newStartTime = Math.round(flick.contentX * (endTime - startTime) / flick.width) +
- qmlProfilerModelProxy.traceStartTime();
+ zoomControl.windowStart();
if (Math.abs(newStartTime - startTime) > 1) {
var newEndTime = Math.round((flick.contentX + flick.width) *
(endTime - startTime) /
- flick.width) +
- qmlProfilerModelProxy.traceStartTime();
+ flick.width) + zoomControl.windowStart();
zoomControl.setRange(newStartTime, newEndTime);
}
}
- function updateFlickRange(start, end) {
- var duration = end - start;
- if (recursionGuard || duration <= 0 || (start === startTime && end === endTime))
+ function updateWindow() {
+ var duration = zoomControl.duration();
+ if (recursionGuard || duration <= 0)
return;
recursionGuard = true;
- startTime = start;
- endTime = end;
- if (!flick.flickingHorizontally) {
+ if (!flick.movingHorizontally) {
// This triggers an unwanted automatic change in contentX. We ignore that by
// checking recursionGuard in this function and in updateZoomControl.
- flick.contentWidth = qmlProfilerModelProxy.traceDuration() * flick.width /
- duration;
+ flick.contentWidth = zoomControl.windowLength() * flick.width / duration;
- var newStartX = (startTime - qmlProfilerModelProxy.traceStartTime()) *
- flick.width / duration;
+ var newStartX = (startTime - zoomControl.windowStart()) * flick.width /
+ duration;
if (isFinite(newStartX) && Math.abs(newStartX - flick.contentX) >= 1)
flick.contentX = newStartX;
@@ -418,7 +419,9 @@ Rectangle {
function updateZoomLevel() {
zoomSlider.externalUpdate = true;
- zoomSlider.value = Math.pow((view.endTime - view.startTime) / qmlProfilerModelProxy.traceDuration(), 1 / zoomSlider.exponent) * zoomSlider.maximumValue;
+ zoomSlider.value = Math.pow((view.endTime - view.startTime) /
+ zoomControl.windowLength(),
+ 1 / zoomSlider.exponent) * zoomSlider.maximumValue;
}
@@ -434,7 +437,7 @@ Rectangle {
property int minWindowLength: 1e5 // 0.1 ms
onValueChanged: {
- if (externalUpdate || qmlProfilerModelProxy.traceEndTime() <= qmlProfilerModelProxy.traceStartTime()) {
+ if (externalUpdate || zoomControl.windowEnd() <= zoomControl.windowStart()) {
// Zoom range is independently updated. We shouldn't mess
// with it here as otherwise we might introduce rounding
// or arithmetic errors.
@@ -443,7 +446,7 @@ Rectangle {
}
var windowLength = Math.max(
- Math.pow(value / maximumValue, exponent) * qmlProfilerModelProxy.traceDuration(),
+ Math.pow(value / maximumValue, exponent) * zoomControl.windowLength(),
minWindowLength);
var fixedPoint = (view.startTime + view.endTime) / 2;
@@ -454,7 +457,7 @@ Rectangle {
fixedPoint = newFixedPoint;
}
- var startTime = Math.max(qmlProfilerModelProxy.traceStartTime(), fixedPoint - windowLength / 2)
+ var startTime = Math.max(zoomControl.windowStart(), fixedPoint - windowLength / 2)
zoomControl.setRange(startTime, startTime + windowLength);
}
}
diff --git a/src/plugins/qmlprofiler/qml/SelectionRange.qml b/src/plugins/qmlprofiler/qml/SelectionRange.qml
index b54d0d3eeee..7931bdea3a5 100644
--- a/src/plugins/qmlprofiler/qml/SelectionRange.qml
+++ b/src/plugins/qmlprofiler/qml/SelectionRange.qml
@@ -38,7 +38,7 @@ RangeMover {
property string endTimeString: detailedPrintTime(startTime+duration)
property string durationString: detailedPrintTime(duration)
- property double startTime: getLeft() * viewTimePerPixel + qmlProfilerModelProxy.traceStartTime()
+ property double startTime: getLeft() * viewTimePerPixel + zoomControl.windowStart()
property double duration: Math.max(getWidth() * viewTimePerPixel, 500)
property double viewTimePerPixel: 1
property double creationReference : 0
diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
index 17b894647ed..4ec8c71ed0a 100644
--- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
@@ -112,18 +112,24 @@ qint64 QmlProfilerTraceTime::duration() const
void QmlProfilerTraceTime::clear()
{
- m_startTime = -1;
- m_endTime = -1;
+ setStartTime(-1);
+ setEndTime(-1);
}
void QmlProfilerTraceTime::setStartTime(qint64 time)
{
- m_startTime = time;
+ if (time != m_startTime) {
+ m_startTime = time;
+ emit startTimeChanged(time);
+ }
}
void QmlProfilerTraceTime::setEndTime(qint64 time)
{
- m_endTime = time;
+ if (time != m_endTime) {
+ m_endTime = time;
+ emit endTimeChanged(time);
+ }
}
diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.h b/src/plugins/qmlprofiler/qmlprofilermodelmanager.h
index c9e2047cead..1be9abd973f 100644
--- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.h
+++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.h
@@ -84,6 +84,10 @@ public:
qint64 endTime() const;
qint64 duration() const;
+signals:
+ void startTimeChanged(qint64);
+ void endTimeChanged(qint64);
+
public slots:
void clear();
void setStartTime(qint64 time);
diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp
index c8f6562704d..6d7fa6a5944 100644
--- a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp
@@ -61,15 +61,88 @@ namespace QmlProfiler {
namespace Internal {
/////////////////////////////////////////////////////////
+ZoomControl::ZoomControl(const QmlProfilerTraceTime *traceTime, QObject *parent) :
+ QObject(parent), m_startTime(traceTime->startTime()), m_endTime(traceTime->endTime()),
+ m_windowStart(traceTime->startTime()), m_windowEnd(traceTime->endTime()),
+ m_traceTime(traceTime), m_windowLocked(false)
+{
+ connect(traceTime, SIGNAL(startTimeChanged(qint64)), this, SLOT(rebuildWindow()));
+ connect(traceTime, SIGNAL(endTimeChanged(qint64)), this, SLOT(rebuildWindow()));
+ connect(&m_timer, SIGNAL(timeout()), this, SLOT(moveWindow()));
+}
+
void ZoomControl::setRange(qint64 startTime, qint64 endTime)
{
if (m_startTime != startTime || m_endTime != endTime) {
+ m_timer.stop();
m_startTime = startTime;
m_endTime = endTime;
+ rebuildWindow();
emit rangeChanged();
}
}
+void ZoomControl::rebuildWindow()
+{
+ qint64 minDuration = 1; // qMax needs equal data types, so literal 1 won't do
+ qint64 shownDuration = qMax(duration(), minDuration);
+
+ qint64 oldWindowStart = m_windowStart;
+ qint64 oldWindowEnd = m_windowEnd;
+ if (m_traceTime->duration() / shownDuration < MAX_ZOOM_FACTOR) {
+ m_windowStart = m_traceTime->startTime();
+ m_windowEnd = m_traceTime->endTime();
+ } else if (windowLength() / shownDuration > MAX_ZOOM_FACTOR ||
+ windowLength() / shownDuration * 2 < MAX_ZOOM_FACTOR) {
+ qint64 keep = shownDuration * MAX_ZOOM_FACTOR / 2 - shownDuration;
+ m_windowStart = m_startTime - keep;
+ if (m_windowStart < m_traceTime->startTime()) {
+ keep += m_traceTime->startTime() - m_windowStart;
+ m_windowStart = m_traceTime->startTime();
+ }
+
+ m_windowEnd = m_endTime + keep;
+ if (m_windowEnd > m_traceTime->endTime()) {
+ m_windowStart = qMax(m_traceTime->startTime(),
+ m_windowStart - m_windowEnd - m_traceTime->endTime());
+ m_windowEnd = m_traceTime->endTime();
+ }
+ } else {
+ m_timer.start(500);
+ }
+ if (oldWindowStart != m_windowStart || oldWindowEnd != m_windowEnd)
+ emit windowChanged();
+}
+
+void ZoomControl::moveWindow()
+{
+ if (m_windowLocked)
+ return;
+ m_timer.stop();
+
+ qint64 offset = (m_endTime - m_windowEnd + m_startTime - m_windowStart) / 2;
+ if (offset == 0 || (offset < 0 && m_windowStart == m_traceTime->startTime()) ||
+ (offset > 0 && m_windowEnd == m_traceTime->endTime())) {
+ return;
+ } else if (offset > duration()) {
+ offset = (offset + duration()) / 2;
+ } else if (offset < -duration()) {
+ offset = (offset - duration()) / 2;
+ }
+ m_windowStart += offset;
+ if (m_windowStart < m_traceTime->startTime()) {
+ m_windowEnd += m_traceTime->startTime() - m_windowStart;
+ m_windowStart = m_traceTime->startTime();
+ }
+ m_windowEnd += offset;
+ if (m_windowEnd > m_traceTime->endTime()) {
+ m_windowStart -= m_windowEnd - m_traceTime->endTime();
+ m_windowEnd = m_traceTime->endTime();
+ }
+ emit windowChanged();
+ m_timer.start(100);
+}
+
/////////////////////////////////////////////////////////
class QmlProfilerTraceView::QmlProfilerTraceViewPrivate
{
@@ -108,7 +181,7 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, Analyzer::IAnalyzerT
{
setObjectName(QLatin1String("QML Profiler"));
- d->m_zoomControl = new ZoomControl(this);
+ d->m_zoomControl = new ZoomControl(modelManager->traceTime(), this);
connect(d->m_zoomControl, SIGNAL(rangeChanged()), this, SLOT(updateRange()));
QVBoxLayout *groupLayout = new QVBoxLayout;
@@ -396,6 +469,18 @@ void QmlProfilerTraceView::resizeEvent(QResizeEvent *event)
emit resized();
}
+void QmlProfilerTraceView::mousePressEvent(QMouseEvent *event)
+{
+ d->m_zoomControl->setWindowLocked(true);
+ QWidget::mousePressEvent(event);
+}
+
+void QmlProfilerTraceView::mouseReleaseEvent(QMouseEvent *event)
+{
+ d->m_zoomControl->setWindowLocked(false);
+ QWidget::mouseReleaseEvent(event);
+}
+
////////////////////////////////////////////////////////////////
// Context menu
void QmlProfilerTraceView::contextMenuEvent(QContextMenuEvent *ev)
diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.h b/src/plugins/qmlprofiler/qmlprofilertraceview.h
index d6c0210c547..2203e643474 100644
--- a/src/plugins/qmlprofiler/qmlprofilertraceview.h
+++ b/src/plugins/qmlprofiler/qmlprofilertraceview.h
@@ -30,8 +30,10 @@
#ifndef QMLPROFILERTRACEVIEW_H
#define QMLPROFILERTRACEVIEW_H
+#include "qmlprofilermodelmanager.h"
#include
#include
+#include
namespace Analyzer { class IAnalyzerTool; }
@@ -47,19 +49,38 @@ class QmlProfilerViewManager;
class ZoomControl : public QObject {
Q_OBJECT
public:
- ZoomControl(QObject *parent=0):QObject(parent),m_startTime(0),m_endTime(0) {}
+ static const qint64 MAX_ZOOM_FACTOR = 1 << 12;
+
+ ZoomControl(const QmlProfilerTraceTime *traceTime, QObject *parent = 0);
~ZoomControl(){}
Q_INVOKABLE void setRange(qint64 startTime, qint64 endTime);
- Q_INVOKABLE qint64 startTime() { return m_startTime; }
- Q_INVOKABLE qint64 endTime() { return m_endTime; }
+ Q_INVOKABLE qint64 startTime() const { return m_startTime; }
+ Q_INVOKABLE qint64 endTime() const { return m_endTime; }
+ Q_INVOKABLE qint64 duration() const { return m_endTime - m_startTime; }
+
+ Q_INVOKABLE qint64 windowStart() const { return m_windowStart; }
+ Q_INVOKABLE qint64 windowEnd() const { return m_windowEnd; }
+ Q_INVOKABLE qint64 windowLength() const { return m_windowEnd - m_windowStart; }
+ void setWindowLocked(bool lock) { m_windowLocked = lock; }
signals:
void rangeChanged();
+ void windowChanged();
+
+private slots:
+ void rebuildWindow();
+ void moveWindow();
private:
qint64 m_startTime;
qint64 m_endTime;
+ qint64 m_windowStart;
+ qint64 m_windowEnd;
+
+ const QmlProfilerTraceTime *m_traceTime;
+ QTimer m_timer;
+ bool m_windowLocked;
};
class QmlProfilerTraceView : public QWidget
@@ -97,6 +118,8 @@ private slots:
protected:
virtual void resizeEvent(QResizeEvent *event);
virtual void contextMenuEvent(QContextMenuEvent *event);
+ virtual void mousePressEvent(QMouseEvent *event);
+ virtual void mouseReleaseEvent(QMouseEvent *event);
private slots:
void setZoomSliderEnabled(bool enabled);
diff --git a/src/plugins/qtsupport/exampleslistmodel.cpp b/src/plugins/qtsupport/exampleslistmodel.cpp
index 22f4bf66d1f..ebab7763180 100644
--- a/src/plugins/qtsupport/exampleslistmodel.cpp
+++ b/src/plugins/qtsupport/exampleslistmodel.cpp
@@ -54,6 +54,7 @@ static bool debugExamples()
}
static const char kSelectedExampleSetKey[] = "WelcomePage/SelectedExampleSet";
+static const char kExamplesSearchStringKey[] = "WelcomePage/ExamplesSearchString";
void ExampleSetModel::writeCurrentIdToSettings(int currentIndex) const
{
@@ -841,6 +842,16 @@ void ExamplesListModelFilter::filterForExampleSet(int index)
m_sourceModel->selectExampleSet(index);
}
+void ExamplesListModelFilter::writeSearchStringToSettings(const QString &string)
+{
+ Core::ICore::settings()->setValue(QLatin1String(kExamplesSearchStringKey), string);
+}
+
+QString ExamplesListModelFilter::readSearchStringsFromSettings()
+{
+ return Core::ICore::settings()->value(QLatin1String(kExamplesSearchStringKey)).toString();
+}
+
void ExamplesListModelFilter::setShowTutorialsOnly(bool showTutorialsOnly)
{
m_showTutorialsOnly = showTutorialsOnly;
diff --git a/src/plugins/qtsupport/exampleslistmodel.h b/src/plugins/qtsupport/exampleslistmodel.h
index 6a2607de741..ae30ec9290f 100644
--- a/src/plugins/qtsupport/exampleslistmodel.h
+++ b/src/plugins/qtsupport/exampleslistmodel.h
@@ -185,6 +185,8 @@ public:
QAbstractItemModel* exampleSetModel();
Q_INVOKABLE void filterForExampleSet(int index);
+ Q_INVOKABLE void writeSearchStringToSettings(const QString &string);
+ Q_INVOKABLE QString readSearchStringsFromSettings();
public slots:
void setFilterTags(const QStringList &arg)
diff --git a/src/plugins/winrt/winrtpackagedeploymentstep.cpp b/src/plugins/winrt/winrtpackagedeploymentstep.cpp
index ff746e2c3d7..71a53155d39 100644
--- a/src/plugins/winrt/winrtpackagedeploymentstep.cpp
+++ b/src/plugins/winrt/winrtpackagedeploymentstep.cpp
@@ -35,8 +35,14 @@
#include
#include
#include
+#include
+#include
+#include
+#include
#include
+#include
+
using namespace ProjectExplorer;
using Utils::QtcProcess;
@@ -45,6 +51,7 @@ namespace Internal {
WinRtPackageDeploymentStep::WinRtPackageDeploymentStep(BuildStepList *bsl)
: AbstractProcessStep(bsl, Constants::WINRT_BUILD_STEP_DEPLOY)
+ , m_createMappingFile(false)
{
setDisplayName(tr("Run windeployqt"));
m_args = defaultWinDeployQtArguments();
@@ -56,11 +63,46 @@ bool WinRtPackageDeploymentStep::init()
const QString targetPath
= target()->applicationTargets().targetForProject(proFile).toString()
+ QLatin1String(".exe");
+ QString targetDir = targetPath.left(targetPath.lastIndexOf(QLatin1Char('/')) + 1);
// ### Actually, targetForProject is supposed to return the file path including the file
// extension. Whenever this will eventually work, we have to remove the .exe suffix here.
+ const QtSupport::BaseQtVersion *qt = QtSupport::QtKitInformation::qtVersion(target()->kit());
+ if (!qt)
+ return false;
+
+ m_isWinPhone = (qt->type() == QLatin1String(Constants::WINRT_WINPHONEQT));
+
QString args = QtcProcess::quoteArg(QDir::toNativeSeparators(targetPath));
args += QLatin1Char(' ') + m_args;
+ if (m_isWinPhone) {
+ m_manifestFileName = QLatin1String("WMAppManifest");
+ m_createMappingFile = true;
+ } else {
+ m_manifestFileName = QLatin1String("AppxManifest");
+ }
+
+ if (m_createMappingFile) {
+ args += QLatin1String(" -list mapping");
+ m_mappingFileContent = QLatin1String("[Files]\n\"") + QDir::toNativeSeparators(targetDir)
+ + m_manifestFileName + QLatin1String(".xml\" \"") + m_manifestFileName + QLatin1String(".xml\"\n");
+
+ QDir assetDirectory(targetDir + QLatin1String("assets"));
+ if (assetDirectory.exists()) {
+ QStringList iconsToDeploy;
+ const QString fullManifestPath = targetDir + m_manifestFileName + QLatin1String(".xml");
+ if (!parseIconsAndExecutableFromManifest(fullManifestPath, &iconsToDeploy,
+ &m_executablePathInManifest)) {
+ raiseError(tr("Cannot parse manifest file %1.").arg(fullManifestPath));
+ return false;
+ }
+ foreach (QString icon, iconsToDeploy) {
+ m_mappingFileContent += QLatin1Char('"')
+ + QDir::toNativeSeparators(targetDir + icon) + QLatin1String("\" \"")
+ + QDir::toNativeSeparators(icon) + QLatin1String("\"\n");
+ }
+ }
+ }
ProcessParameters *params = processParameters();
params->setCommand(QLatin1String("windeployqt.exe"));
@@ -70,6 +112,67 @@ bool WinRtPackageDeploymentStep::init()
return AbstractProcessStep::init();
}
+bool WinRtPackageDeploymentStep::processSucceeded(int exitCode, QProcess::ExitStatus status)
+{
+ if (m_createMappingFile) {
+ Utils::FileName proFile = Utils::FileName::fromString(project()->projectFilePath());
+ QString targetPath
+ = target()->applicationTargets().targetForProject(proFile).toString();
+ QString targetDir = targetPath.left(targetPath.lastIndexOf(QLatin1Char('/')) + 1);
+ QString targetInstallationPath;
+ // The list holds the local file paths and the "remote" file paths
+ QList > installableFilesList;
+ foreach (DeployableFile file, target()->deploymentData().allFiles()) {
+ QString remoteFilePath = file.remoteFilePath();
+ QString localFilePath = file.localFilePath().toString();
+ if (localFilePath == targetPath) {
+ if (!targetPath.endsWith(QLatin1String(".exe"))) {
+ remoteFilePath += QLatin1String(".exe");
+ localFilePath += QLatin1String(".exe");
+ }
+ targetInstallationPath = remoteFilePath;
+ }
+ installableFilesList.append(QPair(localFilePath, remoteFilePath));
+ }
+
+ // if there are no INSTALLS set we just deploy the files from windeployqt, the manifest
+ // and the icons referenced in there and the actual build target
+ if (targetInstallationPath.isEmpty()) {
+ targetPath += QLatin1String(".exe");
+ m_mappingFileContent
+ += QLatin1Char('"') + QDir::toNativeSeparators(targetPath) + QLatin1String("\" \"")
+ + QDir::toNativeSeparators(m_executablePathInManifest) + QLatin1String("\"\n");
+ } else {
+ targetInstallationPath = targetInstallationPath.left(targetInstallationPath.lastIndexOf(QLatin1Char('/')) + 1);
+ for (int i = 0; i < installableFilesList.length(); ++i) {
+ QPair pair = installableFilesList.at(i);
+ // For the mapping file we need the remote paths relative to the application's executable
+ const QString relativeRemotePath = QDir(targetInstallationPath).relativeFilePath(pair.second);
+ m_mappingFileContent += QLatin1Char('"') + QDir::toNativeSeparators(pair.first)
+ + QLatin1String("\" \"") + QDir::toNativeSeparators(relativeRemotePath)
+ + QLatin1String("\"\n");
+ }
+ }
+
+ const QString mappingFilePath = targetDir + m_manifestFileName + QLatin1String(".map");
+ QFile mappingFile(mappingFilePath);
+ if (!mappingFile.open(QFile::WriteOnly | QFile::Text)) {
+ raiseError(tr("Cannot open mapping file %1 for writing.").arg(mappingFilePath));
+ return false;
+ }
+ mappingFile.write(m_mappingFileContent.toUtf8());
+ }
+
+ return AbstractProcessStep::processSucceeded(exitCode, status);
+}
+
+void WinRtPackageDeploymentStep::stdOutput(const QString &line)
+{
+ if (m_createMappingFile)
+ m_mappingFileContent += line;
+ AbstractProcessStep::stdOutput(line);
+}
+
BuildStepConfigWidget *WinRtPackageDeploymentStep::createConfigWidget()
{
return new WinRtPackageDeploymentStepWidget(this);
@@ -93,6 +196,13 @@ QString WinRtPackageDeploymentStep::defaultWinDeployQtArguments() const
return args;
}
+void WinRtPackageDeploymentStep::raiseError(const QString &errorMessage)
+{
+ emit addOutput(errorMessage, BuildStep::ErrorMessageOutput);
+ emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Error, errorMessage, Utils::FileName(), -1,
+ ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT));
+}
+
bool WinRtPackageDeploymentStep::fromMap(const QVariantMap &map)
{
if (!AbstractProcessStep::fromMap(map))
@@ -110,5 +220,31 @@ QVariantMap WinRtPackageDeploymentStep::toMap() const
return map;
}
+bool WinRtPackageDeploymentStep::parseIconsAndExecutableFromManifest(QString manifestFileName, QStringList *icons, QString *executable)
+{
+ if (!icons->isEmpty())
+ icons->clear();
+ QFile manifestFile(manifestFileName);
+ if (!manifestFile.open(QFile::ReadOnly))
+ return false;
+ const QString contents = QString::fromUtf8(manifestFile.readAll());
+
+ QRegularExpression iconPattern(QStringLiteral("[\\\\/a-zA-Z0-9_\\-\\!]*\\.(png|jpg|jpeg)"));
+ QRegularExpressionMatchIterator iterator = iconPattern.globalMatch(contents);
+ while (iterator.hasNext()) {
+ QRegularExpressionMatch match = iterator.next();
+ const QString icon = match.captured(0);
+ icons->append(icon);
+ }
+
+ QRegularExpression executablePattern(QStringLiteral("ImagePath=\"([a-zA-Z0-9_-]*\\.exe)\""));
+ QRegularExpressionMatch match = executablePattern.match(contents);
+ if (!match.hasMatch())
+ return false;
+ *executable = match.captured(1);
+
+ return true;
+}
+
} // namespace Internal
} // namespace WinRt
diff --git a/src/plugins/winrt/winrtpackagedeploymentstep.h b/src/plugins/winrt/winrtpackagedeploymentstep.h
index 592395827b1..0c567b93d4f 100644
--- a/src/plugins/winrt/winrtpackagedeploymentstep.h
+++ b/src/plugins/winrt/winrtpackagedeploymentstep.h
@@ -41,17 +41,28 @@ class WinRtPackageDeploymentStep : public ProjectExplorer::AbstractProcessStep
public:
explicit WinRtPackageDeploymentStep(ProjectExplorer::BuildStepList *bsl);
bool init();
+ bool processSucceeded(int exitCode, QProcess::ExitStatus status);
+ void stdOutput(const QString &line);
ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
void setWinDeployQtArguments(const QString &args);
QString winDeployQtArguments() const;
QString defaultWinDeployQtArguments() const;
+ void raiseError(const QString &errorMessage);
+
bool fromMap(const QVariantMap &map);
QVariantMap toMap() const;
private:
+ bool parseIconsAndExecutableFromManifest(QString manifestFileName, QStringList *items, QString *executable);
+
QString m_args;
+ QString m_executablePathInManifest;
+ QString m_mappingFileContent;
+ QString m_manifestFileName;
+ bool m_isWinPhone;
+ bool m_createMappingFile;
};
} // namespace Internal
diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp
index bb781a50a5a..024dbb52fc6 100644
--- a/src/shared/proparser/profileevaluator.cpp
+++ b/src/shared/proparser/profileevaluator.cpp
@@ -100,7 +100,8 @@ QString ProFileEvaluator::sysrootify(const QString &path, const QString &baseDir
#endif
const bool isHostSystemPath =
option->sysroot.isEmpty() || path.startsWith(option->sysroot, cs)
- || path.startsWith(baseDir, cs) || path.startsWith(d->m_outputDir, cs);
+ || path.startsWith(baseDir, cs) || path.startsWith(d->m_outputDir, cs)
+ || !QFileInfo(option->sysroot + path).exists();
return isHostSystemPath ? path : option->sysroot + path;
}
diff --git a/tests/system/suite_QMLS/tst_QMLS03/test.py b/tests/system/suite_QMLS/tst_QMLS03/test.py
index d8b435b24e1..a46a13999cf 100644
--- a/tests/system/suite_QMLS/tst_QMLS03/test.py
+++ b/tests/system/suite_QMLS/tst_QMLS03/test.py
@@ -79,7 +79,7 @@ def main():
if not startedWithoutPluginError():
return
# open example project
- openQmakeProject(examplePath)
+ openQmakeProject(examplePath, Targets.DESKTOP_480_GCC)
# open qml file
openDocument("propertyanimation.QML.qml.color-animation\\.qml")
# get editor
diff --git a/tests/system/suite_editors/tst_qml_editor/test.py b/tests/system/suite_editors/tst_qml_editor/test.py
index fe188db5129..cd6fca51585 100644
--- a/tests/system/suite_editors/tst_qml_editor/test.py
+++ b/tests/system/suite_editors/tst_qml_editor/test.py
@@ -43,7 +43,7 @@ def main():
addHelpDocumentation([os.path.join(sdkPath, "Documentation", "qt.qch")])
templateDir = prepareTemplate(sourceExample)
installLazySignalHandler("{type='Core::FutureProgress' unnamed='1'}", "finished()", "__handleFutureProgress__")
- openQmakeProject(os.path.join(templateDir,proFile))
+ openQmakeProject(os.path.join(templateDir,proFile), Targets.DESKTOP_480_GCC)
openDocument("focus.QML.qml.focus\\.qml")
testRenameId()
testFindUsages()
diff --git a/tests/system/suite_general/tst_session_handling/test.py b/tests/system/suite_general/tst_session_handling/test.py
index 9d81da376d0..1bfec7e6951 100644
--- a/tests/system/suite_general/tst_session_handling/test.py
+++ b/tests/system/suite_general/tst_session_handling/test.py
@@ -42,7 +42,7 @@ def main():
test.verify(waitFor("sessionName in str(mainWindow.windowTitle)", 2000),
"Verifying window title contains created session name.")
for project in projects:
- openQmakeProject(project)
+ openQmakeProject(project, Targets.DESKTOP_480_GCC)
progressBarWait(20000)
checkNavigator(68, "Verifying whether all projects have been opened.")
openDocument("propertyanimation.QML.qml.color-animation\\.qml")
diff --git a/tests/system/suite_qtquick/tst_qml_outline/test.py b/tests/system/suite_qtquick/tst_qml_outline/test.py
index 46420f3310d..879e05e3089 100644
--- a/tests/system/suite_qtquick/tst_qml_outline/test.py
+++ b/tests/system/suite_qtquick/tst_qml_outline/test.py
@@ -42,11 +42,7 @@ def main():
startApplication("qtcreator" + SettingsPath)
if not startedWithoutPluginError():
return
- targets = openQmakeProject(os.path.join(templateDir, proFile))
- # make sure we use the 474 kit for having QtQuick 1.0 support
- switchViewTo(ViewConstants.PROJECTS)
- switchToBuildOrRunSettingsFor(len(targets), 0, ProjectSettings.BUILD)
- switchViewTo(ViewConstants.EDIT)
+ openQmakeProject(os.path.join(templateDir, proFile), Targets.DESKTOP_480_GCC)
qmlFiles = ["focus.QML.qml.focus\\.qml", "focus.QML.qml.Core.ListMenu\\.qml"]
checkOutlineFor(qmlFiles)
testModify()