aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md5
-rw-r--r--dist/changes-4.1.0.md4
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/ComboBox.qml9
-rw-r--r--src/plugins/autotest/qtest/qttestoutputreader.cpp2
-rw-r--r--src/plugins/autotest/testoutputreader.cpp2
-rw-r--r--src/plugins/autotest/testresult.cpp5
-rw-r--r--src/plugins/autotest/testresult.h1
-rw-r--r--src/plugins/autotest/testresultmodel.cpp9
-rw-r--r--src/plugins/coreplugin/fancyactionbar.cpp11
-rw-r--r--src/plugins/coreplugin/opendocumentstreeview.cpp1
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.cpp4
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp44
-rw-r--r--src/plugins/qmldesigner/componentsplugin/Controls/TabPositionComboBox.qml4
-rw-r--r--src/plugins/qmlprofiler/memoryusagemodel.cpp41
-rw-r--r--src/plugins/qmlprofiler/pixmapcachemodel.cpp40
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp63
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertraceclient.cpp20
-rw-r--r--tests/auto/algorithm/algorithm.pro5
-rw-r--r--tests/auto/algorithm/algorithm.qbs10
-rw-r--r--tests/auto/algorithm/tst_algorithm.cpp116
-rw-r--r--tests/auto/auto.pro1
-rw-r--r--tests/system/objects.map8
-rw-r--r--tests/system/suite_SCOM/tst_SCOM04/test.py1
23 files changed, 332 insertions, 74 deletions
diff --git a/README.md b/README.md
index d195cbf6790..05efbffd27f 100644
--- a/README.md
+++ b/README.md
@@ -21,12 +21,15 @@ Prerequisites:
* jom
* On Mac OS X: latest Xcode
* On Linux: g++ 4.8 or later
-* LLVM 3.8.0 or later for the Clang Code Model
+* LLVM 3.8.0 or later (optional, needed for the Clang Code Model)
The installed toolchains have to match the one Qt was compiled with.
You can build Qt Creator with
+ # Optional, needed for the Clang Code Model:
+ export LLVM_INSTALL_DIR=/path/to/llvm (or "set" on Windows)
+
cd $SOURCE_DIRECTORY
qmake -r
make (or mingw32-make or nmake or jom, depending on your platform)
diff --git a/dist/changes-4.1.0.md b/dist/changes-4.1.0.md
index ce25b28dfe0..f9160eb7b4f 100644
--- a/dist/changes-4.1.0.md
+++ b/dist/changes-4.1.0.md
@@ -48,6 +48,10 @@ CMake Projects
(QTCREATORBUG-15934)
* Fixed that CMake was automatically run even if the Qt Creator application
is not in the foreground (QTCREATORBUG-16354)
+* QML_IMPORT_PATH can now be set in CMakeLists.txt files. This information
+ will be passed on to the QmlJS code model (QTCREATORBUG-11328)
+ Example CMakeLists.txt code:
+ `set(QML_IMPORT_PATH ${CMAKE_SOURCE_DIR}/qml ${CMAKE_BINARY_DIR}/imports CACHE string "" FORCE)`
Qbs Projects
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/ComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/ComboBox.qml
index 85af3f1638b..849a7eb78aa 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/ComboBox.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/ComboBox.qml
@@ -43,6 +43,8 @@ Controls.ComboBox {
signal valueFromBackendChanged
+ property bool block: false
+
ColorLogic {
id: colorLogic
backendValue: comboBox.backendValue
@@ -52,6 +54,11 @@ Controls.ComboBox {
function invalidate() {
+ if (block)
+ return
+
+ block = true
+
if (manualMapping) {
valueFromBackendChanged();
} else if (!comboBox.useInteger) {
@@ -72,6 +79,8 @@ Controls.ComboBox {
if (comboBox.currentIndex !== backendValue.value)
comboBox.currentIndex = backendValue.value
}
+
+ block = false
}
}
diff --git a/src/plugins/autotest/qtest/qttestoutputreader.cpp b/src/plugins/autotest/qtest/qttestoutputreader.cpp
index 6ed3b7c4d14..c66a32305b3 100644
--- a/src/plugins/autotest/qtest/qttestoutputreader.cpp
+++ b/src/plugins/autotest/qtest/qttestoutputreader.cpp
@@ -241,7 +241,7 @@ void QtTestOutputReader::processOutput()
break;
default:
// this must come from plain printf() calls - but this will be ignored anyhow
- qWarning() << "Ignored plain output:" << text.toString();
+ qWarning() << "AutoTest.Run: Ignored plain output:" << text.toString();
break;
}
break;
diff --git a/src/plugins/autotest/testoutputreader.cpp b/src/plugins/autotest/testoutputreader.cpp
index a6bfdbd1d1c..f28775128e7 100644
--- a/src/plugins/autotest/testoutputreader.cpp
+++ b/src/plugins/autotest/testoutputreader.cpp
@@ -45,7 +45,7 @@ TestOutputReader::TestOutputReader(const QFutureInterface<TestResultPtr> &future
void TestOutputReader::processStdError()
{
- qWarning() << "Ignored plain output:" << m_testApplication->readAllStandardError();
+ qWarning() << "AutoTest.Run: Ignored plain output:" << m_testApplication->readAllStandardError();
}
} // namespace Internal
diff --git a/src/plugins/autotest/testresult.cpp b/src/plugins/autotest/testresult.cpp
index 55ae77596cf..df89706c8db 100644
--- a/src/plugins/autotest/testresult.cpp
+++ b/src/plugins/autotest/testresult.cpp
@@ -65,6 +65,8 @@ Result::Type TestResult::resultFromString(const QString &resultString)
return Result::Skip;
if (resultString == QLatin1String("qdebug"))
return Result::MessageDebug;
+ if (resultString == QLatin1String("qinfo"))
+ return Result::MessageInfo;
if (resultString == QLatin1String("warn") || resultString == QLatin1String("qwarn"))
return Result::MessageWarn;
if (resultString == QLatin1String("qfatal"))
@@ -105,6 +107,8 @@ QString TestResult::resultToString(const Result::Type type)
return QLatin1String("BENCH");
case Result::MessageDebug:
return QLatin1String("DEBUG");
+ case Result::MessageInfo:
+ return QLatin1String("INFO");
case Result::MessageWarn:
return QLatin1String("WARN");
case Result::MessageFatal:
@@ -136,6 +140,7 @@ QColor TestResult::colorForType(const Result::Type type)
case Result::Skip:
return creatorTheme->color(Utils::Theme::OutputPanes_TestSkipTextColor);
case Result::MessageDebug:
+ case Result::MessageInfo:
return creatorTheme->color(Utils::Theme::OutputPanes_TestDebugTextColor);
case Result::MessageWarn:
return creatorTheme->color(Utils::Theme::OutputPanes_TestWarnTextColor);
diff --git a/src/plugins/autotest/testresult.h b/src/plugins/autotest/testresult.h
index 4756d1225b5..86c7f8e3c65 100644
--- a/src/plugins/autotest/testresult.h
+++ b/src/plugins/autotest/testresult.h
@@ -46,6 +46,7 @@ enum Type {
BlacklistedFail,
Benchmark,
MessageDebug,
+ MessageInfo,
MessageWarn,
MessageFatal,
diff --git a/src/plugins/autotest/testresultmodel.cpp b/src/plugins/autotest/testresultmodel.cpp
index b42ab5cd628..05d53a69563 100644
--- a/src/plugins/autotest/testresultmodel.cpp
+++ b/src/plugins/autotest/testresultmodel.cpp
@@ -46,7 +46,7 @@ TestResultItem::~TestResultItem()
}
static QIcon testResultIcon(Result::Type result) {
- static QIcon icons[11] = {
+ static QIcon icons[] = {
QIcon(QLatin1String(":/images/pass.png")),
QIcon(QLatin1String(":/images/fail.png")),
QIcon(QLatin1String(":/images/xfail.png")),
@@ -56,6 +56,7 @@ static QIcon testResultIcon(Result::Type result) {
QIcon(QLatin1String(":/images/blacklisted_fail.png")),
QIcon(QLatin1String(":/images/benchmark.png")),
QIcon(QLatin1String(":/images/debug.png")),
+ QIcon(QLatin1String(":/images/debug.png")), // Info get's the same handling as Debug for now
QIcon(QLatin1String(":/images/warn.png")),
QIcon(QLatin1String(":/images/fatal.png")),
}; // provide an icon for unknown??
@@ -298,7 +299,7 @@ void TestResultFilterModel::enableAllResultTypes()
<< Result::MessageCurrentTest << Result::MessageTestCaseStart
<< Result::MessageTestCaseSuccess << Result::MessageTestCaseWarn
<< Result::MessageTestCaseFail << Result::MessageTestCaseEnd
- << Result::MessageTestCaseRepetition;
+ << Result::MessageTestCaseRepetition << Result::MessageInfo;
invalidateFilter();
}
@@ -308,10 +309,14 @@ void TestResultFilterModel::toggleTestResultType(Result::Type type)
m_enabled.remove(type);
if (type == Result::MessageInternal)
m_enabled.remove(Result::MessageTestCaseEnd);
+ if (type == Result::MessageDebug)
+ m_enabled.remove(Result::MessageInfo);
} else {
m_enabled.insert(type);
if (type == Result::MessageInternal)
m_enabled.insert(Result::MessageTestCaseEnd);
+ if (type == Result::MessageDebug)
+ m_enabled.insert(Result::MessageInfo);
}
invalidateFilter();
}
diff --git a/src/plugins/coreplugin/fancyactionbar.cpp b/src/plugins/coreplugin/fancyactionbar.cpp
index 28a334637cb..e6ad99bc1bd 100644
--- a/src/plugins/coreplugin/fancyactionbar.cpp
+++ b/src/plugins/coreplugin/fancyactionbar.cpp
@@ -230,10 +230,15 @@ void FancyToolButton::paintEvent(QPaintEvent *event)
} else {
splitBuildConfiguration = splitInTwoLines(buildConfiguration, boldFm, availableWidth);
}
- // draw the two lines for the build configuration
+
+ // draw the two text lines for the build configuration
painter.setPen(creatorTheme()->color(isEnabled()
- ? Theme::FancyTabWidgetEnabledSelectedTextColor
- : Theme::FancyTabWidgetDisabledSelectedTextColor));
+ // Intentionally using the "Unselected" colors,
+ // because the text color won't change in the pressed
+ // state as they would do on the mode buttons.
+ ? Theme::FancyTabWidgetEnabledUnselectedTextColor
+ : Theme::FancyTabWidgetDisabledUnselectedTextColor));
+
for (int i = 0; i < 2; ++i) {
if (splitBuildConfiguration[i].isEmpty())
continue;
diff --git a/src/plugins/coreplugin/opendocumentstreeview.cpp b/src/plugins/coreplugin/opendocumentstreeview.cpp
index 1f3a6463d86..b7da6cb0bee 100644
--- a/src/plugins/coreplugin/opendocumentstreeview.cpp
+++ b/src/plugins/coreplugin/opendocumentstreeview.cpp
@@ -108,6 +108,7 @@ OpenDocumentsTreeView::OpenDocumentsTreeView(QWidget *parent) :
setTextElideMode(Qt::ElideMiddle);
setFrameStyle(QFrame::NoFrame);
setAttribute(Qt::WA_MacShowFocusRect, false);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
viewport()->setAttribute(Qt::WA_Hover);
setSelectionMode(QAbstractItemView::SingleSelection);
diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp
index eb35908f4d7..bb084b644e9 100644
--- a/src/plugins/projectexplorer/msvctoolchain.cpp
+++ b/src/plugins/projectexplorer/msvctoolchain.cpp
@@ -622,9 +622,11 @@ static ToolChain *findOrCreateToolChain(const QList<ToolChain *> &alreadyKnown,
ToolChain::Detection d = ToolChain::ManualDetection)
{
ToolChain *tc = Utils::findOrDefault(alreadyKnown,
- [&varsBat, &varsBatArg](ToolChain *tc) -> bool {
+ [&varsBat, &varsBatArg, &abi](ToolChain *tc) -> bool {
if (tc->typeId() != Constants::MSVC_TOOLCHAIN_TYPEID)
return false;
+ if (tc->targetAbi() != abi)
+ return false;
auto mtc = static_cast<MsvcToolChain *>(tc);
return mtc->varsBat() == varsBat
&& mtc->varsBatArg() == varsBatArg;
diff --git a/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp b/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp
index a5ce3183c64..31b16e2e2d2 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp
@@ -758,16 +758,21 @@ void QmlAnchorBindingProxy::anchorTop()
{
m_locked = true;
+ bool topTargetIsParent = m_topTarget == m_qmlItemNode.instanceParentItem();
+
if (m_relativeTopTarget == SameEdge) {
- qreal topMargin = transformedBoundingBox().top() - parentBoundingBox().top();
+ qreal topPos = topTargetIsParent ? parentBoundingBox().top() : boundingBox(m_topTarget).top();
+ qreal topMargin = transformedBoundingBox().top() - topPos;
m_qmlItemNode.anchors().setMargin( AnchorLineTop, topMargin);
m_qmlItemNode.anchors().setAnchor(AnchorLineTop, m_topTarget, AnchorLineTop);
} else if (m_relativeTopTarget == OppositeEdge) {
- qreal topMargin = boundingBox(m_qmlItemNode).top() - boundingBox(m_topTarget).bottom();
+ qreal bottomPos = topTargetIsParent ? parentBoundingBox().bottom() : boundingBox(m_topTarget).bottom();
+ qreal topMargin = transformedBoundingBox().top() - bottomPos;
m_qmlItemNode.anchors().setMargin( AnchorLineTop, topMargin);
m_qmlItemNode.anchors().setAnchor(AnchorLineTop, m_topTarget, AnchorLineBottom);
} else if (m_relativeTopTarget == Center) {
- qreal topMargin = boundingBox(m_qmlItemNode).top() - boundingBox(m_topTarget).center().y();
+ qreal centerPos = topTargetIsParent ? parentBoundingBox().center().y() : boundingBox(m_topTarget).center().y();
+ qreal topMargin = transformedBoundingBox().top() - centerPos;
m_qmlItemNode.anchors().setMargin(AnchorLineTop, topMargin);
m_qmlItemNode.anchors().setAnchor(AnchorLineTop, m_topTarget, AnchorLineVerticalCenter);
}
@@ -779,16 +784,21 @@ void QmlAnchorBindingProxy::anchorBottom()
{
m_locked = true;
+ bool bottomTargetIsParent = m_bottomTarget == m_qmlItemNode.instanceParentItem();
+
if (m_relativeBottomTarget == SameEdge) {
- qreal bottomMargin = parentBoundingBox().bottom() - transformedBoundingBox().bottom();
+ qreal bottomPos = bottomTargetIsParent ? parentBoundingBox().bottom() : boundingBox(m_bottomTarget).bottom();
+ qreal bottomMargin = bottomPos - transformedBoundingBox().bottom();
m_qmlItemNode.anchors().setMargin( AnchorLineBottom, bottomMargin);
m_qmlItemNode.anchors().setAnchor(AnchorLineBottom, m_bottomTarget, AnchorLineBottom);
} else if (m_relativeBottomTarget == OppositeEdge) {
- qreal bottomMargin = boundingBox(m_bottomTarget).top()- boundingBox(m_qmlItemNode).bottom();
+ qreal topPos = bottomTargetIsParent ? parentBoundingBox().top() : boundingBox(m_bottomTarget).top();
+ qreal bottomMargin = topPos - transformedBoundingBox().bottom();
m_qmlItemNode.anchors().setMargin( AnchorLineBottom, bottomMargin);
m_qmlItemNode.anchors().setAnchor(AnchorLineBottom, m_bottomTarget, AnchorLineTop);
} else if (m_relativeBottomTarget == Center) {
- qreal bottomMargin = boundingBox(m_qmlItemNode).top() - boundingBox(m_bottomTarget).center().y();
+ qreal centerPos = bottomTargetIsParent ? parentBoundingBox().center().y() : boundingBox(m_bottomTarget).center().y();
+ qreal bottomMargin = centerPos - transformedBoundingBox().bottom();
m_qmlItemNode.anchors().setMargin(AnchorLineBottom, bottomMargin);
m_qmlItemNode.anchors().setAnchor(AnchorLineBottom, m_bottomTarget, AnchorLineVerticalCenter);
}
@@ -800,16 +810,21 @@ void QmlAnchorBindingProxy::anchorLeft()
{
m_locked = true;
+ bool leftTargetIsParent = m_leftTarget == m_qmlItemNode.instanceParentItem();
+
if (m_relativeLeftTarget == SameEdge) {
- qreal leftMargin = transformedBoundingBox().left() - parentBoundingBox().left();
+ qreal leftPos = leftTargetIsParent ? parentBoundingBox().left() : boundingBox(m_leftTarget).left();
+ qreal leftMargin = transformedBoundingBox().left() - leftPos;
m_qmlItemNode.anchors().setMargin(AnchorLineLeft, leftMargin);
m_qmlItemNode.anchors().setAnchor(AnchorLineLeft, m_leftTarget, AnchorLineLeft);
} else if (m_relativeLeftTarget == OppositeEdge) {
- qreal leftMargin = boundingBox(m_qmlItemNode).left() - boundingBox(m_leftTarget).right();
+ qreal rightPos = leftTargetIsParent ? parentBoundingBox().right() : boundingBox(m_leftTarget).right();
+ qreal leftMargin = transformedBoundingBox().left() - rightPos;
m_qmlItemNode.anchors().setMargin( AnchorLineLeft, leftMargin);
m_qmlItemNode.anchors().setAnchor(AnchorLineLeft, m_leftTarget, AnchorLineRight);
} else if (m_relativeLeftTarget == Center) {
- qreal leftMargin = boundingBox(m_qmlItemNode).top() - boundingBox(m_leftTarget).center().x();
+ qreal centerPos = leftTargetIsParent ? parentBoundingBox().center().x() : boundingBox(m_leftTarget).center().x();
+ qreal leftMargin = transformedBoundingBox().left() - centerPos;
m_qmlItemNode.anchors().setMargin(AnchorLineLeft, leftMargin);
m_qmlItemNode.anchors().setAnchor(AnchorLineLeft, m_leftTarget, AnchorLineHorizontalCenter);
}
@@ -821,16 +836,21 @@ void QmlAnchorBindingProxy::anchorRight()
{
m_locked = true;
+ bool rightTargetIsParent = m_rightTarget == m_qmlItemNode.instanceParentItem();
+
if (m_relativeRightTarget == SameEdge) {
- qreal rightMargin = parentBoundingBox().right() - transformedBoundingBox().right();
+ qreal rightPos = rightTargetIsParent ? parentBoundingBox().right() : boundingBox(m_rightTarget).right();
+ qreal rightMargin = rightPos - transformedBoundingBox().right();
m_qmlItemNode.anchors().setMargin( AnchorLineRight, rightMargin);
m_qmlItemNode.anchors().setAnchor(AnchorLineRight, m_rightTarget, AnchorLineRight);
} else if (m_relativeRightTarget == OppositeEdge) {
- qreal rightMargin = boundingBox(m_rightTarget).left() - boundingBox(m_qmlItemNode).right();
+ qreal leftPos = rightTargetIsParent ? parentBoundingBox().left() : boundingBox(m_rightTarget).left();
+ qreal rightMargin = leftPos - transformedBoundingBox().right();
m_qmlItemNode.anchors().setMargin( AnchorLineRight, rightMargin);
m_qmlItemNode.anchors().setAnchor(AnchorLineRight, m_rightTarget, AnchorLineLeft);
} else if (m_relativeRightTarget == Center) {
- qreal rightMargin = boundingBox(m_qmlItemNode).top() - boundingBox(m_rightTarget).center().x();
+ qreal centerPos = rightTargetIsParent ? parentBoundingBox().center().x() : boundingBox(m_rightTarget).center().x();
+ qreal rightMargin = centerPos - transformedBoundingBox().right();
m_qmlItemNode.anchors().setMargin(AnchorLineRight, rightMargin);
m_qmlItemNode.anchors().setAnchor(AnchorLineRight, m_rightTarget, AnchorLineHorizontalCenter);
}
diff --git a/src/plugins/qmldesigner/componentsplugin/Controls/TabPositionComboBox.qml b/src/plugins/qmldesigner/componentsplugin/Controls/TabPositionComboBox.qml
index 3f2065f7bc0..8900276d27c 100644
--- a/src/plugins/qmldesigner/componentsplugin/Controls/TabPositionComboBox.qml
+++ b/src/plugins/qmldesigner/componentsplugin/Controls/TabPositionComboBox.qml
@@ -23,10 +23,8 @@
**
****************************************************************************/
-import QtQuick 2.1
+import QtQuick 2.6
import HelperWidgets 2.0
-import QtQuick.Layouts 1.0
-import QtQuick.Controls 1.1 as Controls
ComboBox {
useInteger: true
diff --git a/src/plugins/qmlprofiler/memoryusagemodel.cpp b/src/plugins/qmlprofiler/memoryusagemodel.cpp
index d07b40df2fb..b0541fa7d00 100644
--- a/src/plugins/qmlprofiler/memoryusagemodel.cpp
+++ b/src/plugins/qmlprofiler/memoryusagemodel.cpp
@@ -177,11 +177,19 @@ void MemoryUsageModel::loadEvent(const QmlEvent &event, const QmlEventType &type
m_currentUsage = allocation.size;
if (m_currentUsageIndex != -1) {
- insertEnd(m_currentUsageIndex,
- event.timestamp() - startTime(m_currentUsageIndex) - 1);
+ qint64 duration = event.timestamp() - startTime(m_currentUsageIndex);
+ if (duration > 0) {
+ insertEnd(m_currentUsageIndex, duration - 1);
+ m_currentUsageIndex = insertStart(event.timestamp(), SmallItem);
+ m_data.insert(m_currentUsageIndex, allocation);
+ } else {
+ // Ignore ranges of 0 duration. We only need to keep track of the sizes.
+ m_data[m_currentUsageIndex] = allocation;
+ }
+ } else {
+ m_currentUsageIndex = insertStart(event.timestamp(), SmallItem);
+ m_data.insert(m_currentUsageIndex, allocation);
}
- m_currentUsageIndex = insertStart(event.timestamp(), SmallItem);
- m_data.insert(m_currentUsageIndex, allocation);
m_continuation = m_continuation | ContinueUsage;
}
}
@@ -201,11 +209,22 @@ void MemoryUsageModel::loadEvent(const QmlEvent &event, const QmlEventType &type
if (m_currentSize > m_maxSize)
m_maxSize = m_currentSize;
- if (m_currentJSHeapIndex != -1)
- insertEnd(m_currentJSHeapIndex,
- event.timestamp() - startTime(m_currentJSHeapIndex) - 1);
- m_currentJSHeapIndex = insertStart(event.timestamp(), type.detailType());
- m_data.insert(m_currentJSHeapIndex, allocation);
+
+ if (m_currentJSHeapIndex != -1) {
+ qint64 duration = event.timestamp() - startTime(m_currentJSHeapIndex);
+ if (duration > 0){
+ insertEnd(m_currentJSHeapIndex, duration - 1);
+ m_currentJSHeapIndex = insertStart(event.timestamp(), type.detailType());
+ m_data.insert(m_currentJSHeapIndex, allocation);
+ } else {
+ // Ignore ranges of 0 duration. We only need to keep track of the sizes.
+ m_data[m_currentJSHeapIndex] = allocation;
+ }
+ } else {
+ m_currentJSHeapIndex = insertStart(event.timestamp(), type.detailType());
+ m_data.insert(m_currentJSHeapIndex, allocation);
+ }
+
m_continuation = m_continuation | ContinueAllocation;
}
}
@@ -215,10 +234,10 @@ void MemoryUsageModel::finalize()
{
if (m_currentJSHeapIndex != -1)
insertEnd(m_currentJSHeapIndex, modelManager()->traceTime()->endTime() -
- startTime(m_currentJSHeapIndex) - 1);
+ startTime(m_currentJSHeapIndex));
if (m_currentUsageIndex != -1)
insertEnd(m_currentUsageIndex, modelManager()->traceTime()->endTime() -
- startTime(m_currentUsageIndex) - 1);
+ startTime(m_currentUsageIndex));
computeNesting();
diff --git a/src/plugins/qmlprofiler/pixmapcachemodel.cpp b/src/plugins/qmlprofiler/pixmapcachemodel.cpp
index e21fcca8231..b38256c9a8c 100644
--- a/src/plugins/qmlprofiler/pixmapcachemodel.cpp
+++ b/src/plugins/qmlprofiler/pixmapcachemodel.cpp
@@ -214,8 +214,6 @@ void PixmapCacheModel::loadEvent(const QmlEvent &event, const QmlEventType &type
break;
}
case PixmapCacheCountChanged: {// Cache Size Changed Event
- pixmapStartTime = event.timestamp() + 1; // delay 1 ns for proper sorting
-
bool uncache = m_cumulatedCount > event.number<qint32>(2);
m_cumulatedCount = event.number<qint32>(2);
qint64 pixSize = 0;
@@ -433,11 +431,16 @@ void PixmapCacheModel::computeMaxCacheSize()
void PixmapCacheModel::resizeUnfinishedLoads()
{
- // all the "load start" events with duration 0 continue till the end of the trace
- for (int i = 0; i < count(); i++) {
- if (m_data[i].pixmapEventType == PixmapCacheModel::PixmapLoadingStarted &&
- duration(i) == 0) {
- insertEnd(i, modelManager()->traceTime()->endTime() - startTime(i));
+ // all the unfinished "load start" events continue till the end of the trace
+ for (auto pixmap = m_pixmaps.begin(), pixmapsEnd = m_pixmaps.end();
+ pixmap != pixmapsEnd; ++pixmap) {
+ for (auto size = pixmap->sizes.begin(), sizesEnd = pixmap->sizes.end(); size != sizesEnd;
+ ++size) {
+ if (size->loadState == Loading) {
+ insertEnd(size->started,
+ modelManager()->traceTime()->endTime() - startTime(size->started));
+ size->loadState = Error;
+ }
}
}
}
@@ -477,17 +480,26 @@ int PixmapCacheModel::updateCacheCount(int lastCacheSizeEvent,
{
newEvent.pixmapEventType = PixmapCacheCountChanged;
newEvent.rowNumberCollapsed = 1;
+ newEvent.typeId = typeId;
- qint64 prevSize = 0;
+ int index = lastCacheSizeEvent;
if (lastCacheSizeEvent != -1) {
- prevSize = m_data[lastCacheSizeEvent].cacheSize;
- insertEnd(lastCacheSizeEvent, pixmapStartTime - startTime(lastCacheSizeEvent));
+ newEvent.cacheSize = m_data[lastCacheSizeEvent].cacheSize + pixSize;
+ qint64 duration = pixmapStartTime - startTime(lastCacheSizeEvent);
+ if (duration > 0) {
+ insertEnd(lastCacheSizeEvent, duration);
+ index = insertStart(pixmapStartTime, 0);
+ m_data.insert(index, newEvent);
+ } else {
+ // If the timestamps are the same, just replace it
+ m_data[index] = newEvent;
+ }
+ } else {
+ newEvent.cacheSize = pixSize;
+ index = insertStart(pixmapStartTime, 0);
+ m_data.insert(index, newEvent);
}
- newEvent.cacheSize = prevSize + pixSize;
- newEvent.typeId = typeId;
- int index = insertStart(pixmapStartTime, 0);
- m_data.insert(index, newEvent);
return index;
}
diff --git a/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp b/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp
index c5908924926..0390d493cd0 100644
--- a/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp
@@ -187,6 +187,15 @@ void QmlProfilerDataModel::QmlProfilerDataModelPrivate::rewriteType(int typeInde
detailsRewriter->requestDetailsForLocation(typeIndex, type.location());
}
+static bool isStateful(const QmlEventType &type)
+{
+ // Events of these types carry state that has to be taken into account when adding later events:
+ // PixmapCacheEvent: Total size of the cache and size of pixmap currently being loaded
+ // MemoryAllocation: Total size of the JS heap and the amount of it currently in use
+ const Message message = type.message();
+ return message == PixmapCacheEvent || message == MemoryAllocation;
+}
+
void QmlProfilerDataModel::replayEvents(qint64 rangeStart, qint64 rangeEnd,
QmlProfilerModelManager::EventLoader loader) const
{
@@ -196,6 +205,7 @@ void QmlProfilerDataModel::replayEvents(qint64 rangeStart, qint64 rangeEnd,
QFile file(d->file.fileName());
file.open(QIODevice::ReadOnly);
QDataStream stream(&file);
+ bool crossedRangeStart = false;
while (!stream.atEnd()) {
stream >> event;
if (stream.status() == QDataStream::ReadPastEnd)
@@ -203,35 +213,48 @@ void QmlProfilerDataModel::replayEvents(qint64 rangeStart, qint64 rangeEnd,
const QmlEventType &type = d->eventTypes[event.typeIndex()];
if (rangeStart != -1 && rangeEnd != -1) {
- if (event.timestamp() < rangeStart) {
+ // Double-check if rangeStart has been crossed. Some versions of Qt send dirty data.
+ if (event.timestamp() < rangeStart && !crossedRangeStart) {
if (type.rangeType() != MaximumRangeType) {
if (event.rangeStage() == RangeStart)
stack.push(event);
else if (event.rangeStage() == RangeEnd)
stack.pop();
+ continue;
+ } else if (isStateful(type)) {
+ event.setTimestamp(rangeStart);
+ } else {
+ continue;
}
- continue;
- } else if (event.timestamp() > rangeEnd) {
- if (type.rangeType() != MaximumRangeType) {
- if (event.rangeStage() == RangeEnd) {
- if (stack.isEmpty()) {
- QmlEvent endEvent(event);
- endEvent.setTimestamp(rangeEnd);
- loader(endEvent, d->eventTypes[event.typeIndex()]);
- } else {
- stack.pop();
- }
- } else if (event.rangeStage() == RangeStart) {
- stack.push(event);
+ } else {
+ if (!crossedRangeStart) {
+ foreach (QmlEvent stashed, stack) {
+ stashed.setTimestamp(rangeStart);
+ loader(stashed, d->eventTypes[stashed.typeIndex()]);
}
+ stack.clear();
+ crossedRangeStart = true;
}
- continue;
- } else if (!stack.isEmpty()) {
- foreach (QmlEvent stashed, stack) {
- stashed.setTimestamp(rangeStart);
- loader(stashed, d->eventTypes[stashed.typeIndex()]);
+ if (event.timestamp() > rangeEnd) {
+ if (type.rangeType() != MaximumRangeType) {
+ if (event.rangeStage() == RangeEnd) {
+ if (stack.isEmpty()) {
+ QmlEvent endEvent(event);
+ endEvent.setTimestamp(rangeEnd);
+ loader(endEvent, d->eventTypes[event.typeIndex()]);
+ } else {
+ stack.pop();
+ }
+ } else if (event.rangeStage() == RangeStart) {
+ stack.push(event);
+ }
+ continue;
+ } else if (isStateful(type)) {
+ event.setTimestamp(rangeEnd);
+ } else {
+ continue;
+ }
}
- stack.clear();
}
}
diff --git a/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp b/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
index 4c586a37eaf..0e8b16d444d 100644
--- a/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
@@ -32,6 +32,8 @@
#include <qmldebug/qpacketprotocol.h>
#include <utils/qtcassert.h>
+#include <QQueue>
+
namespace QmlProfiler {
class QmlProfilerTraceClientPrivate {
@@ -70,6 +72,7 @@ public:
QHash<QmlEventType, int> eventTypeIds;
QHash<qint64, int> serverTypeIds;
QStack<QmlTypedEvent> rangesInProgress;
+ QQueue<QmlEvent> pendingMessages;
};
int QmlProfilerTraceClientPrivate::resolveType(const QmlTypedEvent &event)
@@ -109,6 +112,10 @@ int QmlProfilerTraceClientPrivate::resolveStackTop()
typeIndex = resolveType(typedEvent);
typedEvent.event.setTypeIndex(typeIndex);
+ while (!pendingMessages.isEmpty()
+ && pendingMessages.head().timestamp() < typedEvent.event.timestamp()) {
+ model->addEvent(pendingMessages.dequeue());
+ }
model->addEvent(typedEvent.event);
return typeIndex;
}
@@ -130,6 +137,8 @@ void QmlProfilerTraceClientPrivate::processCurrentEvent()
int typeIndex = resolveStackTop();
QTC_ASSERT(typeIndex != -1, break);
currentEvent.event.setTypeIndex(typeIndex);
+ while (!pendingMessages.isEmpty())
+ model->addEvent(pendingMessages.dequeue());
model->addEvent(currentEvent.event);
rangesInProgress.pop();
break;
@@ -143,7 +152,10 @@ void QmlProfilerTraceClientPrivate::processCurrentEvent()
default: {
int typeIndex = resolveType(currentEvent);
currentEvent.event.setTypeIndex(typeIndex);
- model->addEvent(currentEvent.event);
+ if (rangesInProgress.isEmpty())
+ model->addEvent(currentEvent.event);
+ else
+ pendingMessages.enqueue(currentEvent.event);
break;
}
}
@@ -281,6 +293,12 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data)
d->maximumTime = qMax(d->currentEvent.event.timestamp(), d->maximumTime);
if (d->currentEvent.type.message() == Complete) {
+ while (!d->rangesInProgress.isEmpty()) {
+ d->currentEvent = d->rangesInProgress.top();
+ d->currentEvent.event.setRangeStage(RangeEnd);
+ d->currentEvent.event.setTimestamp(d->maximumTime);
+ d->processCurrentEvent();
+ }
emit complete(d->maximumTime);
setRecordingFromServer(false);
} else if (d->currentEvent.type.message() == Event
diff --git a/tests/auto/algorithm/algorithm.pro b/tests/auto/algorithm/algorithm.pro
new file mode 100644
index 00000000000..d1e88a924d5
--- /dev/null
+++ b/tests/auto/algorithm/algorithm.pro
@@ -0,0 +1,5 @@
+QTC_LIB_DEPENDS = utils
+include(../qttest.pri)
+
+SOURCES += tst_algorithm.cpp
+OTHER_FILES += $$IDE_SOURCE_TREE/src/libs/utils/algorithm.h
diff --git a/tests/auto/algorithm/algorithm.qbs b/tests/auto/algorithm/algorithm.qbs
new file mode 100644
index 00000000000..6131f95f86e
--- /dev/null
+++ b/tests/auto/algorithm/algorithm.qbs
@@ -0,0 +1,10 @@
+import qbs
+
+QtcAutotest {
+ name: "Algorithm autotest"
+ Depends { name: "Utils" }
+
+ files: [
+ "tst_algorithm.cpp",
+ ]
+}
diff --git a/tests/auto/algorithm/tst_algorithm.cpp b/tests/auto/algorithm/tst_algorithm.cpp
new file mode 100644
index 00000000000..e591965dfcc
--- /dev/null
+++ b/tests/auto/algorithm/tst_algorithm.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <utils/algorithm.h>
+
+#include <QtTest>
+
+class tst_Algorithm : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void transform();
+};
+
+
+int stringToInt(const QString &s)
+{
+ return s.toInt();
+}
+
+void tst_Algorithm::transform()
+{
+ // same container type
+ {
+ // QList has standard inserter
+ const QList<QString> strings({"1", "3", "132"});
+ const QList<int> i1 = Utils::transform(strings, [](const QString &s) { return s.toInt(); });
+ QCOMPARE(i1, QList<int>({1, 3, 132}));
+ const QList<int> i2 = Utils::transform(strings, stringToInt);
+ QCOMPARE(i2, QList<int>({1, 3, 132}));
+ const QList<int> i3 = Utils::transform(strings, &QString::size);
+ QCOMPARE(i3, QList<int>({1, 1, 3}));
+ }
+ {
+ // QStringList
+ const QStringList strings({"1", "3", "132"});
+ const QList<int> i1 = Utils::transform(strings, [](const QString &s) { return s.toInt(); });
+ QCOMPARE(i1, QList<int>({1, 3, 132}));
+ const QList<int> i2 = Utils::transform(strings, stringToInt);
+ QCOMPARE(i2, QList<int>({1, 3, 132}));
+ const QList<int> i3 = Utils::transform(strings, &QString::size);
+ QCOMPARE(i3, QList<int>({1, 1, 3}));
+ }
+ {
+ // QSet internally needs special inserter
+ const QSet<QString> strings({"1", "3", "132"});
+ const QSet<int> i1 = Utils::transform(strings, [](const QString &s) { return s.toInt(); });
+ QCOMPARE(i1, QSet<int>({1, 3, 132}));
+ const QSet<int> i2 = Utils::transform(strings, stringToInt);
+ QCOMPARE(i2, QSet<int>({1, 3, 132}));
+ const QSet<int> i3 = Utils::transform(strings, &QString::size);
+ QCOMPARE(i3, QSet<int>({1, 3}));
+ }
+
+ // different container types
+ {
+ // QList to QSet
+ const QList<QString> strings({"1", "3", "132"});
+ const QSet<int> i1 = Utils::transform<QSet>(strings, [](const QString &s) { return s.toInt(); });
+ QCOMPARE(i1, QSet<int>({1, 3, 132}));
+ const QSet<int> i2 = Utils::transform<QSet>(strings, stringToInt);
+ QCOMPARE(i2, QSet<int>({1, 3, 132}));
+ const QSet<int> i3 = Utils::transform<QSet>(strings, &QString::size);
+ QCOMPARE(i3, QSet<int>({1, 3}));
+ }
+ {
+ // QStringList to QSet
+ const QStringList strings({"1", "3", "132"});
+ const QSet<int> i1 = Utils::transform<QSet>(strings, [](const QString &s) { return s.toInt(); });
+ QCOMPARE(i1, QSet<int>({1, 3, 132}));
+ const QSet<int> i2 = Utils::transform<QSet>(strings, stringToInt);
+ QCOMPARE(i2, QSet<int>({1, 3, 132}));
+ const QSet<int> i3 = Utils::transform<QSet>(strings, &QString::size);
+ QCOMPARE(i3, QSet<int>({1, 3}));
+ }
+ {
+ // QSet to QList
+ const QSet<QString> strings({"1", "3", "132"});
+ QList<int> i1 = Utils::transform<QList>(strings, [](const QString &s) { return s.toInt(); });
+ qSort(i1);
+ QCOMPARE(i1, QList<int>({1, 3, 132}));
+ QList<int> i2 = Utils::transform<QList>(strings, stringToInt);
+ qSort(i2);
+ QCOMPARE(i2, QList<int>({1, 3, 132}));
+ QList<int> i3 = Utils::transform<QList>(strings, &QString::size);
+ qSort(i3);
+ QCOMPARE(i3, QList<int>({1, 1, 3}));
+ }
+}
+
+QTEST_MAIN(tst_Algorithm)
+
+#include "tst_algorithm.moc"
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 1612ea7f63a..af26b3319dc 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -1,6 +1,7 @@
TEMPLATE = subdirs
SUBDIRS += \
+ algorithm \
aggregation \
changeset \
clangstaticanalyzer \
diff --git a/tests/system/objects.map b/tests/system/objects.map
index 29b6fcbe8da..9c78f4ec13e 100644
--- a/tests/system/objects.map
+++ b/tests/system/objects.map
@@ -3,17 +3,17 @@
:*Qt Creator.Cancel Build_QToolButton {text='Cancel Build' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.Cancel_QPushButton {text='Cancel' type='QPushButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.Clear_QToolButton {text='Clear' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
-:*Qt Creator.Continue_Core::Internal::FancyToolButton {text='Continue' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
+:*Qt Creator.Continue_Core::Internal::FancyToolButton {toolTip?='Continue *' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.DoubleTabWidget_ProjectExplorer::Internal::DoubleTabWidget {name='ProjectExplorer__Internal__DoubleTabWidget' type='ProjectExplorer::Internal::DoubleTabWidget' visible='1' window=':Qt Creator_Core::Internal::MainWindow' windowTitle='DoubleTabWidget'}
:*Qt Creator.Events_QDockWidget {name='QmlProfilerStatisticsViewDockWidget' type='QDockWidget' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.Events_QTabBar {aboveWidget=':*Qt Creator.Events_QDockWidget' type='QTabBar' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.Find_Find::Internal::FindToolBar {name='Core__Internal__FindWidget' type='Core::Internal::FindToolBar' visible='1' window=':Qt Creator_Core::Internal::MainWindow' windowTitle='Find'}
:*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack {name='FormEditorStack' type='Designer::Internal::FormEditorStack' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
-:*Qt Creator.Interrupt_Core::Internal::FancyToolButton {text='Interrupt' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
+:*Qt Creator.Interrupt_Core::Internal::FancyToolButton {toolTip='Interrupt' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.JavaScript_QDockWidget {name='QmlProfilerV8ProfileViewDockWidget' type='QDockWidget' visible='1' window=':Qt Creator_Core::Internal::MainWindow' windowTitle='V8'}
:*Qt Creator.JavaScript_QTabBar {aboveWidget=':*Qt Creator.JavaScript_QDockWidget' type='QTabBar' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.Run_Core::Internal::FancyToolButton {text='Run' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
-:*Qt Creator.Start Debugging_Core::Internal::FancyToolButton {text='Start Debugging' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
+:*Qt Creator.Start Debugging_Core::Internal::FancyToolButton {toolTip?='Start Debugging *' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.Timeline_QDockWidget {name='QML ProfilerDockWidget' type='QDockWidget' visible='1' window=':Qt Creator_Core::Internal::MainWindow' windowTitle='Timeline'}
:*Qt Creator.Timeline_QTabBar {aboveWidget=':*Qt Creator.Timeline_QDockWidget' type='QTabBar' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.Widget Box_QDockWidget {name='WidgetBoxDockWidget' type='QDockWidget' visible='1' window=':Qt Creator_Core::Internal::MainWindow' windowTitle='Widget Box'}
@@ -61,7 +61,7 @@
:DebugModeWidget.Toolbar_QDockWidget {container=':Qt Creator.DebugModeWidget_QSplitter' name='Toolbar' type='QDockWidget' visible='1'}
:DebugModeWidget_Debugger::Internal::ConsoleView {container=':Qt Creator.DebugModeWidget_QSplitter' type='Debugger::Internal::ConsoleView' unnamed='1' visible='1'}
:DebugModeWidget_QComboBox {container=':Qt Creator.DebugModeWidget_QSplitter' occurrence='2' type='QComboBox' unnamed='1' visible='1'}
-:Debugger Toolbar.Continue_QToolButton {container=':DebugModeWidget.Toolbar_QDockWidget' text='Continue' type='QToolButton' unnamed='1' visible='1'}
+:Debugger Toolbar.Continue_QToolButton {container=':DebugModeWidget.Toolbar_QDockWidget' toolTip?='Continue *' type='QToolButton' unnamed='1' visible='1'}
:Debugger Toolbar.Exit Debugger_QToolButton {container=':DebugModeWidget.Toolbar_QDockWidget' text='Stop Debugger' type='QToolButton' unnamed='1' visible='1'}
:Debugger Toolbar.StatusText_Utils::StatusLabel {container=':DebugModeWidget.Toolbar_QDockWidget' type='Utils::StatusLabel' unnamed='1'}
:Debugger.Docks.BreakDockWidget.Debugger.Docks.Break_QFrame {container=':DebugModeWidget.Debugger.Docks.BreakDockWidget_QDockWidget' name='Debugger.Docks.Break' type='QFrame' visible='1'}
diff --git a/tests/system/suite_SCOM/tst_SCOM04/test.py b/tests/system/suite_SCOM/tst_SCOM04/test.py
index 33a6870e299..5698cae8eb7 100644
--- a/tests/system/suite_SCOM/tst_SCOM04/test.py
+++ b/tests/system/suite_SCOM/tst_SCOM04/test.py
@@ -30,6 +30,7 @@ source("../../shared/suites_qtta.py")
def main():
# expected error texts - for different compilers
expectedErrorAlternatives = ["'SyntaxError' was not declared in this scope",
+ "\xe2\x80\x98SyntaxError\xe2\x80\x99 was not declared in this scope",
"'SyntaxError' : undeclared identifier",
"use of undeclared identifier 'SyntaxError'",
"unknown type name 'SyntaxError'"]