aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--doc/images/qmldesigner-new-project.pngbin18186 -> 49117 bytes
-rw-r--r--doc/images/qtcreator-add-resource-wizard.pngbin17451 -> 41460 bytes
-rw-r--r--doc/images/qtcreator-android-run-settings.pngbin0 -> 32885 bytes
-rw-r--r--doc/images/qtcreator-build-dependencies.pngbin6571 -> 8470 bytes
-rw-r--r--doc/images/qtcreator-custom-project-wizards.pngbin34175 -> 37418 bytes
-rw-r--r--doc/images/qtcreator-custom-wizard.pngbin14697 -> 38956 bytes
-rw-r--r--doc/images/qtcreator-editor-settings.pngbin24066 -> 70636 bytes
-rw-r--r--doc/images/qtcreator-ios-preferences.pngbin0 -> 66515 bytes
-rw-r--r--doc/images/qtcreator-ios-simulator-deploy.pngbin0 -> 41536 bytes
-rw-r--r--doc/images/qtcreator-kits.pngbin25059 -> 95845 bytes
-rw-r--r--doc/images/qtcreator-new-opengl-file.pngbin19929 -> 49173 bytes
-rw-r--r--doc/images/qtcreator-new-qt-gui-application.pngbin18045 -> 49035 bytes
-rw-r--r--doc/images/qtcreator-new-qt-quick-project-wizard.pngbin18301 -> 49392 bytes
-rw-r--r--doc/images/qtcreator-options-code-style-qml.pngbin9531 -> 41145 bytes
-rw-r--r--doc/src/android/androiddev.qdoc69
-rw-r--r--doc/src/android/creator-projects-settings-run-android.qdocinc64
-rw-r--r--doc/src/android/deploying-android.qdoc10
-rw-r--r--doc/src/debugger/qtquick-debugging.qdoc39
-rw-r--r--doc/src/editors/creator-editors.qdoc10
-rw-r--r--doc/src/ios/creator-ios-dev.qdoc50
-rw-r--r--doc/src/linux-mobile/creator-projects-settings-run-b2qt.qdocinc2
-rw-r--r--doc/src/linux-mobile/creator-projects-settings-run-linux.qdocinc2
-rw-r--r--doc/src/projects/creator-projects-custom-wizards-xml.qdoc127
-rw-r--r--doc/src/projects/creator-projects-settings-code-style.qdoc6
-rw-r--r--doc/src/projects/creator-projects-settings-dependencies.qdoc5
-rw-r--r--doc/src/projects/creator-projects-settings-editor.qdoc3
-rw-r--r--doc/src/projects/creator-projects-settings-run-analyze.qdocinc2
-rw-r--r--doc/src/projects/creator-projects-settings-run-debug.qdocinc2
-rw-r--r--doc/src/projects/creator-projects-settings-run-desktop.qdocinc2
-rw-r--r--doc/src/projects/creator-projects-settings-run.qdoc3
-rw-r--r--doc/src/projects/creator-projects-targets.qdoc9
-rw-r--r--doc/src/qnx/creator-projects-settings-run-qnx.qdocinc2
-rw-r--r--doc/src/qtquick/qtquick-toolbars.qdoc7
-rw-r--r--share/qtcreator/debugger/gdbbridge.py6
-rw-r--r--share/qtcreator/debugger/lldbbridge.py3
-rw-r--r--share/qtcreator/debugger/qttypes.py19
-rw-r--r--share/qtcreator/debugger/stdtypes.py19
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/ExtendedFunctionButton.qml2
-rw-r--r--share/qtcreator/translations/qtcreator_ru.ts2124
-rw-r--r--src/app/app.qbs7
-rw-r--r--src/libs/cplusplus/LookupContext.cpp2
-rw-r--r--src/libs/cplusplus/MatchingText.cpp5
-rw-r--r--src/libs/qmljs/qmljscheck.cpp3
-rw-r--r--src/libs/utils/persistentsettings.cpp32
-rw-r--r--src/libs/utils/treemodel.cpp23
-rw-r--r--src/libs/utils/treemodel.h2
-rw-r--r--src/libs/utils/wizard.cpp1
-rw-r--r--src/plugins/android/androidanalyzesupport.cpp4
-rw-r--r--src/plugins/android/androidbuildapkstep.cpp5
-rw-r--r--src/plugins/android/androiddebugsupport.cpp2
-rw-r--r--src/plugins/autotest/gtest/gtesttreeitem.cpp2
-rw-r--r--src/plugins/autotest/quick/quicktesttreeitem.cpp36
-rw-r--r--src/plugins/autotest/testconfiguration.cpp108
-rw-r--r--src/plugins/autotest/testtreeitem.cpp2
-rw-r--r--src/plugins/baremetal/baremetaldebugsupport.cpp2
-rw-r--r--src/plugins/clangcodemodel/clangassistproposalitem.cpp57
-rw-r--r--src/plugins/clangcodemodel/clangassistproposalitem.h5
-rw-r--r--src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp3
-rw-r--r--src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp2
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp8
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp17
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectnodes.h6
-rw-r--r--src/plugins/cmakeprojectmanager/servermodereader.cpp26
-rw-r--r--src/plugins/cmakeprojectmanager/tealeafreader.cpp2
-rw-r--r--src/plugins/coreplugin/find/searchresultwidget.cpp15
-rw-r--r--src/plugins/coreplugin/find/searchresultwidget.h2
-rw-r--r--src/plugins/cppeditor/cppautocompleter.cpp3
-rw-r--r--src/plugins/cppeditor/cppeditor.cpp2
-rw-r--r--src/plugins/cppeditor/cppuseselectionsupdater.cpp2
-rw-r--r--src/plugins/debugger/cdb/cdbengine.cpp10
-rw-r--r--src/plugins/debugger/debuggerengine.cpp56
-rw-r--r--src/plugins/debugger/debuggerplugin.cpp6
-rw-r--r--src/plugins/debugger/debuggerruncontrol.cpp32
-rw-r--r--src/plugins/debugger/debuggerstartparameters.h1
-rw-r--r--src/plugins/debugger/logwindow.cpp2
-rw-r--r--src/plugins/diffeditor/diffeditorplugin.cpp2
-rw-r--r--src/plugins/diffeditor/diffutils.cpp729
-rw-r--r--src/plugins/diffeditor/sidebysidediffeditorwidget.cpp11
-rw-r--r--src/plugins/diffeditor/unifieddiffeditorwidget.cpp10
-rw-r--r--src/plugins/diffeditor/unifieddiffeditorwidget.h1
-rw-r--r--src/plugins/ios/iosrunner.cpp6
-rw-r--r--src/plugins/ios/iossettingswidget.cpp4
-rw-r--r--src/plugins/projectexplorer/devicesupport/desktopdevice.cpp100
-rw-r--r--src/plugins/projectexplorer/devicesupport/desktopdevice.h1
-rw-r--r--src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp77
-rw-r--r--src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h8
-rw-r--r--src/plugins/projectexplorer/devicesupport/idevice.h3
-rw-r--r--src/plugins/projectexplorer/kitinformation.cpp48
-rw-r--r--src/plugins/projectexplorer/kitinformation.h1
-rw-r--r--src/plugins/projectexplorer/projectmodels.cpp29
-rw-r--r--src/plugins/projectexplorer/projectmodels.h3
-rw-r--r--src/plugins/projectexplorer/projectnodes.cpp32
-rw-r--r--src/plugins/projectexplorer/projectnodes.h15
-rw-r--r--src/plugins/projectexplorer/projecttreewidget.cpp13
-rw-r--r--src/plugins/projectexplorer/projecttreewidget.h6
-rw-r--r--src/plugins/projectexplorer/runconfiguration.cpp301
-rw-r--r--src/plugins/projectexplorer/runconfiguration.h9
-rw-r--r--src/plugins/qbsprojectmanager/qbsprofilessettingswidget.ui6
-rw-r--r--src/plugins/qbsprojectmanager/qbsproject.cpp2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakekitinformation.cpp2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeproject.cpp2
-rw-r--r--src/plugins/qmldesigner/components/formeditor/movetool.cpp14
-rw-r--r--src/plugins/qmldesigner/components/formeditor/selectiontool.cpp14
-rw-r--r--src/plugins/qmldesigner/qmldesignerextension/connectioneditor/connectionviewwidget.ui12
-rw-r--r--src/plugins/qmlprofiler/flamegraphmodel.cpp38
-rw-r--r--src/plugins/qmlprofiler/flamegraphmodel.h2
-rw-r--r--src/plugins/qmlprofiler/flamegraphview.cpp8
-rw-r--r--src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml7
-rw-r--r--src/plugins/qmlprofiler/qmlprofiler.qbs1
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerplugin.cpp2
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp140
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerruncontrol.h13
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerstatisticsview.cpp10
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertool.cpp137
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertool.h3
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertraceview.cpp18
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertraceview.h1
-rw-r--r--src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp144
-rw-r--r--src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.h13
-rw-r--r--src/plugins/qmlprofiler/tests/qmlprofilertraceview_test.cpp67
-rw-r--r--src/plugins/qmlprofiler/tests/qmlprofilertraceview_test.h51
-rw-r--r--src/plugins/qmlprofiler/tests/tests.pri6
-rw-r--r--src/plugins/qnx/qnxanalyzesupport.cpp6
-rw-r--r--src/plugins/qnx/qnxdebugsupport.cpp6
-rw-r--r--src/plugins/qnx/qnxdevice.cpp14
-rw-r--r--src/plugins/qnx/slog2inforunner.cpp9
-rw-r--r--src/plugins/qtsupport/baseqtversion.cpp5
-rw-r--r--src/plugins/remotelinux/linuxdevice.cpp8
-rw-r--r--src/plugins/remotelinux/remotelinuxanalyzesupport.cpp11
-rw-r--r--src/plugins/remotelinux/remotelinuxdebugsupport.cpp4
-rw-r--r--src/plugins/scxmleditor/outputpane/errorwidget.cpp2
-rw-r--r--src/plugins/scxmleditor/plugin_interface/scattributeitemmodel.cpp4
-rw-r--r--src/plugins/scxmleditor/plugin_interface/stateitem.cpp2
-rw-r--r--src/plugins/valgrind/memcheckengine.cpp2
-rw-r--r--src/plugins/winrt/winrtrunnerhelper.cpp2
m---------src/shared/qbs0
-rw-r--r--src/tools/clangbackend/ipcsource/clangbackend_global.h7
-rw-r--r--src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri6
-rw-r--r--src/tools/clangbackend/ipcsource/clangcodemodelserver.cpp14
-rw-r--r--src/tools/clangbackend/ipcsource/clangcodemodelserver.h1
-rw-r--r--src/tools/clangbackend/ipcsource/clangdocument.cpp28
-rw-r--r--src/tools/clangbackend/ipcsource/clangdocument.h6
-rw-r--r--src/tools/clangbackend/ipcsource/clangdocuments.cpp3
-rw-r--r--src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.cpp141
-rw-r--r--src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.h62
-rw-r--r--src/tools/clangbackend/ipcsource/clangiasyncjob.cpp8
-rw-r--r--src/tools/clangbackend/ipcsource/clangjobqueue.cpp67
-rw-r--r--src/tools/clangbackend/ipcsource/clangjobrequest.cpp44
-rw-r--r--src/tools/clangbackend/ipcsource/clangjobrequest.h13
-rw-r--r--src/tools/clangbackend/ipcsource/clangresumedocumentjob.cpp54
-rw-r--r--src/tools/clangbackend/ipcsource/clangresumedocumentjob.h44
-rw-r--r--src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.cpp73
-rw-r--r--src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.h44
-rw-r--r--src/tools/clangbackend/ipcsource/clangtranslationunit.cpp13
-rw-r--r--src/tools/clangbackend/ipcsource/clangtranslationunit.h2
-rw-r--r--src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.cpp16
-rw-r--r--src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.h8
-rw-r--r--src/tools/clangbackend/ipcsource/highlightingmark.cpp3
-rw-r--r--src/tools/qml2puppet/qml2puppet.qbs5
-rw-r--r--src/tools/qtcdebugger/main.cpp11
-rw-r--r--tests/auto/json/json.qbs2
-rw-r--r--tests/helper/README.txt3
-rw-r--r--tests/helper/qmlapplicationviewer/qmlapplicationviewer.cpp226
-rw-r--r--tests/helper/qmlapplicationviewer/qmlapplicationviewer.h77
-rw-r--r--tests/helper/qmlapplicationviewer/qmlapplicationviewer.pri156
-rw-r--r--tests/manual/debugger/python/README.md4
-rw-r--r--tests/manual/debugger/python/math.py2
-rw-r--r--tests/manual/debugger/python/python.pyqtc1
-rw-r--r--tests/system/README51
-rw-r--r--tests/system/patch.txt17
-rw-r--r--tests/system/settings/mac/QtProject/qtcreator/profiles.xml35
-rw-r--r--tests/system/settings/mac/QtProject/qtcreator/qtversion.xml16
-rw-r--r--tests/system/settings/unix/QtProject/qtcreator/profiles.xml35
-rw-r--r--tests/system/settings/unix/QtProject/qtcreator/qtversion.xml18
-rw-r--r--tests/system/settings/windows/QtProject/qtcreator/profiles.xml44
-rw-r--r--tests/system/settings/windows/QtProject/qtcreator/qtversion.xml18
-rw-r--r--tests/system/settings/windows/QtProject/qtcreator/toolchains.xml44
-rw-r--r--tests/system/shared/classes.py17
-rw-r--r--tests/system/shared/debugger.py13
-rw-r--r--tests/system/shared/editor_utils.py5
-rw-r--r--tests/system/shared/project.py15
-rw-r--r--tests/system/shared/qtcreator.py8
-rw-r--r--tests/system/suite_APTW/tst_APTW03/test.py9
-rwxr-xr-xtests/system/suite_CCOM/tst_CCOM01/test.py3
-rw-r--r--tests/system/suite_CSUP/tst_CSUP04/test.py10
-rw-r--r--tests/system/suite_CSUP/tst_CSUP05/test.py6
-rw-r--r--tests/system/suite_CSUP/tst_CSUP06/test.py12
-rwxr-xr-xtests/system/suite_HELP/tst_HELP02/test.py10
-rwxr-xr-xtests/system/suite_HELP/tst_HELP04/test.py11
-rw-r--r--tests/system/suite_debugger/tst_simple_analyze/test.py6
-rw-r--r--tests/system/suite_debugger/tst_simple_debug/test.py7
-rw-r--r--tests/system/suite_editors/tst_memberoperator/test.py6
-rw-r--r--tests/system/suite_general/tst_build_speedcrunch/test.py2
-rw-r--r--tests/system/suite_general/tst_openqt_creator/test.py2
-rw-r--r--tests/system/suite_general/tst_session_handling/test.py3
-rw-r--r--tests/system/suite_tools/tst_git_local/test.py8
-rw-r--r--tests/unit/unittest/clangasyncjob-base.cpp1
-rw-r--r--tests/unit/unittest/clangdocumentsuspenderresumer-test.cpp295
-rw-r--r--tests/unit/unittest/clangjobqueue-test.cpp46
-rw-r--r--tests/unit/unittest/clangresumedocumentjob-test.cpp92
-rw-r--r--tests/unit/unittest/clangsuspenddocumentjob-test.cpp73
-rw-r--r--tests/unit/unittest/data/empty1.cpp0
-rw-r--r--tests/unit/unittest/data/empty2.cpp0
-rw-r--r--tests/unit/unittest/data/empty3.cpp0
-rw-r--r--tests/unit/unittest/data/highlightingmarks.cpp3
-rw-r--r--tests/unit/unittest/highlightingmarks-test.cpp28
-rw-r--r--tests/unit/unittest/matchingtext-test.cpp7
-rw-r--r--tests/unit/unittest/unittest.pro3
209 files changed, 4992 insertions, 2409 deletions
diff --git a/.gitignore b/.gitignore
index 335868cd0f..47924d6b97 100644
--- a/.gitignore
+++ b/.gitignore
@@ -111,6 +111,7 @@ phony.c
/dist/gdb/qtcreator-*/
/dist/gdb/source/
/dist/gdb/staging/
+/doc/qbs/
/doc/qtcreator/
/doc/qtcreator-dev/
/doc/pluginhowto/html/
diff --git a/doc/images/qmldesigner-new-project.png b/doc/images/qmldesigner-new-project.png
index 59e17f2449..10480502f9 100644
--- a/doc/images/qmldesigner-new-project.png
+++ b/doc/images/qmldesigner-new-project.png
Binary files differ
diff --git a/doc/images/qtcreator-add-resource-wizard.png b/doc/images/qtcreator-add-resource-wizard.png
index e9f8d7bfd1..921ef724bb 100644
--- a/doc/images/qtcreator-add-resource-wizard.png
+++ b/doc/images/qtcreator-add-resource-wizard.png
Binary files differ
diff --git a/doc/images/qtcreator-android-run-settings.png b/doc/images/qtcreator-android-run-settings.png
new file mode 100644
index 0000000000..2ed8b065c5
--- /dev/null
+++ b/doc/images/qtcreator-android-run-settings.png
Binary files differ
diff --git a/doc/images/qtcreator-build-dependencies.png b/doc/images/qtcreator-build-dependencies.png
index 62db9b21ac..b67341f94f 100644
--- a/doc/images/qtcreator-build-dependencies.png
+++ b/doc/images/qtcreator-build-dependencies.png
Binary files differ
diff --git a/doc/images/qtcreator-custom-project-wizards.png b/doc/images/qtcreator-custom-project-wizards.png
index 581322b37a..43a0d0b6be 100644
--- a/doc/images/qtcreator-custom-project-wizards.png
+++ b/doc/images/qtcreator-custom-project-wizards.png
Binary files differ
diff --git a/doc/images/qtcreator-custom-wizard.png b/doc/images/qtcreator-custom-wizard.png
index 9155866e41..3f03954511 100644
--- a/doc/images/qtcreator-custom-wizard.png
+++ b/doc/images/qtcreator-custom-wizard.png
Binary files differ
diff --git a/doc/images/qtcreator-editor-settings.png b/doc/images/qtcreator-editor-settings.png
index 583af66502..81b4af6a39 100644
--- a/doc/images/qtcreator-editor-settings.png
+++ b/doc/images/qtcreator-editor-settings.png
Binary files differ
diff --git a/doc/images/qtcreator-ios-preferences.png b/doc/images/qtcreator-ios-preferences.png
new file mode 100644
index 0000000000..b6ad26f268
--- /dev/null
+++ b/doc/images/qtcreator-ios-preferences.png
Binary files differ
diff --git a/doc/images/qtcreator-ios-simulator-deploy.png b/doc/images/qtcreator-ios-simulator-deploy.png
new file mode 100644
index 0000000000..e2fc146a39
--- /dev/null
+++ b/doc/images/qtcreator-ios-simulator-deploy.png
Binary files differ
diff --git a/doc/images/qtcreator-kits.png b/doc/images/qtcreator-kits.png
index 0eaf814d07..2d9a312364 100644
--- a/doc/images/qtcreator-kits.png
+++ b/doc/images/qtcreator-kits.png
Binary files differ
diff --git a/doc/images/qtcreator-new-opengl-file.png b/doc/images/qtcreator-new-opengl-file.png
index 3e64d1fff5..0e35bf7e14 100644
--- a/doc/images/qtcreator-new-opengl-file.png
+++ b/doc/images/qtcreator-new-opengl-file.png
Binary files differ
diff --git a/doc/images/qtcreator-new-qt-gui-application.png b/doc/images/qtcreator-new-qt-gui-application.png
index 54c807bb9f..62895ef9d1 100644
--- a/doc/images/qtcreator-new-qt-gui-application.png
+++ b/doc/images/qtcreator-new-qt-gui-application.png
Binary files differ
diff --git a/doc/images/qtcreator-new-qt-quick-project-wizard.png b/doc/images/qtcreator-new-qt-quick-project-wizard.png
index 35aebe6a16..5b518dc225 100644
--- a/doc/images/qtcreator-new-qt-quick-project-wizard.png
+++ b/doc/images/qtcreator-new-qt-quick-project-wizard.png
Binary files differ
diff --git a/doc/images/qtcreator-options-code-style-qml.png b/doc/images/qtcreator-options-code-style-qml.png
index 538155eb7b..7755be5581 100644
--- a/doc/images/qtcreator-options-code-style-qml.png
+++ b/doc/images/qtcreator-options-code-style-qml.png
Binary files differ
diff --git a/doc/src/android/androiddev.qdoc b/doc/src/android/androiddev.qdoc
index 5d57ce1beb..34cf3f7d6a 100644
--- a/doc/src/android/androiddev.qdoc
+++ b/doc/src/android/androiddev.qdoc
@@ -57,16 +57,14 @@
\li \l{http://www.oracle.com/technetwork/java/javase/downloads/index.html}
{Java SE Development Kit (JDK)} version 6, or later
- \li A build tool for building application packages for Android devices:
+ \li \l{http://www.gradle.org}{Gradle} for building application packages
+ for Android devices (APK). Gradle is delivered with Qt 5.9, and
+ later.
- \list
-
- \li \l{http://ant.apache.org/bindownload.cgi}{Apache Ant} 1.8.0,
- or later
-
- \li \l{http://www.gradle.org}{Gradle}
-
- \endlist
+ \note Using Ant to build APKs is still possible when developing with
+ Qt 5.8 or earlier together with Android SDK tools versions 25.2.5 or
+ earlier, but Ant support has been deprecated since \QC 4.3 and will
+ be removed in a future version.
\li A tool chain for building applications for Android devices provided
by the \l{http://developer.android.com/tools/sdk/ndk/index.html}
@@ -74,20 +72,10 @@
\li \l{http://developer.android.com/sdk/index.html}{Android SDK Tools}
- After installing the Tools, update the Android SDK to get the API
- and tools packages required for development. You can use the
- \l{http://developer.android.com/tools/help/android.html}{android}
- tool that comes with the SDK Tools package. For example, on Ubuntu
- the following command starts the SDK update:
-
- \code
- ./android update sdk
- \endcode
-
- \note The android tool is deprecated since SDK tools version 25.3.0.
- Consider using
+ After installing the Tools, you can use the
\l{https://developer.android.com/studio/command-line/sdkmanager.html}
- {sdkmanager} instead.
+ {sdkmanager} to get the API and tools packages required for
+ development.
\li On Windows, you also need the following:
@@ -108,33 +96,17 @@
\endlist
- \section1 Selecting the APK Build Tool
-
- On Android, applications are distributed in specially structured type of ZIP
- packages called APK. You can use either Ant or Gradle to build APKs. Using
- Gradle has the following benefits:
-
- \list
-
- \li It is 25 to 50 percent faster than Ant when rebuilding packages.
-
- \li It is delivered with Qt 5.9.
-
- \li It supports easily adding Android Extras libraries, such as
- Google Play services or Android extension files (.obb) to your
- project.
-
- \endlist
-
- \note Android SDK tools version 25.3.0 onwards do not contain Ant scripts
- anymore. Therefore, Gradle builds are forced and you must use Qt 5.9 or
- later when using these tools versions.
-
\section1 Setting Up the Development Environment
You must download and install the latest Android NDK and SDK, and update the
- SDK to get the API and tools packages needed for development. In addition,
- you must install Qt for Android as part of Qt 5.2, or later.
+ SDK to get the build and platform tools needed for development. Since
+ SDK tools version 25.3.0, \QC, you must use the
+ \l{https://developer.android.com/studio/command-line/sdkmanager.html}
+ {sdkmanager} command line tool for SDK package management and the
+ \l{https://developer.android.com/studio/command-line/avdmanager.html}
+ {avdmanager} tool for Android Virtual Device (AVD) management.
+
+ In addition, you must install Qt for Android as part of Qt 5.2, or later.
For more information, see \l{Qt for Android}.
@@ -165,6 +137,9 @@
\li To use Ant, add the path to the Ant executable in the
\uicontrol {Ant executable} field.
+ \note Ant support has been deprecated since \QC 4.3. We
+ recommend that you use Gradle instead.
+
\endlist
\li Select \uicontrol File > \uicontrol {New File or Project} > \uicontrol Application >
@@ -213,7 +188,7 @@
\image qtcreator-android-select-devices.png "Select Android Devices dialog"
- Android Virtual Devices (AVD) are also listed. To create new AVDs, select
+ AVDs are also listed. To create new AVDs, select
\uicontrol {Create Android Virtual Device}.
To set a device as the default device for a particular Android architecture,
diff --git a/doc/src/android/creator-projects-settings-run-android.qdocinc b/doc/src/android/creator-projects-settings-run-android.qdocinc
new file mode 100644
index 0000000000..fa3deeb907
--- /dev/null
+++ b/doc/src/android/creator-projects-settings-run-android.qdocinc
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Creator documentation.
+**
+** 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 Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+**
+****************************************************************************/
+
+/*!
+//! [run settings android]
+
+ \section1 Specifying Run Settings for Android Devices
+
+ To run and debug an application on an Android device, you must create
+ connections from the development host to the device, as instructed in
+ \l {Connecting Android Devices}.
+
+ A default set of Android Activity manager (am) start options is applied when
+ starting applications. You can specify additional start options in the
+ \uicontrol {Activity manager start options} field. However, if the default
+ options conflict with the added options, the application might not start.
+
+ For example, to run the application as a particular user, enter the start
+ option \c {--user 10}, where \c 10 is the user ID of the user account.
+
+ \image qtcreator-android-run-settings.png
+
+ You can specify shell commands to run before the application is started and
+ after it is quit. For example, enter the following commands to unlock the
+ screen and to switch to the user account \c 10 on the device before running
+ the application:
+
+ \code
+ input keyevent 82
+ am switch-user 10
+ \endcode
+
+ Enter the following commands to switch back to the default user, \c 0, and
+ to unlock the screen after the application is quit:
+
+ \code
+ am switch-user 0
+ input keyevent 82
+ \endcode
+
+//! [run settings android]
+*/
diff --git a/doc/src/android/deploying-android.qdoc b/doc/src/android/deploying-android.qdoc
index 0bbd71f379..cf9018ce31 100644
--- a/doc/src/android/deploying-android.qdoc
+++ b/doc/src/android/deploying-android.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -55,6 +55,9 @@
To specify settings for application packages, select \uicontrol Projects >
\uicontrol {Build Android APK} > \uicontrol Details.
+ For more information about options that you have for running applications,
+ see \l {Specifying Run Settings for Android Devices}.
+
\section1 Creating Distributable APK Packages
To copy Qt libraries and files to the project directory and to bundle them
@@ -128,8 +131,9 @@
\endlist
- The Gradle wrappers and scripts are bundled only if you use
- \l{Selecting the APK Build Tool}{Gradle} to build the application packages.
+ The Gradle wrappers and scripts are bundled only if you use Gradle to build
+ the application packages. For more information, see
+ \l{Connecting Android Devices}.
To view the packages that the \c androiddeployqt tool created, select the
\uicontrol {Open package location after build} check box.
diff --git a/doc/src/debugger/qtquick-debugging.qdoc b/doc/src/debugger/qtquick-debugging.qdoc
index 003429dc5b..53578482d8 100644
--- a/doc/src/debugger/qtquick-debugging.qdoc
+++ b/doc/src/debugger/qtquick-debugging.qdoc
@@ -37,7 +37,7 @@
\title Debugging Qt Quick Projects
- \note You need Qt 4.8 or later to debug Qt Quick projects.
+ \note You need Qt 5.0 or later to debug Qt Quick projects.
For an example of how to debug Qt Quick Projects, see
\l{Debugging a Qt Quick Example Application}.
@@ -55,17 +55,14 @@
\list 1
- \li Debugging is enabled by default for Qt 4.8, or later. For Qt 4.7,
- select \uicontrol Projects, and then select the
- \uicontrol {Enable QML debugging and profiling} check box in the \uicontrol qmake
- section in \uicontrol {Build Steps}.
+ \li Debugging is enabled by default for Qt 5.0, or later.
You might have to compile the library first, by selecting the
\uicontrol Compile link.
\image qml-link-debugging-library.png "Build Steps"
- \note Debugging requires opening a socket at a well-known port,
+ \note Debugging requires opening a socket at a TCP port,
which presents a security risk. Anyone on the Internet could connect
to the application that you are debugging and execute any JavaScript
functions. Therefore, you must make sure that the port is properly
@@ -78,7 +75,7 @@
\li Select \uicontrol {Build > Rebuild Project} to clean and rebuild the
project.
- \li To debug applications on devices, check that Qt 4.7.4, or later,
+ \li To debug applications on devices, check that Qt 5.0, or later,
libraries are installed on the device and
\l{Running on Multiple Platforms}{select the corresponding kit for the device}
before you start debugging.
@@ -107,9 +104,8 @@
\li Execute JavaScript expressions to get information about the state of
the application
- \li Change QML code and immediately see the changes at runtime
-
- \li Inspect QML code and change it temporarily at runtime
+ \li Inspect QML properties and JavaScript variables and change them
+ temporarily at runtime
\endlist
@@ -121,13 +117,8 @@
parameters (if you build the application with \QC, it automatically
uses the correct configuration):
- \list
-
- \li Qt Quick 1: \c {CONFIG+=declarative_debug}
-
- \li Qt Quick 2: \c {CONFIG+=qml_debug}
+ \c {CONFIG+=qml_debug}
- \endlist
\li Start the application with the following arguments:
@@ -210,7 +201,7 @@
\section1 Inspecting User Interfaces
When you debug complex applications, you can jump to the position in code
- where an item is defined or you can zoom into the user interface.
+ where an item is defined.
In the selection mode, you can click items in the running
application to jump to their definitions in the code. The properties of the
@@ -222,18 +213,8 @@
You can also view the item hierarchy in the running application:
- \list
-
- \li When debugging Qt Quick 1 applications, right-click an item in the
- running application to view the item hierarchy as a context menu.
-
- \image qml-observer-context-menu.png "QML item hierarchy"
-
- \li When debugging Qt Quick 2 applications, double-click an item in the
- running application to cycle through the item stack at the cursor
- position.
-
- \endlist
+ Double-click an item in the running application to cycle through the item
+ stack at the cursor position.
To switch out of the selection mode, toggle the \uicontrol Select menu item.
diff --git a/doc/src/editors/creator-editors.qdoc b/doc/src/editors/creator-editors.qdoc
index 1c040afe5a..8e49e9665a 100644
--- a/doc/src/editors/creator-editors.qdoc
+++ b/doc/src/editors/creator-editors.qdoc
@@ -233,7 +233,7 @@
in Windows. To check JSON data structure, copy the JSON schema file to the
above folder.
- \section1 Checking JavaScript and QML Syntax
+ \section2 Checking JavaScript and QML Syntax
To run the checks, select \uicontrol Tools > \uicontrol {QML/JS} >
\uicontrol {Run Checks} or press \key {Ctrl+Shift+C}. The results are shown
@@ -241,7 +241,7 @@
pane.
- \section1 List of JavaScript and QML Checks
+ \section2 List of JavaScript and QML Checks
Many of the JavaScript checks are similar to the ones in Douglas Crockford's
\l{http://www.jslint.com}{JSLint} tool.
@@ -811,6 +811,12 @@
To inspect QML and JavaScript properties, methods, and enums, move the
cursor over them and select \uicontrol Tools > \uicontrol {QML/JS} >
\uicontrol {Inspect API for Element Under Cursor}.
+
+ \section1 Automatically Formatting QML/JS Files
+
+ To automatically format QML/JS files upon saving, select \uicontrol Tools >
+ \uicontrol Options > \uicontrol {Qt Quick} > \uicontrol {QML/JS Editing} >
+ \uicontrol {Enable auto format on file save}.
*/
diff --git a/doc/src/ios/creator-ios-dev.qdoc b/doc/src/ios/creator-ios-dev.qdoc
index 4f97e3d804..d3678c0d1c 100644
--- a/doc/src/ios/creator-ios-dev.qdoc
+++ b/doc/src/ios/creator-ios-dev.qdoc
@@ -148,20 +148,62 @@
For more information, see \l{Expressing Supported iOS Versions}.
- \section1 Testing on iOS Simulator
+ \section1 Testing on Simulator
If you do not have an iOS device or you do not want to create an account,
you can test applications on
\l{http://developer.apple.com/library/ios/documentation/IDEs/Conceptual/iOS_Simulator_Guide/Introduction/Introduction.html}
- {iOS Simulator}, which is installed as part of Xcode. Each Xcode version
+ {Simulator}, which is installed as part of Xcode. Each Xcode version
simulates a predefined set of hardware devices and software versions.
You can change the simulated hardware and software version in the run
settings for the project. Select \uicontrol Projects > \uicontrol Run, and then select
the device to simulate in the \uicontrol {Device type} field.
- \QC uses the Xcode version set as current on the Mac computer.
- To check the version, enter the following command:
+ \image qtcreator-ios-simulator-deploy.png
+
+ The simulator is started automatically when you run the application.
+ To start the simulator manually, select \uicontrol Preferences >
+ \uicontrol Devices > \uicontrol iOS > \uicontrol Start.
+
+ To take screenshots of the simulator, select \uicontrol Preferences >
+ \uicontrol Devices > \uicontrol iOS > \uicontrol Screenshot. The screenshots
+ are stored in the directory specified in the
+ \uicontrol {Screenshot directory} field.
+
+ \section2 Managing Simulators
+
+ The available simulators are listed in \uicontrol Preferences >
+ \uicontrol Devices > \uicontrol iOS.
+
+ \image qtcreator-ios-preferences.png
+
+ To create a new simulator instance:
+
+ \list
+
+ \li Select \uicontrol Create.
+
+ \li In the \uicontrol {Device type} field, select the device type from
+ a list of devices supported by the Xcode version set as current on
+ the Mac computer.
+
+ \li In the \uicontrol {OS version} field, select an OS version from a
+ list of OS versions supported by the selected device and the current
+ Xcode version.
+
+ \endlist
+
+ To rename the selected simulator, select \uicontrol Rename.
+
+ To reset the contents and settings of the selected simulators, select
+ \uicontrol Reset.
+
+ To delete the selected simulator, select \uicontrol Delete.
+
+ \section2 Checking Current Xcode Version
+
+ To check the current Xcode version, enter the following command:
\c {xcode-select --print-path}
diff --git a/doc/src/linux-mobile/creator-projects-settings-run-b2qt.qdocinc b/doc/src/linux-mobile/creator-projects-settings-run-b2qt.qdocinc
index bbbe220a1d..ea34ff83de 100644
--- a/doc/src/linux-mobile/creator-projects-settings-run-b2qt.qdocinc
+++ b/doc/src/linux-mobile/creator-projects-settings-run-b2qt.qdocinc
@@ -26,7 +26,7 @@
/*!
//! [run settings embedded]
- \section2 Specifying Run Settings for Embedded Devices
+ \section1 Specifying Run Settings for Embedded Devices
To run and debug an application on an embedded device (commercial only), you
must create connections from the development host to the device and add the
diff --git a/doc/src/linux-mobile/creator-projects-settings-run-linux.qdocinc b/doc/src/linux-mobile/creator-projects-settings-run-linux.qdocinc
index 968cb881ee..5ae14681fb 100644
--- a/doc/src/linux-mobile/creator-projects-settings-run-linux.qdocinc
+++ b/doc/src/linux-mobile/creator-projects-settings-run-linux.qdocinc
@@ -26,7 +26,7 @@
/*!
//! [run settings linux]
- \section2 Specifying Run Settings for Linux-Based Devices
+ \section1 Specifying Run Settings for Linux-Based Devices
To run and debug an application on a Linux-based device,
you must create connections from the development
diff --git a/doc/src/projects/creator-projects-custom-wizards-xml.qdoc b/doc/src/projects/creator-projects-custom-wizards-xml.qdoc
index 787a90fd32..2cb3244e74 100644
--- a/doc/src/projects/creator-projects-custom-wizards-xml.qdoc
+++ b/doc/src/projects/creator-projects-custom-wizards-xml.qdoc
@@ -41,29 +41,16 @@
{JSON-Based wizards} instead. XML wizards are deprecated and support for
them will be removed in future versions of \QC.
- To display the XML-based example wizards in \QC, rename
- \c {wizard_sample.xml} as \c {wizard.xml} in the
- \c {\share\qtcreator\templates\wizards\helloworld} and
- \c {\share\qtcreator\templates\wizards\listmodel} folders. After
- you restart \QC, the \uicontrol {Custom Classes}
- and \uicontrol {Custom Projects} categories (1) appear in the \uicontrol New
- dialog. For each category, an icon (2), a display name (3), and a
- description (4) are displayed.
-
- \image qtcreator-custom-project-wizards.png "The New dialog with custom projects and classes"
-
- Files can be generated by using either \l{Processing Template Files}
- {templates} or \l{Using Generator Scripts}{generator scripts}, where a
- script is called to create the files.
-
- \note The generator option mainly exists to accommodate existing generator
- scripts or cases where complicated algorithmic logic is required when
- generating files. Writing cross-platform scripts is inherently difficult,
- and therefore, it is not recommended for new wizards.
+ To see examples of XML-based wizards, select \uicontrol File >
+ \uicontrol {New File or Project} > \uicontrol Library. For each wizard, an
+ icon (1), a display name (2), and a description (3) are displayed.
+
+ \image qtcreator-custom-project-wizards.png "The New dialog"
+
+ Files can be generated by using \l{Processing Template Files}{templates}.
XML-based wizard template directories contain an XML configuration file
- called wizard.xml, the template source files, and optionally, the generator
- script.
+ called wizard.xml and the template source files.
\section1 Creating XML-Based Project Wizards
@@ -71,10 +58,11 @@
\list 1
- \li Make a copy of the \c {share/qtcreator/templates/wizards/helloworld}
- or \c {share/qtcreator/templates/wizards/listmodel} folder.
+ \li Make a copy of a folder in the \c share/qtcreator/templates/wizards/
+ folder that contains an XML-based wizard (\c codesnippet,
+ \c qtcreatorplugin, or \c qtquick2-extension).
- \li Modify the wizard_example.xml file.
+ \li Modify the wizard.xml file.
\li The following code determines the type of the wizard and its place
in the \uicontrol New dialog:
@@ -89,8 +77,7 @@
\list
- \li \c version is the version of the file contents. Do not modify
- this value.
+ \li \c version is the version of the file contents.
\li \c kind specifies the type of the wizard: \c project or
\c class.
@@ -146,12 +133,7 @@
\endlist
- \li Files to be added to the project:
-
- \list
-
- \li Template-based: The following code specifies the files to add to
- the project:
+ \li The following code specifies the files to add to the project:
\code
<files>
<file source="main.cpp" openeditor="true" />
@@ -183,41 +165,6 @@
See also \l{Processing Template Files}.
- \li Generator-script: The following code specifies that the script
- \c generate.pl is to be used to create the files:
-
- \code
- <generatorscript binary="generate.pl">
- <argument value="--class-name=%ClassName%"/>
- <argument value="--project-name=%ProjectName%"/>
- <argument value="--header-suffix=%CppHeaderSuffix%" omit-empty="true"/>
- <argument value="--source-suffix=%CppSourceSuffix%" omit-empty="true"/>
- <argument value="--description=%Description%" omit-empty="true" write-file="true"/>
- </generatorscript>
- \endcode
-
- In each argument, the field placeholders are replaced by the
- field values. There are additional boolean attributes which give
- fine-grained control:
-
- \list
-
- \li \c omit-empty specifies that complete argument is to be
- omitted when all placeholders expand to empty values. In
- the above example, the option \c --source-suffix will
- not be passed to the script if the value is empty.
-
- \li \c write-file indicates that instead of the expanded
- value, the value will be written to a temporary file and
- its file name will be passed to the script instead. This
- is useful for multi-line text fields.
-
- \endlist
-
- See also \l{Using Generator Scripts}.
-
- \endlist
-
\li The following code creates a page that specifies settings for the project:
\code
@@ -600,50 +547,4 @@
of the base class. If the validation fails, a red label displaying the
message appears at the bottom of the wizard page.
- \section1 Using Generator Scripts
-
- The values entered in the wizard page are passed to the script
- as command line arguments as defined by the wizard configuration file.
-
- In addition, the script must implement a \c{--dry-run} command line option.
-
- \QC needs to know the file names before the files are created to check
- whether files with identical names already exist, for example. Therefore,
- script file generation is a two-step process:
-
- \list 1
-
- \li Determine file names and attributes: The script is called with the
- command line \c{--dry-run} option and the field values. It then prints
- the relative path names of the files it intends to create, followed by
- comma-separated attributes matching those of the \c{<file>} element, for
- example:
-
- \code
- myclass.cpp,openeditor
- myclass.h,openeditor
- myproject.pro,openproject
- \endcode
-
- \li Create files: The script is called with the parameters only in the
- working directory. It then actually creates the files. If directories
- are needed, the script should create them, too.
-
- \endlist
-
- The \c{scriptgeneratedproject} sample wizard illustrates the usage.
- A typical script invocation for this example (obtained by running \QC with
- \c{--customwizard-verbose}) looks as follows:
-
- \code
- generate.pl --class-name=TestClass --project-name=TestProject --header-suffix=h --source-suffix=cpp --description=/tmp/qtcreatorj26629.txt
- \endcode
-
- By default, the scripts are run in the directory corresponding to
- \c %TargetPath%. This can be overridden by specifying the attribute
- \c workingdirectory on the element \c generatorscript. For example, if the
- script creates the project directory by itself, %Path% can be specified. In
- that case, \c --dry-run should output the correct relative paths or absolute
- paths constructed using the value of \c %Path%.
-
*/
diff --git a/doc/src/projects/creator-projects-settings-code-style.qdoc b/doc/src/projects/creator-projects-settings-code-style.qdoc
index e2665f8540..8479124a00 100644
--- a/doc/src/projects/creator-projects-settings-code-style.qdoc
+++ b/doc/src/projects/creator-projects-settings-code-style.qdoc
@@ -58,9 +58,11 @@
\list 1
- \li Select \uicontrol Projects > \uicontrol {Code Style}.
+ \li Select \uicontrol Projects > \uicontrol {Project Settings} >
+ \uicontrol {Code Style}.
- \li In the \uicontrol Language field, select \uicontrol C++ or \uicontrol {Qt Quick}.
+ \li In the \uicontrol Language field, select \uicontrol C++,
+ \uicontrol {Qt Quick}, or \uicontrol Nim.
\li In the \uicontrol {Current settings} field, select the settings to modify
and click \uicontrol Copy.
diff --git a/doc/src/projects/creator-projects-settings-dependencies.qdoc b/doc/src/projects/creator-projects-settings-dependencies.qdoc
index d1c9b20b50..51c2c7f0a4 100644
--- a/doc/src/projects/creator-projects-settings-dependencies.qdoc
+++ b/doc/src/projects/creator-projects-settings-dependencies.qdoc
@@ -51,9 +51,8 @@
\list 1
- \li In \uicontrol Projects, select a project.
-
- \li Click \uicontrol Dependencies.
+ \li Select \uicontrol Projects > \uicontrol {Project Settings} >
+ \uicontrol Dependencies.
\li Select projects that must be built before the current project is
built.
diff --git a/doc/src/projects/creator-projects-settings-editor.qdoc b/doc/src/projects/creator-projects-settings-editor.qdoc
index c2b8a108bd..c3ea91b00d 100644
--- a/doc/src/projects/creator-projects-settings-editor.qdoc
+++ b/doc/src/projects/creator-projects-settings-editor.qdoc
@@ -50,7 +50,8 @@
\list 1
- \li Select \uicontrol Projects > \uicontrol Editor.
+ \li Select \uicontrol Projects > \uicontrol {Project Settings} >
+ \uicontrol Editor.
\li In the \uicontrol {Editor settings} field, select \uicontrol {Custom}.
diff --git a/doc/src/projects/creator-projects-settings-run-analyze.qdocinc b/doc/src/projects/creator-projects-settings-run-analyze.qdocinc
index 00cd86828b..f802f89f0d 100644
--- a/doc/src/projects/creator-projects-settings-run-analyze.qdocinc
+++ b/doc/src/projects/creator-projects-settings-run-analyze.qdocinc
@@ -26,7 +26,7 @@
/*!
//! [settings valgrind]
- \section2 Specifying Valgrind Settings
+ \section1 Specifying Valgrind Settings
\QC integrates \l{Analyzing Code}{Valgrind code analysis tools} for
detecting memory leaks and profiling function execution. You can configure
diff --git a/doc/src/projects/creator-projects-settings-run-debug.qdocinc b/doc/src/projects/creator-projects-settings-run-debug.qdocinc
index 191cdf0b48..ef3389e27d 100644
--- a/doc/src/projects/creator-projects-settings-run-debug.qdocinc
+++ b/doc/src/projects/creator-projects-settings-run-debug.qdocinc
@@ -26,7 +26,7 @@
/*!
//! [run settings debugger]
- \section2 Specifying Debugger Settings
+ \section1 Specifying Debugger Settings
\image qtquick-debugging-settings.png "Debugger Settings"
diff --git a/doc/src/projects/creator-projects-settings-run-desktop.qdocinc b/doc/src/projects/creator-projects-settings-run-desktop.qdocinc
index b1c9a00d77..c9c2ef06db 100644
--- a/doc/src/projects/creator-projects-settings-run-desktop.qdocinc
+++ b/doc/src/projects/creator-projects-settings-run-desktop.qdocinc
@@ -26,7 +26,7 @@
/*!
//! [run settings desktop]
- \section2 Specifying Run Settings for Desktop Device Types
+ \section1 Specifying Run Settings for Desktop Device Types
You can specify command line arguments to be passed to the executable
and the working directory to use. The working directory defaults to
diff --git a/doc/src/projects/creator-projects-settings-run.qdoc b/doc/src/projects/creator-projects-settings-run.qdoc
index 3641596107..36a2f4307d 100644
--- a/doc/src/projects/creator-projects-settings-run.qdoc
+++ b/doc/src/projects/creator-projects-settings-run.qdoc
@@ -53,7 +53,7 @@
\QC automatically adds run configurations for all targets specified in the
CMake project file, \c {CMakeLists.txt}.
- \section2 Creating Run Configurations for Subprojects
+ \section1 Creating Run Configurations for Subprojects
To prevent \QC from automatically creating run configurations for SUBDIRS
projects, specify the following variable in the .pro file of the SUBDIRS
@@ -65,6 +65,7 @@
\include projects/creator-projects-settings-run-desktop.qdocinc run settings desktop
\include projects/creator-projects-settings-run-analyze.qdocinc settings valgrind
\include projects/creator-projects-settings-run-debug.qdocinc run settings debugger
+ \include android/creator-projects-settings-run-android.qdocinc run settings android
\include linux-mobile/creator-projects-settings-run-linux.qdocinc run settings linux
\include qnx/creator-projects-settings-run-qnx.qdocinc run settings qnx
\include linux-mobile/creator-projects-settings-run-b2qt.qdocinc run settings embedded
diff --git a/doc/src/projects/creator-projects-targets.qdoc b/doc/src/projects/creator-projects-targets.qdoc
index e3366e8489..dace3e18a4 100644
--- a/doc/src/projects/creator-projects-targets.qdoc
+++ b/doc/src/projects/creator-projects-targets.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -107,6 +107,9 @@
add debuggers to the list. For more information, see
\l{Adding Debuggers}.
+ For Android kits, the \uicontrol {Android GDB server} field will
+ display the path to GDB server executable.
+
\li In the \uicontrol {Qt version} field, select the Qt version to use for
building the project. You can add Qt versions to the list if they
are installed on the development PC, but were not detected
@@ -137,6 +140,10 @@
\uicontrol Change to edit the variables of the CMake configuration
for the kit.
+ \li In the \uicontrol {Additional Qbs profile settings} field, select
+ \uicontrol Change to add settings to Qbs build profiles. For more
+ information, see \l {Editing Build Profiles}.
+
\endlist
\QC uses the \e {default kit} if it does not have enough information to
diff --git a/doc/src/qnx/creator-projects-settings-run-qnx.qdocinc b/doc/src/qnx/creator-projects-settings-run-qnx.qdocinc
index ea832dbc6e..b86eed55f8 100644
--- a/doc/src/qnx/creator-projects-settings-run-qnx.qdocinc
+++ b/doc/src/qnx/creator-projects-settings-run-qnx.qdocinc
@@ -26,7 +26,7 @@
/*!
//! [run settings qnx]
- \section2 Specifying Run Settings for QNX Devices
+ \section1 Specifying Run Settings for QNX Devices
To run and debug an application on a QNX device, you must
create connections from the development PC to the device. Click
diff --git a/doc/src/qtquick/qtquick-toolbars.qdoc b/doc/src/qtquick/qtquick-toolbars.qdoc
index 54fd768646..d4943517c7 100644
--- a/doc/src/qtquick/qtquick-toolbars.qdoc
+++ b/doc/src/qtquick/qtquick-toolbars.qdoc
@@ -42,14 +42,13 @@
. Select the icon to open the toolbar.
To open toolbars immediately when you select a QML type, select
- \uicontrol{Tools > Options > Qt Quick > Qt Quick Toolbar > Always show Qt Quick
- Toolbar}.
+ \uicontrol Tools > \uicontrol Options > \uicontrol {Qt Quick} >
+ \uicontrol {QML/JS Editing} > \uicontrol {Always show Qt Quick Toolbar}.
Drag the toolbar to pin it to another location. Select
\inlineimage qml-toolbar-pin.png
to unpin the toolbar and move it to its default location. To pin toolbars
- by default, select \uicontrol{Tools > Options > Qt Quick > Qt Quick Toolbar
- > Pin Quick Toolbar}.
+ by default, select \uicontrol {Pin Quick Toolbar}.
\section1 Previewing Images
diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py
index feaebb9b6a..8514cb64ca 100644
--- a/share/qtcreator/debugger/gdbbridge.py
+++ b/share/qtcreator/debugger/gdbbridge.py
@@ -741,7 +741,7 @@ class Dumper(DumperBase):
typeName = "'" + typeName + "'"
# 'class' is needed, see http://sourceware.org/bugzilla/show_bug.cgi?id=11912
#exp = '((class %s*)%s)->%s(%s)' % (typeName, value.laddress, function, arg)
- addr = value.laddress
+ addr = value.address()
if addr is None:
addr = self.pokeValue(value)
#warn('PTR: %s -> %s(%s)' % (value, function, addr))
@@ -750,7 +750,7 @@ class Dumper(DumperBase):
result = gdb.parse_and_eval(exp)
#warn(' -> %s' % result)
res = self.fromNativeValue(result)
- if value.laddress is None:
+ if value.address() is None:
self.releaseValue(addr)
return res
@@ -1056,7 +1056,7 @@ class Dumper(DumperBase):
typeName = typeName[0:pos]
if typeName in self.qqEditable and not simpleType:
#self.qqEditable[typeName](self, expr, value)
- expr = gdb.parse_and_eval(expr)
+ expr = self.parseAndEvaluate(expr)
self.qqEditable[typeName](self, expr, value)
else:
cmd = 'set variable (%s)=%s' % (expr, value)
diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py
index edf63044eb..800def2498 100644
--- a/share/qtcreator/debugger/lldbbridge.py
+++ b/share/qtcreator/debugger/lldbbridge.py
@@ -1558,7 +1558,8 @@ class Dumper(DumperBase):
self.target.BreakpointDelete(bp.GetID())
res = frame.SetPC(loc.GetLoadAddress())
status = 'Jumped.' if res else 'Cannot jump.'
- self.reportResult(self.describeStatus(status) + self.describeLocation(frame), args)
+ self.report(self.describeLocation(frame))
+ self.reportResult(self.describeStatus(status), args)
def breakList(self):
result = lldb.SBCommandReturnObject()
diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py
index 7028e3200a..3bcd9afb77 100644
--- a/share/qtcreator/debugger/qttypes.py
+++ b/share/qtcreator/debugger/qttypes.py
@@ -46,6 +46,11 @@ def qform__QByteArray():
return [Latin1StringFormat, SeparateLatin1StringFormat,
Utf8StringFormat, SeparateUtf8StringFormat ]
+def qedit__QByteArray(d, value, data):
+ d.call('void', value, 'resize', str(len(data)))
+ (base, size, alloc) = d.stringData(value)
+ d.setValues(base, 'char', [ord(c) for c in data])
+
def qdump__QByteArray(d, value):
data, size, alloc = d.byteArrayData(value)
d.check(alloc == 0 or (0 <= size and size <= alloc and alloc <= 100000000))
@@ -1776,17 +1781,9 @@ def qdump__QVariant(d, value):
def qedit__QVector(d, value, data):
values = data.split(',')
- size = len(values)
- d.call('void', value, 'resize', str(size))
- innerType = value.type[0]
- try:
- # Qt 5. Will fail on Qt 4 due to the missing 'offset' member.
- offset = value['d']['offset']
- base = value['d'].address() + offset
- except:
- # Qt 4.
- base = value['p']['array'].pointer()
- d.setValues(base, innerType, values)
+ d.call('void', value, 'resize', str(len(values)))
+ base, vsize, valloc = d.vectorDataHelper(d.extractPointer(value))
+ d.setValues(base, value.type[0].name, values)
def qform__QVector():
diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py
index cf8b97641e..75b7dbc2b9 100644
--- a/share/qtcreator/debugger/stdtypes.py
+++ b/share/qtcreator/debugger/stdtypes.py
@@ -46,6 +46,7 @@ def qdump__std__complex(d, value):
innerType = value.type[0]
(real, imag) = value.split('{%s}{%s}' % (innerType.name, innerType.name))
d.putValue("(%s, %s)" % (real.display(), imag.display()))
+ d.putNumChild(2)
if d.isExpanded():
with Children(d, 2, childType=innerType):
d.putSubItem("real", real)
@@ -887,10 +888,10 @@ def qedit__std__vector(d, value, data):
import gdb
values = data.split(',')
n = len(values)
- innerType = value.type[0]
+ innerType = value.type[0].name
cmd = "set $d = (%s*)calloc(sizeof(%s)*%s,1)" % (innerType, innerType, n)
gdb.execute(cmd)
- cmd = "set {void*[3]}%s = {$d, $d+%s, $d+%s}" % (value.address, n, n)
+ cmd = "set {void*[3]}%s = {$d, $d+%s, $d+%s}" % (value.address(), n, n)
gdb.execute(cmd)
cmd = "set (%s[%d])*$d={%s}" % (innerType, n, data)
gdb.execute(cmd)
@@ -975,11 +976,23 @@ def qdump__std____debug__vector(d, value):
def qedit__std__string(d, value, data):
- d.call(value, "assign", '"%s"' % data.replace('"', '\\"'))
+ d.call('void', value, 'assign', '"%s"' % data.replace('"', '\\"'))
def qedit__string(d, expr, value):
qedit__std__string(d, expr, value)
+def qedit__std____cxx11__string(d, expr, value):
+ qedit__std__string(d, expr, value)
+
+def qedit__std__wstring(d, value, data):
+ d.call('void', value, 'assign', 'L"%s"' % data.replace('"', '\\"'))
+
+def qedit__wstring(d, expr, value):
+ qedit__std__wstring(d, expr, value)
+
+def qedit__std____cxx11__wstring(d, expr, value):
+ qedit__std__wstring(d, expr, value)
+
def qdump__string(d, value):
qdump__std__string(d, value)
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/ExtendedFunctionButton.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/ExtendedFunctionButton.qml
index 82178c23a7..492cf2f625 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/ExtendedFunctionButton.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/ExtendedFunctionButton.qml
@@ -130,8 +130,6 @@ Item {
exportMenuItem.enabled = !backendValue.isAttachedProperty()
}
- onAboutToHide: menuLoader.active = false
-
Controls.MenuItem {
text: qsTr("Reset")
onTriggered: {
diff --git a/share/qtcreator/translations/qtcreator_ru.ts b/share/qtcreator/translations/qtcreator_ru.ts
index de410f0609..97fd9c79cd 100644
--- a/share/qtcreator/translations/qtcreator_ru.ts
+++ b/share/qtcreator/translations/qtcreator_ru.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.1" language="ru">
<context>
+ <name>AdbCommandsWidget</name>
+ <message>
+ <source>Widget</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
<name>AddSignalHandlerDialog</name>
<message>
<source>Implement Signal Handler</source>
@@ -786,10 +793,30 @@ Do you want to uninstall the existing package?</source>
</message>
</context>
<context>
- <name>Android::Internal::AndroidRunControl</name>
+ <name>Android::Internal::AndroidRunConfigurationWidget</name>
<message>
- <source>Starting remote process.</source>
- <translation>Запуск внешнего процесса.</translation>
+ <source>Form</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Activity manager start options:</source>
+ <translation>Параметры запуска менеджера действий:</translation>
+ </message>
+ <message>
+ <source>If the &quot;am start&quot; options conflict, the application might not start.</source>
+ <translation>Если есть конфликт параметров для «am start», то приложение может не запуститься.</translation>
+ </message>
+ <message>
+ <source>Shell commands to run on Android device before application launch.</source>
+ <translation>Команды среды запускаемые на устройстве Android до запуска приложения.</translation>
+ </message>
+ <message>
+ <source>Shell commands to run on Android device after application quits.</source>
+ <translation>Команды среды запускаемые на устройстве Android после завершения приложения.</translation>
+ </message>
+ <message>
+ <source>Android run settings</source>
+ <translation>Настройки запуска Android</translation>
</message>
</context>
<context>
@@ -1661,6 +1688,30 @@ Deploying local Qt libraries is incompatible with Android 5.</source>
<source>Perf</source>
<translation>Perf</translation>
</message>
+ <message>
+ <source>XML output recommended as it avoids parsing issues, while plain text is more human readable.
+
+Warning: Plain text output is missing some information (e.g. duration)</source>
+ <translation>Рекомендуется вывод в формате XML, так как исключает проблемы при разборе. Простой же текст более удобен для чтения человеком.
+
+Предупреждение: простой текст не содержит некоторую информацию (например, длительность)</translation>
+ </message>
+ <message>
+ <source>Use XML output</source>
+ <translation>Использовать вывод XML</translation>
+ </message>
+ <message>
+ <source>Verbose benchmarks</source>
+ <translation>Детальные тесты производительности</translation>
+ </message>
+ <message>
+ <source>Log every signal emission and resulting slot invocations.</source>
+ <translation>Логировать каждую генерацию сигналов и соответствующее срабатывание слота.</translation>
+ </message>
+ <message>
+ <source>Log signals and slots</source>
+ <translation>Логировать сигналы и слоты</translation>
+ </message>
</context>
<context>
<name>Autotest::Internal::TestCodeParser</name>
@@ -1766,6 +1817,10 @@ Deploying local Qt libraries is incompatible with Android 5.</source>
<translation>Фильтрация результатов тестирования</translation>
</message>
<message>
+ <source>Switch Between Visual and Text Display</source>
+ <translation>Переключение между визуальным и текстовым отображением</translation>
+ </message>
+ <message>
<source>Test Results</source>
<translation>Результаты тестирования</translation>
</message>
@@ -2293,16 +2348,16 @@ Only desktop kits are supported. Make sure the currently active kit is a desktop
<context>
<name>BareMetal::Internal::BareMetalDebugSupport</name>
<message>
- <source>Debugging failed.</source>
- <translation>Ошибка отладки.</translation>
+ <source>Cannot debug: Kit has no device.</source>
+ <translation>Отладка невозможна: отсутствует устройство в комплекте.</translation>
</message>
<message>
- <source>Initial setup failed: %1</source>
- <translation>Не удалось выполнить начальную настройку: %1</translation>
+ <source>Cannot debug: Local executable is not set.</source>
+ <translation>Отладка невозможна: локальная программа не задана.</translation>
</message>
<message>
- <source>Starting GDB server...</source>
- <translation>Запускается сервер GDB...</translation>
+ <source>Cannot debug: Could not find executable for &quot;%1&quot;.</source>
+ <translation>Отладка невозможна: не удалось найти программу для «%1».</translation>
</message>
</context>
<context>
@@ -2405,25 +2460,6 @@ Only desktop kits are supported. Make sure the currently active kit is a desktop
</message>
</context>
<context>
- <name>BareMetal::Internal::BareMetalRunControlFactory</name>
- <message>
- <source>Cannot debug: Local executable is not set.</source>
- <translation>Отладка невозможна: локальная программа не задана.</translation>
- </message>
- <message>
- <source>Cannot debug: Could not find executable for &quot;%1&quot;.</source>
- <translation>Отладка невозможна: не удалось найти программу для «%1».</translation>
- </message>
- <message>
- <source>Cannot debug: Kit has no device.</source>
- <translation>Отладка невозможна: комплект не имеет устройства.</translation>
- </message>
- <message>
- <source>Cannot debug: Device has no GDB server provider configuration.</source>
- <translation>Отладка невозможна: у устройства не настроена конфигурация GDB сервера.</translation>
- </message>
-</context>
-<context>
<name>BareMetal::Internal::DefaultGdbServerProviderConfigWidget</name>
<message>
<source>Host:</source>
@@ -3228,6 +3264,10 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<source>Beautifier</source>
<translation>Стилизатор</translation>
</message>
+ <message>
+ <source>Bea&amp;utifier</source>
+ <translation>Стили&amp;затор</translation>
+ </message>
</context>
<context>
<name>Beautifier::Internal::AbstractSettings</name>
@@ -3266,6 +3306,10 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<source>Artistic Style</source>
<translation>Artistic Style</translation>
</message>
+ <message>
+ <source>&amp;Artistic Style</source>
+ <translation>&amp;Artistic Style</translation>
+ </message>
</context>
<context>
<name>Beautifier::Internal::ArtisticStyle::ArtisticStyleOptionsPage</name>
@@ -3306,6 +3350,17 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<source>Restrict to MIME types:</source>
<translation>Только для MIME-типов:</translation>
</message>
+ <message>
+ <source>Use specific config file:</source>
+ <translation>Особый файл конфигурации:</translation>
+ </message>
+</context>
+<context>
+ <name>Beautifier::Internal::ArtisticStyle::ArtisticStyleOptionsPageWidget</name>
+ <message>
+ <source>AStyle (*.astylerc)</source>
+ <translation>AStyle (*.astylerc)</translation>
+ </message>
</context>
<context>
<name>Beautifier::Internal::BeautifierPlugin</name>
@@ -3350,14 +3405,14 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<translation>Не удалось получить файл настроек %1.</translation>
</message>
<message>
- <source>Format Current File</source>
+ <source>Format &amp;Current File</source>
<extracomment>Menu entry</extracomment>
- <translation>Форматировать текущий файл</translation>
+ <translation>&amp;Форматировать текущий файл</translation>
</message>
<message>
- <source>Format Selected Text</source>
+ <source>Format &amp;Selected Text</source>
<extracomment>Menu entry</extracomment>
- <translation>Форматировать выделенное</translation>
+ <translation>Ф&amp;орматировать выделенное</translation>
</message>
<message>
<source>%1 Command</source>
@@ -3371,6 +3426,10 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<source>ClangFormat</source>
<translation>ClangFormat</translation>
</message>
+ <message>
+ <source>&amp;ClangFormat</source>
+ <translation>&amp;ClangFormat</translation>
+ </message>
</context>
<context>
<name>Beautifier::Internal::ClangFormat::ClangFormatOptionsPage</name>
@@ -3403,10 +3462,6 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<translation>Использовать особый стиль:</translation>
</message>
<message>
- <source>For action Format Selected Text</source>
- <translation>Для операции «Форматировать выделенное»</translation>
- </message>
- <message>
<source>Format entire file if no text was selected</source>
<translation>Форматировать весь файл, если ничего не выбрано</translation>
</message>
@@ -3414,6 +3469,14 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<source>Restrict to MIME types:</source>
<translation>Только для MIME-типов:</translation>
</message>
+ <message>
+ <source>Fallback style:</source>
+ <translation>Резервный стиль:</translation>
+ </message>
+ <message>
+ <source>For action Format Selected Text.</source>
+ <translation>Для операции форматирования вылеленного текста.</translation>
+ </message>
</context>
<context>
<name>Beautifier::Internal::ClangFormat::ClangFormatSettings</name>
@@ -3505,6 +3568,10 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<source>Uncrustify</source>
<translation>Uncrustify</translation>
</message>
+ <message>
+ <source>&amp;Uncrustify</source>
+ <translation>&amp;Uncrustify</translation>
+ </message>
</context>
<context>
<name>Beautifier::Internal::Uncrustify::UncrustifyOptionsPage</name>
@@ -3555,7 +3622,7 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
</message>
<message>
<source>Use file specific uncrustify.cfg</source>
- <translation type="unfinished">Использовать особый uncrustify.cfg</translation>
+ <translation type="unfinished">Особый uncrustify.cfg для каждого файла</translation>
</message>
</context>
<context>
@@ -3758,6 +3825,10 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<source>New Folder</source>
<translation>Новая папка</translation>
</message>
+ <message>
+ <source>Bookmark</source>
+ <translation>Закладка</translation>
+ </message>
</context>
<context>
<name>BookmarkWidget</name>
@@ -3789,10 +3860,6 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<context>
<name>Bookmarks::Internal::BookmarkManager</name>
<message>
- <source>Bookmark</source>
- <translation>Закладка</translation>
- </message>
- <message>
<source>Edit Bookmark</source>
<translation>Изменение закладки</translation>
</message>
@@ -3946,6 +4013,13 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
</message>
</context>
<context>
+ <name>BreakHandler</name>
+ <message>
+ <source>Breakpoint</source>
+ <translation>Точка останова</translation>
+ </message>
+</context>
+<context>
<name>BuildSettingsPanel</name>
<message>
<source>Build Settings</source>
@@ -4098,10 +4172,6 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<source>The build configuration is currently disabled.</source>
<translation>Конфигурация сборки сейчас отключена.</translation>
</message>
- <message>
- <source>Qt Creator needs a CMake Tool set up to build. Configure a CMake Tool in the kit options.</source>
- <translation>Для сборки необходимо, чтобы была задана утилита CMake. Задайте её в настройках комлекта.</translation>
- </message>
</context>
<context>
<name>CMakeProjectManager::CMakeConfigItem</name>
@@ -4352,6 +4422,10 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<translation>Каталог сборки:</translation>
</message>
<message>
+ <source>Filter</source>
+ <translation>Фильтр</translation>
+ </message>
+ <message>
<source>&amp;Add</source>
<translation>&amp;Добавить</translation>
</message>
@@ -4404,6 +4478,14 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<translation>Сборка CMake</translation>
</message>
<message>
+ <source>Qt Creator needs a CMake Tool set up to build. Configure a CMake Tool in the kit options.</source>
+ <translation>Для сборки необходимо, чтобы была задана утилита CMake. Задайте её в настройках комлекта.</translation>
+ </message>
+ <message>
+ <source>There is a CMakeCache.txt file in &quot;%1&quot;, which suggest an in-source build was done before. You are now building in &quot;%2&quot;, and the CMakeCache.txt file might confuse CMake.</source>
+ <translation>Судя по наличию файла CMakeCache.txt в «%1», ранее сборка производилась в каталоге исходников. Сейчас же сборка производится в «%2», а файл CMakeCache.txt может смутить CMake.</translation>
+ </message>
+ <message>
<source>Persisting CMake state...</source>
<translation>Фиксация состояния CMake...</translation>
</message>
@@ -4411,6 +4493,12 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<source>Running CMake in preparation to build...</source>
<translation>Запуск CMake при подготовке к сборке...</translation>
</message>
+ <message>
+ <source>Error parsing CMake: %1
+</source>
+ <translation>Ошибка разбора CMake: %1
+</translation>
+ </message>
</context>
<context>
<name>CMakeProjectManager::Internal::CMakeBuildStepConfigWidget</name>
@@ -4553,6 +4641,11 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<context>
<name>CMakeProjectManager::Internal::CMakeProjectPlugin</name>
<message>
+ <source>CMake</source>
+ <comment>SnippetProvider</comment>
+ <translation>CMake</translation>
+ </message>
+ <message>
<source>Build</source>
<translation>Собрать</translation>
</message>
@@ -4584,13 +4677,6 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
</message>
</context>
<context>
- <name>CMakeProjectManager::Internal::CMakeSnippetProvider</name>
- <message>
- <source>CMake</source>
- <translation>CMake</translation>
- </message>
-</context>
-<context>
<name>CMakeProjectManager::Internal::CMakeTarget</name>
<message>
<source>Desktop</source>
@@ -4719,6 +4805,14 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<context>
<name>CMakeProjectManager::Internal::ServerModeReader</name>
<message>
+ <source>Parsing of CMake project failed: Connection to CMake server lost.</source>
+ <translation>Не удалось разобрать проект CMake: потеряно соединение с сервером CMake.</translation>
+ </message>
+ <message>
+ <source>Starting to parse CMake project for Qt Creator.</source>
+ <translation>Начинается разбор проекта CMake для Qt Creator.</translation>
+ </message>
+ <message>
<source>Configuring &quot;%1&quot;</source>
<translation>Настройка «%1»</translation>
</message>
@@ -4735,6 +4829,14 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<translation>&lt;Другие места&gt;</translation>
</message>
<message>
+ <source>CMake Project was parsed successfully.</source>
+ <translation>Проект CMake был успешно разобран.</translation>
+ </message>
+ <message>
+ <source>CMake Project parsing failed.</source>
+ <translation>Не удалось разобрать проект CMake.</translation>
+ </message>
+ <message>
<source>&lt;Headers&gt;</source>
<translation>&lt;Заголовки&gt;</translation>
</message>
@@ -4900,8 +5002,26 @@ For example, &quot;Revision: 15&quot; will leave the branch at revision 15.</sou
<translation>Модель кода Clang</translation>
</message>
<message>
- <source>Global setting (%1)</source>
- <translation>Глобальная настройка (%1)</translation>
+ <source>Global</source>
+ <translation>Глобальные</translation>
+ </message>
+ <message>
+ <source>Custom</source>
+ <translation>Особые</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Основное</translation>
+ </message>
+ <message>
+ <source>Parse templates in a MSVC-compliant way. This helps to parse headers for example from Active Template Library (ATL) or Windows Runtime Library (WRL).
+However, using the relaxed and extended rules means also that no highlighting/completion can be provided within template functions.</source>
+ <translation>Разбирать шаблоны, как MSVC. Это поможет разобрать заголовки, например из Active Template Library (ATL) и Windows Runtime Library (WRL).
+Однако, использование ослабленных или расширенных правил подразумевает отсутствие подсветки и дополнения внутри шаблонных функций.</translation>
+ </message>
+ <message>
+ <source>Enable MSVC-compliant template parsing</source>
+ <translation>Включить разбор, совместимый с MSVC</translation>
</message>
</context>
<context>
@@ -5095,64 +5215,6 @@ Please set a real Clang executable.</source>
</message>
</context>
<context>
- <name>ClangStaticAnalyzer::Internal::ClangStaticAnalyzerRunControl</name>
- <message>
- <source>Clang Static Analyzer</source>
- <translation>Статический анализатор Clang</translation>
- </message>
- <message>
- <source>Running Clang Static Analyzer on %1</source>
- <translation>Выполнения статического анализа Clang для %1</translation>
- </message>
- <message>
- <source>Clang Static Analyzer: Invalid executable &quot;%1&quot;, stop.</source>
- <translation>Статический анализатор Clang: Неверная программа «%1», остановлено.</translation>
- </message>
- <message>
- <source>Clang Static Analyzer: Running with possibly unsupported version, could not determine version from executable &quot;%1&quot;.</source>
- <translation>Статический анализатор Clang: работа с,возможно, неподдерживаемой версией, так как её не удалось определить из программы «%1».</translation>
- </message>
- <message>
- <source>Clang Static Analyzer: Running with unsupported version %1, supported version is %2.</source>
- <translation>Статический анализатор Clang: работа с неподдерживаемой версией %1; поддерживается %2.</translation>
- </message>
- <message>
- <source>Clang Static Analyzer: Failed to create temporary dir, stop.</source>
- <translation>Статический анализатор Clang: Не удалось создать временный каталог, остановлено.</translation>
- </message>
- <message>
- <source>Analyzing</source>
- <translation>Анализ</translation>
- </message>
- <message>
- <source>Clang Static Analyzer stopped by user.</source>
- <translation>Статический анализатор Clang остановлен пользователем.</translation>
- </message>
- <message>
- <source>Analyzing &quot;%1&quot;.</source>
- <translation>Анализ «%1».</translation>
- </message>
- <message>
- <source>Failed to analyze &quot;%1&quot;: %2</source>
- <translation>Не удалось проанализировать «%1»: %2</translation>
- </message>
- <message>
- <source>Clang Static Analyzer finished: Processed %1 files successfully, %2 failed.</source>
- <translation>Работа статического анализатора Clang завершена: Успешно обработано %1 файлов и %2 не удалось.</translation>
- </message>
- <message>
- <source>Clang Static Analyzer: Not all files could be analyzed.</source>
- <translation>Статический анализатор Clang: Не все файлы удалось проанализовать.</translation>
- </message>
-</context>
-<context>
- <name>ClangStaticAnalyzer::Internal::ClangStaticAnalyzerRunControlFactory</name>
- <message>
- <source>The project configuration changed since the start of the Clang Static Analyzer. Please re-run with current configuration.</source>
- <translation>Конфигурация проекта изменилась с момента запуска статического анализатора Clang. Перезапустите его.</translation>
- </message>
-</context>
-<context>
<name>ClangStaticAnalyzer::Internal::ClangStaticAnalyzerRunner</name>
<message>
<source>An error occurred with the Clang Static Analyzer process.</source>
@@ -5242,6 +5304,61 @@ Output:
</message>
</context>
<context>
+ <name>ClangStaticAnalyzer::Internal::ClangStaticAnalyzerToolRunner</name>
+ <message>
+ <source>Clang Static Analyzer</source>
+ <translation>Статический анализатор Clang</translation>
+ </message>
+ <message>
+ <source>The project configuration changed since the start of the Clang Static Analyzer. Please re-run with current configuration.</source>
+ <translation>Конфигурация проекта изменилась с момента запуска статического анализатора Clang. Перезапустите его.</translation>
+ </message>
+ <message>
+ <source>Running Clang Static Analyzer on %1</source>
+ <translation>Выполнение статического анализа Clang для %1</translation>
+ </message>
+ <message>
+ <source>Clang Static Analyzer: Invalid executable &quot;%1&quot;, stop.</source>
+ <translation>Статический анализатор Clang: Неверная программа «%1», остановлено.</translation>
+ </message>
+ <message>
+ <source>Clang Static Analyzer: Running with possibly unsupported version, could not determine version from executable &quot;%1&quot;.</source>
+ <translation>Статический анализатор Clang: возможно, работа с неподдерживаемой версией, так как её не удалось определить из программы «%1».</translation>
+ </message>
+ <message>
+ <source>Clang Static Analyzer: Running with unsupported version %1, supported version is %2.</source>
+ <translation>Статический анализатор Clang: работа с неподдерживаемой версией %1; поддерживается %2.</translation>
+ </message>
+ <message>
+ <source>Clang Static Analyzer: Failed to create temporary dir, stop.</source>
+ <translation>Статический анализатор Clang: Не удалось создать временный каталог, остановлено.</translation>
+ </message>
+ <message>
+ <source>Analyzing</source>
+ <translation>Анализ</translation>
+ </message>
+ <message>
+ <source>Clang Static Analyzer stopped by user.</source>
+ <translation>Статический анализатор Clang остановлен пользователем.</translation>
+ </message>
+ <message>
+ <source>Analyzing &quot;%1&quot;.</source>
+ <translation>Анализ «%1».</translation>
+ </message>
+ <message>
+ <source>Failed to analyze &quot;%1&quot;: %2</source>
+ <translation>Не удалось проанализировать «%1»: %2</translation>
+ </message>
+ <message>
+ <source>Clang Static Analyzer finished: Processed %1 files successfully, %2 failed.</source>
+ <translation>Работа статического анализатора Clang завершена: Успешно обработано %1 файлов и %2 не удалось.</translation>
+ </message>
+ <message>
+ <source>Clang Static Analyzer: Not all files could be analyzed.</source>
+ <translation>Статический анализатор Clang: Не все файлы удалось проанализовать.</translation>
+ </message>
+</context>
+<context>
<name>ClangStaticAnalyzer::Internal::DummyRunConfiguration</name>
<message>
<source>Clang Static Analyzer</source>
@@ -5824,22 +5941,10 @@ Output:
<translation>Подтвердите версию для извлечения</translation>
</message>
<message>
- <source>There are multiple versions of &apos;%1&apos; which can be considered for checkout. Please select version to checkout:</source>
- <translation>Существует несколько версий «%1», которые подходят для извлечения. Выберите нужную:</translation>
- </message>
- <message>
- <source>&amp;Loaded Version</source>
- <translation>&amp;Загруженная версия</translation>
- </message>
- <message>
<source>Version after &amp;update</source>
<translation>&amp;Версия после обновления</translation>
</message>
<message>
- <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;b&gt;NOTE: You will not be able to check in this file without merging the changes (not supported by the plugin)&lt;/b&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;b&gt;Внимание! Невозможно зафиксировать данный файл без объединения изменений, которое не поддерживается эти модулем&lt;/b&gt;</translation>
- </message>
- <message>
<source>Created by:</source>
<translation>Автор:</translation>
</message>
@@ -5848,6 +5953,18 @@ Output:
<extracomment>Date</extracomment>
<translation>Создано:</translation>
</message>
+ <message>
+ <source>Multiple versions of &quot;%1&quot; can be checked out. Select the version to check out:</source>
+ <translation>Может быть выгружено несколько версий «%1». Выберите подходящую:</translation>
+ </message>
+ <message>
+ <source>&amp;Loaded version</source>
+ <translation>&amp;Загруженная версия</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;b&gt;Note: You will not be able to check in this file without merging the changes (not supported by the plugin)&lt;/b&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;b&gt;Внимание! Невозможно зафиксировать данный файл без объединения изменений, которое не поддерживается эти модулем&lt;/b&gt;</translation>
+ </message>
</context>
<context>
<name>CodePaster</name>
@@ -6912,6 +7029,10 @@ Continue?</source>
<translation>Qt Creator работает под unix-подобной ОС?</translation>
</message>
<message>
+ <source>The directory where Qt Creator finds its pre-installed resources.</source>
+ <translation>Каталог, в котором Qt Creator ищет свои предустановленные ресурсы.</translation>
+ </message>
+ <message>
<source>The current date (QDate formatstring).</source>
<translation>Текущая дата (строка форматирования QDate).</translation>
</message>
@@ -7795,12 +7916,8 @@ Do you want to kill it?</source>
<translation>Ctrl+K</translation>
</message>
<message>
- <source>Type to locate</source>
- <translation>Быстрый поиск</translation>
- </message>
- <message>
- <source>Type to locate (%1)</source>
- <translation>Быстрый поиск (%1)</translation>
+ <source>Locate...</source>
+ <translation>Найти...</translation>
</message>
<message>
<source>&lt;html&gt;&lt;body style=&quot;color:#909090; font-size:14px&quot;&gt;&lt;div align=&apos;center&apos;&gt;&lt;div style=&quot;font-size:20px&quot;&gt;Open a document&lt;/div&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;hr/&gt;&lt;div style=&quot;margin-top: 5px&quot;&gt;&amp;bull; File &gt; Open File or Project (%1)&lt;/div&gt;&lt;div style=&quot;margin-top: 5px&quot;&gt;&amp;bull; File &gt; Recent Files&lt;/div&gt;&lt;div style=&quot;margin-top: 5px&quot;&gt;&amp;bull; Tools &gt; Locate (%2) and&lt;/div&gt;&lt;div style=&quot;margin-left: 1em&quot;&gt;- type to open file from any open project&lt;/div&gt;%4%5&lt;div style=&quot;margin-left: 1em&quot;&gt;- type &lt;code&gt;%3&amp;lt;space&amp;gt;&amp;lt;filename&amp;gt;&lt;/code&gt; to open file from file system&lt;/div&gt;&lt;div style=&quot;margin-left: 1em&quot;&gt;- select one of the other filters for jumping to a location&lt;/div&gt;&lt;div style=&quot;margin-top: 5px&quot;&gt;&amp;bull; Drag and drop files here&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;</source>
@@ -7887,16 +8004,16 @@ Do you want to kill it?</source>
<translation>Обновить</translation>
</message>
<message>
- <source>Locate...</source>
- <translation>Найти...</translation>
+ <source>Type to locate</source>
+ <translation>Быстрый поиск</translation>
</message>
<message>
- <source>Options</source>
- <translation>Параметры</translation>
+ <source>Type to locate (%1)</source>
+ <translation>Быстрый поиск (%1)</translation>
</message>
<message>
- <source>&lt;type here&gt;</source>
- <translation>&lt;введите здесь&gt;</translation>
+ <source>Options</source>
+ <translation>Параметры</translation>
</message>
</context>
<context>
@@ -8620,6 +8737,10 @@ Do you want to kill it?</source>
<translation>Продолжить</translation>
</message>
<message>
+ <source>Cannot replace because replacement text is unchanged.</source>
+ <translation>Невозможно заменить, так как замещающий текст не изменился.</translation>
+ </message>
+ <message>
<source>No matches found.</source>
<translation>Совпадений не найдено.</translation>
</message>
@@ -8945,6 +9066,13 @@ Do you want to kill it?</source>
</message>
</context>
<context>
+ <name>Core::LocatorManager</name>
+ <message>
+ <source>&lt;type here&gt;</source>
+ <translation>&lt;введите здесь&gt;</translation>
+ </message>
+</context>
+<context>
<name>Core::ModeManager</name>
<message>
<source>Switch to &lt;b&gt;%1&lt;/b&gt; mode</source>
@@ -9274,6 +9402,11 @@ to version control (%2)
<translation>Переключить объявление/реализацию функции</translation>
</message>
<message>
+ <source>C++</source>
+ <comment>SnippetProvider</comment>
+ <translation>C++</translation>
+ </message>
+ <message>
<source>Additional Preprocessor Directives...</source>
<translation>Дополнительные директивы препроцессора...</translation>
</message>
@@ -9402,13 +9535,6 @@ to version control (%2)
</message>
</context>
<context>
- <name>CppEditor::Internal::CppSnippetProvider</name>
- <message>
- <source>C++</source>
- <translation></translation>
- </message>
-</context>
-<context>
<name>CppEditor::Internal::CppTypeHierarchyFactory</name>
<message>
<source>Type Hierarchy</source>
@@ -10098,6 +10224,16 @@ These prefixes are used in addition to current file name on Switch Header/Source
<translation>Поиск использований</translation>
</message>
<message>
+ <source>Re&amp;name %1 files</source>
+ <translation>&amp;Переименовать %1 файл(ов)</translation>
+ </message>
+ <message>
+ <source>Files:
+%1</source>
+ <translation>Файлы:
+%1</translation>
+ </message>
+ <message>
<source>C++ Macro Usages:</source>
<translation>Использование макросов C++:</translation>
</message>
@@ -10803,53 +10939,6 @@ Flags: %3</source>
</message>
</context>
<context>
- <name>Debugger::AnalyzerAction</name>
- <message>
- <source>Cannot start %1 without a project. Please open the project and try again.</source>
- <translation>Невозможно запустить %1 без проекта. Откройте проект и попробуйте снова.</translation>
- </message>
- <message>
- <source>Debug</source>
- <translation>отладки</translation>
- </message>
- <message>
- <source>Profile</source>
- <translation>профилирования</translation>
- </message>
- <message>
- <source>Release</source>
- <translation>выпуска</translation>
- </message>
- <message>
- <source>in Debug mode</source>
- <translation>она создана для режима отладки</translation>
- </message>
- <message>
- <source>in Profile mode</source>
- <translation>она создана для режима профилирования</translation>
- </message>
- <message>
- <source>in Release mode</source>
- <translation>она создана для режима выпуска</translation>
- </message>
- <message>
- <source>with debug symbols (Debug or Profile mode)</source>
- <translation>ей требуются отладочные символы (отладка или профилирование)</translation>
- </message>
- <message>
- <source>on optimized code (Profile or Release mode)</source>
- <translation>ей требуется оптимизированный код (профилирование или выпуск)</translation>
- </message>
- <message>
- <source>Run %1 in %2 Mode?</source>
- <translation>Выполнить %1 в режиме %2?</translation>
- </message>
- <message>
- <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;You are trying to run the tool &quot;%1&quot; on an application in %2 mode. The tool is designed to be used %3.&lt;/p&gt;&lt;p&gt;Run-time characteristics differ significantly between optimized and non-optimized binaries. Analytical findings for one mode may or may not be relevant for the other.&lt;/p&gt;&lt;p&gt;Running tools that need debug symbols on binaries that don&apos;t provide any may lead to missing function names or otherwise insufficient output.&lt;/p&gt;&lt;p&gt;Do you want to continue and run the tool in %2 mode?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Вы пытаетесь запустить утилиту «%1» для приложения в режиме %2, а %3.&lt;/p&gt;&lt;p&gt;Характер работы приложения сильно зависит от оптимизации. Выводы, сделанные для одного режима, могут быть неверны для другого.&lt;/p&gt;&lt;p&gt;Запуск утилиты требующей отладочные символы для программ их не имеющих приведёт к проблемам определения имён функций или некорректному выводу информации.&lt;/p&gt;&lt;p&gt;Запустить утилиту в режиме %2?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
- </message>
-</context>
-<context>
<name>Debugger::AnalyzerRunConfigWidget</name>
<message>
<source>Use Customized Settings</source>
@@ -11018,7 +11107,11 @@ Flags: %3</source>
</message>
</context>
<context>
- <name>Debugger::DebuggerRunControl</name>
+ <name>Debugger::DebuggerRunTool</name>
+ <message>
+ <source>No executable specified.</source>
+ <translation>Программа не указана.</translation>
+ </message>
<message>
<source>Debugger</source>
<translation>Отладчик</translation>
@@ -11028,10 +11121,6 @@ Flags: %3</source>
<translation>&amp;Показывать это сообщение в дальнейшем.</translation>
</message>
<message>
- <source>No executable specified.</source>
- <translation>Программа не указана.</translation>
- </message>
- <message>
<source>Debugging starts</source>
<translation>Отладка запущена</translation>
</message>
@@ -11044,12 +11133,16 @@ Flags: %3</source>
<translation>Отладка завершена</translation>
</message>
<message>
+ <source>Close Debugging Session</source>
+ <translation>Закрытие сессии отладки</translation>
+ </message>
+ <message>
<source>A debugging session is still in progress. Terminating the session in the current state can leave the target in an inconsistent state. Would you still like to terminate it?</source>
<translation>Идёт отладка. Если её сейчас завершить, то программа может остаться в неизвестном состоянии. Завершить отладку?</translation>
</message>
<message>
- <source>Close Debugging Session</source>
- <translation>Закрытие сессии отладки</translation>
+ <source>Debugged executable</source>
+ <translation>Отлаживаемая программа</translation>
</message>
</context>
<context>
@@ -11060,6 +11153,32 @@ Flags: %3</source>
</message>
</context>
<context>
+ <name>Debugger::GdbServerPortsGatherer</name>
+ <message>
+ <source>Checking available ports...</source>
+ <translation>Проверка доступных портов...</translation>
+ </message>
+ <message>
+ <source>Found %1 free ports</source>
+ <translation>Обнаружено %1 свободных портов</translation>
+ </message>
+ <message>
+ <source>Not enough free ports on device for C++ debugging.</source>
+ <translation>Недостаточно свободных портов на устройстве для отладки C++.</translation>
+ </message>
+ <message>
+ <source>Not enough free ports on device for QML debugging.</source>
+ <translation>Недостаточно свободных портов на устройстве для отладки QML.</translation>
+ </message>
+</context>
+<context>
+ <name>Debugger::GdbServerRunner</name>
+ <message>
+ <source>Starting gdbserver...</source>
+ <translation>Запускается gdbserver...</translation>
+ </message>
+</context>
+<context>
<name>Debugger::Internal::AddressDialog</name>
<message>
<source>Select Start Address</source>
@@ -11323,10 +11442,6 @@ Flags: %3</source>
<translation>&amp;Условие:</translation>
</message>
<message>
- <source>Breakpoint</source>
- <translation>Точка останова</translation>
- </message>
- <message>
<source>Data at 0x%1</source>
<translation>Данные с 0x%1</translation>
</message>
@@ -11712,14 +11827,6 @@ Flags: %3</source>
<translation>Программа CDB не указана.</translation>
</message>
<message>
- <source>Internal error: The extension %1 cannot be found.
-If you have updated Qt Creator via Maintenance Tool you may need to rerun the Tool and select &quot;Add or remove components&quot;and then select the
-Qt &gt; Tools &gt; Qt Creator &gt; Qt Creator CDB Debugger Support component.</source>
- <translation>Внутренняя ошибка: Невозможно найти расширение %1.
-Если Qt Creator был обновлён через Maintenance Tool, то необходимо её перезапустить и выбрать «Добавление и удаление компонентов», а
-затем отметить компонент Qt &gt; Tools &gt; Qt Creator &gt; Qt Creator CDB Debugger Support.</translation>
- </message>
- <message>
<source>Interrupting is not possible in remote sessions.</source>
<translation>Прерывание в удалённых сессиях невозможно.</translation>
</message>
@@ -11752,6 +11859,18 @@ Qt &gt; Tools &gt; Qt Creator &gt; Qt Creator CDB Debugger Support component.</s
<translation>Неподдерживаемая CDB основная система.</translation>
</message>
<message>
+ <source>Internal error: The extension %1 cannot be found.
+If you have updated Qt Creator via Maintenance Tool, you may need to rerun the Tool and select &quot;Add or remove components&quot; and then select the
+Qt &gt; Tools &gt; Qt Creator &gt; Qt Creator CDB Debugger Support component.
+If you build Qt Creator from sources and want to use a CDB executable with another bitness than your Qt Creator build,
+you will need to build a separate CDB extension with the same bitness as the CDB you want to use.</source>
+ <translation>Внутренняя ошибка: Не удалось найти расширение %1.
+Если Qt Creator был обновлён через Maintenance Tool, то следует перезапустить её и выбрать &quot;Добавить или удалить компоненты&quot;, затем
+отметить компонент Qt &gt; Tools -&gt; Qt Creator &gt; Qt Creator CDB Debugger Support.
+Если же Qt Creator был собран из исходников и требует программу CDB отличной разрядности, то необходимо собрать
+отдельное расширение CDB соответствующее разрядности используемого CDB.</translation>
+ </message>
+ <message>
<source>Switching to main thread...</source>
<translation>Переключение в основной поток...</translation>
</message>
@@ -11823,8 +11942,8 @@ Qt &gt; Tools &gt; Qt Creator &gt; Qt Creator CDB Debugger Support component.</s
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Пытаться исправить положение точки останова, если она установлена на строке файла, для которой код не создаётся (комментарий, например). Коррекция производится согласно модели кода.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <source>Use Python dumper when available</source>
- <translation>По возможности использовать дампер</translation>
+ <source>Use Python dumper</source>
+ <translation>Использовать дампер</translation>
</message>
</context>
<context>
@@ -12080,6 +12199,14 @@ Qt &gt; Tools &gt; Qt Creator &gt; Qt Creator CDB Debugger Support component.</s
<translation>Невозможно отобразить содержимое памяти, так как модуль просмотра двоичных данных не загружен.</translation>
</message>
<message>
+ <source>Adapter start failed</source>
+ <translation>Не удалось запустить адаптер</translation>
+ </message>
+ <message>
+ <source>Debugging complex command lines is currently not supported on Windows.</source>
+ <translation>Отладка сложных командных строк под Windows пока не поддерживается.</translation>
+ </message>
+ <message>
<source>Taking notice of pid %1</source>
<translation>Получено уведомление от pid %1</translation>
</message>
@@ -12123,9 +12250,17 @@ Qt &gt; Tools &gt; Qt Creator &gt; Qt Creator CDB Debugger Support component.</s
</message>
<message>
<source>The inferior is in the Portable Executable format.
-Selecting CDB as debugger would improve the debugging experience for this binary format.</source>
+Selecting %1 as debugger would improve the debugging experience for this binary format.</source>
<translation>Программа имеет формат Portable Executable.
-Рекомендуется использовать отладчик CDB для улучшения отладочных возможностей.</translation>
+Рекомендуется использовать отладчик %1 для улучшения отладочных возможностей.</translation>
+ </message>
+ <message>
+ <source>The selected debugger may be inappropriate for the inferior.
+Examining symbols and setting breakpoints by file name and line number may fail.
+</source>
+ <translation>Возможно, выбранный отладчик не подходит для отлаживаемой программы.
+Обзор символов и установка точек останова по имени файла и строке может не работать.
+</translation>
</message>
<message>
<source>The inferior is in the ELF format.
@@ -12150,14 +12285,6 @@ Selecting GDB or LLDB as debugger would improve the debugging experience for thi
<translation>Предупреждение</translation>
</message>
<message>
- <source>The selected debugger may be inappropiate for the inferior.
-Examining symbols and setting breakpoints by file name and line number may fail.
-</source>
- <translation>Выбранный отладчик возможно не подходит для отлаживаемой программы.
-Обзор символов и установка точек останова по имени файла и строке может не работать.
-</translation>
- </message>
- <message>
<source>This does not seem to be a &quot;Debug&quot; build.
Setting breakpoints by file name and line number may fail.</source>
<translation>Это не похоже на отладочную сборку.
@@ -12187,10 +12314,6 @@ Setting breakpoints by file name and line number may fail.</source>
<context>
<name>Debugger::Internal::DebuggerEnginePrivate</name>
<message>
- <source>Debugged executable</source>
- <translation>Отлаживаемая программа</translation>
- </message>
- <message>
<source>Attempting to interrupt.</source>
<translation>Попытка прервать.</translation>
</message>
@@ -12297,12 +12420,60 @@ Setting breakpoints by file name and line number may fail.</source>
<translation>Отладчик</translation>
</message>
<message>
+ <source>Cannot start %1 without a project. Please open the project and try again.</source>
+ <translation>Невозможно запустить %1 без проекта. Откройте проект и попробуйте снова.</translation>
+ </message>
+ <message>
+ <source>Profile</source>
+ <translation>Профилирование</translation>
+ </message>
+ <message>
+ <source>Release</source>
+ <translation>Выпуск</translation>
+ </message>
+ <message>
+ <source>in Debug mode</source>
+ <translation>она создана для режима отладки</translation>
+ </message>
+ <message>
+ <source>in Profile mode</source>
+ <translation>она создана для режима профилирования</translation>
+ </message>
+ <message>
+ <source>in Release mode</source>
+ <translation>она создана для режима выпуска</translation>
+ </message>
+ <message>
+ <source>with debug symbols (Debug or Profile mode)</source>
+ <translation>ей требуются отладочные символы (отладка или профилирование)</translation>
+ </message>
+ <message>
+ <source>on optimized code (Profile or Release mode)</source>
+ <translation>ей требуется оптимизированный код (профилирование или выпуск)</translation>
+ </message>
+ <message>
+ <source>Run %1 in %2 Mode?</source>
+ <translation>Выполнить %1 в режиме %2?</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;You are trying to run the tool &quot;%1&quot; on an application in %2 mode. The tool is designed to be used %3.&lt;/p&gt;&lt;p&gt;Run-time characteristics differ significantly between optimized and non-optimized binaries. Analytical findings for one mode may or may not be relevant for the other.&lt;/p&gt;&lt;p&gt;Running tools that need debug symbols on binaries that don&apos;t provide any may lead to missing function names or otherwise insufficient output.&lt;/p&gt;&lt;p&gt;Do you want to continue and run the tool in %2 mode?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Вы пытаетесь запустить утилиту «%1» для приложения в режиме %2, а %3.&lt;/p&gt;&lt;p&gt;Характер работы приложения сильно зависит от оптимизации. Выводы, сделанные для одного режима, могут быть неверны для другого.&lt;/p&gt;&lt;p&gt;Запуск утилиты требующей отладочные символы для программ их не имеющих приведёт к проблемам определения имён функций или некорректному выводу информации.&lt;/p&gt;&lt;p&gt;Запустить утилиту в режиме %2?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
<source>Some breakpoints cannot be handled by the debugger languages currently active, and will be ignored.
Affected are breakpoints %1</source>
<translation>Будут пропущены следующие точки останова, так как не поддерживаются активными языками отладчика:
%1</translation>
</message>
<message>
+ <source>The debugging engine required for combined QML/C++ debugging could not be created: %1</source>
+ <translation>Не удалось создать отладчик для комбинированной отладки QML/C++: %1</translation>
+ </message>
+ <message>
+ <source>Unable to create a debugging engine of the type &quot;%1&quot;</source>
+ <translation>Не удалось создать отладчик типа «%1»</translation>
+ </message>
+ <message>
<source>Not enough free ports for QML debugging.</source>
<translation>Недостаточно свободных портов для отладки QML.</translation>
</message>
@@ -12311,10 +12482,6 @@ Affected are breakpoints %1</source>
<translation>Неизвестный отладчик типа «%1»</translation>
</message>
<message>
- <source>Unable to create a debugger engine of the type &quot;%1&quot;</source>
- <translation>Не удалось создать отладчик типа «%1»</translation>
- </message>
- <message>
<source>Install &amp;Debug Information</source>
<translation>Установить &amp;отладочную информацию</translation>
</message>
@@ -12542,6 +12709,30 @@ Qt Creator не может подключиться к нему.</translation>
<translation>Программа отладчика</translation>
</message>
<message>
+ <source>&amp;Breakpoints</source>
+ <translation>&amp;Точки останова</translation>
+ </message>
+ <message>
+ <source>&amp;Modules</source>
+ <translation>&amp;Модули</translation>
+ </message>
+ <message>
+ <source>Reg&amp;isters</source>
+ <translation>&amp;Регистры</translation>
+ </message>
+ <message>
+ <source>&amp;Stack</source>
+ <translation>&amp;Стек</translation>
+ </message>
+ <message>
+ <source>&amp;Threads</source>
+ <translation>&amp;Потоки</translation>
+ </message>
+ <message>
+ <source>Locals and &amp;Expressions</source>
+ <translation>Переменные и &amp;выражения</translation>
+ </message>
+ <message>
<source>Debugger</source>
<translation>Отладчик</translation>
</message>
@@ -12622,10 +12813,6 @@ Qt Creator не может подключиться к нему.</translation>
<translation>Запустить «%1» и встать на функции «main()»</translation>
</message>
<message>
- <source>Breakpoints</source>
- <translation>Точки останова</translation>
- </message>
- <message>
<source>Select a valid expression to evaluate.</source>
<translation>Выберите корректное выражение для вычисления.</translation>
</message>
@@ -12638,30 +12825,10 @@ Qt Creator не может подключиться к нему.</translation>
<translation>Память...</translation>
</message>
<message>
- <source>Modules</source>
- <translation>Модули</translation>
- </message>
- <message>
- <source>Registers</source>
- <translation>Регистры</translation>
- </message>
- <message>
- <source>Stack</source>
- <translation>Стек</translation>
- </message>
- <message>
<source>Source Files</source>
<translation>Файлы исходных текстов</translation>
</message>
<message>
- <source>Threads</source>
- <translation>Потоки</translation>
- </message>
- <message>
- <source>Locals and Expressions</source>
- <translation>Переменные и выражения</translation>
- </message>
- <message>
<source>Snapshots</source>
<translation>Снимки</translation>
</message>
@@ -13144,10 +13311,6 @@ Qt Creator не может подключиться к нему.</translation>
<context>
<name>Debugger::Internal::GdbEngine</name>
<message>
- <source>The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again.</source>
- <translation>У последней функции waitFor...() истекло время ожидания. Состояние QProcess не изменилось, и вы можете попробовать вызвать waitFor...() снова.</translation>
- </message>
- <message>
<source>Reading %1...</source>
<translation>Чтение %1...</translation>
</message>
@@ -13156,22 +13319,6 @@ Qt Creator не может подключиться к нему.</translation>
<translation>Библиотека %1 загружена</translation>
</message>
<message>
- <source>The gdb process crashed some time after starting successfully.</source>
- <translation>Процесс gdb аварийно завершился через некоторое время после успешного запуска.</translation>
- </message>
- <message>
- <source>The gdb process was ended forcefully</source>
- <translation>Процесс gdb был принудительно завершён</translation>
- </message>
- <message>
- <source>An error occurred when attempting to write to the gdb process. For example, the process may not be running, or it may have closed its input channel.</source>
- <translation>Ошибка при отправке данных процессу gdb. Например, процесс уже перестал работать или закрыл свой входной канал.</translation>
- </message>
- <message>
- <source>An error occurred when attempting to read from the gdb process. For example, the process may not be running.</source>
- <translation>Ошибка при получении данных от процесса gdb. Например, процесс уже перестал работать.</translation>
- </message>
- <message>
<source>Library %1 unloaded</source>
<translation>Библиотека %1 выгружена</translation>
</message>
@@ -13206,12 +13353,6 @@ Try: %2</source>
<translation>Не удалось запустить процесс gdb.</translation>
</message>
<message>
- <source>Either the invoked program &quot;%1&quot; is missing, or you may have insufficient permissions to invoke the program.
-%2</source>
- <translation>Или программа «%1» отсутствует, или недостаточно прав на её запуск.
-%2</translation>
- </message>
- <message>
<source>Stopping temporarily</source>
<translation>Временно остановлено</translation>
</message>
@@ -13302,10 +13443,6 @@ Try: %2</source>
%1</translation>
</message>
<message>
- <source>An unknown error in the gdb process occurred.</source>
- <translation>У процесса gdb возникла неопознанная ошибка.</translation>
- </message>
- <message>
<source>An exception was triggered:</source>
<translation>Возникло исключение:</translation>
</message>
@@ -13596,20 +13733,8 @@ markers in the source code editor.</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Следующие команды GDB будут выполнены, когда GDB успешно подключится к внешней цели.&lt;/p&gt;&lt;p&gt;Вы можете добавить тут команды для дополнительной настройки цели, например: «monitor reset» или «load».&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <source>Debugging Helper Customization</source>
- <translation>Настройка помощников отладчика</translation>
- </message>
- <message>
- <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;GDB commands entered here will be executed after Qt Creator&apos;s debugging helpers have been loaded and fully initialized. You can load additional debugging helpers or modify existing ones here.&lt;/p&gt;%1&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Введённые здесь команды будут выполняться при запуске GDB после загрузки и полной инициализации помощников отладчика. Здесь вы можете указать загрузку дополнительных помощников или изменить существующие.&lt;/p&gt;%1&lt;/body&gt;&lt;/html&gt;</translation>
- </message>
- <message>
- <source>Extra Debugging Helpers</source>
- <translation>Дополнительные помощники отладчика</translation>
- </message>
- <message>
- <source>Path to a Python file containing additional data dumpers.</source>
- <translation>Путь к файлу на языке Python, содержащему дополнительные фильтры данных.</translation>
+ <source>Debug all child processes</source>
+ <translation>Отлаживать все дочерние процессы</translation>
</message>
<message>
<source>GDB</source>
@@ -13648,10 +13773,6 @@ markers in the source code editor.</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Включение обратной отладки.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Внимание!&lt;/b&gt; Эта функция очень медлительна и нестабильна со стороны GDB. Она может привести к непредсказуемому поведению при обратном проходе через системный вызов и краху отладочной сессии.&lt;/p&gt;&lt;body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <source>Debug all children</source>
- <translation>Отлаживать всех потомков</translation>
- </message>
- <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;Keeps debugging all children after a fork.&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;Продолжать отладку всех потомков после выполнения fork.&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -13705,6 +13826,10 @@ markers in the source code editor.</source>
<translation>Ошибка</translation>
</message>
<message>
+ <source>Upload failed: %1</source>
+ <translation>Не удалось выгрузить: %1</translation>
+ </message>
+ <message>
<source>No symbol file given.</source>
<translation>Не обнаружен файл символов.</translation>
</message>
@@ -13780,8 +13905,8 @@ markers in the source code editor.</source>
<translation>Не удалось найти ABI для внешнего процесса «%1».</translation>
</message>
<message>
- <source>Remote: &quot;%1:%2&quot;</source>
- <translation>Внешний: «%1:%2»</translation>
+ <source>Remote: &quot;%1&quot;</source>
+ <translation>Внешний: «%1»</translation>
</message>
<message>
<source>Process gdbserver finished. Status: %1</source>
@@ -13864,10 +13989,6 @@ markers in the source code editor.</source>
<source>An error occurred when attempting to read from the Lldb process. For example, the process may not be running.</source>
<translation>Ошибка при получении данных от процесса Lldb. Например, процесс уже перестал работать.</translation>
</message>
- <message>
- <source>Adapter start failed</source>
- <translation>Не удалось запустить адаптер</translation>
- </message>
</context>
<context>
<name>Debugger::Internal::LocalsAndExpressionsOptionsPage</name>
@@ -13880,6 +14001,22 @@ markers in the source code editor.</source>
<translation>Помощники отладчика используются для корректного отображения объектов некоторых типов, вроде QString и std::map в обзоре «Переменные» режима отладки.</translation>
</message>
<message>
+ <source>Debugging Helper Customization</source>
+ <translation>Настройка помощников отладчика</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Python commands entered here will be executed after Qt Creator&apos;s debugging helpers have been loaded and fully initialized. You can load additional debugging helpers or modify existing ones here.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Введённые здесь команды на языке Python будут выполнены после загрузки и полной инициализации помощников отладчика. Здесь же можно загрузить дополнительные помощники или изменить существующие.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Extra Debugging Helpers</source>
+ <translation>Дополнительные помощники отладчика</translation>
+ </message>
+ <message>
+ <source>Path to a Python file containing additional data dumpers.</source>
+ <translation>Путь к файлу на языке Python, содержащему дополнительные фильтры данных.</translation>
+ </message>
+ <message>
<source>&lt;unlimited&gt;</source>
<translation>&lt;бесконечна&gt;</translation>
</message>
@@ -13895,8 +14032,8 @@ markers in the source code editor.</source>
<context>
<name>Debugger::Internal::LogWindow</name>
<message>
- <source>Debugger Log</source>
- <translation>Журнал отладки</translation>
+ <source>Debugger &amp;Log</source>
+ <translation>&amp;Журнал отладки</translation>
</message>
<message>
<source>Repeat last command for debug reasons.</source>
@@ -13907,7 +14044,7 @@ markers in the source code editor.</source>
<translation>Команда:</translation>
</message>
<message>
- <source>NOTE: This log contains possibly confidential information about your machine, environment variables, in-memory data of the processes you are debugging, and more. It is never transferred over the internet by Qt Creator, and only stored to disk if you manually use the respective option from the context menu, or through mechanisms that are not under Qt Creator&apos;s control, for instance in swap files.
+ <source>Note: This log contains possibly confidential information about your machine, environment variables, in-memory data of the processes you are debugging, and more. It is never transferred over the internet by Qt Creator, and only stored to disk if you manually use the respective option from the context menu, or through mechanisms that are not under Qt Creator&apos;s control, for instance in swap files.
You may be asked to share the contents of this log when reporting bugs related to debugger operation. In this case, make sure your submission does not contain data you do not want to or you are not allowed to share.
</source>
@@ -14055,10 +14192,6 @@ You may be asked to share the contents of this log when reporting bugs related t
<context>
<name>Debugger::Internal::QmlCppEngine</name>
<message>
- <source>The slave debugging engine required for combined QML/C++-Debugging could not be created: %1</source>
- <translation>Не удалось создать ведомый отладчик для комбинированной отладки QML/C++: %1</translation>
- </message>
- <message>
<source>C++ debugger activated</source>
<translation>Отладчик C++ активирован</translation>
</message>
@@ -14096,18 +14229,6 @@ Do you want to retry?</source>
<translation>Запускается %1 %2</translation>
</message>
<message>
- <source>Failed to start application</source>
- <translation>Не удалось запустить приложение</translation>
- </message>
- <message>
- <source>Application startup failed: %1</source>
- <translation>Запуск приложения не удался: %1</translation>
- </message>
- <message>
- <source>QML debugging port not set: Unable to convert %1 to unsigned int.</source>
- <translation>Порт отладки QML не задан: невозможно преобразовать %1 к unsigned int.</translation>
- </message>
- <message>
<source>Waiting for JavaScript engine to interrupt on next statement.</source>
<translation>Ожидание прерывания на следующем операторе от движка JavaScript.</translation>
</message>
@@ -14482,6 +14603,15 @@ Do you want to retry?</source>
<translation>Запуск отладчика</translation>
</message>
<message>
+ <source>Override server channel:</source>
+ <translation>Переопределить канал сервера:</translation>
+ </message>
+ <message>
+ <source>For example, %1</source>
+ <extracomment>&quot;For example, /dev/ttyS0, COM1, 127.0.0.1:1234&quot;</extracomment>
+ <translation>Например, %1</translation>
+ </message>
+ <message>
<source>Select Executable</source>
<translation>Выбор программы</translation>
</message>
@@ -14502,10 +14632,6 @@ Do you want to retry?</source>
<translation>Порт сервера:</translation>
</message>
<message>
- <source>Override server address</source>
- <translation>Переопределить адрес сервера</translation>
- </message>
- <message>
<source>This option can be used to point to a script that will be used to start a debug server. If the field is empty, Qt Creator&apos;s default methods to set up debug servers will be used.</source>
<translation>Этот параметр позволяет указать сценарий для запуска сервера отладки. Если оставить его пустым, то будет использоваться стандартный метод запуска.</translation>
</message>
@@ -14546,6 +14672,12 @@ Do you want to retry?</source>
<translation>Отладочная &amp;информация:</translation>
</message>
<message>
+ <source>Normally, the running server is identified by the IP of the device in the kit and the server port selected above.
+You can choose another communication channel here, such as a serial line or custom ip:port.</source>
+ <translation>Обычно, работающий сервер определяется по IP устройства в комплекте и порту сервера, выбранному выше.
+Здесь можно выбрать другой канал передачи данных, например, последовательный порт или ip:port.</translation>
+ </message>
+ <message>
<source>&amp;Recent:</source>
<translation>&amp;Недавние:</translation>
</message>
@@ -15319,13 +15451,6 @@ Do you want to retry?</source>
</message>
</context>
<context>
- <name>DebuggerEngine</name>
- <message>
- <source>Debugging complex command lines is currently not supported on Windows.</source>
- <translation>Отладка сложных командных строк под Windows пока не поддерживаеться.</translation>
- </message>
-</context>
-<context>
<name>DebuggerItemManagerPrivate</name>
<message>
<source>Auto-detected CDB at %1</source>
@@ -15642,22 +15767,6 @@ Rebuilding the project might help.</source>
</message>
</context>
<context>
- <name>DiffEditor::DiffEditorController</name>
- <message numerus="yes">
- <source>and %n more</source>
- <extracomment>Displayed after the untranslated message &quot;Branches: branch1, branch2 &apos;and %n more&apos;&quot;</extracomment>
- <translation>
- <numerusform>и ещё %n</numerusform>
- <numerusform>и ещё %n</numerusform>
- <numerusform>и ещё %n</numerusform>
- </translation>
- </message>
- <message>
- <source>&lt;None&gt;</source>
- <translation>&lt;Нет&gt;</translation>
- </message>
-</context>
-<context>
<name>DiffEditor::Internal::DiffCurrentFileController</name>
<message>
<source>Saved</source>
@@ -15851,8 +15960,8 @@ Rebuilding the project might help.</source>
<translation>Пропущено неизвестное количество строк...</translation>
</message>
<message>
- <source>No difference</source>
- <translation>Различий нет</translation>
+ <source>No difference.</source>
+ <translation>Различий нет.</translation>
</message>
</context>
<context>
@@ -15866,8 +15975,8 @@ Rebuilding the project might help.</source>
<translation>Ожидание данных...</translation>
</message>
<message>
- <source>Failed</source>
- <translation>Сбой</translation>
+ <source>Retrieving data failed.</source>
+ <translation>Не удалось получить данные.</translation>
</message>
</context>
<context>
@@ -15895,8 +16004,8 @@ Rebuilding the project might help.</source>
<translation>Ожидание данных...</translation>
</message>
<message>
- <source>Failed</source>
- <translation>Сбой</translation>
+ <source>Retrieving data failed.</source>
+ <translation>Не удалось получить данные.</translation>
</message>
</context>
<context>
@@ -16216,8 +16325,8 @@ Rebuilding the project might help.</source>
<translation>Зависимость: %1</translation>
</message>
<message>
- <source>Dependency: &quot;%1&quot; must be &quot;%2&quot; or &quot;%3&quot; (is &quot;%4&quot;)</source>
- <translation>Зависимость: «%1» должно быть «%2» или «%3» (есть «%4»)</translation>
+ <source>Dependency: &quot;%1&quot; must be &quot;%2&quot; or &quot;%3&quot; (is &quot;%4&quot;).</source>
+ <translation>Зависимость: «%1» должно быть «%2» или «%3» (есть «%4»).</translation>
</message>
<message>
<source>Argument: %1</source>
@@ -16956,6 +17065,13 @@ will also disable the following plugins:
</message>
</context>
<context>
+ <name>Form</name>
+ <message>
+ <source>Form</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
<name>FormEditorW</name>
<message>
<source>Widget box</source>
@@ -17324,10 +17440,6 @@ will also disable the following plugins:
<translation>Перенести &amp;изменения</translation>
</message>
<message>
- <source>Fallback</source>
- <translation>Резервный</translation>
- </message>
- <message>
<source>Fetching &quot;%1&quot;...</source>
<translation>Загружается «%1»...</translation>
</message>
@@ -17340,8 +17452,16 @@ will also disable the following plugins:
<translation>Внешнее хранилище:</translation>
</message>
<message>
- <source>Refresh Remote Servers</source>
- <translation>Обновить внешние хранилища</translation>
+ <source>Certificate Error</source>
+ <translation>Ошибка сертификата</translation>
+ </message>
+ <message>
+ <source>Server certificate for %1 cannot be authenticated.
+Do you want to disable SSL verification for this server?
+Note: This can expose you to man-in-the-middle attack.</source>
+ <translation>Не удалось проверить сертификат сервера для %1.
+Отключить SSL проверку для этого сервера?
+Внимание: Это может повлечь атаку «человек посередине».</translation>
</message>
</context>
<context>
@@ -17570,6 +17690,17 @@ Partial names can be used if they are unambiguous.</source>
</message>
</context>
<context>
+ <name>Gerrit::Internal::GerritRemoteChooser</name>
+ <message>
+ <source>Refresh Remote Servers</source>
+ <translation>Обновить внешние хранилища</translation>
+ </message>
+ <message>
+ <source>Fallback</source>
+ <translation>Резервный</translation>
+ </message>
+</context>
+<context>
<name>Gerrit::Internal::QueryContext</name>
<message>
<source>Querying Gerrit</source>
@@ -17776,10 +17907,6 @@ Would you like to terminate it?</source>
<translation>&amp;История</translation>
</message>
<message>
- <source>&amp;Checkout</source>
- <translation>&amp;Перейти</translation>
- </message>
- <message>
<source>&amp;Merge</source>
<translation>О&amp;бъединить</translation>
</message>
@@ -17792,10 +17919,6 @@ Would you like to terminate it?</source>
<translation>Пере&amp;именовать</translation>
</message>
<message>
- <source>Cherry Pick</source>
- <translation>Перенести изменения</translation>
- </message>
- <message>
<source>&amp;Track</source>
<translation>С&amp;вязать</translation>
</message>
@@ -17804,10 +17927,6 @@ Would you like to terminate it?</source>
<translation>Перенести последнюю фиксацию из выбранной ветки.</translation>
</message>
<message>
- <source>Reset</source>
- <translation>Сбросить</translation>
- </message>
- <message>
<source>Set current branch to track the selected one.</source>
<translation>Сделать текущую ветку связанной с выбранной.</translation>
</message>
@@ -17815,6 +17934,22 @@ Would you like to terminate it?</source>
<source>&amp;Include old entries</source>
<translation>В&amp;ключая старые элементы</translation>
</message>
+ <message>
+ <source>Include ta&amp;gs</source>
+ <translation>Включить т&amp;эги</translation>
+ </message>
+ <message>
+ <source>C&amp;heckout</source>
+ <translation>&amp;Перейти</translation>
+ </message>
+ <message>
+ <source>Re&amp;set</source>
+ <translation>Сб&amp;росить</translation>
+ </message>
+ <message>
+ <source>Cherry &amp;Pick</source>
+ <translation>Перенести &amp;изменения</translation>
+ </message>
</context>
<context>
<name>Git::Internal::BranchModel</name>
@@ -17996,22 +18131,6 @@ Commit now?</source>
<translation>Необходимо зафиксировать изменения для завершения объединения.
Зафиксировать?</translation>
</message>
- <message numerus="yes">
- <source>Committed %n file(s).</source>
- <translation>
- <numerusform>Фиксирован %n файл.</numerusform>
- <numerusform>Фиксировано %n файла.</numerusform>
- <numerusform>Фиксировано %n файлов.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>Amended &quot;%1&quot; (%n file(s)).</source>
- <translation>
- <numerusform>Внесено изменение «%1» (%n файл).</numerusform>
- <numerusform>Внесено изменение «%1» (%n файла).</numerusform>
- <numerusform>Внесено изменение «%1» (%n файлов).</numerusform>
- </translation>
- </message>
<message>
<source>Git SVN Log</source>
<translation>Git - история SVN</translation>
@@ -18092,14 +18211,6 @@ Commit now?</source>
<source>Cannot obtain log of &quot;%1&quot;: %2</source>
<translation>Не удалось получить историю «%1»: %2</translation>
</message>
- <message numerus="yes">
- <source>Cannot reset %n file(s) in &quot;%1&quot;: %2</source>
- <translation>
- <numerusform>Не удалось сбросить %n файл в «%1»: %2</numerusform>
- <numerusform>Не удалось сбросить %n файла в «%1»: %2</numerusform>
- <numerusform>Не удалось сбросить %n файлов в «%1»: %2</numerusform>
- </translation>
- </message>
<message>
<source>Cannot checkout &quot;%1&quot; of %2 in &quot;%3&quot;: %4</source>
<extracomment>Meaning of the arguments: %1: revision, %2: files, %3: repository, %4: Error message</extracomment>
@@ -18110,10 +18221,51 @@ Commit now?</source>
<extracomment>Failed to find parent revisions of a SHA1 for &quot;annotate previous&quot;</extracomment>
<translation>Не удалось найти родительские ревизии для «%1» в «%2»: %3</translation>
</message>
+ <message numerus="yes">
+ <source>and %n more</source>
+ <extracomment>Displayed after the untranslated message &quot;Branches: branch1, branch2 &apos;and %n more&apos;&quot;</extracomment>
+ <translation>
+ <numerusform>и ещё %n</numerusform>
+ <numerusform>и ещё %n</numerusform>
+ <numerusform>и ещё %n</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>&lt;None&gt;</source>
+ <translation>&lt;Нет&gt;</translation>
+ </message>
<message>
<source>No changes found.</source>
<translation>Изменений не найдено.</translation>
</message>
+ <message numerus="yes">
+ <source>Committed %n files.</source>
+ <translation>
+ <numerusform>Фиксирован %n файл.</numerusform>
+ <numerusform>Фиксировано %n файла.</numerusform>
+ <numerusform>Фиксировано %n файлов.</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>Amended &quot;%1&quot; (%n files).</source>
+ <translation>
+ <numerusform>Внесено изменение «%1» (%n файл).</numerusform>
+ <numerusform>Внесено изменение «%1» (%n файла).</numerusform>
+ <numerusform>Внесено изменение «%1» (%n файлов).</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>Cannot commit %n files: %1
+</source>
+ <translation>
+ <numerusform>Не удалось фиксировать %n файл: %1
+</numerusform>
+ <numerusform>Не удалось фиксировать %n файла: %1
+</numerusform>
+ <numerusform>Не удалось фиксировать %n файлов: %1
+</numerusform>
+ </translation>
+ </message>
<message>
<source>Conflicts detected with commit %1.</source>
<translation>Обнаружены конфликты с фиксацией %1.</translation>
@@ -18168,6 +18320,14 @@ Commit now?</source>
<source>Detached HEAD</source>
<translation>Отцеплённая HEAD</translation>
</message>
+ <message numerus="yes">
+ <source>Cannot reset %n files in &quot;%1&quot;: %2</source>
+ <translation>
+ <numerusform>Не удалось сбросить %n файл в «%1»: %2</numerusform>
+ <numerusform>Не удалось сбросить %n файла в «%1»: %2</numerusform>
+ <numerusform>Не удалось сбросить %n файлов в «%1»: %2</numerusform>
+ </translation>
+ </message>
<message>
<source>Cannot describe revision &quot;%1&quot; in &quot;%2&quot;: %3</source>
<translation>Не удалось получить описание ревизии «%1» в «%2»: %3</translation>
@@ -18267,18 +18427,6 @@ Commit now?</source>
<source>Amended &quot;%1&quot;.</source>
<translation>Внесено изменение «%1».</translation>
</message>
- <message numerus="yes">
- <source>Cannot commit %n file(s): %1
-</source>
- <translation>
- <numerusform>Не удалось фиксировать %n файл: %1
-</numerusform>
- <numerusform>Не удалось фиксировать %n файла: %1
-</numerusform>
- <numerusform>Не удалось фиксировать %n файлов: %1
-</numerusform>
- </translation>
- </message>
<message>
<source>Revert</source>
<translation>Откат</translation>
@@ -19267,10 +19415,6 @@ Perl через переменные среды окружения.</translation
<translation>Команда:</translation>
</message>
<message>
- <source>Show tags in Branches dialog</source>
- <translation>Показывать метки в диалоге веток</translation>
- </message>
- <message>
<source>Repository Browser</source>
<translation>Обозреватель хранилища</translation>
</message>
@@ -20414,14 +20558,26 @@ Ids must begin with a lowercase letter.</source>
</message>
</context>
<context>
- <name>Ios::Internal::IosAnalyzeSupport</name>
+ <name>Ios::Internal::CreateSimulatorDialog</name>
<message>
- <source>Run ended with error.</source>
- <translation>Выполнение завершилось с ошибкой.</translation>
+ <source>Create Simulator</source>
+ <translation>Создание эмулятора</translation>
</message>
<message>
- <source>Run ended.</source>
- <translation>Выполнение завершено.</translation>
+ <source>Simulator name:</source>
+ <translation>Название:</translation>
+ </message>
+ <message>
+ <source>Device type:</source>
+ <translation>Тип устройства:</translation>
+ </message>
+ <message>
+ <source>OS version:</source>
+ <translation>Верия OS:</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Нет</translation>
</message>
</context>
<context>
@@ -20529,13 +20685,17 @@ Ids must begin with a lowercase letter.</source>
<context>
<name>Ios::Internal::IosConfigurations</name>
<message>
- <source>%1 %2</source>
- <translation>%1 %2</translation>
+ <source>%1 Simulator</source>
+ <translation>Эмулятор %1</translation>
</message>
</context>
<context>
<name>Ios::Internal::IosDebugSupport</name>
<message>
+ <source>Application not running.</source>
+ <translation>Приложение не запущено.</translation>
+ </message>
+ <message>
<source>Could not find device specific debug symbols at %1. Debugging initialization will be slow until you open the Organizer window of Xcode with the device connected to have the symbols generated.</source>
<translation>Не удалось найти отладочные символы для устройства в %1. Инициализация отладки займёт много времени. Для её ускорения необходимо подключить устройство и открыть окно органайзера Xcode для генерации символов.</translation>
</message>
@@ -20547,22 +20707,6 @@ Ids must begin with a lowercase letter.</source>
<source>The dSYM %1 seems to be outdated, it might confuse the debugger.</source>
<translation>Видимо dSYM %1 устарел, он может смутить отладчик.</translation>
</message>
- <message>
- <source>Could not get debug server file descriptor.</source>
- <translation>Не удалось получить дескриптор файла сервера отладки.</translation>
- </message>
- <message>
- <source>Got an invalid process id.</source>
- <translation>Получен неверный идентификатор процесса.</translation>
- </message>
- <message>
- <source>Run ended with error.</source>
- <translation>Выполнение завершилось с ошибкой.</translation>
- </message>
- <message>
- <source>Run ended.</source>
- <translation>Выполнение завершено.</translation>
- </message>
</context>
<context>
<name>Ios::Internal::IosDeployConfiguration</name>
@@ -20690,6 +20834,13 @@ Ids must begin with a lowercase letter.</source>
</message>
</context>
<context>
+ <name>Ios::Internal::IosQmlProfilerSupport</name>
+ <message>
+ <source>Could not get necessary ports for the profiler connection.</source>
+ <translation>Не удалось получить необходимые порты для подключения профайлера.</translation>
+ </message>
+</context>
+<context>
<name>Ios::Internal::IosQtVersion</name>
<message>
<source>Failed to detect the ABIs used by the Qt version.</source>
@@ -20761,19 +20912,11 @@ Ids must begin with a lowercase letter.</source>
</message>
</context>
<context>
- <name>Ios::Internal::IosRunControl</name>
+ <name>Ios::Internal::IosRunSupport</name>
<message>
<source>Starting remote process.</source>
<translation>Запуск внешнего процесса.</translation>
</message>
- <message>
- <source>Run ended with error.</source>
- <translation>Выполнение завершилось с ошибкой.</translation>
- </message>
- <message>
- <source>Run ended.</source>
- <translation>Выполнение завершено.</translation>
- </message>
</context>
<context>
<name>Ios::Internal::IosRunner</name>
@@ -20782,6 +20925,18 @@ Ids must begin with a lowercase letter.</source>
<translation>Не удалось найти %1.</translation>
</message>
<message>
+ <source>Could not get necessary ports for the debugger connection.</source>
+ <translation>Не удалось получить необходимые порты для подключения отладчика.</translation>
+ </message>
+ <message>
+ <source>Could not get inferior PID.</source>
+ <translation>Не удалось получить PID процесса.</translation>
+ </message>
+ <message>
+ <source>Could not get necessary ports the debugger connection.</source>
+ <translation>Не удалось получить необходимые порты для подключения отладчика.</translation>
+ </message>
+ <message>
<source>Run failed. The settings in the Organizer window of Xcode might be incorrect.</source>
<translation>Не удалось запустить. Настройки Xcode в окне Organizer могут быть неверны.</translation>
</message>
@@ -20789,6 +20944,14 @@ Ids must begin with a lowercase letter.</source>
<source>The device is locked, please unlock.</source>
<translation>Устройство заблокировано, разблокируйте его.</translation>
</message>
+ <message>
+ <source>Run ended.</source>
+ <translation>Выполнение завершено.</translation>
+ </message>
+ <message>
+ <source>Run ended with error.</source>
+ <translation>Выполнение завершилось с ошибкой.</translation>
+ </message>
</context>
<context>
<name>Ios::Internal::IosSettingsPage</name>
@@ -20807,6 +20970,174 @@ Ids must begin with a lowercase letter.</source>
<source>Ask about devices not in developer mode</source>
<translation>Спрашивать об устройствах не в режиме разработки</translation>
</message>
+ <message>
+ <source>Devices</source>
+ <translation>Устройства</translation>
+ </message>
+ <message>
+ <source>Simulator</source>
+ <translation>Эмулятор</translation>
+ </message>
+ <message>
+ <source>Rename a simulator device.</source>
+ <translation>Переименовать эмулируемое устройство.</translation>
+ </message>
+ <message>
+ <source>Rename</source>
+ <translation>Переименовать</translation>
+ </message>
+ <message>
+ <source>Delete simulator devices.</source>
+ <translation>Удалить эмулируемые устройства.</translation>
+ </message>
+ <message>
+ <source>Delete</source>
+ <translation>Удалить</translation>
+ </message>
+ <message>
+ <source>Reset contents and settings of simulator devices.</source>
+ <translation>Сбросить содержимое и настройки эмулируемых устройств.</translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation>Сбросить</translation>
+ </message>
+ <message>
+ <source>Screenshot directory:</source>
+ <translation>Каталог снимков экрана:</translation>
+ </message>
+ <message>
+ <source>Create a new simulator device.</source>
+ <translation>Создать новое эмулируемое устройство.</translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation>Создать</translation>
+ </message>
+ <message>
+ <source>Start simulator devices.</source>
+ <translation>Запустить эмулируемые устройства.</translation>
+ </message>
+ <message>
+ <source>Start</source>
+ <translation>Запустить</translation>
+ </message>
+ <message>
+ <source>Screenshot</source>
+ <translation>Снимок экрана</translation>
+ </message>
+ <message numerus="yes">
+ <source>You are trying to launch %n simulators simultaneously. This will take significant system resources. Do you really want to continue?</source>
+ <translation>
+ <numerusform>Вы пытаетесь запустить одновременно %n эмулятор. На это уйдёт значительное число ресурсов системы. Продолжить?</numerusform>
+ <numerusform>Вы пытаетесь запустить одновременно %n эмулятора. На это уйдёт значительное число ресурсов системы. Продолжить?</numerusform>
+ <numerusform>Вы пытаетесь запустить одновременно %n эмуляторов. На это уйдёт значительное число ресурсов системы. Продолжить?</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Simulator Start</source>
+ <translation>Запустить эмулятор</translation>
+ </message>
+ <message numerus="yes">
+ <source>Starting simulator devices...</source>
+ <translation>
+ <numerusform>Запуск эмулируемых устройств...</numerusform>
+ <numerusform>Запуск эмулируемых устройств...</numerusform>
+ <numerusform>Запуск эмулируемых устройств...</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Cannot start simulator (%1, %2) in current state: %3</source>
+ <translation>Невозможно запустить эмулятор (%1, %2) в текущем состоянии: %3</translation>
+ </message>
+ <message>
+ <source>simulator start</source>
+ <translation>запуск эмулятора</translation>
+ </message>
+ <message>
+ <source>Creating simulator device...</source>
+ <translation>Создание эмулируемого устройства...</translation>
+ </message>
+ <message>
+ <source>Simulator device (%1) created.
+UDID: %2</source>
+ <translation>Эмулируемое устройство (%1) создано.
+UDID: %2</translation>
+ </message>
+ <message>
+ <source>Simulator device (%1) creation failed.
+Error: %2</source>
+ <translation>Не удалось создать эмулируемое устройство (%1).
+Ошибка: %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>Do you really want to reset the contents and settings of the selected devices?</source>
+ <translation>
+ <numerusform>Удалить содержимое и настройки выбранных устройств?</numerusform>
+ <numerusform>Удалить содержимое и настройки выбранных устройств?</numerusform>
+ <numerusform>Удалить содержимое и настройки выбранных устройств?</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Resetting contents and settings...</source>
+ <translation>Сброс содержимого и настроек...</translation>
+ </message>
+ <message>
+ <source>simulator reset</source>
+ <translation>сброс эмулятора</translation>
+ </message>
+ <message>
+ <source>Rename %1</source>
+ <translation>Переименование %1</translation>
+ </message>
+ <message>
+ <source>Enter new name:</source>
+ <translation>Введите новое название:</translation>
+ </message>
+ <message>
+ <source>Renaming simulator device...</source>
+ <translation>Переименование эмулируемого устройства...</translation>
+ </message>
+ <message>
+ <source>simulator rename</source>
+ <translation>переименование эмулятора</translation>
+ </message>
+ <message>
+ <source>Delete Device</source>
+ <translation>Удаление устройства</translation>
+ </message>
+ <message numerus="yes">
+ <source>Do you really want to delete the selected devices?</source>
+ <translation>
+ <numerusform>Удалить выбранные устройства?</numerusform>
+ <numerusform>Удалить выбранные устройства?</numerusform>
+ <numerusform>Удалить выбранные устройства?</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>Deleting simulator devices...</source>
+ <translation>
+ <numerusform>Удаление эмулируемых устройств...</numerusform>
+ <numerusform>Удаление эмулируемых устройств...</numerusform>
+ <numerusform>Удаление эмулируемых устройств...</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>simulator delete</source>
+ <translation>удаление эмулятора</translation>
+ </message>
+ <message numerus="yes">
+ <source>Capturing screenshots from devices...</source>
+ <translation>
+ <numerusform>Создание снимка экрана устройств...</numerusform>
+ <numerusform>Создание снимка экрана устройств...</numerusform>
+ <numerusform>Создание снимка экрана устройств...</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>simulator screenshot</source>
+ <translation>снимок экрана эмулятора</translation>
+ </message>
</context>
<context>
<name>Ios::Internal::IosSimulator</name>
@@ -20823,28 +21154,78 @@ Ids must begin with a lowercase letter.</source>
</message>
</context>
<context>
- <name>Ios::IosToolHandler</name>
+ <name>Ios::Internal::SimulatorInfoModel</name>
<message>
- <source>iOS tool Error %1</source>
- <translation>Ошибка %1 утилиты iOS</translation>
+ <source>UDID: %1</source>
+ <translation>UDID: %1</translation>
</message>
<message>
- <source>Application install on Simulator failed. %1</source>
- <translation>Не удалось установить приложение на эмулятор. %1</translation>
+ <source>Simulator Name</source>
+ <translation>Название эмулятора</translation>
+ </message>
+ <message>
+ <source>Runtime</source>
+ <translation type="unfinished">Программа</translation>
+ </message>
+ <message>
+ <source>Current State</source>
+ <translation>Текущее состояние</translation>
+ </message>
+</context>
+<context>
+ <name>Ios::Internal::SimulatorOperationDialog</name>
+ <message>
+ <source>Simulator Operation Status</source>
+ <translation>Состояние эмулятора</translation>
+ </message>
+ <message>
+ <source>%1, %2
+Operation %3 completed successfully.</source>
+ <translation>%1, %2
+Операция %3 успешно выполнена.</translation>
+ </message>
+ <message>
+ <source>%1, %2
+Operation %3 failed.
+UDID: %4
+Error: %5</source>
+ <translation>%1, %2
+Не удалось выполнить операции %3.
+UDID: %4
+Error: %5</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Неизвестная</translation>
+ </message>
+ <message>
+ <source>Done.</source>
+ <translation>Готово.</translation>
+ </message>
+</context>
+<context>
+ <name>Ios::IosToolHandler</name>
+ <message>
+ <source>iOS tool error %1</source>
+ <translation>Ошибка %1 утилиты iOS</translation>
</message>
<message>
- <source>Application install on Simulator failed. Simulator not running.</source>
+ <source>Application install on simulator failed. Simulator not running.</source>
<translation>Не удалось установить приложение на эмулятор. Он не запущен.</translation>
</message>
<message>
- <source>Application launch on Simulator failed. Invalid Bundle path %1</source>
+ <source>Application launch on simulator failed. Invalid bundle path %1</source>
<translation>Запуск приложения на эмуляторе не удался. Неверный путь пакета %1</translation>
</message>
<message>
- <source>Application launch on Simulator failed. Simulator not running.</source>
+ <source>Application launch on simulator failed. Simulator not running.</source>
<translation>Не удалось запустить приложение на эмуляторе. Он не запущен.</translation>
</message>
<message>
+ <source>Application install on simulator failed. %1</source>
+ <translation>Не удалось установить приложение на эмулятор. %1</translation>
+ </message>
+ <message>
<source>Cannot capture console output from %1. Error redirecting output to %2.*</source>
<translation>Не удалось захватить вывод в консоль с %1. Ошибка перенаправления вывода в %2.*</translation>
</message>
@@ -20853,7 +21234,7 @@ Ids must begin with a lowercase letter.</source>
<translation>Не удалось захватить вывод в консоль с %1. Установить Xcode 8 или более поздний.</translation>
</message>
<message>
- <source>Application launch on Simulator failed. %1</source>
+ <source>Application launch on simulator failed. %1</source>
<translation>Запуск приложения на эмуляторе не удался. %1</translation>
</message>
<message>
@@ -21931,6 +22312,13 @@ Ids must begin with a lowercase letter.</source>
</message>
</context>
<context>
+ <name>ModelEditor::Internal::ElementTasks</name>
+ <message>
+ <source>Update Include Dependencies</source>
+ <translation>Обновить зависимость от включаемых файлов</translation>
+ </message>
+</context>
+<context>
<name>ModelEditor::Internal::ExtPropertiesMView</name>
<message>
<source>Select Custom Configuration Folder</source>
@@ -22234,6 +22622,14 @@ Ids must begin with a lowercase letter.</source>
</message>
</context>
<context>
+ <name>Nim::NimPlugin</name>
+ <message>
+ <source>Nim</source>
+ <comment>SnippetProvider</comment>
+ <translation>Nim</translation>
+ </message>
+</context>
+<context>
<name>Nim::NimProject</name>
<message>
<source>Scanning for Nim files</source>
@@ -22339,13 +22735,6 @@ Ids must begin with a lowercase letter.</source>
</message>
</context>
<context>
- <name>NimSnippetProvider</name>
- <message>
- <source>Nim</source>
- <translation>Nim</translation>
- </message>
-</context>
-<context>
<name>OpenWith::Editors</name>
<message>
<source>Plain Text Editor</source>
@@ -23915,6 +24304,10 @@ cannot be found in the path.</source>
<source>Private key file</source>
<translation>Файл секретного ключа</translation>
</message>
+ <message>
+ <source>Device name</source>
+ <translation>Название устройства</translation>
+ </message>
</context>
<context>
<name>ProjectExplorer::DeviceManagerModel</name>
@@ -24054,7 +24447,7 @@ cannot be found in the path.</source>
<context>
<name>ProjectExplorer::EnvironmentWidget</name>
<message>
- <source>&amp;Edit</source>
+ <source>Ed&amp;it</source>
<translation>&amp;Изменить</translation>
</message>
<message>
@@ -25103,7 +25496,7 @@ Excluding: %2
<message>
<source>project</source>
<comment>Appears in &quot;Open project &lt;name&gt;&quot;</comment>
- <translation type="unfinished">проект</translation>
+ <translation>проект</translation>
</message>
</context>
<context>
@@ -25442,6 +25835,13 @@ to project &quot;%2&quot;.</source>
</message>
</context>
<context>
+ <name>ProjectExplorer::Internal::RunControlPrivate</name>
+ <message>
+ <source>Unexpected run control state %1 when worker %2 started.</source>
+ <translation type="unfinished">Неожиданное состояние %1 при запуске исполнителя %2.</translation>
+ </message>
+</context>
+<context>
<name>ProjectExplorer::Internal::RunSettingsWidget</name>
<message>
<source>Remove Run Configuration?</source>
@@ -25534,11 +25934,22 @@ to project &quot;%2&quot;.</source>
</message>
</context>
<context>
+ <name>ProjectExplorer::Internal::RunWorkerPrivate</name>
+ <message>
+ <source>Worker start timed out.</source>
+ <translation>Время запуска исполнителя истекло.</translation>
+ </message>
+ <message>
+ <source>Worker stop timed out.</source>
+ <translation>Время остановки исполнителя истекло.</translation>
+ </message>
+</context>
+<context>
<name>ProjectExplorer::Internal::SessionDelegate</name>
<message>
<source>session</source>
<comment>Appears in &quot;Open session &lt;name&gt;&quot;</comment>
- <translation type="unfinished">сессию</translation>
+ <translation>сессию</translation>
</message>
</context>
<context>
@@ -25594,13 +26005,6 @@ to project &quot;%2&quot;.</source>
<source>New Session Name</source>
<translation>Имя новой сессии</translation>
</message>
-</context>
-<context>
- <name>ProjectExplorer::Internal::SessionNameInputDialog</name>
- <message>
- <source>Enter the name of the session:</source>
- <translation>Введите название сессии:</translation>
- </message>
<message>
<source>&amp;Create</source>
<translation>&amp;Создать</translation>
@@ -25609,6 +26013,33 @@ to project &quot;%2&quot;.</source>
<source>Create and &amp;Open</source>
<translation>Создать и &amp;открыть</translation>
</message>
+ <message>
+ <source>&amp;Clone</source>
+ <translation>&amp;Копировать</translation>
+ </message>
+ <message>
+ <source>Clone and &amp;Open</source>
+ <translation>Копировать и &amp;открыть</translation>
+ </message>
+ <message>
+ <source>Rename Session</source>
+ <translation>Переименование сессии</translation>
+ </message>
+ <message>
+ <source>&amp;Rename</source>
+ <translation>&amp;Переименовать</translation>
+ </message>
+ <message>
+ <source>Rename and &amp;Open</source>
+ <translation>Переименовать и &amp;открыть</translation>
+ </message>
+</context>
+<context>
+ <name>ProjectExplorer::Internal::SessionNameInputDialog</name>
+ <message>
+ <source>Enter the name of the session:</source>
+ <translation>Введите название сессии:</translation>
+ </message>
</context>
<context>
<name>ProjectExplorer::Internal::ShowInEditorTaskHandler</name>
@@ -25794,28 +26225,6 @@ to project &quot;%2&quot;.</source>
</message>
</context>
<context>
- <name>ProjectExplorer::Internal::WinCEToolChainConfigWidget</name>
- <message>
- <source>SDK:</source>
- <translation>SDK:</translation>
- </message>
- <message>
- <source>WinCE Version:</source>
- <translation>Версия WinCE:</translation>
- </message>
- <message>
- <source>ABI:</source>
- <translation>ABI:</translation>
- </message>
-</context>
-<context>
- <name>ProjectExplorer::Internal::WinCEToolChainFactory</name>
- <message>
- <source>WinCE</source>
- <translation>WinCE</translation>
- </message>
-</context>
-<context>
<name>ProjectExplorer::Internal::WizardPage</name>
<message>
<source>The following files will be added:
@@ -26086,7 +26495,7 @@ to project &quot;%2&quot;.</source>
<translation>Не удалось открыть редактор для «%1».</translation>
</message>
<message>
- <source>When parsing fields of page &apos;%1&apos;: %2</source>
+ <source>When parsing fields of page &quot;%1&quot;: %2</source>
<translation>При обработке полей страницы «%1»: %2</translation>
</message>
<message>
@@ -27215,6 +27624,17 @@ Please close all running instances of your application before starting a build.<
</message>
</context>
<context>
+ <name>ProjectExplorer::PortsGatherer</name>
+ <message>
+ <source>Checking available ports...</source>
+ <translation>Проверка доступных портов...</translation>
+ </message>
+ <message>
+ <source>Found %1 free ports</source>
+ <translation>Обнаружено %1 свободных портов</translation>
+ </message>
+</context>
+<context>
<name>ProjectExplorer::Project</name>
<message>
<source>Project</source>
@@ -27407,10 +27827,6 @@ Please close all running instances of your application before starting a build.<
<translation>С&amp;ессии</translation>
</message>
<message>
- <source>Session &amp;Manager...</source>
- <translation>&amp;Управление сессиями...</translation>
- </message>
- <message>
<source>Close Pro&amp;ject &quot;%1&quot;</source>
<translation>Закрыть про&amp;ект «%1»</translation>
</message>
@@ -27480,10 +27896,6 @@ Please close all running instances of your application before starting a build.<
<translation>Имя текущей активной конфигурации запуска.</translation>
</message>
<message>
- <source>The currently active run configuration&apos;s executable (if applicable)</source>
- <translation>Исполняемый файл текущей активной конфигурации исполнения (если применимо)</translation>
- </message>
- <message>
<source>Cancel Build &amp;&amp; Unload</source>
<translation>Отменить сборку и выгрузить</translation>
</message>
@@ -27504,10 +27916,6 @@ Please close all running instances of your application before starting a build.<
<translation>Остановить процесс сборки и выгрузить проект?</translation>
</message>
<message>
- <source>Failed opening project &quot;%1&quot;: Project is not a file</source>
- <translation>Не удалось открыть проект «%1»: проект не является файлом</translation>
- </message>
- <message>
<source>Failed opening project &quot;%1&quot;: No plugin can open project type &quot;%2&quot;.</source>
<translation>Не удалось открыть проект «%1»: нет модуля для открытия проектов типа «%2».</translation>
</message>
@@ -27680,6 +28088,10 @@ Do you want to ignore them?</source>
<translation>Очистить</translation>
</message>
<message>
+ <source>&amp;Manage...</source>
+ <translation>&amp;Управление...</translation>
+ </message>
+ <message>
<source>Close All Projects and Editors</source>
<translation>Закрыть все документы и проекты</translation>
</message>
@@ -27732,6 +28144,10 @@ Do you want to ignore them?</source>
<translation>Название активной конфигурации сборки.</translation>
</message>
<message>
+ <source>The currently active run configuration&apos;s executable (if applicable).</source>
+ <translation>Исполняемый файл текущей активной конфигурации исполнения (если применимо).</translation>
+ </message>
+ <message>
<source>The currently active build configuration&apos;s type.</source>
<translation>Тип активной конфигурации сборки.</translation>
</message>
@@ -27760,6 +28176,10 @@ Do you want to ignore them?</source>
<translation>&lt;h3&gt;Проект уже открыт&lt;/h3&gt;</translation>
</message>
<message>
+ <source>Failed opening project &quot;%1&quot;: Project is not a file.</source>
+ <translation>Не удалось открыть проект «%1»: проект не является файлом.</translation>
+ </message>
+ <message>
<source>Unknown error</source>
<translation>Неизвестная ошибка</translation>
</message>
@@ -27930,6 +28350,33 @@ Do you want to ignore them?</source>
</message>
</context>
<context>
+ <name>ProjectExplorer::RunWorker</name>
+ <message>
+ <source>The process failed to start.</source>
+ <translation>Не удалось запустить процесс.</translation>
+ </message>
+ <message>
+ <source>An unknown error in the process occurred.</source>
+ <translation>У процесса возникла неизвестная ошибка.</translation>
+ </message>
+ <message>
+ <source>Either the invoked program &quot;%1&quot; is missing, or you may have insufficient permissions to invoke the program.</source>
+ <translation>Или отсутствует запущенная программа «%1», или недостаточно прав для её запуска.</translation>
+ </message>
+ <message>
+ <source>The process was ended forcefully.</source>
+ <translation>Процесс был завершён принудительно.</translation>
+ </message>
+ <message>
+ <source>An error occurred when attempting to write to the process. For example, the process may not be running, or it may have closed its input channel.</source>
+ <translation>Возникла ошибка при попытке отправить данные процессу. Возможно, процесс не запущен или он закрыл входной канал.</translation>
+ </message>
+ <message>
+ <source>An error occurred when attempting to read from the process. For example, the process may not be running.</source>
+ <translation>Ошибка при получении данных от процесса. Возможно, процесс уже перестал работать.</translation>
+ </message>
+</context>
+<context>
<name>ProjectExplorer::SelectableFilesDialogAddDirectory</name>
<message>
<source>Add Existing Directory</source>
@@ -28049,14 +28496,14 @@ These files are preserved.</source>
</message>
</context>
<context>
- <name>ProjectExplorer::SimpleRunControl</name>
+ <name>ProjectExplorer::SimpleTargetRunner</name>
<message>
<source>%1 crashed.</source>
<translation>%1 аварийно завершился.</translation>
</message>
<message>
- <source>%1 exited with code %2</source>
- <translation>%1 завершился с кодом %2</translation>
+ <source>%2 exited with code %1</source>
+ <translation>%2 завершился с кодом %1</translation>
</message>
</context>
<context>
@@ -28183,17 +28630,6 @@ These files are preserved.</source>
</message>
</context>
<context>
- <name>ProjectExplorer::TaskHub</name>
- <message>
- <source>Error</source>
- <translation>Ошибка</translation>
- </message>
- <message>
- <source>Warning</source>
- <translation>Предупреждение</translation>
- </message>
-</context>
-<context>
<name>ProjectExplorer::TerminalAspect</name>
<message>
<source>Terminal</source>
@@ -28498,6 +28934,25 @@ App ID: %2
</message>
</context>
<context>
+ <name>QSsh::Internal::SshAgent</name>
+ <message>
+ <source>Cannot connect to ssh-agent: SSH_AUTH_SOCK is not set.</source>
+ <translation>Не удалось подключиться к ssh-agent: не задан SSH_AUTH_SOCK.</translation>
+ </message>
+ <message>
+ <source>Lost connection to ssh-agent for unknown reason.</source>
+ <translation>Подключение к ssh-agent потеряно по неизвестной причине.</translation>
+ </message>
+ <message>
+ <source>ssh-agent failed to retrieve keys.</source>
+ <translation>ssh-agent не смог получить ключи.</translation>
+ </message>
+ <message>
+ <source>Protocol error when talking to ssh-agent.</source>
+ <translation>Ошибка протокола при общении с ssh-agent.</translation>
+ </message>
+</context>
+<context>
<name>QSsh::Internal::SshChannelManager</name>
<message>
<source>Unexpected request success packet.</source>
@@ -28555,10 +29010,18 @@ App ID: %2
<translation>Неожиданный пакет типа %1.</translation>
</message>
<message>
+ <source>ssh-agent has no keys.</source>
+ <translation>У ssh-agent нет ключей.</translation>
+ </message>
+ <message>
<source>Password expired.</source>
<translation>Время действия пароля истекло.</translation>
</message>
<message>
+ <source>The server rejected all keys known to the ssh-agent.</source>
+ <translation>Сервер отклонил все ключи известные ssh-agent.</translation>
+ </message>
+ <message>
<source>Server rejected password.</source>
<translation>Сервер отклонил пароль.</translation>
</message>
@@ -28567,6 +29030,14 @@ App ID: %2
<translation>Сервер отклонил ключ.</translation>
</message>
<message>
+ <source>Server sent unexpected SSH_MSG_USERAUTH_PK_OK packet.</source>
+ <translation>Сервер отправил неожиданный пакет SSH_MSG_USERAUTH_PK_OK.</translation>
+ </message>
+ <message>
+ <source>Server sent unexpected key in SSH_MSG_USERAUTH_PK_OK packet.</source>
+ <translation>Сервер отправил неожиданный ключ в пакете SSH_MSG_USERAUTH_PK_OK.</translation>
+ </message>
+ <message>
<source>The server sent an unexpected SSH packet of type SSH_MSG_UNIMPLEMENTED.</source>
<translation>Сервер послал неожиданный пакет SSH типа SSH_MSG_UNIMPLEMENTED.</translation>
</message>
@@ -28579,6 +29050,10 @@ App ID: %2
<translation>Соединение неожиданно закрылось.</translation>
</message>
<message>
+ <source>Timeout waiting for keys from ssh-agent.</source>
+ <translation>Истекло время ожидания ключей от ssh-agent.</translation>
+ </message>
+ <message>
<source>Timeout waiting for reply from server.</source>
<translation>Истекло время ожидания ответа от сервера.</translation>
</message>
@@ -28755,13 +29230,12 @@ App ID: %2
<source>Qbs</source>
<translation>Qbs</translation>
</message>
+</context>
+<context>
+ <name>QbsProjectManager::Internal::ConfigWidget</name>
<message>
- <source>Profiles</source>
- <translation>Профили</translation>
- </message>
- <message>
- <source>Version Info</source>
- <translation>Информация о версии</translation>
+ <source>Change...</source>
+ <translation>Изменить...</translation>
</message>
</context>
<context>
@@ -28840,6 +29314,10 @@ App ID: %2
<source>Build directory:</source>
<translation>Каталог сборки:</translation>
</message>
+ <message>
+ <source>Configuration name:</source>
+ <translation>Название конфигурации:</translation>
+ </message>
</context>
<context>
<name>QbsProjectManager::Internal::QbsBuildStep</name>
@@ -28989,14 +29467,55 @@ App ID: %2
</message>
</context>
<context>
- <name>QbsProjectManager::Internal::QbsInfoWidget</name>
+ <name>QbsProjectManager::Internal::QbsInstallStep</name>
<message>
- <source>Form</source>
- <translation></translation>
+ <source>Qbs Install</source>
+ <translation>Установка с Qbs</translation>
</message>
+</context>
+<context>
+ <name>QbsProjectManager::Internal::QbsInstallStepConfigWidget</name>
<message>
- <source>Qbs version:</source>
- <translation>Версия Qbs:</translation>
+ <source>Install root:</source>
+ <translation>Корень установки:</translation>
+ </message>
+ <message>
+ <source>Flags:</source>
+ <translation>Флаги:</translation>
+ </message>
+ <message>
+ <source>Dry run</source>
+ <translation>Тестовое выполнение</translation>
+ </message>
+ <message>
+ <source>Keep going</source>
+ <translation>Пропускать ошибки</translation>
+ </message>
+ <message>
+ <source>Remove first</source>
+ <translation type="unfinished">Сначала удалить</translation>
+ </message>
+ <message>
+ <source>Equivalent command line:</source>
+ <translation>Итоговая командная строка:</translation>
+ </message>
+ <message>
+ <source>&lt;b&gt;Qbs:&lt;/b&gt; %1</source>
+ <translation>&lt;b&gt;Qbs:&lt;/b&gt; %1</translation>
+ </message>
+</context>
+<context>
+ <name>QbsProjectManager::Internal::QbsInstallStepFactory</name>
+ <message>
+ <source>Qbs Install</source>
+ <translation>Установка с Qbs</translation>
+ </message>
+</context>
+<context>
+ <name>QbsProjectManager::Internal::QbsKitInformation</name>
+ <message>
+ <source>Additional Qbs Profile Settings</source>
+ <translation>Дополнительные настройки профиля Qbs</translation>
</message>
</context>
<context>
@@ -29033,13 +29552,17 @@ App ID: %2
<translation>&amp;Свернуть все</translation>
</message>
<message>
- <source>&amp;Edit...</source>
- <translation>&amp;Изменить...</translation>
- </message>
- <message>
<source>Store profiles in Qt Creator settings directory</source>
<translation>Хранить профили в каталоге настроек Qt Creator</translation>
</message>
+ <message>
+ <source>Qbs version:</source>
+ <translation>Версия Qbs:</translation>
+ </message>
+ <message>
+ <source>TextLabel</source>
+ <translation></translation>
+ </message>
</context>
<context>
<name>QbsProjectManager::Internal::QbsProject</name>
@@ -29052,8 +29575,16 @@ App ID: %2
<translation>Не удалось записать в файл проекта %1.</translation>
</message>
<message>
- <source>Cannot build: Selected products do not exist anymore.</source>
- <translation>Невозможно собрать: выбранный продукт больше не существует.</translation>
+ <source>%1: Selected products do not exist anymore.</source>
+ <translation>%1: выбранный продукт больше не существует.</translation>
+ </message>
+ <message>
+ <source>Cannot clean</source>
+ <translation>Очистка невозможна</translation>
+ </message>
+ <message>
+ <source>Cannot build</source>
+ <translation>Сборка невозможна</translation>
</message>
<message>
<source>Reading Project &quot;%1&quot;</source>
@@ -29095,6 +29626,30 @@ App ID: %2
<translation>Ctrl+Alt+Shift+B</translation>
</message>
<message>
+ <source>Clean</source>
+ <translation>Очистить</translation>
+ </message>
+ <message>
+ <source>Clean Product</source>
+ <translation>Очистить продукт</translation>
+ </message>
+ <message>
+ <source>Clean Product &quot;%1&quot;</source>
+ <translation>Очистить продукт «%1»</translation>
+ </message>
+ <message>
+ <source>Rebuild</source>
+ <translation>Пересобрать</translation>
+ </message>
+ <message>
+ <source>Rebuild Product</source>
+ <translation>Пересобрать продукт</translation>
+ </message>
+ <message>
+ <source>Rebuild Product &quot;%1&quot;</source>
+ <translation>Пересобрать продукт «%1»</translation>
+ </message>
+ <message>
<source>Build Subproject</source>
<translation>Собрать подпроект</translation>
</message>
@@ -29106,6 +29661,22 @@ App ID: %2
<source>Ctrl+Shift+B</source>
<translation>Ctrl+Shift+B</translation>
</message>
+ <message>
+ <source>Clean Subproject</source>
+ <translation>Очистить подпроект</translation>
+ </message>
+ <message>
+ <source>Clean Subproject &quot;%1&quot;</source>
+ <translation>Очистить подпроект «%1»</translation>
+ </message>
+ <message>
+ <source>Rebuild Subproject</source>
+ <translation>Пересобрать подпроект</translation>
+ </message>
+ <message>
+ <source>Rebuild Subproject &quot;%1&quot;</source>
+ <translation>Пересобрать подпроект «%1»</translation>
+ </message>
</context>
<context>
<name>QbsProjectManager::Internal::QbsRunConfiguration</name>
@@ -29268,6 +29839,10 @@ The files in the Android package source directory are copied to the build direct
<translation>Обнаружен старый каталог «android» в директории исходников. Qt 5.2 не использует его по умолчанию.</translation>
</message>
<message>
+ <source>Android build SDK not defined. Check Android settings.</source>
+ <translation>Не задан Android SDK для сборки. Проверьте настройки Android.</translation>
+ </message>
+ <message>
<source>No application .pro file found, not building an APK.</source>
<translation>Не найден файл .pro приложения, APK не собирается.</translation>
</message>
@@ -31019,12 +31594,12 @@ Neither the path to the library nor the path to its includes is added to the .pr
<context>
<name>QmlDesigner::Internal::MetaInfoReader</name>
<message>
- <source>Illegal state while parsing</source>
- <translation>При разборе обнаружен неверный state</translation>
+ <source>Illegal state while parsing.</source>
+ <translation>При разборе обнаружен неверный state.</translation>
</message>
<message>
- <source>No property definition allowed</source>
- <translation>Определение свойства недопустимо</translation>
+ <source>No property definition allowed.</source>
+ <translation>Определение свойства недопустимо.</translation>
</message>
<message>
<source>Invalid type %1</source>
@@ -31248,6 +31823,11 @@ Neither the path to the library nor the path to its includes is added to the .pr
<source>qsTranslate()</source>
<translation>qsTranslate()</translation>
</message>
+ <message>
+ <source>Root Item Init Size</source>
+ <translatorcomment>Полный перевод (начальный размер корневого элемента) не помещается в заголовке GroupBox</translatorcomment>
+ <translation>Начальный размер</translation>
+ </message>
</context>
<context>
<name>QmlDesigner::InvalidArgumentException</name>
@@ -31327,6 +31907,9 @@ This is independent of the visibility property in QML.</source>
<source>Use QML emulation layer that is built with the selected Qt</source>
<translation>Используйте слой эмуляции QML, собранный выбранным Qt</translation>
</message>
+</context>
+<context>
+ <name>QmlDesigner::NavigatorTreeView</name>
<message>
<source>Invalid Id</source>
<translation>Неверный идентификатор</translation>
@@ -31655,6 +32238,14 @@ This is independent of the visibility property in QML.</source>
<comment>Title of Editor widget</comment>
<translation>Состояния</translation>
</message>
+ <message>
+ <source>Cannot create QtQuick View</source>
+ <translation>Не удалось создать QtQuick View</translation>
+ </message>
+ <message>
+ <source>StatesEditorWidget: %1 cannot be created. Most likely QtQuick.Controls 1 are not installed.</source>
+ <translation>StatesEditorWidget: не удалось создать %1. Скорее всего не установлен QtQuick.Controls 1.</translation>
+ </message>
</context>
<context>
<name>QmlDesigner::TextEditorView</name>
@@ -32752,6 +33343,11 @@ For more information, see the &quot;Checking Code Syntax&quot; documentation.</s
<context>
<name>QmlJSEditor::Internal::QmlJSEditorPlugin</name>
<message>
+ <source>QML</source>
+ <comment>SnippetProvider</comment>
+ <translation>QML</translation>
+ </message>
+ <message>
<source>Find Usages</source>
<translation>Найти использование</translation>
</message>
@@ -32820,21 +33416,6 @@ For more information, see the &quot;Checking Code Syntax&quot; documentation.</s
</message>
</context>
<context>
- <name>QmlJSEditor::Internal::QmlJSHoverHandler</name>
- <message>
- <source>Library at %1</source>
- <translation>Библиотека в %1</translation>
- </message>
- <message>
- <source>Dumped plugins successfully.</source>
- <translation>Данные модулей успешно получены.</translation>
- </message>
- <message>
- <source>Read typeinfo files successfully.</source>
- <translation>Файлы информации о типах успешно прочитаны.</translation>
- </message>
-</context>
-<context>
<name>QmlJSEditor::Internal::QmlJSOutlineTreeView</name>
<message>
<source>Expand All</source>
@@ -32870,13 +33451,6 @@ For more information, see the &quot;Checking Code Syntax&quot; documentation.</s
</message>
</context>
<context>
- <name>QmlJSEditor::Internal::QmlJSSnippetProvider</name>
- <message>
- <source>QML</source>
- <translation></translation>
- </message>
-</context>
-<context>
<name>QmlJSEditor::Internal::QmlJsEditingSettingsPage</name>
<message>
<source>Form</source>
@@ -32923,6 +33497,21 @@ For more information, see the &quot;Checking Code Syntax&quot; documentation.</s
</message>
</context>
<context>
+ <name>QmlJSHoverHandler</name>
+ <message>
+ <source>Library at %1</source>
+ <translation>Библиотека в %1</translation>
+ </message>
+ <message>
+ <source>Dumped plugins successfully.</source>
+ <translation>Данные модулей успешно получены.</translation>
+ </message>
+ <message>
+ <source>Read typeinfo files successfully.</source>
+ <translation>Файлы информации о типах успешно прочитаны.</translation>
+ </message>
+</context>
+<context>
<name>QmlJSTools</name>
<message>
<source>Code Style</source>
@@ -33577,6 +34166,10 @@ Qt Creator know about a likely URI.</source>
<translation>Запуск профайлера QML</translation>
</message>
<message>
+ <source>Select an externally started QML-debug enabled application.&lt;p&gt;Commonly used command-line arguments are:</source>
+ <translation>Выберите внешнее QML приложение, собранное в отладочном режиме.&lt;p&gt;Часто используемые аргументы командной строки:</translation>
+ </message>
+ <message>
<source>Kit:</source>
<translation>Комплект:</translation>
</message>
@@ -33690,13 +34283,6 @@ the program.</source>
</message>
</context>
<context>
- <name>QmlProfiler::Internal::QmlProfilerRunControlFactory</name>
- <message>
- <source>No executable file to launch.</source>
- <translation>Нет программы для запуска.</translation>
- </message>
-</context>
-<context>
<name>QmlProfiler::Internal::QmlProfilerStateWidget</name>
<message numerus="yes">
<source>Profiling application: %n events</source>
@@ -33851,8 +34437,8 @@ the program.</source>
<translation>Сохранить трассировку QML</translation>
</message>
<message>
- <source>QML Profiler (External)</source>
- <translation>Профайлер QML (внешний)</translation>
+ <source>QML Profiler (Attach to Waiting Application)</source>
+ <translation>Профайлер QML (подключение к ожидающему приложению)</translation>
</message>
<message>
<source>A QML Profiler analysis is still in progress.</source>
@@ -34010,7 +34596,7 @@ Do you want to save the data first?</source>
</message>
</context>
<context>
- <name>QmlProfiler::QmlProfilerRunControl</name>
+ <name>QmlProfiler::QmlProfilerRunner</name>
<message>
<source>Qt Creator</source>
<translation>Qt Creator</translation>
@@ -34173,32 +34759,6 @@ Do you want to save the data first?</source>
</message>
</context>
<context>
- <name>Qnx::Internal::QnxAbstractRunSupport</name>
- <message>
- <source>Not enough free ports on device for debugging.</source>
- <translation>Недостаточно свободных портов на устройстве для отладки.</translation>
- </message>
-</context>
-<context>
- <name>Qnx::Internal::QnxAnalyzeSupport</name>
- <message>
- <source>Preparing remote side...</source>
- <translation>Подготовка удалённой стороны...</translation>
- </message>
- <message>
- <source>The %1 process closed unexpectedly.</source>
- <translation>Процесс %1 неожиданно завершился.</translation>
- </message>
- <message>
- <source>Initial setup failed: %1</source>
- <translation>Не удалось выполнить начальную настройку: %1</translation>
- </message>
- <message>
- <source>Warning: &quot;slog2info&quot; is not found on the device, debug output not available.</source>
- <translation>Предупреждение: «slog2info» не найдена на устройстве, вывод отладчика недоступен.</translation>
- </message>
-</context>
-<context>
<name>Qnx::Internal::QnxAttachDebugDialog</name>
<message>
<source>Project source directory:</source>
@@ -34216,12 +34776,8 @@ Do you want to save the data first?</source>
<translation>Недостаточно свободных портов для отладки.</translation>
</message>
<message>
- <source>Remote: &quot;%1:%2&quot; - Process %3</source>
- <translation>Удалённо: «%1:%2» - процесс %3</translation>
- </message>
- <message>
- <source>Attaching failed.</source>
- <translation>Подключение не удалось.</translation>
+ <source>Remote: &quot;%1&quot; - Process %2</source>
+ <translation>Удалённо: «%1» - процесс %2</translation>
</message>
</context>
<context>
@@ -34261,18 +34817,6 @@ Do you want to save the data first?</source>
<source>Preparing remote side...</source>
<translation>Подготовка удалённой стороны...</translation>
</message>
- <message>
- <source>The %1 process closed unexpectedly.</source>
- <translation>Процесс %1 неожиданно завершился.</translation>
- </message>
- <message>
- <source>Initial setup failed: %1</source>
- <translation>Не удалось выполнить начальную настройку: %1</translation>
- </message>
- <message>
- <source>Warning: &quot;slog2info&quot; is not found on the device, debug output not available.</source>
- <translation>Предупреждение: «slog2info» не найдена на устройстве, вывод отладчика недоступен.</translation>
- </message>
</context>
<context>
<name>Qnx::Internal::QnxDeployConfigurationFactory</name>
@@ -34392,6 +34936,13 @@ Are you sure you want to continue?</source>
</message>
</context>
<context>
+ <name>Qnx::Internal::QnxQmlProfilerSupport</name>
+ <message>
+ <source>Preparing remote side...</source>
+ <translation>Подготовка удалённой стороны...</translation>
+ </message>
+</context>
+<context>
<name>Qnx::Internal::QnxQtVersion</name>
<message>
<source>QNX %1</source>
@@ -34418,13 +34969,6 @@ Are you sure you want to continue?</source>
</message>
</context>
<context>
- <name>Qnx::Internal::QnxRunControl</name>
- <message>
- <source>Warning: &quot;slog2info&quot; is not found on the device, debug output not available.</source>
- <translation>Предупреждение: «slog2info» не найдена на устройстве, вывод отладчика недоступен.</translation>
- </message>
-</context>
-<context>
<name>Qnx::Internal::QnxSettingsPage</name>
<message>
<source>QNX</source>
@@ -34518,6 +35062,10 @@ Are you sure you want to continue?</source>
<context>
<name>Qnx::Internal::Slog2InfoRunner</name>
<message>
+ <source>Warning: &quot;slog2info&quot; is not found on the device, debug output not available.</source>
+ <translation>Предупреждение: «slog2info» не найдена на устройстве, вывод отладчика недоступен.</translation>
+ </message>
+ <message>
<source>Cannot show slog2info output. Error: %1</source>
<translation>Не удалось отобразить вывод slog2info. Ошибка: %1</translation>
</message>
@@ -35166,11 +35714,6 @@ For more details, see /etc/sysctl.d/10-ptrace.conf
<translation>qmlscene не установлен.</translation>
</message>
<message>
- <source>Qt for WinCE</source>
- <comment>Qt Version is meant for WinCE</comment>
- <translation>Qt для WinCE</translation>
- </message>
- <message>
<source>Embedded Linux</source>
<comment>Qt Version is used for embedded Linux development</comment>
<translation>Встраиваемый Linux</translation>
@@ -35373,6 +35916,17 @@ For more details, see /etc/sysctl.d/10-ptrace.conf
</message>
</context>
<context>
+ <name>RemoteLinux::FifoGatherer</name>
+ <message>
+ <source>Creating remote socket...</source>
+ <translation>Создание внешнего сокета...</translation>
+ </message>
+ <message>
+ <source>Created fifo: %1</source>
+ <translation>Создан канал: %1</translation>
+ </message>
+</context>
+<context>
<name>RemoteLinux::GenericDirectUploadService</name>
<message>
<source>SFTP initialization failed: %1</source>
@@ -35519,6 +36073,10 @@ For more details, see /etc/sysctl.d/10-ptrace.conf
<source>&amp;Check host key</source>
<translation>Проверять кл&amp;юч хоста</translation>
</message>
+ <message>
+ <source>Key via ssh-agent</source>
+ <translation>Ключ через ssh-agent</translation>
+ </message>
</context>
<context>
<name>RemoteLinux::GenericLinuxDeviceConfigurationWizard</name>
@@ -35654,6 +36212,10 @@ In addition, device connectivity will be tested.</source>
<source>The username to log into the device:</source>
<translation>Имя пользователя для входа в устройство:</translation>
</message>
+ <message>
+ <source>Agent</source>
+ <translation>Агент</translation>
+ </message>
</context>
<context>
<name>RemoteLinux::Internal::LinuxDevice</name>
@@ -35770,21 +36332,6 @@ In addition, device connectivity will be tested.</source>
</message>
</context>
<context>
- <name>RemoteLinux::Internal::RemoteLinuxRunControlFactory</name>
- <message>
- <source>Cannot debug: Kit has no device.</source>
- <translation>Отладка невозможна: комплект не имеет устройства.</translation>
- </message>
- <message>
- <source>Cannot debug: Not enough free ports available.</source>
- <translation>Отладка невозможна: недостаточно свободных портов.</translation>
- </message>
- <message>
- <source>Cannot debug: Local executable is not set.</source>
- <translation>Отладка невозможна: локальная программа не задана.</translation>
- </message>
-</context>
-<context>
<name>RemoteLinux::Internal::TypeSpecificDeviceConfigurationListModel</name>
<message>
<source>%1 (default)</source>
@@ -35794,24 +36341,8 @@ In addition, device connectivity will be tested.</source>
<context>
<name>RemoteLinux::LinuxDeviceDebugSupport</name>
<message>
- <source>Checking available ports...</source>
- <translation>Проверка доступных портов...</translation>
- </message>
- <message>
- <source>Not enough free ports on device for C++ debugging.</source>
- <translation>Недостаточно свободных портов на устройстве для отладки C++.</translation>
- </message>
- <message>
- <source>Not enough free ports on device for QML debugging.</source>
- <translation>Недостаточно свободных портов на устройстве для отладки QML.</translation>
- </message>
- <message>
- <source>Debugging failed.</source>
- <translation>Ошибка отладки.</translation>
- </message>
- <message>
- <source>Initial setup failed: %1</source>
- <translation>Не удалось выполнить начальную настройку: %1</translation>
+ <source>Cannot debug: Local executable is not set.</source>
+ <translation>Отладка невозможна: локальная программа не задана.</translation>
</message>
</context>
<context>
@@ -35838,33 +36369,6 @@ In addition, device connectivity will be tested.</source>
</message>
</context>
<context>
- <name>RemoteLinux::RemoteLinuxAnalyzeSupport</name>
- <message>
- <source>Checking available ports...</source>
- <translation>Проверка доступных портов...</translation>
- </message>
- <message>
- <source>Creating remote socket...</source>
- <translation>Создание внешнего сокета...</translation>
- </message>
- <message>
- <source>Not enough free ports on device for profiling.</source>
- <translation>Недостаточно свободных портов на устройстве для профилирования.</translation>
- </message>
- <message>
- <source>FIFO for profiling data could not be created.</source>
- <translation>Не удалось создать канал для данных профилирования.</translation>
- </message>
- <message>
- <source>Failure running remote process.</source>
- <translation>Ошибка работы внешнего процесса.</translation>
- </message>
- <message>
- <source>Initial setup failed: %1</source>
- <translation>Не удалось выполнить начальную настройку: %1</translation>
- </message>
-</context>
-<context>
<name>RemoteLinux::RemoteLinuxCheckForFreeDiskSpaceService</name>
<message>
<source>Remote process failed to start.</source>
@@ -35964,6 +36468,13 @@ In addition, device connectivity will be tested.</source>
</message>
</context>
<context>
+ <name>RemoteLinux::RemoteLinuxPerfSupport</name>
+ <message>
+ <source>FIFO for profiling data could not be created.</source>
+ <translation>Не удалось создать канал для данных профилирования.</translation>
+ </message>
+</context>
+<context>
<name>RemoteLinux::RemoteLinuxRunConfiguration</name>
<message>
<source>%1 (on Remote Device)</source>
@@ -36743,14 +37254,14 @@ In addition, device connectivity will be tested.</source>
<translation>Ошибки(%1) / Предупреждения(%2) / Информация(%3)</translation>
</message>
<message>
- <source>Export To File</source>
- <translation>Экспорт в файл</translation>
- </message>
- <message>
<source>CSV files (*.csv)</source>
<translation>Файлы CSV (*.csv)</translation>
</message>
<message>
+ <source>Export to File</source>
+ <translation>Экспорт в файл</translation>
+ </message>
+ <message>
<source>Export Failed</source>
<translation>Ошибка экспорта</translation>
</message>
@@ -37214,6 +37725,10 @@ Row: %4, Column: %5
<translation>Приблизиться к состоянию</translation>
</message>
<message>
+ <source>Re-Layout</source>
+ <translation>Перекомпоновать</translation>
+ </message>
+ <message>
<source>Relayout</source>
<translation>Перекомпоновать</translation>
</message>
@@ -37301,8 +37816,8 @@ Row: %4, Column: %5
<context>
<name>SilverSearcher::FindInFilesSilverSearcher</name>
<message>
- <source>SilverSearcher is not available on system</source>
- <translation>SilverSearcher недоступен в системе</translation>
+ <source>Silver Searcher is not available on the system.</source>
+ <translation>Silver Searcher отсутствует в системе.</translation>
</message>
</context>
<context>
@@ -37935,6 +38450,17 @@ with a password, which you can enter below.</source>
</message>
</context>
<context>
+ <name>TaskHub</name>
+ <message>
+ <source>Error</source>
+ <translation>Ошибка</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Предупреждение</translation>
+ </message>
+</context>
+<context>
<name>TaskList::Internal::StopMonitoringHandler</name>
<message>
<source>Stop Monitoring</source>
@@ -38083,11 +38609,11 @@ with a password, which you can enter below.</source>
<translation>Прерывание замены.</translation>
</message>
<message numerus="yes">
- <source>%n found</source>
+ <source>%n found.</source>
<translation>
- <numerusform>%n найден</numerusform>
- <numerusform>%n найдено</numerusform>
- <numerusform>%n найдено</numerusform>
+ <numerusform>%n найден.</numerusform>
+ <numerusform>%n найдено.</numerusform>
+ <numerusform>%n найдено.</numerusform>
</translation>
</message>
</context>
@@ -38624,10 +39150,6 @@ Specifies how backspace interacts with indentation.
<translation>Убрать фон.</translation>
</message>
<message>
- <source>Underline:</source>
- <translation>Подчёркивание:</translation>
- </message>
- <message>
<source>No Underline</source>
<translatorcomment>Подчёркивание: отсутствует</translatorcomment>
<translation>Отсутствует</translation>
@@ -38657,14 +39179,6 @@ Specifies how backspace interacts with indentation.
<translation>Штрихпунктирное с двумя точками</translation>
</message>
<message>
- <source>Saturation</source>
- <translation>Насыщенность</translation>
- </message>
- <message>
- <source>Lightness</source>
- <translation>Яркость</translation>
- </message>
- <message>
<source>Relative Foreground</source>
<translation>Относительно переднего слоя</translation>
</message>
@@ -38672,6 +39186,26 @@ Specifies how backspace interacts with indentation.
<source>Relative Background</source>
<translation>Относительно заднего слоя</translation>
</message>
+ <message>
+ <source>Lightness:</source>
+ <translation>Яркость:</translation>
+ </message>
+ <message>
+ <source>Saturation:</source>
+ <translation>Насыщенность:</translation>
+ </message>
+ <message>
+ <source>Font</source>
+ <translation>Шрифт</translation>
+ </message>
+ <message>
+ <source>Underline</source>
+ <translation>Подчёркивание</translation>
+ </message>
+ <message>
+ <source>Color:</source>
+ <translation>Цвет:</translation>
+ </message>
</context>
<context>
<name>TextEditor::Internal::CompletionSettingsPage</name>
@@ -38902,6 +39436,26 @@ In addition, Shift+Enter inserts an escape character at the cursor position and
<source>Highlight search results on the scrollbar</source>
<translation>Результаты поиска на полосе прокрутки</translation>
</message>
+ <message>
+ <source>Animate navigation within file</source>
+ <translation>Анимировать навигацию по файлу</translation>
+ </message>
+ <message>
+ <source>Annotations next to lines</source>
+ <translation>Построчная аннотация</translation>
+ </message>
+ <message>
+ <source>Next to editor content</source>
+ <translation>За содержимым редактора</translation>
+ </message>
+ <message>
+ <source>Next to right margin</source>
+ <translation>За правой границей</translation>
+ </message>
+ <message>
+ <source>Aligned at right side</source>
+ <translation>Прижать к правому краю</translation>
+ </message>
</context>
<context>
<name>TextEditor::Internal::FindInCurrentFile</name>
@@ -39132,13 +39686,6 @@ In addition, Shift+Enter inserts an escape character at the cursor position and
</message>
</context>
<context>
- <name>TextEditor::Internal::PlainTextSnippetProvider</name>
- <message>
- <source>Text</source>
- <translation>Текст</translation>
- </message>
-</context>
-<context>
<name>TextEditor::Internal::SnippetsCollection</name>
<message>
<source>Cannot create user snippet directory %1</source>
@@ -39344,6 +39891,10 @@ Influences the indentation of continuation lines.
<translation>Удалить строк&amp;у</translation>
</message>
<message>
+ <source>Delete Line from Cursor On</source>
+ <translation>Удалить строку с курсором</translation>
+ </message>
+ <message>
<source>Delete Word from Cursor On</source>
<translation>Удалить слово под курсором</translation>
</message>
@@ -39352,6 +39903,10 @@ Influences the indentation of continuation lines.
<translation>Удалить слово под курсором с учётом верблюжьего регистра</translation>
</message>
<message>
+ <source>Delete Line up to Cursor</source>
+ <translation>Удалить строку над курсором</translation>
+ </message>
+ <message>
<source>Delete Word up to Cursor</source>
<translation>Удалить слово перед курсором</translation>
</message>
@@ -39803,6 +40358,15 @@ Influences the indentation of continuation lines.
<translation></translation>
</message>
<message>
+ <source>Show Context Menu</source>
+ <translation>Показать контекстное меню</translation>
+ </message>
+ <message>
+ <source>Text</source>
+ <comment>SnippetProvider</comment>
+ <translation>Текст</translation>
+ </message>
+ <message>
<source>Selected text within the current document.</source>
<translation>Выделенный текст внутри текущего документа.</translation>
</message>
@@ -40420,6 +40984,13 @@ Will not be applied to whitespace in comments and strings.</source>
</message>
</context>
<context>
+ <name>TextEditorWidgetPrivate</name>
+ <message>
+ <source>Other annotations:</source>
+ <translation>Другие аннотации:</translation>
+ </message>
+</context>
+<context>
<name>TextFieldSpecifics</name>
<message>
<source>Text Field</source>
@@ -40926,8 +41497,8 @@ Will not be applied to whitespace in comments and strings.</source>
<context>
<name>Utils::DebuggerMainWindow</name>
<message>
- <source>Views</source>
- <translation>Обзоры</translation>
+ <source>&amp;Views</source>
+ <translation>&amp;Обзоры</translation>
</message>
<message>
<source>Toolbar</source>
@@ -41167,6 +41738,10 @@ Will not be applied to whitespace in comments and strings.</source>
<translation>Ошибка файла</translation>
</message>
<message>
+ <source>Cannot write file %1: %2</source>
+ <translation>Не удалось записать файл %1: %2</translation>
+ </message>
+ <message>
<source>Cannot write file %1. Disk full?</source>
<translation>Не удалось записать файл %1. Нет места?</translation>
</message>
@@ -41490,6 +42065,13 @@ Will not be applied to whitespace in comments and strings.</source>
</message>
</context>
<context>
+ <name>Utils::SaveFile</name>
+ <message>
+ <source>File might be locked.</source>
+ <translation>Файл может быть заблокирован.</translation>
+ </message>
+</context>
+<context>
<name>Utils::SettingsAccessor</name>
<message>
<source>No Valid Settings Found</source>
@@ -41871,17 +42453,6 @@ Will not be applied to whitespace in comments and strings.</source>
<source>Callgrind unpaused.</source>
<translation>Callgrind продолжает работу.</translation>
</message>
- <message>
- <source>Downloading remote profile data...</source>
- <translation>Загрузка внешних данных профилирования...</translation>
- </message>
-</context>
-<context>
- <name>Valgrind::Callgrind::CallgrindRunner</name>
- <message>
- <source>Parsing Profile Data...</source>
- <translation>Обработка данных профилирования...</translation>
- </message>
</context>
<context>
<name>Valgrind::Callgrind::DataModel</name>
@@ -42040,17 +42611,6 @@ Will not be applied to whitespace in comments and strings.</source>
</message>
</context>
<context>
- <name>Valgrind::Internal::CallgrindRunControl</name>
- <message>
- <source>Profiling</source>
- <translation>Профилирование</translation>
- </message>
- <message>
- <source>Profiling %1</source>
- <translation>Профилирование %1</translation>
- </message>
-</context>
-<context>
<name>Valgrind::Internal::CallgrindTool</name>
<message>
<source>Valgrind Function Profiler uses the Callgrind tool to record function calls when a program runs.</source>
@@ -42214,21 +42774,25 @@ Will not be applied to whitespace in comments and strings.</source>
</message>
</context>
<context>
- <name>Valgrind::Internal::MemcheckErrorView</name>
+ <name>Valgrind::Internal::CallgrindToolRunner</name>
<message>
- <source>Suppress Error</source>
- <translation>Игнорировать ошибку</translation>
+ <source>Profiling</source>
+ <translation>Профилирование</translation>
</message>
-</context>
-<context>
- <name>Valgrind::Internal::MemcheckRunControl</name>
<message>
- <source>Analyzing Memory</source>
- <translation>Анализ памяти</translation>
+ <source>Profiling %1</source>
+ <translation>Профилирование %1</translation>
</message>
<message>
- <source>Analyzing memory of %1</source>
- <translation>Анализ памяти %1</translation>
+ <source>Parsing Profile Data...</source>
+ <translation>Обработка данных профилирования...</translation>
+ </message>
+</context>
+<context>
+ <name>Valgrind::Internal::MemcheckErrorView</name>
+ <message>
+ <source>Suppress Error</source>
+ <translation>Игнорировать ошибку</translation>
</message>
</context>
<context>
@@ -42357,6 +42921,13 @@ When a problem is detected, the application is interrupted and can be debugged.<
</message>
</context>
<context>
+ <name>Valgrind::Internal::MemcheckToolRunner</name>
+ <message>
+ <source>Analyzing Memory</source>
+ <translation>Анализ памяти</translation>
+ </message>
+</context>
+<context>
<name>Valgrind::Internal::SuppressionDialog</name>
<message>
<source>Suppression File:</source>
@@ -42558,7 +43129,7 @@ With cache simulation, further event counters are enabled:
</message>
</context>
<context>
- <name>Valgrind::Internal::ValgrindRunControl</name>
+ <name>Valgrind::Internal::ValgrindToolRunner</name>
<message>
<source>Valgrind options: %1</source>
<translation>Параметры Valgrind: %1</translation>
@@ -42596,7 +43167,7 @@ With cache simulation, further event counters are enabled:
</message>
</context>
<context>
- <name>Valgrind::Memcheck::MemcheckRunner</name>
+ <name>Valgrind::ValgrindRunner</name>
<message>
<source>XmlServer on %1:</source>
<translation>XmlServer на %1:</translation>
@@ -42607,13 +43178,6 @@ With cache simulation, further event counters are enabled:
</message>
</context>
<context>
- <name>Valgrind::ValgrindProcess</name>
- <message>
- <source>Could not determine remote PID.</source>
- <translation>Не удалось определить удалённый PID.</translation>
- </message>
-</context>
-<context>
<name>Valgrind::XmlProtocol</name>
<message>
<source>Function:</source>
@@ -43016,6 +43580,13 @@ should a repository require SSH-authentication (see documentation on SSH and the
</message>
</context>
<context>
+ <name>VcsBase::VcsBaseDiffEditorControllerPrivate</name>
+ <message>
+ <source>Processing diff</source>
+ <translation>Обработка отличий</translation>
+ </message>
+</context>
+<context>
<name>VcsBase::VcsBaseEditorWidget</name>
<message>
<source>Annotate &quot;%1&quot;</source>
@@ -43263,16 +43834,16 @@ should a repository require SSH-authentication (see documentation on SSH and the
<context>
<name>WidgetPluginManager</name>
<message>
- <source>Failed to create instance of file &apos;%1&apos;: %2</source>
+ <source>Failed to create instance of file &quot;%1&quot;: %2</source>
<translation>Не удалось создать экземпляр файла «%1»: %2</translation>
</message>
<message>
- <source>Failed to create instance of file &apos;%1&apos;.</source>
+ <source>Failed to create instance of file &quot;%1&quot;.</source>
<translation>Не удалось создать экземпляр файла «%1».</translation>
</message>
<message>
- <source>File &apos;%1&apos; is not a QmlDesigner plugin.</source>
- <translation>Файл «%1» не является модулем QmlDesigner.</translation>
+ <source>File &quot;%1&quot; is not a Qt Quick Designer plugin.</source>
+ <translation>Файл «%1» не является модулем Qt Quick Designer.</translation>
</message>
</context>
<context>
@@ -43449,17 +44020,6 @@ should a repository require SSH-authentication (see documentation on SSH and the
</message>
</context>
<context>
- <name>WinRt::Internal::WinRtRunControlFactory</name>
- <message>
- <source>Unsupported run mode %1.</source>
- <translation>Режим запуска %1 не поддерживается.</translation>
- </message>
- <message>
- <source>WinRT Run Control Factory</source>
- <translation>Фабрика компонентов WinRT</translation>
- </message>
-</context>
-<context>
<name>WinRt::Internal::WinRtRunnerHelper</name>
<message>
<source>The current kit has no Qt version.</source>
diff --git a/src/app/app.qbs b/src/app/app.qbs
index b67ff28a2c..d0c2885c46 100644
--- a/src/app/app.qbs
+++ b/src/app/app.qbs
@@ -20,9 +20,10 @@ QtcProduct {
targetName: qtc.ide_app_target
version: qtc.qtcreator_version
- installDir: bundle.isBundle ? qtc.ide_app_path : qtc.ide_bin_path
- installTags: bundle.isBundle ? ["bundle.content"] : base
- installSourceBase: bundle.isBundle ? buildDirectory : base
+ property bool isBundle: qbs.targetOS.contains("darwin") && bundle.isBundle
+ installDir: isBundle ? qtc.ide_app_path : qtc.ide_bin_path
+ installTags: isBundle ? ["bundle.content"] : base
+ installSourceBase: isBundle ? buildDirectory : base
property bool qtcRunnable: true
cpp.rpaths: qbs.targetOS.contains("macos") ? ["@executable_path/../Frameworks"]
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp
index 0e9fccead2..3f09e7b1a2 100644
--- a/src/libs/cplusplus/LookupContext.cpp
+++ b/src/libs/cplusplus/LookupContext.cpp
@@ -1387,6 +1387,8 @@ void ClassOrNamespace::instantiateNestedClasses(ClassOrNamespace *enclosingTempl
void ClassOrNamespace::NestedClassInstantiator::instantiate(ClassOrNamespace *enclosingTemplateClass,
ClassOrNamespace *enclosingTemplateClassInstantiation)
{
+ if (_alreadyConsideredNestedClassInstantiations.size() >= 3)
+ return;
if (_alreadyConsideredNestedClassInstantiations.contains(enclosingTemplateClass))
return;
_alreadyConsideredNestedClassInstantiations.insert(enclosingTemplateClass);
diff --git a/src/libs/cplusplus/MatchingText.cpp b/src/libs/cplusplus/MatchingText.cpp
index e2f04e4f0f..447c91ea59 100644
--- a/src/libs/cplusplus/MatchingText.cpp
+++ b/src/libs/cplusplus/MatchingText.cpp
@@ -326,6 +326,11 @@ static bool allowAutoClosingBrace(const QTextCursor &cursor,
int prevState;
const Tokens tokens = getTokens(cursor, prevState);
+
+ const Token token = tokenAtPosition(tokens, cursor.positionInBlock());
+ if (token.isStringLiteral())
+ return false;
+
if (isAfterNamespaceDefinition(tokens, cursor.positionInBlock()))
return false;
diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index 1076bd27c0..52180c4cc3 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -1781,6 +1781,9 @@ const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
addMessage(ErrInvalidMember, idPart->identifierToken, propertyName, objectValue->className());
return 0;
}
+ // resolve references
+ if (const Reference *ref = value->asReference())
+ value = _context->lookupReference(ref);
}
return value;
diff --git a/src/libs/utils/persistentsettings.cpp b/src/libs/utils/persistentsettings.cpp
index d665aaabe0..de6e883816 100644
--- a/src/libs/utils/persistentsettings.cpp
+++ b/src/libs/utils/persistentsettings.cpp
@@ -104,30 +104,17 @@ namespace Utils {
struct Context // Basic context containing element name string constants.
{
- Context();
-
- const QString qtCreatorElement;
- const QString dataElement;
- const QString variableElement;
- const QString typeAttribute;
- const QString valueElement;
- const QString valueListElement;
- const QString valueMapElement;
- const QString keyAttribute;
+ Context() {}
+ const QString qtCreatorElement = QString("qtcreator");
+ const QString dataElement = QString("data");
+ const QString variableElement = QString("variable");
+ const QString typeAttribute = QString("type");
+ const QString valueElement = QString("value");
+ const QString valueListElement = QString("valuelist");
+ const QString valueMapElement = QString("valuemap");
+ const QString keyAttribute = QString("key");
};
-Context::Context() :
- qtCreatorElement(QLatin1String("qtcreator")),
- dataElement(QLatin1String("data")),
- variableElement(QLatin1String("variable")),
- typeAttribute(QLatin1String("type")),
- valueElement(QLatin1String("value")),
- valueListElement(QLatin1String("valuelist")),
- valueMapElement(QLatin1String("valuemap")),
- keyAttribute(QLatin1String("key"))
-{
-}
-
struct ParseValueStackEntry
{
explicit ParseValueStackEntry(QVariant::Type t = QVariant::Invalid, const QString &k = QString()) : type(t), key(k) {}
@@ -225,7 +212,6 @@ QVariantMap ParseContext::parse(QFile &file)
qWarning("Error reading %s:%d: %s", qPrintable(file.fileName()),
int(r.lineNumber()), qPrintable(r.errorString()));
return QVariantMap();
- break;
default:
break;
} // switch token
diff --git a/src/libs/utils/treemodel.cpp b/src/libs/utils/treemodel.cpp
index 19f3fc72c4..b4684eedfe 100644
--- a/src/libs/utils/treemodel.cpp
+++ b/src/libs/utils/treemodel.cpp
@@ -689,6 +689,20 @@ void TreeItem::insertChild(int pos, TreeItem *item)
}
}
+void TreeItem::removeChildAt(int pos)
+{
+ QTC_ASSERT(0 <= pos && pos < m_children.count(), return);
+
+ if (m_model) {
+ QModelIndex idx = index();
+ m_model->beginRemoveRows(idx, pos, pos);
+ removeItemAt(pos);
+ m_model->endRemoveRows();
+ } else {
+ removeItemAt(pos);
+ }
+}
+
void TreeItem::removeChildren()
{
if (childCount() == 0)
@@ -863,6 +877,15 @@ void TreeItem::clear()
}
}
+void TreeItem::removeItemAt(int pos)
+{
+ TreeItem *item = m_children.at(pos);
+ item->m_model = nullptr;
+ item->m_parent = nullptr;
+ delete item;
+ m_children.removeAt(pos);
+}
+
void TreeItem::expand()
{
QTC_ASSERT(m_model, return);
diff --git a/src/libs/utils/treemodel.h b/src/libs/utils/treemodel.h
index d62670867b..8e0c4407d2 100644
--- a/src/libs/utils/treemodel.h
+++ b/src/libs/utils/treemodel.h
@@ -54,6 +54,7 @@ public:
void prependChild(TreeItem *item);
void appendChild(TreeItem *item);
void insertChild(int pos, TreeItem *item);
+ void removeChildAt(int pos);
void removeChildren();
void sortChildren(const std::function<bool(const TreeItem *, const TreeItem *)> &cmp);
void update();
@@ -90,6 +91,7 @@ private:
void operator=(const TreeItem &) = delete;
void clear();
+ void removeItemAt(int pos);
void propagateModel(BaseTreeModel *m);
TreeItem *m_parent; // Not owned.
diff --git a/src/libs/utils/wizard.cpp b/src/libs/utils/wizard.cpp
index 7829744314..d00d0345d6 100644
--- a/src/libs/utils/wizard.cpp
+++ b/src/libs/utils/wizard.cpp
@@ -432,6 +432,7 @@ void Wizard::showVariables()
label->setWordWrap(true);
label->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
scrollArea->setWidget(label);
+ scrollArea->setWidgetResizable(true);
layout->addWidget(scrollArea);
layout->addWidget(buttons);
diff --git a/src/plugins/android/androidanalyzesupport.cpp b/src/plugins/android/androidanalyzesupport.cpp
index eaea7196ba..59ccb047ca 100644
--- a/src/plugins/android/androidanalyzesupport.cpp
+++ b/src/plugins/android/androidanalyzesupport.cpp
@@ -37,10 +37,10 @@ AndroidQmlProfilerSupport::AndroidQmlProfilerSupport(RunControl *runControl)
setDisplayName("AndroidQmlProfilerSupport");
auto runner = new AndroidRunner(runControl);
- addDependency(runner);
+ addStartDependency(runner);
auto profiler = runControl->createWorker(runControl->runMode());
- profiler->addDependency(this);
+ profiler->addStartDependency(this);
connect(runner, &AndroidRunner::qmlServerReady, [this, runner, profiler](const QUrl &server) {
profiler->recordData("QmlServerUrl", server);
diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp
index 4461807198..13d32a37ab 100644
--- a/src/plugins/android/androidbuildapkstep.cpp
+++ b/src/plugins/android/androidbuildapkstep.cpp
@@ -142,11 +142,12 @@ bool AndroidBuildApkStep::init(QList<const BuildStep *> &earlierSteps)
if (!version)
return false;
- if (AndroidConfigurations::currentConfig().sdkToolsVersion() >= gradleScriptRevokedSdkVersion &&
+ const QVersionNumber sdkToolsVersion = AndroidConfigurations::currentConfig().sdkToolsVersion();
+ if (sdkToolsVersion >= gradleScriptRevokedSdkVersion &&
QVersionNumber::fromString(version->qtVersionString()) < gradleScriptsContainedQtVersion) {
emit addOutput(tr("The installed SDK tools version (%1) does not include Gradle scripts. The "
"minimum Qt version required for Gradle build to work is %2")
- .arg(gradleScriptRevokedSdkVersion.toString())
+ .arg(sdkToolsVersion.toString())
.arg(gradleScriptsContainedQtVersion.toString()), OutputFormat::Stderr);
return false;
}
diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp
index 31f7f304ae..92b80cf2cf 100644
--- a/src/plugins/android/androiddebugsupport.cpp
+++ b/src/plugins/android/androiddebugsupport.cpp
@@ -99,7 +99,7 @@ AndroidDebugSupport::AndroidDebugSupport(RunControl *runControl)
{
setDisplayName("AndroidDebugger");
m_runner = new AndroidRunner(runControl);
- addDependency(m_runner);
+ addStartDependency(m_runner);
}
void AndroidDebugSupport::start()
diff --git a/src/plugins/autotest/gtest/gtesttreeitem.cpp b/src/plugins/autotest/gtest/gtesttreeitem.cpp
index b9308a4e73..f41afacf7a 100644
--- a/src/plugins/autotest/gtest/gtesttreeitem.cpp
+++ b/src/plugins/autotest/gtest/gtesttreeitem.cpp
@@ -295,7 +295,7 @@ QSet<QString> GTestTreeItem::internalTargets() const
const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject());
for (const CppTools::ProjectPart::Ptr projectPart : projectInfo.projectParts()) {
if (projectPart->projectFile == proFile())
- result.insert(projectPart->buildSystemTarget);
+ result.insert(projectPart->buildSystemTarget + '|' + projectPart->projectFile);
}
return result;
}
diff --git a/src/plugins/autotest/quick/quicktesttreeitem.cpp b/src/plugins/autotest/quick/quicktesttreeitem.cpp
index c4de28c691..9ebcdd48c6 100644
--- a/src/plugins/autotest/quick/quicktesttreeitem.cpp
+++ b/src/plugins/autotest/quick/quicktesttreeitem.cpp
@@ -193,31 +193,10 @@ QList<TestConfiguration *> QuickTestTreeItem::getSelectedTestConfigurations() co
QuickTestConfiguration *tc = nullptr;
QHash<QString, QuickTestConfiguration *> foundProFiles;
- // unnamed Quick Tests must be handled first
- if (TestTreeItem *unnamed = unnamedQuickTests()) {
- for (int childRow = 0, ccount = unnamed->childCount(); childRow < ccount; ++ childRow) {
- const TestTreeItem *grandChild = unnamed->childItem(childRow);
- const QString &proFile = grandChild->proFile();
- if (foundProFiles.contains(proFile)) {
- QTC_ASSERT(tc,
- qWarning() << "Illegal state (unnamed Quick Test listed as named)";
- return QList<TestConfiguration *>());
- foundProFiles[proFile]->setTestCaseCount(tc->testCaseCount() + 1);
- } else {
- tc = new QuickTestConfiguration;
- tc->setTestCaseCount(1);
- tc->setUnnamedOnly(true);
- tc->setProjectFile(proFile);
- tc->setProject(project);
- tc->setInternalTargets(grandChild->internalTargets());
- foundProFiles.insert(proFile, tc);
- }
- }
- }
for (int row = 0, count = childCount(); row < count; ++row) {
const TestTreeItem *child = childItem(row);
- // unnamed Quick Tests have been handled separately already
+ // unnamed Quick Tests cannot get selected explicitly
if (child->name().isEmpty())
continue;
@@ -239,15 +218,8 @@ QList<TestConfiguration *> QuickTestTreeItem::getSelectedTestConfigurations() co
if (foundProFiles.contains(child->proFile())) {
tc = foundProFiles[child->proFile()];
QStringList oldFunctions(tc->testCases());
- // if oldFunctions.size() is 0 this test configuration is used for at least one
- // unnamed test case
- if (oldFunctions.size() == 0) {
- tc->setTestCaseCount(tc->testCaseCount() + testFunctions.size());
- tc->setUnnamedOnly(false);
- } else {
- oldFunctions << testFunctions;
- tc->setTestCases(oldFunctions);
- }
+ oldFunctions << testFunctions;
+ tc->setTestCases(oldFunctions);
} else {
tc = new QuickTestConfiguration;
tc->setTestCases(testFunctions);
@@ -321,7 +293,7 @@ QSet<QString> QuickTestTreeItem::internalTargets() const
const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject());
for (const CppTools::ProjectPart::Ptr projectPart : projectInfo.projectParts()) {
if (projectPart->projectFile == proFile()) {
- result.insert(projectPart->buildSystemTarget);
+ result.insert(projectPart->buildSystemTarget + '|' + projectPart->projectFile);
break;
}
}
diff --git a/src/plugins/autotest/testconfiguration.cpp b/src/plugins/autotest/testconfiguration.cpp
index 8440348d7d..7606b4827b 100644
--- a/src/plugins/autotest/testconfiguration.cpp
+++ b/src/plugins/autotest/testconfiguration.cpp
@@ -33,6 +33,7 @@
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildtargetinfo.h>
+#include <projectexplorer/deploymentdata.h>
#include <projectexplorer/environmentaspect.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/runnables.h>
@@ -40,6 +41,10 @@
#include <projectexplorer/session.h>
#include <projectexplorer/target.h>
+#include <QLoggingCategory>
+
+static Q_LOGGING_CATEGORY(LOG, "qtc.autotest.testconfiguration")
+
using namespace ProjectExplorer;
namespace Autotest {
@@ -61,6 +66,13 @@ static bool isLocal(RunConfiguration *runConfiguration)
return DeviceTypeKitInformation::deviceTypeId(kit) == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE;
}
+static QString ensureExeEnding(const QString& file)
+{
+ if (!Utils::HostOsInfo::isWindowsHost() || file.isEmpty() || file.toLower().endsWith(".exe"))
+ return file;
+ return Utils::HostOsInfo::withExecutableSuffix(file);
+}
+
void TestConfiguration::completeTestInformation(int runMode)
{
QTC_ASSERT(!m_projectFile.isEmpty(), return);
@@ -73,8 +85,12 @@ void TestConfiguration::completeTestInformation(int runMode)
Target *target = project->activeTarget();
if (!target)
return;
+ qCDebug(LOG) << "ActiveTargetName\n " << target->displayName();
+ if (const auto kit = target->kit())
+ qCDebug(LOG) << "SupportedPlatforms\n " << kit->supportedPlatforms();
const QSet<QString> buildSystemTargets = m_buildTargets;
+ qCDebug(LOG) << "BuildSystemTargets\n " << buildSystemTargets;
const BuildTargetInfo targetInfo
= Utils::findOrDefault(target->applicationTargets().list,
[&buildSystemTargets] (const BuildTargetInfo &bti) {
@@ -82,44 +98,81 @@ void TestConfiguration::completeTestInformation(int runMode)
const QStringList targWithProjectFile = b.split('|');
if (targWithProjectFile.size() != 2) // some build targets might miss the project file
return false;
- return targWithProjectFile.at(0) == bti.targetName
+ return !bti.targetFilePath.isEmpty() && targWithProjectFile.at(0) == bti.targetName
&& targWithProjectFile.at(1).startsWith(bti.projectFilePath.toString());
});
});
- QString executable = targetInfo.targetFilePath.toString(); // empty if BTI default created
- if (Utils::HostOsInfo::isWindowsHost() && !executable.isEmpty()
- && !executable.toLower().endsWith(".exe")) {
- executable = Utils::HostOsInfo::withExecutableSuffix(executable);
+ if (!QTC_GUARD(!targetInfo.targetFilePath.isEmpty())) { // empty if BTI default created
+ qCDebug(LOG) << "BuildTargetInfos";
+ for (const BuildTargetInfo &bti : target->applicationTargets().list)
+ qCDebug(LOG) << " " << bti.targetName << bti.projectFilePath << bti.targetFilePath;
+ }
+ const QString localExecutable = ensureExeEnding(targetInfo.targetFilePath.toString());
+
+ QString buildBase;
+ if (auto buildConfig = target->activeBuildConfiguration()) {
+ buildBase = buildConfig->buildDirectory().toString();
+ const QString projBase = project->projectDirectory().toString();
+ if (m_projectFile.startsWith(projBase))
+ m_buildDir = QFileInfo(buildBase + m_projectFile.mid(projBase.length())).absolutePath();
}
+ // deployment information should get taken into account, but it pretty much seems as if
+ // each build system uses it differently
+ const DeploymentData &deployData = target->deploymentData();
+ const DeployableFile deploy = deployData.deployableForLocalFile(localExecutable);
+ // we might have a deployable executable
+ const QString deployedExecutable = ensureExeEnding((deploy.isValid() && deploy.isExecutable())
+ ? QDir::cleanPath(deploy.remoteFilePath()) : localExecutable);
+
+ qCDebug(LOG) << " LocalExecutable" << localExecutable;
+ qCDebug(LOG) << " DeployedExecutable" << deployedExecutable;
+ qCDebug(LOG) << "Iterating run configurations";
for (RunConfiguration *runConfig : target->runConfigurations()) {
- if (!isLocal(runConfig)) // TODO add device support
+ qCDebug(LOG) << "RunConfiguration" << runConfig->id();
+ if (!isLocal(runConfig)) { // TODO add device support
+ qCDebug(LOG) << " Skipped as not being local";
continue;
+ }
- const QString bst = runConfig->buildSystemTarget() + '|' + m_projectFile;
- if (buildSystemTargets.contains(bst)) {
- Runnable runnable = runConfig->runnable();
- if (!runnable.is<StandardRunnable>())
- continue;
- StandardRunnable stdRunnable = runnable.as<StandardRunnable>();
- // TODO this might pick up the wrong executable
- m_executableFile = stdRunnable.executable;
- if (Utils::HostOsInfo::isWindowsHost() && !m_executableFile.isEmpty()
- && !m_executableFile.toLower().endsWith(".exe")) {
- m_executableFile = Utils::HostOsInfo::withExecutableSuffix(m_executableFile);
- }
+ Runnable runnable = runConfig->runnable();
+ if (!runnable.is<StandardRunnable>()) {
+ qCDebug(LOG) << " Skipped as not being a StandardRunnable";
+ continue;
+ }
+ StandardRunnable stdRunnable = runnable.as<StandardRunnable>();
+ // not the best approach - but depending on the build system and whether the executables
+ // are going to get installed or not we have to soften the condition...
+ const QString &currentExecutable = ensureExeEnding(stdRunnable.executable);
+ const QString currentBST = runConfig->buildSystemTarget() + '|';
+ qCDebug(LOG) << " CurrentExecutable" << currentExecutable;
+ qCDebug(LOG) << " BST of RunConfig" << currentBST;
+ const bool isQbs = runConfig->id().toString().startsWith("Qbs.RunConfiguration:"); // BAD!
+ if ((localExecutable == currentExecutable)
+ || (deployedExecutable == currentExecutable)
+ || (isQbs && Utils::anyOf(buildSystemTargets, [currentBST] (const QString &b) {
+ return b.startsWith(currentBST);
+ }))) {
+ qCDebug(LOG) << " Using this RunConfig.";
+ m_executableFile = currentExecutable;
m_displayName = runConfig->displayName();
m_workingDir = Utils::FileUtils::normalizePathName(stdRunnable.workingDirectory);
m_environment = stdRunnable.environment;
m_project = project;
if (runMode == TestRunner::Debug)
m_runConfig = new TestRunConfiguration(runConfig->target(), this);
- if (m_executableFile == executable) // we can find a better runConfig if no match
- break;
+ break;
}
}
+
// RunConfiguration for this target could be explicitly removed or not created at all
- if (m_displayName.isEmpty() && !executable.isEmpty()) {
+ // or we might have end up using the (wrong) path of a locally installed executable
+ // for this case try the original executable path of the BuildTargetInfo (the executable
+ // before installation) to have at least something to execute
+ if (m_executableFile.isEmpty() && !localExecutable.isEmpty())
+ m_executableFile = localExecutable;
+ if (m_displayName.isEmpty() && !m_executableFile.isEmpty()) {
+ qCDebug(LOG) << " Fallback";
// we failed to find a valid runconfiguration - but we've got the executable already
if (auto rc = target->activeRunConfiguration()) {
if (isLocal(rc)) { // FIXME for now only Desktop support
@@ -127,26 +180,21 @@ void TestConfiguration::completeTestInformation(int runMode)
if (runnable.is<StandardRunnable>()) {
StandardRunnable stdRunnable = runnable.as<StandardRunnable>();
m_environment = stdRunnable.environment;
- m_executableFile = executable;
m_project = project;
m_guessedConfiguration = true;
m_guessedFrom = rc->displayName();
if (runMode == TestRunner::Debug)
m_runConfig = new TestRunConfiguration(rc->target(), this);
}
+ } else {
+ qCDebug(LOG) << "not using the fallback as the current active run configuration "
+ "appears to be non-Desktop";
}
}
}
- if (auto buildConfig = target->activeBuildConfiguration()) {
- const QString buildBase = buildConfig->buildDirectory().toString();
- const QString projBase = project->projectDirectory().toString();
- if (m_projectFile.startsWith(projBase))
- m_buildDir = QFileInfo(buildBase + m_projectFile.mid(projBase.length())).absolutePath();
- }
-
if (m_displayName.isEmpty()) // happens e.g. when guessing the TestConfiguration or error
- m_displayName = buildSystemTargets.isEmpty() ? "unknown" : (*buildSystemTargets.begin()).split('|').first();
+ m_displayName = (*buildSystemTargets.begin()).split('|').first();
}
/**
diff --git a/src/plugins/autotest/testtreeitem.cpp b/src/plugins/autotest/testtreeitem.cpp
index 3bfa4400c5..60b58ca85d 100644
--- a/src/plugins/autotest/testtreeitem.cpp
+++ b/src/plugins/autotest/testtreeitem.cpp
@@ -291,7 +291,7 @@ QSet<QString> TestTreeItem::internalTargets() const
const QList<CppTools::ProjectPart::Ptr> projectParts = cppMM->projectPart(filePath());
QSet<QString> targets;
for (const CppTools::ProjectPart::Ptr part : projectParts)
- targets.insert(part->buildSystemTarget);
+ targets.insert(part->buildSystemTarget + '|' + part->projectFile);
return targets;
}
diff --git a/src/plugins/baremetal/baremetaldebugsupport.cpp b/src/plugins/baremetal/baremetaldebugsupport.cpp
index af978bfd61..278e018f1c 100644
--- a/src/plugins/baremetal/baremetaldebugsupport.cpp
+++ b/src/plugins/baremetal/baremetaldebugsupport.cpp
@@ -72,7 +72,7 @@ BareMetalDebugSupport::BareMetalDebugSupport(RunControl *runControl)
r.commandLineArguments = Utils::QtcProcess::joinArgs(p->arguments(), Utils::HostOsInfo::hostOs());
m_gdbServer = new SimpleTargetRunner(runControl);
m_gdbServer->setRunnable(r);
- addDependency(m_gdbServer);
+ addStartDependency(m_gdbServer);
}
}
diff --git a/src/plugins/clangcodemodel/clangassistproposalitem.cpp b/src/plugins/clangcodemodel/clangassistproposalitem.cpp
index 75dc40c671..7dba03a45d 100644
--- a/src/plugins/clangcodemodel/clangassistproposalitem.cpp
+++ b/src/plugins/clangcodemodel/clangassistproposalitem.cpp
@@ -32,10 +32,10 @@
#include <cplusplus/Token.h>
#include <texteditor/completionsettings.h>
-#include <texteditor/textdocument.h>
-#include <texteditor/texteditor.h>
#include <texteditor/texteditorsettings.h>
+#include <QTextCursor>
+
using namespace CPlusPlus;
using namespace ClangBackEnd;
@@ -66,6 +66,14 @@ bool ClangAssistProposalItem::implicitlyApplies() const
return true;
}
+static void moveToPrevChar(TextEditor::TextDocumentManipulatorInterface &manipulator,
+ QTextCursor &cursor)
+{
+ cursor.movePosition(QTextCursor::PreviousCharacter);
+ while (manipulator.characterAt(cursor.position()).isSpace())
+ cursor.movePosition(QTextCursor::PreviousCharacter);
+}
+
void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface &manipulator,
int basePosition) const
{
@@ -78,12 +86,11 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface
bool setAutoCompleteSkipPos = false;
int currentPosition = manipulator.currentPosition();
- bool autoParenthesesEnabled = true;
if (m_completionOperator == T_SIGNAL || m_completionOperator == T_SLOT) {
extraCharacters += QLatin1Char(')');
if (m_typedCharacter == QLatin1Char('(')) // Eat the opening parenthesis
m_typedCharacter = QChar();
- } else if (ccr.completionKind() == CodeCompletion::KeywordCompletionKind) {
+ } else if (ccr.completionKind() == CodeCompletion::KeywordCompletionKind) {
CompletionChunksToTextConverter converter;
converter.setupForKeywords();
@@ -116,7 +123,17 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface
cursor.movePosition(QTextCursor::PreviousWord);
while (manipulator.characterAt(cursor.position()) == ':')
cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::MoveAnchor, 2);
- if (manipulator.characterAt(cursor.position()) != '&') {
+
+ // Move to the last character in the previous word
+ cursor.movePosition(QTextCursor::NextWord);
+ moveToPrevChar(manipulator, cursor);
+ bool abandonParen = false;
+ if (manipulator.characterAt(cursor.position()) == '&') {
+ moveToPrevChar(manipulator, cursor);
+ const QChar prevChar = manipulator.characterAt(cursor.position());
+ abandonParen = QString("(;,{}").contains(prevChar);
+ }
+ if (!abandonParen) {
if (completionSettings.m_spaceAfterFunctionName)
extraCharacters += QLatin1Char(' ');
extraCharacters += QLatin1Char('(');
@@ -136,13 +153,13 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface
}
// If the function takes no arguments, automatically place the closing parenthesis
- if (!isOverloaded() && !ccr.hasParameters() && skipClosingParenthesis) {
+ if (!hasOverloadsWithParameters() && !ccr.hasParameters() && skipClosingParenthesis) {
extraCharacters += QLatin1Char(')');
if (endWithSemicolon) {
extraCharacters += semicolon;
m_typedCharacter = QChar();
}
- } else if (autoParenthesesEnabled) {
+ } else {
const QChar lookAhead = manipulator.characterAt(manipulator.currentPosition() + 1);
if (MatchingText::shouldInsertMatchingText(lookAhead)) {
extraCharacters += QLatin1Char(')');
@@ -157,19 +174,6 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface
}
}
}
-
-#if 0
- if (autoInsertBrackets && data().canConvert<CompleteFunctionDeclaration>()) {
- if (m_typedChar == QLatin1Char('('))
- m_typedChar = QChar();
-
- // everything from the closing parenthesis on are extra chars, to
- // make sure an auto-inserted ")" gets replaced by ") const" if necessary
- int closingParen = toInsert.lastIndexOf(QLatin1Char(')'));
- extraChars = toInsert.mid(closingParen);
- toInsert.truncate(closingParen);
- }
-#endif
}
// Append an unhandled typed character, adjusting cursor offset when it had been adjusted before
@@ -315,19 +319,19 @@ quint64 ClangAssistProposalItem::hash() const
return 0;
}
-void ClangAssistProposalItem::keepCompletionOperator(unsigned compOp)
+bool ClangAssistProposalItem::hasOverloadsWithParameters() const
{
- m_completionOperator = compOp;
+ return m_hasOverloadsWithParameters;
}
-bool ClangAssistProposalItem::isOverloaded() const
+void ClangAssistProposalItem::setHasOverloadsWithParameters(bool hasOverloadsWithParameters)
{
- return !m_overloads.isEmpty();
+ m_hasOverloadsWithParameters = hasOverloadsWithParameters;
}
-void ClangAssistProposalItem::addOverload(const CodeCompletion &ccr)
+void ClangAssistProposalItem::keepCompletionOperator(unsigned compOp)
{
- m_overloads.append(ccr);
+ m_completionOperator = compOp;
}
void ClangAssistProposalItem::setCodeCompletion(const CodeCompletion &codeCompletion)
@@ -342,4 +346,3 @@ const ClangBackEnd::CodeCompletion &ClangAssistProposalItem::codeCompletion() co
} // namespace Internal
} // namespace ClangCodeModel
-
diff --git a/src/plugins/clangcodemodel/clangassistproposalitem.h b/src/plugins/clangcodemodel/clangassistproposalitem.h
index 442764bdbf..90dcff35c8 100644
--- a/src/plugins/clangcodemodel/clangassistproposalitem.h
+++ b/src/plugins/clangcodemodel/clangassistproposalitem.h
@@ -53,8 +53,8 @@ public:
void keepCompletionOperator(unsigned compOp);
- bool isOverloaded() const;
- void addOverload(const ClangBackEnd::CodeCompletion &ccr);
+ bool hasOverloadsWithParameters() const;
+ void setHasOverloadsWithParameters(bool hasOverloadsWithParameters);
void setCodeCompletion(const ClangBackEnd::CodeCompletion &codeCompletion);
const ClangBackEnd::CodeCompletion &codeCompletion() const;
@@ -62,6 +62,7 @@ public:
private:
ClangBackEnd::CodeCompletion m_codeCompletion;
QList<ClangBackEnd::CodeCompletion> m_overloads;
+ bool m_hasOverloadsWithParameters = false;
QString m_text;
unsigned m_completionOperator;
mutable QChar m_typedCharacter;
diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
index 101aef1a9e..9d84b3ba81 100644
--- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
+++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
@@ -89,7 +89,8 @@ QList<AssistProposalItemInterface *> toAssistProposalItems(const CodeCompletions
ClangAssistProposalItem *item = items.value(name, 0);
if (item) {
- item->addOverload(codeCompletion);
+ if (codeCompletion.hasParameters())
+ item->setHasOverloadsWithParameters(true);
} else {
item = new ClangAssistProposalItem;
items.insert(name, item);
diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp
index 06ab0df02b..ac5d09ec3f 100644
--- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp
+++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp
@@ -799,7 +799,7 @@ void ClangCodeCompletionTest::testCompleteGlobals()
ProjectLessCompletionTest t("globalCompletion.cpp");
QVERIFY(hasItem(t.proposal, "globalVariable", "int globalVariable"));
- QVERIFY(hasItem(t.proposal, "globalFunction", "void globalFunction ()"));
+ QVERIFY(hasItem(t.proposal, "globalFunction", "void globalFunction()"));
QVERIFY(hasItem(t.proposal, "GlobalClass", "GlobalClass"));
QVERIFY(hasItem(t.proposal, "class", "class")); // Keyword
QVERIFY(hasSnippet(t.proposal, "class")); // Snippet
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
index 98a0788ebc..8fb8775194 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
@@ -80,7 +80,11 @@ ClangStaticAnalyzerToolRunner::ClangStaticAnalyzerToolRunner(RunControl *runCont
RunConfiguration *runConfiguration = runControl->runConfiguration();
auto tool = ClangStaticAnalyzerTool::instance();
tool->stopAction()->disconnect();
- connect(tool->stopAction(), &QAction::triggered, runControl, &RunControl::initiateStop);
+ connect(tool->stopAction(), &QAction::triggered, runControl, [&] {
+ initiateStop();
+ appendMessage(tr("Clang Static Analyzer stopped by user."),
+ Utils::NormalMessageFormat);
+ });
tool->handleWorkerStart(this);
ProjectInfo projectInfoBeforeBuild = tool->projectInfoBeforeBuild();
@@ -605,8 +609,6 @@ void ClangStaticAnalyzerToolRunner::stop()
}
m_runners.clear();
m_unitsToProcess.clear();
- appendMessage(tr("Clang Static Analyzer stopped by user."),
- Utils::NormalMessageFormat);
m_progress.reportFinished();
ClangStaticAnalyzerTool::instance()->onEngineFinished(m_success);
reportStopped();
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
index 88f519cd7d..56e35f019f 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
@@ -37,18 +37,16 @@ using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal;
CMakeInputsNode::CMakeInputsNode(const Utils::FileName &cmakeLists) :
- ProjectExplorer::ProjectNode(CMakeInputsNode::inputsPathFromCMakeListsPath(cmakeLists))
+ ProjectExplorer::ProjectNode(cmakeLists, generateId(cmakeLists))
{
setPriority(Node::DefaultPriority - 10); // Bottom most!
setDisplayName(QCoreApplication::translate("CMakeFilesProjectNode", "CMake Modules"));
setIcon(QIcon(":/projectexplorer/images/session.png")); // TODO: Use a better icon!
}
-Utils::FileName CMakeInputsNode::inputsPathFromCMakeListsPath(const Utils::FileName &cmakeLists)
+QByteArray CMakeInputsNode::generateId(const Utils::FileName &inputFile)
{
- Utils::FileName result = cmakeLists;
- result.appendPath("cmakeInputs"); // cmakeLists is a file, so this can not exist on disk
- return result;
+ return inputFile.toString().toUtf8() + "/cmakeInputs";
}
bool CMakeInputsNode::showInSimpleTree() const
@@ -91,13 +89,18 @@ QString CMakeProjectNode::tooltip() const
return QString();
}
-CMakeTargetNode::CMakeTargetNode(const Utils::FileName &directory) :
- ProjectExplorer::ProjectNode(directory)
+CMakeTargetNode::CMakeTargetNode(const Utils::FileName &directory, const QString &target) :
+ ProjectExplorer::ProjectNode(directory, generateId(directory, target))
{
setPriority(Node::DefaultProjectPriority + 900);
setIcon(QIcon(":/projectexplorer/images/build.png")); // TODO: Use proper icon!
}
+QByteArray CMakeTargetNode::generateId(const Utils::FileName &directory, const QString &target)
+{
+ return directory.toString().toUtf8() + "///::///" + target.toUtf8();
+}
+
bool CMakeTargetNode::showInSimpleTree() const
{
return true;
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h
index d4160c7762..edf031bf57 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h
@@ -35,7 +35,7 @@ class CMakeInputsNode : public ProjectExplorer::ProjectNode
public:
CMakeInputsNode(const Utils::FileName &cmakeLists);
- static Utils::FileName inputsPathFromCMakeListsPath(const Utils::FileName &cmakeLists);
+ static QByteArray generateId(const Utils::FileName &inputFile);
bool showInSimpleTree() const final;
};
@@ -60,7 +60,9 @@ public:
class CMakeTargetNode : public ProjectExplorer::ProjectNode
{
public:
- CMakeTargetNode(const Utils::FileName &directory);
+ CMakeTargetNode(const Utils::FileName &directory, const QString &target);
+
+ static QByteArray generateId(const Utils::FileName &directory, const QString &target);
void setTargetInformation(const QList<Utils::FileName> &artifacts, const QString &type);
diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp
index 7cba11953d..4d3a9f9670 100644
--- a/src/plugins/cmakeprojectmanager/servermodereader.cpp
+++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp
@@ -250,9 +250,12 @@ static void addCMakeVFolder(FolderNode *base, const Utils::FileName &basePath, i
{
if (files.isEmpty())
return;
- auto folder = new VirtualFolderNode(basePath, priority);
- folder->setDisplayName(displayName);
- base->addNode(folder);
+ FolderNode *folder = base;
+ if (!displayName.isEmpty()) {
+ folder = new VirtualFolderNode(basePath, priority);
+ folder->setDisplayName(displayName);
+ base->addNode(folder);
+ }
folder->addNestedNodes(files);
for (FolderNode *fn : folder->folderNodes())
fn->compress();
@@ -268,9 +271,7 @@ static void addCMakeInputs(FolderNode *root,
ProjectNode *cmakeVFolder = new CMakeInputsNode(root->filePath());
root->addNode(cmakeVFolder);
- addCMakeVFolder(cmakeVFolder, sourceDir, 1000,
- QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader", "<Source Directory>"),
- sourceInputs);
+ addCMakeVFolder(cmakeVFolder, sourceDir, 1000, QString(), sourceInputs);
addCMakeVFolder(cmakeVFolder, buildDir, 100,
QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader", "<Build Directory>"),
buildInputs);
@@ -336,7 +337,7 @@ void ServerModeReader::updateCodeModel(CppTools::RawProjectParts &rpps)
CppTools::RawProjectPart rpp;
rpp.setProjectFileLocation(fg->target->sourceDirectory.toString() + "/CMakeLists.txt");
- rpp.setBuildSystemTarget(fg->target->name + '|' + rpp.projectFile);
+ rpp.setBuildSystemTarget(fg->target->name);
rpp.setDisplayName(fg->target->name + QString::number(counter));
rpp.setDefines(defineArg.toUtf8());
rpp.setIncludePaths(includes);
@@ -757,12 +758,13 @@ static CMakeTargetNode *createTargetNode(const QHash<Utils::FileName, ProjectNod
ProjectNode *cmln = cmakeListsNodes.value(dir);
QTC_ASSERT(cmln, return nullptr);
- Utils::FileName targetName = dir;
- targetName.appendPath(".target::" + displayName);
+ QByteArray targetId = CMakeTargetNode::generateId(dir, displayName);
- CMakeTargetNode *tn = static_cast<CMakeTargetNode *>(cmln->projectNode(targetName));
+ CMakeTargetNode *tn = static_cast<CMakeTargetNode *>(cmln->findNode([&targetId](const Node *n) {
+ return n->id() == targetId;
+ }));
if (!tn) {
- tn = new CMakeTargetNode(targetName);
+ tn = new CMakeTargetNode(dir, displayName);
cmln->addNode(tn);
}
tn->setDisplayName(displayName);
@@ -849,7 +851,7 @@ void ServerModeReader::addFileGroups(ProjectNode *targetRoot,
otherFileNodes.append(fn);
}
- addCMakeVFolder(targetRoot, sourceDirectory, 1000, tr("<Source Directory>"), sourceFileNodes);
+ addCMakeVFolder(targetRoot, sourceDirectory, 1000, QString(), sourceFileNodes);
addCMakeVFolder(targetRoot, buildDirectory, 100, tr("<Build Directory>"), buildFileNodes);
addCMakeVFolder(targetRoot, Utils::FileName(), 10, tr("<Other Locations>"), otherFileNodes);
}
diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.cpp b/src/plugins/cmakeprojectmanager/tealeafreader.cpp
index 025cb934e2..eed99dad19 100644
--- a/src/plugins/cmakeprojectmanager/tealeafreader.cpp
+++ b/src/plugins/cmakeprojectmanager/tealeafreader.cpp
@@ -373,7 +373,7 @@ void TeaLeafReader::updateCodeModel(CppTools::RawProjectParts &rpps)
includePaths += m_parameters.buildDirectory.toString();
CppTools::RawProjectPart rpp;
rpp.setProjectFileLocation(cbt.sourceDirectory.toString() + "/CMakeLists.txt");
- rpp.setBuildSystemTarget(cbt.title + '|' + rpp.projectFile);
+ rpp.setBuildSystemTarget(cbt.title);
rpp.setIncludePaths(includePaths);
CppTools::RawProjectPartFlags cProjectFlags;
diff --git a/src/plugins/coreplugin/find/searchresultwidget.cpp b/src/plugins/coreplugin/find/searchresultwidget.cpp
index 9eee8dee63..3db6a08f26 100644
--- a/src/plugins/coreplugin/find/searchresultwidget.cpp
+++ b/src/plugins/coreplugin/find/searchresultwidget.cpp
@@ -210,6 +210,8 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) :
this, &SearchResultWidget::handleReplaceButton);
connect(m_replaceButton, &QAbstractButton::clicked,
this, &SearchResultWidget::handleReplaceButton);
+ connect(m_replaceTextEdit, &QLineEdit::textChanged,
+ this, &SearchResultWidget::handleReplaceEditTextChanged);
}
SearchResultWidget::~SearchResultWidget()
@@ -304,6 +306,7 @@ void SearchResultWidget::setSupportsReplace(bool replaceSupported, const QString
void SearchResultWidget::setTextToReplace(const QString &textToReplace)
{
+ m_replaceText = textToReplace;
m_replaceTextEdit->setText(textToReplace);
}
@@ -406,7 +409,6 @@ void SearchResultWidget::goToPrevious()
void SearchResultWidget::restart()
{
m_replaceTextEdit->setEnabled(false);
- m_replaceButton->setEnabled(false);
m_searchResultTreeView->clear();
m_count = 0;
Id sizeWarningId(SIZE_WARNING_ID);
@@ -416,6 +418,7 @@ void SearchResultWidget::restart()
m_searchAgainButton->setVisible(false);
m_messageWidget->setVisible(false);
updateMatchesFoundLabel();
+ handleReplaceEditTextChanged();
emit restarted();
}
@@ -436,7 +439,6 @@ void SearchResultWidget::finishSearch(bool canceled)
m_infoBar.removeInfo(sizeWarningId);
m_infoBar.enableInfo(sizeWarningId);
m_replaceTextEdit->setEnabled(m_count > 0);
- m_replaceButton->setEnabled(m_count > 0);
m_preserveCaseCheck->setEnabled(m_count > 0);
m_cancelButton->setVisible(false);
m_messageWidget->setVisible(canceled);
@@ -461,6 +463,15 @@ void SearchResultWidget::cancelAfterSizeWarning()
emit paused(false);
}
+void SearchResultWidget::handleReplaceEditTextChanged()
+{
+ const bool enabled = m_replaceTextEdit->text() != m_replaceText;
+ m_replaceButton->setEnabled(enabled);
+ m_replaceButton->setToolTip(enabled
+ ? QString()
+ : tr("Cannot replace because replacement text is unchanged."));
+}
+
void SearchResultWidget::handleJumpToSearchResult(const SearchResultItem &item)
{
emit activated(item);
diff --git a/src/plugins/coreplugin/find/searchresultwidget.h b/src/plugins/coreplugin/find/searchresultwidget.h
index 5309ed69e1..bf4b905544 100644
--- a/src/plugins/coreplugin/find/searchresultwidget.h
+++ b/src/plugins/coreplugin/find/searchresultwidget.h
@@ -115,6 +115,7 @@ private:
void setShowReplaceUI(bool visible);
void continueAfterSizeWarning();
void cancelAfterSizeWarning();
+ void handleReplaceEditTextChanged();
QList<SearchResultItem> checkedItems() const;
void updateMatchesFoundLabel();
@@ -141,6 +142,7 @@ private:
bool m_isShowingReplaceUI = false;
bool m_searchAgainSupported = false;
bool m_replaceSupported = false;
+ QString m_replaceText;
};
} // Internal
diff --git a/src/plugins/cppeditor/cppautocompleter.cpp b/src/plugins/cppeditor/cppautocompleter.cpp
index 2f6a2fc46f..8c1315b973 100644
--- a/src/plugins/cppeditor/cppautocompleter.cpp
+++ b/src/plugins/cppeditor/cppautocompleter.cpp
@@ -249,8 +249,7 @@ void CppEditorPlugin::test_autoComplete_data()
QString expectedText;
int skippedChar = 0;
- // We always expect to get a closing char in an empty file
- if (fc == EmptyFile && isOpeningChar(c))
+ if (fc == EmptyFile && isOpeningChar(c) && c != QLatin1Char('{'))
expectedText = closingChar(c);
if (fc == InBetween) {
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index 65d0c42abf..c20d46ed40 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -457,8 +457,6 @@ void CppEditorWidget::renameSymbolUnderCursor()
void CppEditorWidget::renameSymbolUnderCursorBuiltin()
{
- d->m_useSelectionsUpdater.abortSchedule();
-
updateSemanticInfo(d->m_cppEditorDocument->recalculateSemanticInfo(),
/*updateUseSelectionSynchronously=*/ true);
diff --git a/src/plugins/cppeditor/cppuseselectionsupdater.cpp b/src/plugins/cppeditor/cppuseselectionsupdater.cpp
index 4e13fee597..cf98842729 100644
--- a/src/plugins/cppeditor/cppuseselectionsupdater.cpp
+++ b/src/plugins/cppeditor/cppuseselectionsupdater.cpp
@@ -94,6 +94,8 @@ void CppUseSelectionsUpdater::update(CallType callType)
m_runnerWatcher->setFuture(cppEditorDocument->cursorInfo(params));
} else { // synchronous case
+ abortSchedule();
+
const int startRevision = cppEditorDocument->document()->revision();
QFuture<CursorInfo> future = cppEditorDocument->cursorInfo(params);
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index fd56c4b78e..8911f92280 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -520,14 +520,14 @@ bool CdbEngine::launchCDB(const DebuggerRunParameters &sp, QString *errorMessage
const QFileInfo extensionFi(CdbEngine::extensionLibraryName(cdbIs64Bit));
if (!extensionFi.isFile()) {
*errorMessage = tr("Internal error: The extension %1 cannot be found.\n"
- "If you have updated Qt Creator via Maintenance Tool you may "
- "need to rerun the Tool and select \"Add or remove components\""
+ "If you have updated Qt Creator via Maintenance Tool, you may "
+ "need to rerun the Tool and select \"Add or remove components\" "
"and then select the\n"
"Qt > Tools > Qt Creator > Qt Creator CDB Debugger Support component.\n"
- "If you build Qt Creator from sources and want to use a cdb executable"
+ "If you build Qt Creator from sources and want to use a CDB executable "
"with another bitness than your Qt Creator build,\n"
- "you will need to build a separate cdbextension with the "
- "same bitness as the cdb you want to use.").
+ "you will need to build a separate CDB extension with the "
+ "same bitness as the CDB you want to use.").
arg(QDir::toNativeSeparators(extensionFi.absoluteFilePath()));
return false;
}
diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp
index 543ad8f819..93a2d69aad 100644
--- a/src/plugins/debugger/debuggerengine.cpp
+++ b/src/plugins/debugger/debuggerengine.cpp
@@ -1030,39 +1030,37 @@ RunControl *DebuggerEnginePrivate::runControl() const
void DebuggerEngine::notifyEngineIll()
{
- runControl()->initiateStop();
- return;
//#ifdef WITH_BENCHMARK
// CALLGRIND_STOP_INSTRUMENTATION;
// CALLGRIND_DUMP_STATS;
//#endif
-// showMessage("NOTE: ENGINE ILL ******");
-// runTool()->startDying();
-// d->m_lastGoodState = d->m_state;
-// switch (state()) {
-// case InferiorRunRequested:
-// case InferiorRunOk:
-// // The engine does not look overly ill right now, so attempt to
-// // properly interrupt at least once. If that fails, we are on the
-// // shutdown path due to d->m_targetState anyways.
-// setState(InferiorStopRequested, true);
-// showMessage("ATTEMPT TO INTERRUPT INFERIOR");
-// interruptInferior();
-// break;
-// case InferiorStopRequested:
-// notifyInferiorStopFailed();
-// break;
-// case InferiorStopOk:
-// showMessage("FORWARDING STATE TO InferiorShutdownFailed");
-// setState(InferiorShutdownFailed, true);
-// if (isMasterEngine())
-// d->queueShutdownEngine();
-// break;
-// default:
-// if (isMasterEngine())
-// d->queueShutdownEngine();
-// break;
-// }
+ showMessage("NOTE: ENGINE ILL ******");
+ runTool()->startDying();
+ d->m_lastGoodState = d->m_state;
+ switch (state()) {
+ case InferiorRunRequested:
+ case InferiorRunOk:
+ // The engine does not look overly ill right now, so attempt to
+ // properly interrupt at least once. If that fails, we are on the
+ // shutdown path due to d->m_targetState anyways.
+ setState(InferiorStopRequested, true);
+ showMessage("ATTEMPT TO INTERRUPT INFERIOR");
+ interruptInferior();
+ break;
+ case InferiorStopRequested:
+ notifyInferiorStopFailed();
+ break;
+ case InferiorStopOk:
+ showMessage("FORWARDING STATE TO InferiorShutdownFailed");
+ setState(InferiorShutdownFailed, true);
+ if (isMasterEngine())
+ d->queueShutdownEngine();
+ break;
+ default:
+ if (isMasterEngine())
+ d->queueShutdownEngine();
+ break;
+ }
}
void DebuggerEngine::notifyEngineSpontaneousShutdown()
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 38d867c878..a56b48582f 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -1351,7 +1351,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
connect(m_registerView, &BaseTreeView::aboutToShow,
this, &DebuggerPluginPrivate::reloadRegisters,
Qt::QueuedConnection);
- m_registerWindow = addSearch(m_registerView, tr("&Registers"), DOCKWIDGET_REGISTER);
+ m_registerWindow = addSearch(m_registerView, tr("Reg&isters"), DOCKWIDGET_REGISTER);
m_stackView = new StackTreeView;
m_stackView->setSettings(settings, "Debugger.StackView");
@@ -3561,8 +3561,10 @@ void setPerspectiveEnabled(const QByteArray &perspectiveId, bool enabled)
void selectPerspective(const QByteArray &perspectiveId)
{
- if (dd->m_mainWindow->currentPerspective() == perspectiveId)
+ if (ModeManager::currentMode() == MODE_DEBUG
+ && dd->m_mainWindow->currentPerspective() == perspectiveId) {
return;
+ }
// FIXME: Work-around aslong as the GammaRay integration does not use the same setup,
if (perspectiveId.isEmpty())
diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp
index e95246e713..2687d71be2 100644
--- a/src/plugins/debugger/debuggerruncontrol.cpp
+++ b/src/plugins/debugger/debuggerruncontrol.cpp
@@ -256,8 +256,8 @@ DebuggerEngine *createEngine(DebuggerEngineType cppEngineType,
if (cppEngine) {
engine = createQmlCppEngine(cppEngine, useTerminal);
} else {
- errors->append(DebuggerPlugin::tr("The slave debugging engine required for combined "
- "QML/C++-Debugging could not be created: %1"));
+ errors->append(DebuggerPlugin::tr("The debugging engine required for combined "
+ "QML/C++ debugging could not be created: %1"));
}
break;
}
@@ -266,7 +266,7 @@ DebuggerEngine *createEngine(DebuggerEngineType cppEngineType,
.arg(engineTypeName(et)));
}
if (!engine)
- errors->append(DebuggerPlugin::tr("Unable to create a debugger engine of the type \"%1\"").
+ errors->append(DebuggerPlugin::tr("Unable to create a debugging engine of the type \"%1\"").
arg(engineTypeName(et)));
return engine;
}
@@ -282,7 +282,7 @@ static bool fixupParameters(DebuggerRunParameters &rp, RunControl *runControl, Q
// Extract as much as possible from available RunConfiguration.
const Runnable runnable = runConfig->runnable();
- if (runnable.is<StandardRunnable>()) {
+ if (rp.needFixup && runnable.is<StandardRunnable>()) {
// FIXME: Needed for core dump which stores the executable in inferior, but not in runConfig
// executable.
const QString prevExecutable = rp.inferior.executable;
@@ -295,7 +295,7 @@ static bool fixupParameters(DebuggerRunParameters &rp, RunControl *runControl, Q
}
// We might get an executable from a local PID.
- if (rp.inferior.executable.isEmpty() && rp.attachPID.isValid()) {
+ if (rp.needFixup && rp.inferior.executable.isEmpty() && rp.attachPID.isValid()) {
foreach (const DeviceProcessItem &p, DeviceProcessList::localProcesses()) {
if (p.pid == rp.attachPID.pid()) {
rp.inferior.executable = p.exe;
@@ -313,14 +313,16 @@ static bool fixupParameters(DebuggerRunParameters &rp, RunControl *runControl, Q
if (!envBinary.isEmpty())
rp.debugger.executable = QString::fromLocal8Bit(envBinary);
- if (auto envAspect = runConfig->extraAspect<EnvironmentAspect>()) {
- rp.inferior.environment = envAspect->environment(); // Correct.
- rp.stubEnvironment = rp.inferior.environment; // FIXME: Wrong, but contains DYLD_IMAGE_SUFFIX
+ if (rp.needFixup) {
+ if (auto envAspect = runConfig->extraAspect<EnvironmentAspect>()) {
+ rp.inferior.environment = envAspect->environment(); // Correct.
+ rp.stubEnvironment = rp.inferior.environment; // FIXME: Wrong, but contains DYLD_IMAGE_SUFFIX
- // Copy over DYLD_IMAGE_SUFFIX etc
- for (auto var : QStringList({"DYLD_IMAGE_SUFFIX", "DYLD_LIBRARY_PATH", "DYLD_FRAMEWORK_PATH"}))
- if (rp.inferior.environment.hasKey(var))
- rp.debugger.environment.set(var, rp.inferior.environment.value(var));
+ // Copy over DYLD_IMAGE_SUFFIX etc
+ for (auto var : QStringList({"DYLD_IMAGE_SUFFIX", "DYLD_LIBRARY_PATH", "DYLD_FRAMEWORK_PATH"}))
+ if (rp.inferior.environment.hasKey(var))
+ rp.debugger.environment.set(var, rp.inferior.environment.value(var));
+ }
}
if (Project *project = runConfig->target()->project()) {
rp.projectSourceDirectory = project->projectDirectory().toString();
@@ -623,7 +625,7 @@ RunConfiguration *dummyRunConfigForKit(ProjectExplorer::Kit *kit)
QTC_ASSERT(kit, return nullptr); // Caller needs to look for a suitable kit.
Project *project = SessionManager::startupProject();
Target *target = project ? project->target(kit) : nullptr;
- if (!target) {
+ if (!target || !target->activeRunConfiguration()) {
project = new DummyProject;
target = project->createTarget(kit);
}
@@ -685,7 +687,7 @@ void GdbServerPortsGatherer::handlePortListReady()
return;
}
}
- reportStarted();
+ reportDone();
}
// GdbServerRunner
@@ -731,7 +733,7 @@ void GdbServerRunner::start()
setRunnable(r);
- appendMessage(tr("Starting GDBserver..."), NormalMessageFormat);
+ appendMessage(tr("Starting gdbserver..."), NormalMessageFormat);
SimpleTargetRunner::start();
}
diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h
index 92d379d6f2..db055341ce 100644
--- a/src/plugins/debugger/debuggerstartparameters.h
+++ b/src/plugins/debugger/debuggerstartparameters.h
@@ -65,6 +65,7 @@ public:
Utils::ProcessHandle attachPID;
QStringList solibSearchPath;
bool useTerminal = false;
+ bool needFixup = true; // FIXME: Make false the default...
// Used by Qml debugging.
TcpServerConnection qmlServer;
diff --git a/src/plugins/debugger/logwindow.cpp b/src/plugins/debugger/logwindow.cpp
index f93d866d90..22c2e73ed9 100644
--- a/src/plugins/debugger/logwindow.cpp
+++ b/src/plugins/debugger/logwindow.cpp
@@ -430,7 +430,7 @@ LogWindow::LogWindow(QWidget *parent)
setMinimumHeight(60);
showOutput(LogWarning,
- tr("NOTE: This log contains possibly confidential information about your machine, "
+ tr("Note: This log contains possibly confidential information about your machine, "
"environment variables, in-memory data of the processes you are debugging, and more. "
"It is never transferred over the internet by Qt Creator, and only stored "
"to disk if you manually use the respective option from the context menu, or through "
diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp
index 6391c0ae0a..f906fdb027 100644
--- a/src/plugins/diffeditor/diffeditorplugin.cpp
+++ b/src/plugins/diffeditor/diffeditorplugin.cpp
@@ -856,7 +856,7 @@ void DiffEditor::Internal::DiffEditorPlugin::testMakePatch()
QFETCH(bool, lastChunk);
QFETCH(QString, patchText);
- QString result = DiffUtils::makePatch(sourceChunk, leftFileName, rightFileName, lastChunk);
+ const QString result = DiffUtils::makePatch(sourceChunk, leftFileName, rightFileName, lastChunk);
QCOMPARE(result, patchText);
diff --git a/src/plugins/diffeditor/diffutils.cpp b/src/plugins/diffeditor/diffutils.cpp
index 5b8ca9d674..a9d9b11ae2 100644
--- a/src/plugins/diffeditor/diffutils.cpp
+++ b/src/plugins/diffeditor/diffutils.cpp
@@ -27,6 +27,7 @@
#include "differ.h"
#include "texteditor/fontsettings.h"
+#include "utils/asconst.h"
#include <QFutureInterfaceBase>
#include <QRegularExpression>
@@ -485,6 +486,34 @@ QString DiffUtils::makePatch(const ChunkData &chunkData,
return diffText;
}
+static QString leftFileName(const FileData &fileData, unsigned formatFlags)
+{
+ QString diffText;
+ QTextStream str(&diffText);
+ if (fileData.fileOperation == FileData::NewFile) {
+ str << "/dev/null";
+ } else {
+ if (formatFlags & DiffUtils::AddLevel)
+ str << "a/";
+ str << fileData.leftFileInfo.fileName;
+ }
+ return diffText;
+}
+
+static QString rightFileName(const FileData &fileData, unsigned formatFlags)
+{
+ QString diffText;
+ QTextStream str(&diffText);
+ if (fileData.fileOperation == FileData::DeleteFile) {
+ str << "/dev/null";
+ } else {
+ if (formatFlags & DiffUtils::AddLevel)
+ str << "b/";
+ str << fileData.rightFileInfo.fileName;
+ }
+ return diffText;
+}
+
QString DiffUtils::makePatch(const QList<FileData> &fileDataList, unsigned formatFlags)
{
QString diffText;
@@ -496,26 +525,36 @@ QString DiffUtils::makePatch(const QList<FileData> &fileDataList, unsigned forma
str << "diff --git a/" << fileData.leftFileInfo.fileName
<< " b/" << fileData.rightFileInfo.fileName << '\n';
}
+ if (fileData.fileOperation == FileData::NewFile
+ || fileData.fileOperation == FileData::DeleteFile) { // git only?
+ if (fileData.fileOperation == FileData::NewFile)
+ str << "new";
+ else
+ str << "deleted";
+ str << " file mode 100644\n";
+ }
+ str << "index " << fileData.leftFileInfo.typeInfo << ".." << fileData.rightFileInfo.typeInfo;
+ if (fileData.fileOperation == FileData::ChangeFile)
+ str << " 100644";
+ str << "\n";
+
if (fileData.binaryFiles) {
str << "Binary files ";
- if (formatFlags & AddLevel)
- str << "a/";
- str << fileData.leftFileInfo.fileName << " and ";
- if (formatFlags & AddLevel)
- str << "b/";
- str << fileData.rightFileInfo.fileName << " differ\n";
+ str << leftFileName(fileData, formatFlags);
+ str << " and ";
+ str << rightFileName(fileData, formatFlags);
+ str << " differ\n";
} else {
- str << "--- ";
- if (formatFlags & AddLevel)
- str << "a/";
- str << fileData.leftFileInfo.fileName << "\n+++ ";
- if (formatFlags & AddLevel)
- str << "b/";
- str << fileData.rightFileInfo.fileName << '\n';
- for (int j = 0; j < fileData.chunks.count(); j++) {
- str << makePatch(fileData.chunks.at(j),
- (j == fileData.chunks.count() - 1)
- && fileData.lastChunkAtTheEndOfFile);
+ if (!fileData.chunks.isEmpty()) {
+ str << "--- ";
+ str << leftFileName(fileData, formatFlags) << "\n";
+ str << "+++ ";
+ str << rightFileName(fileData, formatFlags) << "\n";
+ for (int j = 0; j < fileData.chunks.count(); j++) {
+ str << makePatch(fileData.chunks.at(j),
+ (j == fileData.chunks.count() - 1)
+ && fileData.lastChunkAtTheEndOfFile);
+ }
}
}
}
@@ -695,58 +734,128 @@ static QList<RowData> readLines(QStringRef patch,
outputRightDiffList).rows;
}
+static QStringRef readLine(QStringRef text, QStringRef *remainingText, bool *hasNewLine)
+{
+ const QChar newLine('\n');
+ const int indexOfFirstNewLine = text.indexOf(newLine);
+ if (indexOfFirstNewLine < 0) {
+ if (remainingText)
+ *remainingText = QStringRef();
+ if (hasNewLine)
+ *hasNewLine = false;
+ return text;
+ }
+
+ if (hasNewLine)
+ *hasNewLine = true;
+
+ if (remainingText)
+ *remainingText = text.mid(indexOfFirstNewLine + 1);
+
+ return text.left(indexOfFirstNewLine);
+}
+
+static bool detectChunkData(QStringRef chunkDiff,
+ ChunkData *chunkData,
+ QStringRef *remainingPatch)
+{
+ bool hasNewLine;
+ const QStringRef chunkLine = readLine(chunkDiff, remainingPatch, &hasNewLine);
+
+ const QLatin1String leftPosMarker("@@ -");
+ const QLatin1String rightPosMarker(" +");
+ const QLatin1String optionalHintMarker(" @@");
+
+ const int leftPosIndex = chunkLine.indexOf(leftPosMarker);
+ if (leftPosIndex != 0)
+ return false;
+
+ const int rightPosIndex = chunkLine.indexOf(rightPosMarker, leftPosIndex + leftPosMarker.size());
+ if (rightPosIndex < 0)
+ return false;
+
+ const int optionalHintIndex = chunkLine.indexOf(optionalHintMarker, rightPosIndex + rightPosMarker.size());
+ if (optionalHintIndex < 0)
+ return false;
+
+ const int leftPosStart = leftPosIndex + leftPosMarker.size();
+ const int leftPosLength = rightPosIndex - leftPosStart;
+ QStringRef leftPos = chunkLine.mid(leftPosStart, leftPosLength);
+
+ const int rightPosStart = rightPosIndex + rightPosMarker.size();
+ const int rightPosLength = optionalHintIndex - rightPosStart;
+ QStringRef rightPos = chunkLine.mid(rightPosStart, rightPosLength);
+
+ const int optionalHintStart = optionalHintIndex + optionalHintMarker.size();
+ const int optionalHintLength = chunkLine.size() - optionalHintStart;
+ const QStringRef optionalHint = chunkLine.mid(optionalHintStart, optionalHintLength);
+
+ const QChar comma(',');
+ bool ok;
+
+ const int leftCommaIndex = leftPos.indexOf(comma);
+ if (leftCommaIndex >= 0)
+ leftPos = leftPos.left(leftCommaIndex);
+ const int leftLineNumber = leftPos.toString().toInt(&ok);
+ if (!ok)
+ return false;
+
+ const int rightCommaIndex = rightPos.indexOf(comma);
+ if (rightCommaIndex >= 0)
+ rightPos = rightPos.left(rightCommaIndex);
+ const int rightLineNumber = rightPos.toString().toInt(&ok);
+ if (!ok)
+ return false;
+
+ chunkData->leftStartingLineNumber = leftLineNumber - 1;
+ chunkData->rightStartingLineNumber = rightLineNumber - 1;
+ chunkData->contextInfo = optionalHint.toString();
+
+ return true;
+}
+
static QList<ChunkData> readChunks(QStringRef patch,
bool *lastChunkAtTheEndOfFile,
bool *ok)
{
- const QRegularExpression chunkRegExp(
- // beginning of the line
- "(?:\\n|^)"
- // @@ -leftPos[,leftCount] +rightPos[,rightCount] @@
- "@@ -(\\d+)(?:,\\d+)? \\+(\\d+)(?:,\\d+)? @@"
- // optional hint (e.g. function name)
- "(\\ +[^\\n]*)?"
- // end of line (need to be followed by text line)
- "\\n");
+ QList<ChunkData> chunkDataList;
+ int position = -1;
- bool readOk = false;
+ QVector<int> startingPositions; // store starting positions of @@
+ if (patch.startsWith(QStringLiteral("@@ -")))
+ startingPositions.append(position + 1);
- QList<ChunkData> chunkDataList;
+ while ((position = patch.indexOf(QStringLiteral("\n@@ -"), position + 1)) >= 0)
+ startingPositions.append(position + 1);
- QRegularExpressionMatch match = chunkRegExp.match(patch);
- if (match.hasMatch() && match.capturedStart() == 0) {
- int endOfLastChunk = 0;
- do {
- const int pos = match.capturedStart();
- const int leftStartingPos = match.capturedRef(1).toInt();
- const int rightStartingPos = match.capturedRef(2).toInt();
- const QString contextInfo = match.captured(3);
- if (endOfLastChunk > 0) {
- QStringRef lines = patch.mid(endOfLastChunk,
- pos - endOfLastChunk);
- chunkDataList.last().rows = readLines(lines,
- false,
- lastChunkAtTheEndOfFile,
- &readOk);
- if (!readOk)
- break;
- }
- endOfLastChunk = match.capturedEnd();
- ChunkData chunkData;
- chunkData.leftStartingLineNumber = leftStartingPos - 1;
- chunkData.rightStartingLineNumber = rightStartingPos - 1;
- chunkData.contextInfo = contextInfo;
- chunkDataList.append(chunkData);
- match = chunkRegExp.match(patch, endOfLastChunk);
- } while (match.hasMatch());
-
- if (endOfLastChunk > 0) {
- QStringRef lines = patch.mid(endOfLastChunk);
- chunkDataList.last().rows = readLines(lines,
- true,
- lastChunkAtTheEndOfFile,
- &readOk);
- }
+ const QChar newLine('\n');
+ bool readOk = true;
+
+ const int count = startingPositions.count();
+ for (int i = 0; i < count; i++) {
+ const int chunkStart = startingPositions.at(i);
+ const int chunkEnd = (i < count - 1)
+ // drop the newline before the next chunk start
+ ? startingPositions.at(i + 1) - 1
+ // drop the possible newline by the end of patch
+ : (patch.at(patch.count() - 1) == newLine ? patch.count() - 1 : patch.count());
+
+ // extract just one chunk
+ const QStringRef chunkDiff = patch.mid(chunkStart, chunkEnd - chunkStart);
+
+ ChunkData chunkData;
+ QStringRef lines;
+ readOk = detectChunkData(chunkDiff, &chunkData, &lines);
+
+ if (!readOk)
+ break;
+
+ chunkData.rows = readLines(lines, i == (startingPositions.size() - 1),
+ lastChunkAtTheEndOfFile, &readOk);
+ if (!readOk)
+ break;
+
+ chunkDataList.append(chunkData);
}
if (ok)
@@ -881,293 +990,315 @@ static QList<FileData> readDiffPatch(QStringRef patch,
return fileDataList;
}
-static bool fileNameEnd(const QChar &c)
-{
- return c == QLatin1Char('\n') || c == QLatin1Char('\t');
-}
-
-static FileData readGitHeaderAndChunks(QStringRef headerAndChunks,
- const QString &fileName,
- bool *ok)
+// The git diff patch format (ChangeFile, NewFile, DeleteFile)
+// 0. <some text lines to skip, e.g. show description>\n
+// 1. diff --git a/[fileName] b/[fileName]\n
+// 2a. new file mode [fileModeNumber]\n
+// 2b. deleted file mode [fileModeNumber]\n
+// 2c. old mode [oldFileModeNumber]\n
+// new mode [newFileModeNumber]\n
+// 2d. <Nothing, only in case of ChangeFile>
+// 3a. index [leftIndexSha]..[rightIndexSha] <optionally: octalNumber>
+// 3b. <Nothing, only in case of ChangeFile, "Dirty submodule" case>
+// 4a. <Nothing more, only possible in case of NewFile or DeleteFile> ???
+// 4b. \nBinary files [leftFileNameOrDevNull] and [rightFileNameOrDevNull] differ
+// 4c. --- [leftFileNameOrDevNull]\n
+// +++ [rightFileNameOrDevNull]\n
+// <Chunks>
+
+// The git diff patch format (CopyFile, RenameFile)
+// 0. [some text lines to skip, e.g. show description]\n
+// 1. diff --git a/[leftFileName] b/[rightFileName]\n
+// 2. [dis]similarity index [0-100]%\n
+// [copy / rename] from [leftFileName]\n
+// [copy / rename] to [rightFileName]
+// 3a. <Nothing more, only when similarity index was 100%>
+// 3b. index [leftIndexSha]..[rightIndexSha] <optionally: octalNumber>
+// 4. --- [leftFileNameOrDevNull]\n
+// +++ [rightFileNameOrDevNull]\n
+// <Chunks>
+
+static bool detectIndexAndBinary(QStringRef patch,
+ FileData *fileData,
+ QStringRef *remainingPatch)
{
- FileData fileData;
- fileData.leftFileInfo.fileName = fileName;
- fileData.rightFileInfo.fileName = fileName;
-
- QStringRef patch = headerAndChunks;
- bool readOk = false;
-
- const QString devNull(QLatin1String("/dev/null"));
-
- // will be followed by: index 0000000..shasha, file "a" replaced by "/dev/null", @@ -0,0 +m,n @@
- // new file mode octal
- const QRegularExpression newFileMode("^new file mode \\d+\\n");
+ bool hasNewLine;
+ *remainingPatch = patch;
- // will be followed by: index shasha..0000000, file "b" replaced by "/dev/null", @@ -m,n +0,0 @@
- // deleted file mode octal
- const QRegularExpression deletedFileMode("^deleted file mode \\d+\\n");
-
- const QRegularExpression modeChangeRegExp("^old mode \\d+\\nnew mode \\d+\\n");
-
- // index cap1..cap2(optionally: octal)
- const QRegularExpression indexRegExp("^index (\\w+)\\.{2}(\\w+)(?: \\d+)?(\\n|$)");
-
- QString leftFileName = QLatin1String("a/") + fileName;
- QString rightFileName = QLatin1String("b/") + fileName;
-
- const QRegularExpressionMatch newFileMatch = newFileMode.match(patch);
- if (newFileMatch.hasMatch() && newFileMatch.capturedStart() == 0) {
- fileData.fileOperation = FileData::NewFile;
- leftFileName = devNull;
- patch = patch.mid(newFileMatch.capturedEnd());
- } else {
- const QRegularExpressionMatch deletedFileMatch = deletedFileMode.match(patch);
- if (deletedFileMatch.hasMatch() && deletedFileMatch.capturedStart() == 0) {
- fileData.fileOperation = FileData::DeleteFile;
- rightFileName = devNull;
- patch = patch.mid(deletedFileMatch.capturedEnd());
- } else {
- const QRegularExpressionMatch modeChangeMatch = modeChangeRegExp.match(patch);
- if (modeChangeMatch.hasMatch() && modeChangeMatch.capturedStart() == 0) {
- patch = patch.mid(modeChangeMatch.capturedEnd());
- }
- }
+ if (remainingPatch->isEmpty() && (fileData->fileOperation == FileData::CopyFile
+ || fileData->fileOperation == FileData::RenameFile)) {
+ // in case of 100% similarity we don't have more lines in the patch
+ return true;
}
- const QRegularExpressionMatch indexMatch = indexRegExp.match(patch);
- if (indexMatch.hasMatch() && indexMatch.capturedStart() == 0) {
- fileData.leftFileInfo.typeInfo = indexMatch.captured(1);
- fileData.rightFileInfo.typeInfo = indexMatch.captured(2);
+ QStringRef afterNextLine;
+ // index [leftIndexSha]..[rightIndexSha] <optionally: octalNumber>
+ const QStringRef nextLine = readLine(patch, &afterNextLine, &hasNewLine);
+
+ const QLatin1String indexHeader("index ");
+
+ if (nextLine.startsWith(indexHeader)) {
+ const QStringRef indices = nextLine.mid(indexHeader.size());
+ const int dotsPosition = indices.indexOf(QStringLiteral(".."));
+ if (dotsPosition < 0)
+ return false;
+ fileData->leftFileInfo.typeInfo = indices.left(dotsPosition).toString();
+
+ // if there is no space we take the remaining string
+ const int spacePosition = indices.indexOf(QChar::Space, dotsPosition + 2);
+ const int length = spacePosition < 0 ? -1 : spacePosition - dotsPosition - 2;
+ fileData->rightFileInfo.typeInfo = indices.mid(dotsPosition + 2, length).toString();
+
+ *remainingPatch = afterNextLine;
+ } else if (fileData->fileOperation != FileData::ChangeFile) {
+ // no index only in case of ChangeFile,
+ // the dirty submodule diff case, see "Dirty Submodule" test:
+ return false;
+ }
- patch = patch.mid(indexMatch.capturedEnd());
+ if (remainingPatch->isEmpty() && (fileData->fileOperation == FileData::NewFile
+ || fileData->fileOperation == FileData::DeleteFile)) {
+ // OK in case of empty file
+ return true;
}
- const QString binaryLine = QString::fromLatin1("Binary files ") + leftFileName
- + QLatin1String(" and ") + rightFileName + QLatin1String(" differ");
- const QString leftStart = QString::fromLatin1("--- ") + leftFileName;
- QChar leftFollow = patch.count() > leftStart.count() ? patch.at(leftStart.count()) : QLatin1Char('\n');
+ const QString devNull("/dev/null");
+ const QString leftFileName = fileData->fileOperation == FileData::NewFile
+ ? devNull : QLatin1String("a/") + fileData->leftFileInfo.fileName;
+ const QString rightFileName = fileData->fileOperation == FileData::DeleteFile
+ ? devNull : QLatin1String("b/") + fileData->rightFileInfo.fileName;
- // empty or followed either by leftFileRegExp or by binaryRegExp
- if (patch.isEmpty() && (fileData.fileOperation == FileData::NewFile
- || fileData.fileOperation == FileData::DeleteFile)) {
- readOk = true;
- } else if (patch.startsWith(leftStart) && fileNameEnd(leftFollow)) {
- patch = patch.mid(patch.indexOf(QLatin1Char('\n'), leftStart.count()) + 1);
+ const QString binaryLine = QLatin1String("Binary files ")
+ + leftFileName + QLatin1String(" and ")
+ + rightFileName + QLatin1String(" differ");
- const QString rightStart = QString::fromLatin1("+++ ") + rightFileName;
- QChar rightFollow = patch.count() > rightStart.count() ? patch.at(rightStart.count()) : QLatin1Char('\n');
+ if (*remainingPatch == binaryLine) {
+ fileData->binaryFiles = true;
+ *remainingPatch = QStringRef();
+ return true;
+ }
- // followed by rightFileRegExp
- if (patch.startsWith(rightStart) && fileNameEnd(rightFollow)) {
- patch = patch.mid(patch.indexOf(QLatin1Char('\n'), rightStart.count()) + 1);
+ const QString leftStart = QLatin1String("--- ") + leftFileName;
+ QStringRef afterMinuses;
+ // --- leftFileName
+ const QStringRef minuses = readLine(*remainingPatch, &afterMinuses, &hasNewLine);
+ if (!hasNewLine)
+ return false; // we need to have at least one more line
- fileData.chunks = readChunks(patch,
- &fileData.lastChunkAtTheEndOfFile,
- &readOk);
- }
- } else if (patch == binaryLine) {
- readOk = true;
- fileData.binaryFiles = true;
- }
+ if (!minuses.startsWith(leftStart))
+ return false;
- if (ok)
- *ok = readOk;
+ const QString rightStart = QLatin1String("+++ ") + rightFileName;
+ QStringRef afterPluses;
+ // +++ rightFileName
+ const QStringRef pluses = readLine(afterMinuses, &afterPluses, &hasNewLine);
+ if (!hasNewLine)
+ return false; // we need to have at least one more line
- if (!readOk)
- return FileData();
+ if (!pluses.startsWith(rightStart))
+ return false;
- return fileData;
+ *remainingPatch = afterPluses;
+ return true;
}
-static FileData readCopyRenameChunks(QStringRef copyRenameChunks,
- FileData::FileOperation fileOperation,
- const QString &leftFileName,
- const QString &rightFileName,
- bool *ok)
+static bool extractCommonFileName(QStringRef fileNames, QStringRef *fileName)
{
- FileData fileData;
- fileData.fileOperation = fileOperation;
- fileData.leftFileInfo.fileName = leftFileName;
- fileData.rightFileInfo.fileName = rightFileName;
+ // we should have 1 space between filenames
+ if (fileNames.size() % 2 == 0)
+ return false;
- QStringRef patch = copyRenameChunks;
- bool readOk = false;
-
- // index cap1..cap2(optionally: octal)
- const QRegularExpression indexRegExp("^index (\\w+)\\.{2}(\\w+)(?: \\d+)?(\\n|$)");
+ if (!fileNames.startsWith(QStringLiteral("a/")))
+ return false;
- if (fileOperation == FileData::CopyFile || fileOperation == FileData::RenameFile) {
- const QRegularExpressionMatch indexMatch = indexRegExp.match(patch);
- if (indexMatch.hasMatch() && indexMatch.capturedStart() == 0) {
- fileData.leftFileInfo.typeInfo = indexMatch.captured(1);
- fileData.rightFileInfo.typeInfo = indexMatch.captured(2);
+ // drop the space in between
+ const int fileNameSize = fileNames.size() / 2;
+ if (!fileNames.mid(fileNameSize).startsWith(" b/"))
+ return false;
- patch = patch.mid(indexMatch.capturedEnd());
+ // drop "a/"
+ const QStringRef leftFileName = fileNames.mid(2, fileNameSize - 2);
- const QString leftStart = QString::fromLatin1("--- a/") + leftFileName;
- QChar leftFollow = patch.count() > leftStart.count() ? patch.at(leftStart.count()) : QLatin1Char('\n');
+ // drop the first filename + " b/"
+ const QStringRef rightFileName = fileNames.mid(fileNameSize + 3, fileNameSize - 2);
- // followed by leftFileRegExp
- if (patch.startsWith(leftStart) && fileNameEnd(leftFollow)) {
- patch = patch.mid(patch.indexOf(QLatin1Char('\n'), leftStart.count()) + 1);
+ if (leftFileName != rightFileName)
+ return false;
- // followed by rightFileRegExp
- const QString rightStart = QString::fromLatin1("+++ b/") + rightFileName;
- QChar rightFollow = patch.count() > rightStart.count() ? patch.at(rightStart.count()) : QLatin1Char('\n');
+ *fileName = leftFileName;
+ return true;
+}
- // followed by rightFileRegExp
- if (patch.startsWith(rightStart) && fileNameEnd(rightFollow)) {
- patch = patch.mid(patch.indexOf(QLatin1Char('\n'), rightStart.count()) + 1);
+static bool detectFileData(QStringRef patch,
+ FileData *fileData,
+ QStringRef *remainingPatch) {
+ bool hasNewLine;
+
+ QStringRef afterDiffGit;
+ // diff --git a/leftFileName b/rightFileName
+ const QStringRef diffGit = readLine(patch, &afterDiffGit, &hasNewLine);
+ if (!hasNewLine)
+ return false; // we need to have at least one more line
+
+ const QLatin1String gitHeader("diff --git ");
+ const QStringRef fileNames = diffGit.mid(gitHeader.size());
+ QStringRef commonFileName;
+ if (extractCommonFileName(fileNames, &commonFileName)) {
+ // change / new / delete
+
+ fileData->fileOperation = FileData::ChangeFile;
+ fileData->leftFileInfo.fileName = fileData->rightFileInfo.fileName = commonFileName.toString();
+
+ QStringRef afterSecondLine;
+ const QStringRef secondLine = readLine(afterDiffGit, &afterSecondLine, &hasNewLine);
+ if (!hasNewLine)
+ return false; // we need to have at least one more line
+
+ if (secondLine.startsWith(QStringLiteral("new file mode "))) {
+ fileData->fileOperation = FileData::NewFile;
+ *remainingPatch = afterSecondLine;
+ } else if (secondLine.startsWith(QStringLiteral("deleted file mode "))) {
+ fileData->fileOperation = FileData::DeleteFile;
+ *remainingPatch = afterSecondLine;
+ } else if (secondLine.startsWith(QStringLiteral("old mode "))) {
+ QStringRef afterThirdLine;
+ // new mode
+ readLine(afterSecondLine, &afterThirdLine, &hasNewLine);
+ if (!hasNewLine)
+ return false; // we need to have at least one more line
+
+ // TODO: validate new mode line
+ *remainingPatch = afterThirdLine;
+ } else {
+ *remainingPatch = afterDiffGit;
+ }
- fileData.chunks = readChunks(patch,
- &fileData.lastChunkAtTheEndOfFile,
- &readOk);
- }
- }
- } else if (copyRenameChunks.isEmpty()) {
- readOk = true;
+ } else {
+ // copy / rename
+
+ QStringRef afterSimilarity;
+ // (dis)similarity index [0-100]%
+ readLine(afterDiffGit, &afterSimilarity, &hasNewLine);
+ if (!hasNewLine)
+ return false; // we need to have at least one more line
+
+ // TODO: validate similarity line
+
+ QStringRef afterCopyRenameFrom;
+ // [copy / rename] from leftFileName
+ const QStringRef copyRenameFrom = readLine(afterSimilarity, &afterCopyRenameFrom, &hasNewLine);
+ if (!hasNewLine)
+ return false; // we need to have at least one more line
+
+ const QLatin1String copyFrom("copy from ");
+ const QLatin1String renameFrom("rename from ");
+ if (copyRenameFrom.startsWith(copyFrom)) {
+ fileData->fileOperation = FileData::CopyFile;
+ fileData->leftFileInfo.fileName = copyRenameFrom.mid(copyFrom.size()).toString();
+ } else if (copyRenameFrom.startsWith(renameFrom)) {
+ fileData->fileOperation = FileData::RenameFile;
+ fileData->leftFileInfo.fileName = copyRenameFrom.mid(renameFrom.size()).toString();
+ } else {
+ return false;
}
- }
- if (ok)
- *ok = readOk;
+ QStringRef afterCopyRenameTo;
+ // [copy / rename] to rightFileName
+ const QStringRef copyRenameTo = readLine(afterCopyRenameFrom, &afterCopyRenameTo, &hasNewLine);
- if (!readOk)
- return FileData();
+ // if (dis)similarity index is 100% we don't have more lines
- return fileData;
+ const QLatin1String copyTo("copy to ");
+ const QLatin1String renameTo("rename to ");
+ if (fileData->fileOperation == FileData::CopyFile && copyRenameTo.startsWith(copyTo)) {
+ fileData->rightFileInfo.fileName = copyRenameTo.mid(copyTo.size()).toString();
+ } else if (fileData->fileOperation == FileData::RenameFile && copyRenameTo.startsWith(renameTo)) {
+ fileData->rightFileInfo.fileName = copyRenameTo.mid(renameTo.size()).toString();
+ } else {
+ return false;
+ }
+
+ *remainingPatch = afterCopyRenameTo;
+ }
+ return detectIndexAndBinary(*remainingPatch, fileData, remainingPatch);
}
static QList<FileData> readGitPatch(QStringRef patch, bool *ok,
QFutureInterfaceBase *jobController)
{
+ int position = -1;
- const QRegularExpression simpleGitRegExp(
- "^diff --git a/([^\\n]+) b/\\1\\n" // diff --git a/cap1 b/cap1
- , QRegularExpression::MultilineOption);
+ QVector<int> startingPositions; // store starting positions of git headers
+ if (patch.startsWith(QStringLiteral("diff --git ")))
+ startingPositions.append(position + 1);
- const QRegularExpression similarityRegExp(
- "^diff --git a/([^\\n]+) b/([^\\n]+)\\n" // diff --git a/cap1 b/cap2
- "(?:dis)?similarity index \\d{1,3}%\\n" // similarity / dissimilarity index xxx% (100% max)
- "(copy|rename) from \\1\\n" // copy / rename from cap1
- "\\3 to \\2\\n" // copy / rename (cap3) to cap2
- , QRegularExpression::MultilineOption);
+ while ((position = patch.indexOf(QStringLiteral("\ndiff --git "), position + 1)) >= 0)
+ startingPositions.append(position + 1);
- bool readOk = false;
+ class PatchInfo {
+ public:
+ QStringRef patch;
+ FileData fileData;
+ };
- QList<FileData> fileDataList;
+ const QChar newLine('\n');
+ bool readOk = true;
- bool simpleGitMatched;
- int pos = 0;
- QRegularExpressionMatch simpleGitMatch = simpleGitRegExp.match(patch);
- QRegularExpressionMatch similarityMatch = similarityRegExp.match(patch);
- auto calculateGitMatchAndPosition = [&]() {
- if (pos > 0) { // don't advance in the initial call
- if (simpleGitMatch.hasMatch() && similarityMatch.hasMatch()) {
- const int simpleGitPos = simpleGitMatch.capturedStart();
- const int similarityPos = similarityMatch.capturedStart();
- if (simpleGitPos <= similarityPos)
- simpleGitMatch = simpleGitRegExp.match(patch, simpleGitMatch.capturedEnd() - 1); // advance only simpleGit
- else
- similarityMatch = similarityRegExp.match(patch, similarityMatch.capturedEnd() - 1); // advance only similarity
- } else if (simpleGitMatch.hasMatch()) {
- simpleGitMatch = simpleGitRegExp.match(patch, simpleGitMatch.capturedEnd() - 1);
- } else if (similarityMatch.hasMatch()) {
- similarityMatch = similarityRegExp.match(patch, similarityMatch.capturedEnd() - 1);
- }
- }
+ QVector<PatchInfo> patches;
+ const int count = startingPositions.count();
+ for (int i = 0; i < count; i++) {
+ if (jobController && jobController->isCanceled())
+ return QList<FileData>();
- if (simpleGitMatch.hasMatch() && similarityMatch.hasMatch()) {
- const int simpleGitPos = simpleGitMatch.capturedStart();
- const int similarityPos = similarityMatch.capturedStart();
- pos = qMin(simpleGitPos, similarityPos);
- simpleGitMatched = (pos == simpleGitPos);
- return;
- }
+ const int diffStart = startingPositions.at(i);
+ const int diffEnd = (i < count - 1)
+ // drop the newline before the next header start
+ ? startingPositions.at(i + 1) - 1
+ // drop the possible newline by the end of file
+ : (patch.at(patch.count() - 1) == newLine ? patch.count() - 1 : patch.count());
- if (simpleGitMatch.hasMatch()) {
- pos = simpleGitMatch.capturedStart();
- simpleGitMatched = true;
- return;
- }
+ // extract the patch for just one file
+ const QStringRef fileDiff = patch.mid(diffStart, diffEnd - diffStart);
- if (similarityMatch.hasMatch()) {
- pos = similarityMatch.capturedStart();
- simpleGitMatched = false;
- return;
- }
+ FileData fileData;
+ QStringRef remainingFileDiff;
+ readOk = detectFileData(fileDiff, &fileData, &remainingFileDiff);
- pos = -1;
- simpleGitMatched = true;
- };
+ if (!readOk)
+ break;
- // Set both pos and simpleGitMatched according to the first match:
- calculateGitMatchAndPosition();
+ patches.append(PatchInfo { remainingFileDiff, fileData });
+ }
- if (pos >= 0) { // git style patch
- readOk = true;
- int endOfLastHeader = 0;
- QString lastLeftFileName;
- QString lastRightFileName;
- FileData::FileOperation lastOperation = FileData::ChangeFile;
-
- auto collectFileData = [&]() {
- if (endOfLastHeader > 0 && readOk) {
- const int end = pos < 0 ? patch.count() : pos;
- QStringRef headerAndChunks = patch.mid(endOfLastHeader,
- qMax(end - endOfLastHeader - 1, 0));
-
- FileData fileData;
- if (lastOperation == FileData::ChangeFile) {
- fileData = readGitHeaderAndChunks(headerAndChunks,
- lastLeftFileName,
- &readOk);
- } else {
- fileData = readCopyRenameChunks(headerAndChunks,
- lastOperation,
- lastLeftFileName,
- lastRightFileName,
- &readOk);
- }
- if (readOk)
- fileDataList.append(fileData);
- }
- };
+ if (!readOk) {
+ if (ok)
+ *ok = readOk;
+ return QList<FileData>();
+ }
- do {
- if (jobController && jobController->isCanceled())
- return QList<FileData>();
+ if (jobController)
+ jobController->setProgressRange(0, patches.count());
- collectFileData();
- if (!readOk)
- break;
+ QList<FileData> fileDataList;
+ readOk = false;
+ int i = 0;
+ for (const auto &patchInfo : Utils::asConst(patches)) {
+ if (jobController) {
+ if (jobController->isCanceled())
+ return QList<FileData>();
+ jobController->setProgressValue(i++);
+ }
- if (simpleGitMatched) {
- const QString fileName = simpleGitMatch.captured(1);
- pos = simpleGitMatch.capturedEnd();
- lastLeftFileName = fileName;
- lastRightFileName = fileName;
- lastOperation = FileData::ChangeFile;
- } else {
- lastLeftFileName = similarityMatch.captured(1);
- lastRightFileName = similarityMatch.captured(2);
- const QString operation = similarityMatch.captured(3);
- pos = similarityMatch.capturedEnd();
- if (operation == QLatin1String("copy"))
- lastOperation = FileData::CopyFile;
- else if (operation == QLatin1String("rename"))
- lastOperation = FileData::RenameFile;
- else
- break; // either copy or rename, otherwise broken
- }
- endOfLastHeader = pos;
+ FileData fileData = patchInfo.fileData;
+ if (!patchInfo.patch.isEmpty() || fileData.fileOperation == FileData::ChangeFile)
+ fileData.chunks = readChunks(patchInfo.patch, &fileData.lastChunkAtTheEndOfFile, &readOk);
+ else
+ readOk = true;
- // give both pos and simpleGitMatched a new value for the next match
- calculateGitMatchAndPosition();
- } while (pos != -1);
+ if (!readOk)
+ break;
- if (readOk)
- collectFileData();
+ fileDataList.append(fileData);
}
if (ok)
diff --git a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
index 80b2564d11..19d427f88d 100644
--- a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
+++ b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
@@ -112,6 +112,7 @@ protected:
QColor replacementPenColor(int blockNumber) const override;
QString plainTextFromSelection(const QTextCursor &cursor) const override;
void mouseDoubleClickEvent(QMouseEvent *e) override;
+ void keyPressEvent(QKeyEvent *e) override;
void contextMenuEvent(QContextMenuEvent *e) override;
void paintEvent(QPaintEvent *e) override;
void scrollContentsBy(int dx, int dy) override;
@@ -393,6 +394,16 @@ void SideDiffEditorWidget::mouseDoubleClickEvent(QMouseEvent *e)
SelectableTextEditorWidget::mouseDoubleClickEvent(e);
}
+void SideDiffEditorWidget::keyPressEvent(QKeyEvent *e)
+{
+ if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
+ jumpToOriginalFile(textCursor());
+ e->accept();
+ return;
+ }
+ SelectableTextEditorWidget::keyPressEvent(e);
+}
+
void SideDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e)
{
QPointer<QMenu> menu = createStandardContextMenu();
diff --git a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp
index 418c85f821..c2b75c9495 100644
--- a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp
+++ b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp
@@ -161,6 +161,16 @@ void UnifiedDiffEditorWidget::mouseDoubleClickEvent(QMouseEvent *e)
SelectableTextEditorWidget::mouseDoubleClickEvent(e);
}
+void UnifiedDiffEditorWidget::keyPressEvent(QKeyEvent *e)
+{
+ if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
+ jumpToOriginalFile(textCursor());
+ e->accept();
+ return;
+ }
+ SelectableTextEditorWidget::keyPressEvent(e);
+}
+
void UnifiedDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e)
{
QPointer<QMenu> menu = createStandardContextMenu();
diff --git a/src/plugins/diffeditor/unifieddiffeditorwidget.h b/src/plugins/diffeditor/unifieddiffeditorwidget.h
index 260bf2d81b..c05d05e9af 100644
--- a/src/plugins/diffeditor/unifieddiffeditorwidget.h
+++ b/src/plugins/diffeditor/unifieddiffeditorwidget.h
@@ -74,6 +74,7 @@ signals:
protected:
void mouseDoubleClickEvent(QMouseEvent *e) override;
+ void keyPressEvent(QKeyEvent *e) override;
void contextMenuEvent(QContextMenuEvent *e) override;
QString lineNumber(int blockNumber) const override;
int lineNumberDigits() const override;
diff --git a/src/plugins/ios/iosrunner.cpp b/src/plugins/ios/iosrunner.cpp
index 7ecd50b836..a57dbd461f 100644
--- a/src/plugins/ios/iosrunner.cpp
+++ b/src/plugins/ios/iosrunner.cpp
@@ -394,10 +394,10 @@ IosQmlProfilerSupport::IosQmlProfilerSupport(RunControl *runControl)
m_runner = new IosRunner(runControl);
m_runner->setQmlDebugging(QmlDebug::QmlProfilerServices);
- addDependency(m_runner);
+ addStartDependency(m_runner);
m_profiler = runControl->createWorker(runControl->runMode());
- m_profiler->addDependency(this);
+ m_profiler->addStartDependency(this);
}
void IosQmlProfilerSupport::start()
@@ -428,7 +428,7 @@ IosDebugSupport::IosDebugSupport(RunControl *runControl)
m_runner->setCppDebugging(isCppDebugging());
m_runner->setQmlDebugging(isQmlDebugging() ? QmlDebug::QmlDebuggerServices : QmlDebug::NoQmlDebugServices);
- addDependency(m_runner);
+ addStartDependency(m_runner);
}
void IosDebugSupport::start()
diff --git a/src/plugins/ios/iossettingswidget.cpp b/src/plugins/ios/iossettingswidget.cpp
index 0afe270775..6e99dadca2 100644
--- a/src/plugins/ios/iossettingswidget.cpp
+++ b/src/plugins/ios/iossettingswidget.cpp
@@ -185,7 +185,7 @@ void IosSettingsWidget::onReset()
const int userInput = QMessageBox::question(this, tr("Reset"),
tr("Do you really want to reset the contents and settings"
- " of the selected devices", "",
+ " of the selected devices?", "",
simulatorInfoList.count()));
if (userInput == QMessageBox::No)
return;
@@ -243,7 +243,7 @@ void IosSettingsWidget::onDelete()
const int userInput = QMessageBox::question(this, tr("Delete Device"),
tr("Do you really want to delete the selected "
- "devices", "", simulatorInfoList.count()));
+ "devices?", "", simulatorInfoList.count()));
if (userInput == QMessageBox::No)
return;
diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp
index dde4edce5d..7f243e8e43 100644
--- a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp
+++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp
@@ -37,11 +37,13 @@
#include <ssh/sshconnection.h>
#include <utils/environment.h>
+#include <utils/hostosinfo.h>
#include <utils/portlist.h>
#include <QCoreApplication>
using namespace ProjectExplorer::Constants;
+using namespace Utils;
namespace ProjectExplorer {
@@ -137,6 +139,104 @@ DeviceEnvironmentFetcher::Ptr DesktopDevice::environmentFetcher() const
return DeviceEnvironmentFetcher::Ptr(new DesktopDeviceEnvironmentFetcher());
}
+class DesktopPortsGatheringMethod : public PortsGatheringMethod
+{
+ Runnable runnable(QAbstractSocket::NetworkLayerProtocol protocol) const override
+ {
+ // We might encounter the situation that protocol is given IPv6
+ // but the consumer of the free port information decides to open
+ // an IPv4(only) port. As a result the next IPv6 scan will
+ // report the port again as open (in IPv6 namespace), while the
+ // same port in IPv4 namespace might still be blocked, and
+ // re-use of this port fails.
+ // GDBserver behaves exactly like this.
+
+ Q_UNUSED(protocol)
+
+ StandardRunnable runnable;
+ if (HostOsInfo::isWindowsHost()) {
+ runnable.executable = "netstat";
+ runnable.commandLineArguments = "-a -n";
+ } else if (HostOsInfo::isLinuxHost()) {
+ runnable.executable = "/bin/sh";
+ runnable.commandLineArguments = "-c 'cat /proc/net/tcp*'";
+ }
+ return runnable;
+ }
+
+ QList<Utils::Port> usedPorts(const QByteArray &output) const override
+ {
+ QList<Utils::Port> ports;
+ const QList<QByteArray> lines = output.split('\n');
+ if (HostOsInfo::isWindowsHost()) {
+ // Expected output is something like
+ //
+ // Active Connections
+ //
+ // Proto Local Address Foreign Address State
+ // TCP 0.0.0.0:80 0.0.0.0:0 LISTENING
+ // TCP 0.0.0.0:113 0.0.0.0:0 LISTENING
+ // [...]
+ // TCP 10.9.78.4:14714 0.0.0.0:0 LISTENING
+ // TCP 10.9.78.4:50233 12.13.135.180:993 ESTABLISHED
+ for (const QByteArray &line : lines) {
+ const QByteArray trimmed = line.trimmed();
+ if (!trimmed.startsWith("TCP"))
+ continue;
+ int colonPos = trimmed.indexOf(':');
+ if (colonPos < 0)
+ continue;
+ int spacePos = trimmed.indexOf(':', colonPos + 1);
+ if (spacePos < 0)
+ continue;
+ bool ok;
+ int len = spacePos - colonPos - 1;
+ const Utils::Port port(line.mid(colonPos + 1, len).toInt(&ok, 16));
+ if (ok) {
+ if (!ports.contains(port))
+ ports << port;
+ } else {
+ qWarning("%s: Unexpected string '%s' is not a port.",
+ Q_FUNC_INFO, line.data());
+ }
+ }
+ } else if (HostOsInfo::isLinuxHost()) {
+ // Expected outpit is something like
+ //
+ // sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt ...
+ // 0: 00000000:2805 00000000:0000 0A 00000000:00000000 00:00000000 00000000 ...
+ //
+ for (const QByteArray &line : lines) {
+ int firstColonPos = line.indexOf(':');
+ if (firstColonPos < 0)
+ continue;
+ int secondColonPos = line.indexOf(':', firstColonPos + 1);
+ if (secondColonPos < 0)
+ continue;
+ int spacePos = line.indexOf(':', secondColonPos + 1);
+ if (spacePos < 0)
+ continue;
+ bool ok;
+ int len = spacePos - secondColonPos - 1;
+ const Utils::Port port(line.mid(secondColonPos + 1, len).toInt(&ok, 16));
+ if (ok) {
+ if (!ports.contains(port))
+ ports << port;
+ } else {
+ qWarning("%s: Unexpected string '%s' is not a port.",
+ Q_FUNC_INFO, line.data());
+ }
+ }
+ }
+ return ports;
+ }
+};
+
+PortsGatheringMethod::Ptr DesktopDevice::portsGatheringMethod() const
+{
+ return DesktopPortsGatheringMethod::Ptr(new DesktopPortsGatheringMethod);
+}
+
QUrl DesktopDevice::toolControlChannel(const ControlChannelHint &) const
{
QUrl url;
diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.h b/src/plugins/projectexplorer/devicesupport/desktopdevice.h
index 588281c1d2..203dd8fe49 100644
--- a/src/plugins/projectexplorer/devicesupport/desktopdevice.h
+++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.h
@@ -49,6 +49,7 @@ public:
bool canCreateProcessModel() const override;
DeviceProcessList *createProcessListModel(QObject *parent) const override;
bool canCreateProcess() const override { return true; }
+ ProjectExplorer::PortsGatheringMethod::Ptr portsGatheringMethod() const override;
DeviceProcess *createProcess(QObject *parent) const override;
DeviceProcessSignalOperation::Ptr signalOperation() const override;
DeviceEnvironmentFetcher::Ptr environmentFetcher() const override;
diff --git a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
index 17aa4f2ba9..2167f9ddbb 100644
--- a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
+++ b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
@@ -23,14 +23,14 @@
**
****************************************************************************/
+#include "deviceprocess.h"
#include "deviceusedportsgatherer.h"
+#include <projectexplorer/runnables.h>
+
#include <utils/port.h>
#include <utils/portlist.h>
#include <utils/qtcassert.h>
-#include <ssh/sshconnection.h>
-#include <ssh/sshconnectionmanager.h>
-#include <ssh/sshremoteprocess.h>
using namespace QSsh;
using namespace Utils;
@@ -41,12 +41,12 @@ namespace Internal {
class DeviceUsedPortsGathererPrivate
{
public:
- SshConnection *connection;
- SshRemoteProcess::Ptr process;
+ QPointer<DeviceProcess> process;
QList<Port> usedPorts;
QByteArray remoteStdout;
QByteArray remoteStderr;
IDevice::ConstPtr device;
+ PortsGatheringMethod::Ptr portsGatheringMethod;
};
} // namespace Internal
@@ -54,7 +54,6 @@ class DeviceUsedPortsGathererPrivate
DeviceUsedPortsGatherer::DeviceUsedPortsGatherer(QObject *parent) :
QObject(parent), d(new Internal::DeviceUsedPortsGathererPrivate)
{
- d->connection = 0;
}
DeviceUsedPortsGatherer::~DeviceUsedPortsGatherer()
@@ -65,50 +64,36 @@ DeviceUsedPortsGatherer::~DeviceUsedPortsGatherer()
void DeviceUsedPortsGatherer::start(const IDevice::ConstPtr &device)
{
- QTC_ASSERT(!d->connection, return);
- QTC_ASSERT(device && device->portsGatheringMethod(), return);
-
d->device = device;
- d->connection = QSsh::acquireConnection(device->sshParameters());
- connect(d->connection, &SshConnection::error,
- this, &DeviceUsedPortsGatherer::handleConnectionError);
- if (d->connection->state() == SshConnection::Connected) {
- handleConnectionEstablished();
- return;
- }
- connect(d->connection, &SshConnection::connected,
- this, &DeviceUsedPortsGatherer::handleConnectionEstablished);
- if (d->connection->state() == SshConnection::Unconnected)
- d->connection->connectToHost();
-}
+ QTC_ASSERT(d->device, emit error("No device given"); return);
-void DeviceUsedPortsGatherer::handleConnectionEstablished()
-{
- const QAbstractSocket::NetworkLayerProtocol protocol
- = d->connection->connectionInfo().localAddress.protocol();
- const QByteArray commandLine = d->device->portsGatheringMethod()->commandLine(protocol);
- d->process = d->connection->createRemoteProcess(commandLine);
+ d->portsGatheringMethod = d->device->portsGatheringMethod();
+ QTC_ASSERT(d->portsGatheringMethod, emit error("Not implemented"); return);
+
+ const QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::AnyIPProtocol;
+ d->process = d->device->createProcess(this);
- connect(d->process.data(), &SshRemoteProcess::closed, this, &DeviceUsedPortsGatherer::handleProcessClosed);
- connect(d->process.data(), &SshRemoteProcess::readyReadStandardOutput, this, &DeviceUsedPortsGatherer::handleRemoteStdOut);
- connect(d->process.data(), &SshRemoteProcess::readyReadStandardError, this, &DeviceUsedPortsGatherer::handleRemoteStdErr);
+ connect(d->process.data(), &DeviceProcess::finished,
+ this, &DeviceUsedPortsGatherer::handleProcessFinished);
+ connect(d->process.data(), &DeviceProcess::error,
+ this, &DeviceUsedPortsGatherer::handleProcessError);
+ connect(d->process.data(), &DeviceProcess::readyReadStandardOutput,
+ this, &DeviceUsedPortsGatherer::handleRemoteStdOut);
+ connect(d->process.data(), &DeviceProcess::readyReadStandardError,
+ this, &DeviceUsedPortsGatherer::handleRemoteStdErr);
- d->process->start();
+ const Runnable runnable = d->portsGatheringMethod->runnable(protocol);
+ d->process->start(runnable);
}
void DeviceUsedPortsGatherer::stop()
{
- if (!d->connection)
- return;
d->usedPorts.clear();
d->remoteStdout.clear();
d->remoteStderr.clear();
if (d->process)
disconnect(d->process.data(), 0, this, 0);
d->process.clear();
- disconnect(d->connection, 0, this, 0);
- QSsh::releaseConnection(d->connection);
- d->connection = 0;
}
Port DeviceUsedPortsGatherer::getNextFreePort(PortList *freePorts) const
@@ -129,7 +114,7 @@ QList<Port> DeviceUsedPortsGatherer::usedPorts() const
void DeviceUsedPortsGatherer::setupUsedPorts()
{
d->usedPorts.clear();
- const QList<Port> usedPorts = d->device->portsGatheringMethod()->usedPorts(d->remoteStdout);
+ const QList<Port> usedPorts = d->portsGatheringMethod->usedPorts(d->remoteStdout);
foreach (const Port port, usedPorts) {
if (d->device->freePorts().contains(port))
d->usedPorts << port;
@@ -137,27 +122,23 @@ void DeviceUsedPortsGatherer::setupUsedPorts()
emit portListReady();
}
-void DeviceUsedPortsGatherer::handleConnectionError()
+void DeviceUsedPortsGatherer::handleProcessError()
{
- if (!d->connection)
- return;
- emit error(tr("Connection error: %1").arg(d->connection->errorString()));
+ emit error(tr("Connection error: %1").arg(d->process->errorString()));
stop();
}
-void DeviceUsedPortsGatherer::handleProcessClosed(int exitStatus)
+void DeviceUsedPortsGatherer::handleProcessFinished()
{
- if (!d->connection)
+ if (!d->process)
return;
QString errMsg;
+ QProcess::ExitStatus exitStatus = d->process->exitStatus();
switch (exitStatus) {
- case SshRemoteProcess::FailedToStart:
- errMsg = tr("Could not start remote process: %1").arg(d->process->errorString());
- break;
- case SshRemoteProcess::CrashExit:
+ case QProcess::CrashExit:
errMsg = tr("Remote process crashed: %1").arg(d->process->errorString());
break;
- case SshRemoteProcess::NormalExit:
+ case QProcess::NormalExit:
if (d->process->exitCode() == 0)
setupUsedPorts();
else
diff --git a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h
index c298b6fbd0..cb1508aae7 100644
--- a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h
+++ b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h
@@ -33,6 +33,7 @@
namespace ProjectExplorer {
namespace Internal { class DeviceUsedPortsGathererPrivate; }
+class StandardRunnable;
class PROJECTEXPLORER_EXPORT DeviceUsedPortsGatherer : public QObject
{
@@ -42,7 +43,7 @@ public:
DeviceUsedPortsGatherer(QObject *parent = 0);
~DeviceUsedPortsGatherer() override;
- void start(const ProjectExplorer::IDevice::ConstPtr &device);
+ void start(const IDevice::ConstPtr &device);
void stop();
Utils::Port getNextFreePort(Utils::PortList *freePorts) const; // returns -1 if no more are left
QList<Utils::Port> usedPorts() const;
@@ -52,11 +53,10 @@ signals:
void portListReady();
private:
- void handleConnectionEstablished();
- void handleConnectionError();
- void handleProcessClosed(int exitStatus);
void handleRemoteStdOut();
void handleRemoteStdErr();
+ void handleProcessError();
+ void handleProcessFinished();
void setupUsedPorts();
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h
index 4bf9ed09c2..7fa91b0f0e 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.h
+++ b/src/plugins/projectexplorer/devicesupport/idevice.h
@@ -57,6 +57,7 @@ class Connection;
class DeviceProcess;
class DeviceProcessList;
class Kit;
+class Runnable;
class RunControl;
class RunWorker;
@@ -110,7 +111,7 @@ public:
typedef QSharedPointer<const PortsGatheringMethod> Ptr;
virtual ~PortsGatheringMethod() = default;
- virtual QByteArray commandLine(QAbstractSocket::NetworkLayerProtocol protocol) const = 0;
+ virtual Runnable runnable(QAbstractSocket::NetworkLayerProtocol protocol) const = 0;
virtual QList<Utils::Port> usedPorts(const QByteArray &commandOutput) const = 0;
};
diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp
index 3c4c4b76d2..f340f086dc 100644
--- a/src/plugins/projectexplorer/kitinformation.cpp
+++ b/src/plugins/projectexplorer/kitinformation.cpp
@@ -410,6 +410,54 @@ void ToolChainKitInformation::setToolChain(Kit *k, ToolChain *tc)
k->setValue(id(), result);
}
+/**
+ * @brief ToolChainKitInformation::setAllToolChainsToMatch
+ *
+ * Set up all toolchains to be similar to the one toolchain provided. Similar ideally means
+ * that all toolchains use the "same" compiler from the same installation, but we will
+ * settle for a toolchain with a matching API instead.
+ *
+ * @param k The kit to set up
+ * @param tc The toolchain to match other languages for.
+ */
+void ToolChainKitInformation::setAllToolChainsToMatch(Kit *k, ToolChain *tc)
+{
+ QTC_ASSERT(tc, return);
+
+ const QList<ToolChain *> allTcList = ToolChainManager::toolChains();
+ QTC_ASSERT(allTcList.contains(tc), return);
+
+ QVariantMap result = k->value(ToolChainKitInformation::id()).toMap();
+ result.insert(tc->language().toString(), tc->id());
+
+ for (Core::Id l : ToolChainManager::allLanguages()) {
+ if (l == tc->language())
+ continue;
+
+ ToolChain *match = nullptr;
+ ToolChain *bestMatch = nullptr;
+ for (ToolChain *other : allTcList) {
+ if (!other->isValid() || other->language() != l)
+ continue;
+ if (other->targetAbi() == tc->targetAbi())
+ match = other;
+ if (match == other
+ && other->compilerCommand().parentDir() == tc->compilerCommand().parentDir()) {
+ bestMatch = other;
+ break;
+ }
+ }
+ if (bestMatch)
+ result.insert(l.toString(), bestMatch->id());
+ else if (match)
+ result.insert(l.toString(), match->id());
+ else
+ result.insert(l.toString(), QByteArray());
+ }
+
+ k->setValue(id(), result);
+}
+
void ToolChainKitInformation::clearToolChain(Kit *k, Core::Id language)
{
QTC_ASSERT(language.isValid(), return);
diff --git a/src/plugins/projectexplorer/kitinformation.h b/src/plugins/projectexplorer/kitinformation.h
index febd91ec58..d4defd96d4 100644
--- a/src/plugins/projectexplorer/kitinformation.h
+++ b/src/plugins/projectexplorer/kitinformation.h
@@ -98,6 +98,7 @@ public:
static ToolChain *toolChain(const Kit *k, Core::Id language);
static QList<ToolChain *> toolChains(const Kit *k);
static void setToolChain(Kit *k, ToolChain *tc);
+ static void setAllToolChainsToMatch(Kit *k, ToolChain *tc);
static void clearToolChain(Kit *k, Core::Id language);
static Abi targetAbi(const Kit *k);
diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp
index d505a72d43..c36f5c0297 100644
--- a/src/plugins/projectexplorer/projectmodels.cpp
+++ b/src/plugins/projectexplorer/projectmodels.cpp
@@ -212,7 +212,10 @@ void FlatModel::addOrRebuildProjectModel(Project *project)
if (ProjectNode *projectNode = project->rootProjectNode()) {
addFolderNode(container, projectNode, &seen);
- } else {
+ if (m_trimEmptyDirectories)
+ trimEmptyDirectories(container);
+ }
+ if (container->childCount() == 0) {
FileNode *projectFileNode = new FileNode(project->projectFilePath(), FileType::Project, false);
seen.insert(projectFileNode);
container->appendChild(new WrapperNode(projectFileNode));
@@ -344,7 +347,7 @@ void FlatModel::addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<
addFolderNode(parent, subFolderNode, seen);
}
} else if (FileNode *fileNode = node->asFileNode()) {
- const bool isHidden = m_filterProjects && fileNode->isGenerated();
+ const bool isHidden = m_filterGeneratedFiles && fileNode->isGenerated();
if (!isHidden && !seen->contains(fileNode)) {
seen->insert(fileNode);
parent->appendChild(new WrapperNode(fileNode));
@@ -353,6 +356,18 @@ void FlatModel::addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<
}
}
+bool FlatModel::trimEmptyDirectories(WrapperNode *parent)
+{
+ if (!parent->m_node->asFolderNode())
+ return false;
+
+ for (int i = parent->childCount() - 1; i >= 0; --i) {
+ if (trimEmptyDirectories(parent->childAt(i)))
+ parent->removeChildAt(i);
+ }
+ return parent->childCount() == 0;
+}
+
Qt::DropActions FlatModel::supportedDragActions() const
{
return Qt::MoveAction;
@@ -399,10 +414,20 @@ void FlatModel::setProjectFilterEnabled(bool filter)
void FlatModel::setGeneratedFilesFilterEnabled(bool filter)
{
+ if (filter == m_filterGeneratedFiles)
+ return;
m_filterGeneratedFiles = filter;
rebuildModel();
}
+void FlatModel::setTrimEmptyDirectories(bool filter)
+{
+ if (filter == m_trimEmptyDirectories)
+ return;
+ m_trimEmptyDirectories = filter;
+ rebuildModel();
+}
+
bool FlatModel::projectFilterEnabled()
{
return m_filterProjects;
diff --git a/src/plugins/projectexplorer/projectmodels.h b/src/plugins/projectexplorer/projectmodels.h
index e64bbd7102..80fdbbc36d 100644
--- a/src/plugins/projectexplorer/projectmodels.h
+++ b/src/plugins/projectexplorer/projectmodels.h
@@ -76,6 +76,7 @@ public:
bool generatedFilesFilterEnabled();
void setProjectFilterEnabled(bool filter);
void setGeneratedFilesFilterEnabled(bool filter);
+ void setTrimEmptyDirectories(bool filter);
void onExpanded(const QModelIndex &idx);
void onCollapsed(const QModelIndex &idx);
@@ -87,12 +88,14 @@ signals:
private:
bool m_filterProjects = false;
bool m_filterGeneratedFiles = true;
+ bool m_trimEmptyDirectories = true;
static const QLoggingCategory &logger();
void updateSubtree(FolderNode *node);
void rebuildModel();
void addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<Node *> *seen);
+ bool trimEmptyDirectories(WrapperNode *parent);
ExpandData expandDataForNode(const Node *node) const;
void loadExpandData();
diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp
index 0ba7c5cac9..f3755d8492 100644
--- a/src/plugins/projectexplorer/projectnodes.cpp
+++ b/src/plugins/projectexplorer/projectnodes.cpp
@@ -119,8 +119,8 @@ static FolderNode *recursiveFindOrCreateFolderNode(FolderNode *folder,
\sa ProjectExplorer::NodesWatcher
*/
-Node::Node(NodeType nodeType, const Utils::FileName &filePath, int line) :
- m_filePath(filePath), m_line(line), m_nodeType(nodeType)
+Node::Node(NodeType nodeType, const Utils::FileName &filePath, int line, const QByteArray &id) :
+ m_filePath(filePath), m_nodeId(id), m_line(line), m_nodeType(nodeType)
{ }
void Node::setPriority(int p)
@@ -222,6 +222,11 @@ int Node::line() const
return m_line;
}
+QByteArray Node::id() const
+{
+ return m_nodeId;
+}
+
QString Node::displayName() const
{
return filePath().fileName();
@@ -309,9 +314,9 @@ FileType Node::fileTypeForFileName(const Utils::FileName &file)
\sa ProjectExplorer::FolderNode, ProjectExplorer::ProjectNode
*/
-FileNode::FileNode(const Utils::FileName &filePath,
- const FileType fileType,
- bool generated, int line) : Node(NodeType::File, filePath, line),
+FileNode::FileNode(const Utils::FileName &filePath, const FileType fileType, bool generated,
+ int line, const QByteArray &id) :
+ Node(NodeType::File, filePath, line, id),
m_fileType(fileType)
{
setListInProject(true);
@@ -324,7 +329,7 @@ FileNode::FileNode(const Utils::FileName &filePath,
FileNode *FileNode::clone() const
{
- auto fn = new FileNode(filePath(), fileType(), isGenerated(), line());
+ auto fn = new FileNode(filePath(), fileType(), isGenerated(), line(), id());
fn->setEnabled(isEnabled());
fn->setPriority(priority());
fn->setListInProject(listInProject());
@@ -418,8 +423,9 @@ bool FileNode::supportsAction(ProjectAction action, const Node *node) const
\sa ProjectExplorer::FileNode, ProjectExplorer::ProjectNode
*/
-FolderNode::FolderNode(const Utils::FileName &folderPath, NodeType nodeType, const QString &displayName) :
- Node(nodeType, folderPath, -1),
+FolderNode::FolderNode(const Utils::FileName &folderPath, NodeType nodeType,
+ const QString &displayName, const QByteArray &id) :
+ Node(nodeType, folderPath, -1, id),
m_displayName(displayName)
{
setPriority(DefaultFolderPriority);
@@ -745,8 +751,9 @@ bool FolderNode::showInSimpleTree() const
\sa ProjectExplorer::FileNode, ProjectExplorer::ProjectNode
*/
-VirtualFolderNode::VirtualFolderNode(const Utils::FileName &folderPath, int priority) :
- FolderNode(folderPath, NodeType::VirtualFolder, QString())
+VirtualFolderNode::VirtualFolderNode(const Utils::FileName &folderPath, int priority,
+ const QByteArray &id) :
+ FolderNode(folderPath, NodeType::VirtualFolder, QString(), id)
{
setPriority(priority);
}
@@ -771,12 +778,11 @@ QString VirtualFolderNode::addFileFilter() const
/*!
Creates an uninitialized project node object.
*/
-ProjectNode::ProjectNode(const Utils::FileName &projectFilePath) :
- FolderNode(projectFilePath, NodeType::Project)
+ProjectNode::ProjectNode(const Utils::FileName &projectFilePath, const QByteArray &id) :
+ FolderNode(projectFilePath, NodeType::Project, projectFilePath.fileName(), id)
{
setPriority(DefaultProjectPriority);
setListInProject(true);
- setDisplayName(projectFilePath.fileName());
}
bool ProjectNode::canAddSubProject(const QString &proFilePath) const
diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h
index c6158af393..f19e746d03 100644
--- a/src/plugins/projectexplorer/projectnodes.h
+++ b/src/plugins/projectexplorer/projectnodes.h
@@ -125,6 +125,7 @@ public:
const Utils::FileName &filePath() const; // file system path
int line() const;
+ QByteArray id() const;
virtual QString displayName() const;
virtual QString tooltip() const;
bool isEnabled() const;
@@ -154,7 +155,8 @@ public:
static FileType fileTypeForFileName(const Utils::FileName &file);
protected:
- Node(NodeType nodeType, const Utils::FileName &filePath, int line = -1);
+ Node(NodeType nodeType, const Utils::FileName &filePath, int line = -1,
+ const QByteArray &id = {});
void setPriority(int priority);
void setIsGenerated(bool g);
@@ -162,6 +164,7 @@ protected:
private:
FolderNode *m_parentFolderNode = nullptr;
Utils::FileName m_filePath;
+ QByteArray m_nodeId;
int m_line = -1;
int m_priority = DefaultPriority;
const NodeType m_nodeType;
@@ -178,7 +181,8 @@ private:
class PROJECTEXPLORER_EXPORT FileNode : public Node
{
public:
- FileNode(const Utils::FileName &filePath, const FileType fileType, bool generated, int line = -1);
+ FileNode(const Utils::FileName &filePath, const FileType fileType, bool generated, int line = -1,
+ const QByteArray &id = {});
FileNode *clone() const;
@@ -208,7 +212,7 @@ class PROJECTEXPLORER_EXPORT FolderNode : public Node
{
public:
explicit FolderNode(const Utils::FileName &folderPath, NodeType nodeType = NodeType::Folder,
- const QString &displayName = QString());
+ const QString &displayName = QString(), const QByteArray &id = {});
~FolderNode() override;
QString displayName() const override;
@@ -299,7 +303,8 @@ private:
class PROJECTEXPLORER_EXPORT VirtualFolderNode : public FolderNode
{
public:
- explicit VirtualFolderNode(const Utils::FileName &folderPath, int priority);
+ explicit VirtualFolderNode(const Utils::FileName &folderPath, int priority,
+ const QByteArray &id = {});
void setAddFileFilter(const QString &filter) { m_addFileFilter = filter; }
QString addFileFilter() const override;
@@ -334,7 +339,7 @@ public:
const ProjectNode *asProjectNode() const final { return this; }
protected:
- explicit ProjectNode(const Utils::FileName &projectFilePath);
+ explicit ProjectNode(const Utils::FileName &projectFilePath, const QByteArray &id = {});
};
class PROJECTEXPLORER_EXPORT ContainerNode : public FolderNode
diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp
index 81821e981c..f310cd1468 100644
--- a/src/plugins/projectexplorer/projecttreewidget.cpp
+++ b/src/plugins/projectexplorer/projecttreewidget.cpp
@@ -255,6 +255,12 @@ ProjectTreeWidget::ProjectTreeWidget(QWidget *parent) : QWidget(parent)
connect(m_filterGeneratedFilesAction, &QAction::toggled,
this, &ProjectTreeWidget::setGeneratedFilesFilter);
+ m_trimEmptyDirectoriesAction = new QAction(tr("Hide Empty Directories"), this);
+ m_trimEmptyDirectoriesAction->setCheckable(true);
+ m_trimEmptyDirectoriesAction->setChecked(true);
+ connect(m_trimEmptyDirectoriesAction, &QAction::toggled,
+ this, &ProjectTreeWidget::setTrimEmptyDirectories);
+
// connections
connect(m_model, &FlatModel::renamed,
this, &ProjectTreeWidget::renamed);
@@ -494,6 +500,12 @@ void ProjectTreeWidget::setGeneratedFilesFilter(bool filter)
m_filterGeneratedFilesAction->setChecked(filter);
}
+void ProjectTreeWidget::setTrimEmptyDirectories(bool filter)
+{
+ m_model->setTrimEmptyDirectories(filter);
+ m_trimEmptyDirectoriesAction->setChecked(filter);
+}
+
bool ProjectTreeWidget::generatedFilesFilter()
{
return m_model->generatedFilesFilterEnabled();
@@ -527,6 +539,7 @@ NavigationView ProjectTreeWidgetFactory::createWidget()
auto filterMenu = new QMenu(filter);
filterMenu->addAction(ptw->m_filterProjectsAction);
filterMenu->addAction(ptw->m_filterGeneratedFilesAction);
+ filterMenu->addAction(ptw->m_trimEmptyDirectoriesAction);
filter->setMenu(filterMenu);
n.dockToolBarWidgets << filter << ptw->toggleSync();
diff --git a/src/plugins/projectexplorer/projecttreewidget.h b/src/plugins/projectexplorer/projecttreewidget.h
index 69102fedb0..4d87b6ad0f 100644
--- a/src/plugins/projectexplorer/projecttreewidget.h
+++ b/src/plugins/projectexplorer/projecttreewidget.h
@@ -70,6 +70,7 @@ public:
private:
void setProjectFilter(bool filter);
void setGeneratedFilesFilter(bool filter);
+ void setTrimEmptyDirectories(bool filter);
void handleCurrentItemChange(const QModelIndex &current);
void showContextMenu(const QPoint &pos);
@@ -83,8 +84,9 @@ private:
QTreeView *m_view = nullptr;
FlatModel *m_model = nullptr;
QAction *m_filterProjectsAction = nullptr;
- QAction *m_filterGeneratedFilesAction;
- QToolButton *m_toggleSync;
+ QAction *m_filterGeneratedFilesAction = nullptr;
+ QAction *m_trimEmptyDirectoriesAction = nullptr;
+ QToolButton *m_toggleSync = nullptr;
QString m_modelId;
bool m_autoSync = true;
diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp
index 4b1065762b..135acec782 100644
--- a/src/plugins/projectexplorer/runconfiguration.cpp
+++ b/src/plugins/projectexplorer/runconfiguration.cpp
@@ -533,7 +533,7 @@ namespace Internal {
enum class RunWorkerState
{
- Initialized, Starting, Running, Stopping, Done, Failed
+ Initialized, Starting, Running, Stopping, Done
};
static QString stateName(RunWorkerState s)
@@ -545,7 +545,6 @@ static QString stateName(RunWorkerState s)
SN(RunWorkerState::Running)
SN(RunWorkerState::Stopping)
SN(RunWorkerState::Done)
- SN(RunWorkerState::Failed)
}
return QString("<unknown: %1>").arg(int(s));
# undef SN
@@ -557,12 +556,14 @@ public:
RunWorkerPrivate(RunWorker *runWorker, RunControl *runControl);
bool canStart() const;
+ bool canStop() const;
void timerEvent(QTimerEvent *ev) override;
RunWorker *q;
RunWorkerState state = RunWorkerState::Initialized;
QPointer<RunControl> runControl;
- QList<RunWorker *> dependencies;
+ QList<RunWorker *> startDependencies;
+ QList<RunWorker *> stopDependencies;
QString id;
QVariantMap data;
@@ -571,6 +572,7 @@ public:
int stopWatchdogInterval = 0; // 5000;
int stopWatchdogTimerId = -1;
bool supportsReRunning = true;
+ bool essential = false;
};
enum class RunControlState
@@ -637,6 +639,7 @@ public:
void initiateReStart();
void continueStart();
void initiateStop();
+ void continueStopOrFinish();
void initiateFinish();
void onWorkerStarted(RunWorker *worker);
@@ -834,12 +837,6 @@ void RunControlPrivate::continueStart()
case RunWorkerState::Stopping:
debugMessage(" " + workerId + " currently stopping");
continue;
- case RunWorkerState::Failed:
- // Should not happen.
- debugMessage(" " + workerId + " failed before");
- QTC_CHECK(false);
- //setState(RunControlState::Stopped);
- break;
case RunWorkerState::Done:
debugMessage(" " + workerId + " was done before");
break;
@@ -854,11 +851,29 @@ void RunControlPrivate::continueStart()
void RunControlPrivate::initiateStop()
{
- checkState(RunControlState::Running);
+ if (state != RunControlState::Starting && state != RunControlState::Running)
+ qDebug() << "Unexpected initiateStop() in state" << stateName(state);
+
setState(RunControlState::Stopping);
debugMessage("Queue: Stopping for all workers");
+ continueStopOrFinish();
+}
+
+void RunControlPrivate::continueStopOrFinish()
+{
bool allDone = true;
+
+ auto queueStop = [this](RunWorker *worker, const QString &message) {
+ if (worker->d->canStop()) {
+ debugMessage(message);
+ worker->d->state = RunWorkerState::Stopping;
+ QTimer::singleShot(0, worker, &RunWorker::initiateStop);
+ } else {
+ debugMessage(" " + worker->d->id + " is waiting for dependent workers to stop");
+ }
+ };
+
for (RunWorker *worker : m_workers) {
if (worker) {
const QString &workerId = worker->d->id;
@@ -873,33 +888,35 @@ void RunControlPrivate::initiateStop()
allDone = false;
break;
case RunWorkerState::Starting:
- debugMessage(" " + workerId + " was Starting, queuing stop");
- worker->d->state = RunWorkerState::Stopping;
- QTimer::singleShot(0, worker, &RunWorker::initiateStop);
+ queueStop(worker, " " + workerId + " was Starting, queuing stop");
allDone = false;
break;
case RunWorkerState::Running:
- debugMessage(" " + workerId + " was Running, queuing stop");
- worker->d->state = RunWorkerState::Stopping;
+ queueStop(worker, " " + workerId + " was Running, queuing stop");
allDone = false;
- QTimer::singleShot(0, worker, &RunWorker::initiateStop);
break;
case RunWorkerState::Done:
debugMessage(" " + workerId + " was Done. Good.");
break;
- case RunWorkerState::Failed:
- debugMessage(" " + workerId + " was Failed. Good");
- break;
}
} else {
debugMessage("Found unknown deleted worker");
}
}
+
+ RunControlState targetState;
+ if (state == RunControlState::Finishing) {
+ targetState = RunControlState::Finished;
+ } else {
+ checkState(RunControlState::Stopping);
+ targetState = RunControlState::Stopped;
+ }
+
if (allDone) {
- debugMessage("All stopped.");
- setState(RunControlState::Stopped);
+ debugMessage("All Stopped");
+ setState(targetState);
} else {
- debugMessage("Not all workers stopped. Waiting...");
+ debugMessage("Not all workers Stopped. Waiting...");
}
}
@@ -908,48 +925,7 @@ void RunControlPrivate::initiateFinish()
setState(RunControlState::Finishing);
debugMessage("Ramping down");
- bool allDone = true;
- for (RunWorker *worker : m_workers) {
- if (worker) {
- const QString &workerId = worker->d->id;
- debugMessage(" Examining worker " + workerId);
- switch (worker->d->state) {
- case RunWorkerState::Initialized:
- debugMessage(" " + workerId + " was Initialized, setting to Done");
- worker->d->state = RunWorkerState::Done;
- break;
- case RunWorkerState::Stopping:
- debugMessage(" " + workerId + " was already Stopping. Keeping it that way");
- allDone = false;
- break;
- case RunWorkerState::Starting:
- debugMessage(" " + workerId + " was Starting, queuing stop");
- worker->d->state = RunWorkerState::Stopping;
- QTimer::singleShot(0, worker, &RunWorker::initiateStop);
- allDone = false;
- break;
- case RunWorkerState::Running:
- debugMessage(" " + workerId + " was Running, queuing stop");
- worker->d->state = RunWorkerState::Stopping;
- allDone = false;
- QTimer::singleShot(0, worker, &RunWorker::initiateStop);
- break;
- case RunWorkerState::Done:
- debugMessage(" " + workerId + " was Done. Good.");
- break;
- case RunWorkerState::Failed:
- debugMessage(" " + workerId + " was Failed. Good");
- break;
- }
- } else {
- debugMessage("Found unknown deleted worker");
- }
- }
- if (allDone) {
- setState(RunControlState::Finished);
- } else {
- debugMessage("Not all workers finished. Waiting...");
- }
+ continueStopOrFinish();
}
void RunControlPrivate::onWorkerStarted(RunWorker *worker)
@@ -968,10 +944,13 @@ void RunControlPrivate::onWorkerStarted(RunWorker *worker)
void RunControlPrivate::onWorkerFailed(RunWorker *worker, const QString &msg)
{
- worker->d->state = RunWorkerState::Failed;
+ worker->d->state = RunWorkerState::Done;
showError(msg);
- initiateStop();
+ if (state == RunControlState::Running || state == RunControlState::Starting)
+ initiateStop();
+ else
+ continueStopOrFinish();
}
void RunControlPrivate::onWorkerStopped(RunWorker *worker)
@@ -994,10 +973,34 @@ void RunControlPrivate::onWorkerStopped(RunWorker *worker)
default:
debugMessage(workerId + " stopped unexpectedly in state"
+ stateName(worker->d->state));
- worker->d->state = RunWorkerState::Failed;
+ worker->d->state = RunWorkerState::Done;
break;
}
+ if (state == RunControlState::Finishing || state == RunControlState::Stopping) {
+ continueStopOrFinish();
+ return;
+ } else if (worker->isEssential()) {
+ debugMessage(workerId + " is essential. Stopping all others.");
+ initiateStop();
+ return;
+ }
+
+ for (RunWorker *dependent : worker->d->stopDependencies) {
+ switch (dependent->d->state) {
+ case RunWorkerState::Done:
+ break;
+ case RunWorkerState::Initialized:
+ dependent->d->state = RunWorkerState::Done;
+ break;
+ default:
+ debugMessage("Killing " + dependent->d->id + " as it depends on stopped " + workerId);
+ dependent->d->state = RunWorkerState::Stopping;
+ QTimer::singleShot(0, dependent, &RunWorker::initiateStop);
+ break;
+ }
+ }
+
debugMessage("Checking whether all stopped");
bool allDone = true;
for (RunWorker *worker : m_workers) {
@@ -1023,32 +1026,21 @@ void RunControlPrivate::onWorkerStopped(RunWorker *worker)
case RunWorkerState::Done:
debugMessage(" " + workerId + " was Done. Good.");
break;
- case RunWorkerState::Failed:
- debugMessage(" " + workerId + " was Failed. Good");
- break;
}
} else {
debugMessage("Found unknown deleted worker");
}
}
- if (state == RunControlState::Finishing) {
- if (allDone) {
- debugMessage("All finished. Deleting myself");
- setState(RunControlState::Finished);
+
+ if (allDone) {
+ if (state == RunControlState::Stopped) {
+ debugMessage("All workers stopped, but runControl was already stopped.");
} else {
- debugMessage("Not all workers finished. Waiting...");
+ debugMessage("All workers stopped. Set runControl to Stopped");
+ setState(RunControlState::Stopped);
}
} else {
- if (allDone) {
- if (state == RunControlState::Stopped) {
- debugMessage("All workers stopped, but runControl was already stopped.");
- } else {
- debugMessage("All workers stopped. Set runControl to Stopped");
- setState(RunControlState::Stopped);
- }
- } else {
- debugMessage("Not all workers stopped. Waiting...");
- }
+ debugMessage("Not all workers stopped. Waiting...");
}
}
@@ -1254,6 +1246,7 @@ bool RunControlPrivate::isAllowedTransition(RunControlState from, RunControlStat
|| to == RunControlState::Finishing;
case RunControlState::Starting:
return to == RunControlState::Running
+ || to == RunControlState::Stopping
|| to == RunControlState::Finishing;
case RunControlState::Running:
return to == RunControlState::Stopping
@@ -1480,8 +1473,8 @@ bool RunWorkerPrivate::canStart() const
{
if (state != RunWorkerState::Initialized)
return false;
- for (RunWorker *worker : dependencies) {
- QTC_ASSERT(worker, return true);
+ for (RunWorker *worker : startDependencies) {
+ QTC_ASSERT(worker, continue);
if (worker->d->state != RunWorkerState::Done
&& worker->d->state != RunWorkerState::Running)
return false;
@@ -1489,6 +1482,18 @@ bool RunWorkerPrivate::canStart() const
return true;
}
+bool RunWorkerPrivate::canStop() const
+{
+ if (state != RunWorkerState::Starting && state != RunWorkerState::Running)
+ return false;
+ for (RunWorker *worker : stopDependencies) {
+ QTC_ASSERT(worker, continue);
+ if (worker->d->state != RunWorkerState::Done)
+ return false;
+ }
+ return true;
+}
+
void RunWorkerPrivate::timerEvent(QTimerEvent *ev)
{
if (ev->timerId() == startWatchdogTimerId) {
@@ -1501,7 +1506,42 @@ void RunWorkerPrivate::timerEvent(QTimerEvent *ev)
}
}
-// RunWorker
+/*!
+ \class ProjectExplorer::RunWorker
+
+ \brief The RunWorker class encapsulates a task that forms part, or
+ the whole of the operation of a tool for a certain \c RunConfiguration
+ according to some \c RunMode.
+
+ A typical example for a \c RunWorker is a process, either the
+ application process itself, or a helper process, such as a watchdog
+ or a log parser.
+
+ A \c RunWorker has a simple state model covering the \c Initialized,
+ \c Starting, \c Running, \c Stopping, and \c Done states.
+
+ In the course of the operation of tools several \c RunWorkers
+ may co-operate and form a combined state that is presented
+ to the user as \c RunControl, with direct interaction made
+ possible through the buttons in the \uicontrol{Application Output}
+ pane.
+
+ RunWorkers are typically created together with their RunControl.
+ The startup order of RunWorkers under a RunControl can be
+ specified by making a RunWorker dependent on others.
+
+ When a RunControl starts, it calls \c initiateStart() on RunWorkers
+ with fulfilled dependencies until all workers are \c Running, or in case
+ of short-lived helper tasks, \c Done.
+
+ A RunWorker can stop spontaneously, for example when the main application
+ process ends. In this case, it typically calls \c initiateStop()
+ on its RunControl, which in turn passes this to all sibling
+ RunWorkers.
+
+ Pressing the stop button in the \uicontrol{Application Output} pane
+ also calls \c initiateStop on the RunControl.
+*/
RunWorker::RunWorker(RunControl *runControl)
: d(new RunWorkerPrivate(this, runControl))
@@ -1513,6 +1553,10 @@ RunWorker::~RunWorker()
delete d;
}
+/*!
+ * This function is called by the RunControl once all dependencies
+ * are fulfilled.
+ */
void RunWorker::initiateStart()
{
if (d->startWatchdogInterval != 0)
@@ -1521,6 +1565,12 @@ void RunWorker::initiateStart()
start();
}
+/*!
+ * This function has to be called by a RunWorker implementation
+ * to notify its RunControl about the successful start of this RunWorker.
+ *
+ * The RunControl may start other RunWorkers in response.
+ */
void RunWorker::reportStarted()
{
if (d->startWatchdogInterval != 0)
@@ -1529,6 +1579,12 @@ void RunWorker::reportStarted()
emit started();
}
+/*!
+ * This function is called by the RunControl in its own \c initiateStop
+ * implementation, which is triggered in response to pressing the
+ * stop button in the \uicontrol{Application Output} pane or on direct
+ * request of one of the sibling RunWorkers.
+ */
void RunWorker::initiateStop()
{
if (d->stopWatchdogInterval != 0)
@@ -1538,6 +1594,15 @@ void RunWorker::initiateStop()
stop();
}
+/*!
+ * This function has to be called by a RunWorker implementation
+ * to notify its RunControl about this RunWorker having stopped.
+ *
+ * The stop can be spontaneous, or in response to an initiateStop()
+ * or an initiateFinish() call.
+ *
+ * The RunControl will adjust its global state in response.
+ */
void RunWorker::reportStopped()
{
if (d->stopWatchdogInterval != 0)
@@ -1546,11 +1611,47 @@ void RunWorker::reportStopped()
emit stopped();
}
+/*!
+ * This function can be called by a RunWorker implementation for short-lived
+ * tasks to notify its RunControl about this task being successful finished.
+ * Dependent startup tasks can proceed, in cases of spontaneous or scheduled
+ * stops, the effect is the same as \c reportStopped().
+ *
+ */
+void RunWorker::reportDone()
+{
+ switch (d->state) {
+ case RunWorkerState::Initialized:
+ QTC_CHECK(false);
+ d->state = RunWorkerState::Done;
+ break;
+ case RunWorkerState::Starting:
+ reportStarted();
+ reportStopped();
+ break;
+ case RunWorkerState::Running:
+ case RunWorkerState::Stopping:
+ reportStopped();
+ break;
+ case RunWorkerState::Done:
+ break;
+ }
+}
+
+/*!
+ * This function can be called by a RunWorker implementation to
+ * signal a problem in the operation in this worker. The
+ * RunControl will start to ramp down through initiateStop().
+ */
void RunWorker::reportFailure(const QString &msg)
{
d->runControl->d->onWorkerFailed(this, msg);
}
+/*!
+ * Appends a message in the specified \a format to
+ * the owning RunControl's \uicontrol{Application Output} pane.
+ */
void RunWorker::appendMessage(const QString &msg, OutputFormat format)
{
if (msg.endsWith('\n'))
@@ -1574,9 +1675,14 @@ Core::Id RunWorker::runMode() const
return d->runControl->runMode();
}
-void RunWorker::addDependency(RunWorker *dependency)
+void RunWorker::addStartDependency(RunWorker *dependency)
+{
+ d->startDependencies.append(dependency);
+}
+
+void RunWorker::addStopDependency(RunWorker *dependency)
{
- d->dependencies.append(dependency);
+ d->stopDependencies.append(dependency);
}
RunControl *RunWorker::runControl() const
@@ -1619,11 +1725,6 @@ bool RunWorker::supportsReRunning() const
return d->supportsReRunning;
}
-bool RunWorker::hasFailed() const
-{
- return d->state == RunWorkerState::Failed;
-}
-
QString RunWorker::userMessageForProcessError(QProcess::ProcessError error, const QString &program)
{
QString failedToStart = tr("The process failed to start.");
@@ -1657,6 +1758,16 @@ QString RunWorker::userMessageForProcessError(QProcess::ProcessError error, cons
return msg;
}
+bool RunWorker::isEssential() const
+{
+ return d->essential;
+}
+
+void RunWorker::setEssential(bool essential)
+{
+ d->essential = essential;
+}
+
void RunWorker::start()
{
reportStarted();
diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h
index eb27ade61b..4803519bde 100644
--- a/src/plugins/projectexplorer/runconfiguration.h
+++ b/src/plugins/projectexplorer/runconfiguration.h
@@ -326,7 +326,8 @@ public:
RunControl *runControl() const;
- void addDependency(RunWorker *dependency);
+ void addStartDependency(RunWorker *dependency);
+ void addStopDependency(RunWorker *dependency);
void setDisplayName(const QString &id) { setId(id); } // FIXME: Obsoleted by setId.
void setId(const QString &id);
@@ -350,13 +351,17 @@ public:
void initiateStop();
void reportStopped();
+ void reportDone();
+
void reportFailure(const QString &msg = QString());
void setSupportsReRunning(bool reRunningSupported);
bool supportsReRunning() const;
- bool hasFailed() const;
static QString userMessageForProcessError(QProcess::ProcessError, const QString &programName);
+ bool isEssential() const;
+ void setEssential(bool essential);
+
signals:
void started();
void stopped();
diff --git a/src/plugins/qbsprojectmanager/qbsprofilessettingswidget.ui b/src/plugins/qbsprojectmanager/qbsprofilessettingswidget.ui
index ce3f9ed808..001e2723f5 100644
--- a/src/plugins/qbsprojectmanager/qbsprofilessettingswidget.ui
+++ b/src/plugins/qbsprojectmanager/qbsprofilessettingswidget.ui
@@ -62,6 +62,9 @@
<property name="text">
<string/>
</property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
</widget>
</item>
<item row="0" column="0">
@@ -76,6 +79,9 @@
<property name="text">
<string>TextLabel</string>
</property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
</widget>
</item>
</layout>
diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp
index bd9f93ed2a..8a78402236 100644
--- a/src/plugins/qbsprojectmanager/qbsproject.cpp
+++ b/src/plugins/qbsprojectmanager/qbsproject.cpp
@@ -1011,7 +1011,7 @@ void QbsProject::updateCppCodeModel()
rpp.setDisplayName(grp.name());
rpp.setProjectFileLocation(grp.location().filePath(),
grp.location().line(), grp.location().column());
- rpp.setBuildSystemTarget(prd.name() + '|' + rpp.projectFile);
+ rpp.setBuildSystemTarget(prd.name());
QHash<QString, qbs::ArtifactData> filePathToSourceArtifact;
bool hasCFiles = false;
diff --git a/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp b/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp
index 3420fca510..268b01dbc2 100644
--- a/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp
@@ -95,7 +95,7 @@ void QmakeKitInformation::setup(Kit *k)
= Utils::findOr(possibleTcs, possibleTcs.last(),
[&spec](const ToolChain *t) { return t->suggestedMkspecList().contains(spec); });
if (possibleTc)
- ToolChainKitInformation::setToolChain(k, possibleTc);
+ ToolChainKitInformation::setAllToolChainsToMatch(k, possibleTc);
}
}
}
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
index 9e1839fed2..67e0181cc1 100644
--- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
@@ -287,7 +287,7 @@ void QmakeProject::updateCppCodeModel()
CppTools::RawProjectPart rpp;
rpp.setDisplayName(pro->displayName());
rpp.setProjectFileLocation(pro->filePath().toString());
- rpp.setBuildSystemTarget(pro->targetInformation().target + '|' + rpp.projectFile);
+ rpp.setBuildSystemTarget(pro->targetInformation().target);
// TODO: Handle QMAKE_CFLAGS
rpp.setFlagsForCxx({cxxToolChain, pro->variableValue(Variable::CppFlags)});
rpp.setDefines(pro->cxxDefines());
diff --git a/src/plugins/qmldesigner/components/formeditor/movetool.cpp b/src/plugins/qmldesigner/components/formeditor/movetool.cpp
index 5fb29ac88d..d6eaee3b2e 100644
--- a/src/plugins/qmldesigner/components/formeditor/movetool.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/movetool.cpp
@@ -124,6 +124,11 @@ void MoveTool::mouseMoveEvent(const QList<QGraphicsItem*> &itemList,
void MoveTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList,
QGraphicsSceneMouseEvent * event)
{
+ if (itemList.isEmpty()) {
+ view()->changeToSelectionTool();
+ return;
+ }
+
ResizeHandleItem* resizeHandle = ResizeHandleItem::fromGraphicsItem(itemList.first());
if (resizeHandle) {
view()->changeToResizeTool();
@@ -133,11 +138,6 @@ void MoveTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList,
if (view()->hasSingleSelectedModelNode() && selectedItemCursorInMovableArea(event->scenePos()))
return;
- if (itemList.isEmpty()) {
- view()->changeToSelectionTool();
- return;
- }
-
if (!topSelectedItemIsMovable(itemList)) {
view()->changeToSelectionTool();
return;
@@ -246,9 +246,9 @@ void MoveTool::mouseReleaseEvent(const QList<QGraphicsItem*> &itemList,
m_movingItems.clear();
}
- view()->changeToSelectionTool();
-
AbstractFormEditorTool::mouseReleaseEvent(itemList, event);
+
+ view()->changeToSelectionTool();
}
void MoveTool::mouseDoubleClickEvent(const QList<QGraphicsItem*> &itemList, QGraphicsSceneMouseEvent *event)
diff --git a/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp b/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp
index 9a5f55cd19..9938c8f065 100644
--- a/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp
@@ -237,20 +237,6 @@ void SelectionTool::itemsAboutToRemoved(const QList<FormEditorItem*> &/*itemList
}
-//QVariant SelectionTool::itemChange(const QList<QGraphicsItem*> &itemList,
-// QGraphicsItem::GraphicsItemChange change,
-// const QVariant &value )
-//{
-// qDebug() << Q_FUNC_INFO;
-// return QVariant();
-//}
-
-//void SelectionTool::update()
-//{
-//
-//}
-
-
void SelectionTool::clear()
{
m_rubberbandSelectionManipulator.clear(),
diff --git a/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/connectionviewwidget.ui b/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/connectionviewwidget.ui
index 4552fa645b..18df078ec6 100644
--- a/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/connectionviewwidget.ui
+++ b/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/connectionviewwidget.ui
@@ -208,6 +208,18 @@
</widget>
<widget class="QWidget" name="backendViewPage">
<layout class="QGridLayout" name="gridLayout_5">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
<item row="0" column="0">
<widget class="QTableView" name="backendView">
<property name="alternatingRowColors">
diff --git a/src/plugins/qmlprofiler/flamegraphmodel.cpp b/src/plugins/qmlprofiler/flamegraphmodel.cpp
index e3f98cfbcf..ca7e690aee 100644
--- a/src/plugins/qmlprofiler/flamegraphmodel.cpp
+++ b/src/plugins/qmlprofiler/flamegraphmodel.cpp
@@ -38,6 +38,11 @@
namespace QmlProfiler {
namespace Internal {
+static inline quint64 supportedFeatures()
+{
+ return Constants::QML_JS_RANGE_FEATURES | (1ULL << ProfileMemory);
+}
+
FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager,
QObject *parent) : QAbstractItemModel(parent)
{
@@ -51,8 +56,9 @@ FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager,
connect(modelManager->notesModel(), &Timeline::TimelineNotesModel::changed,
this, [this](int typeId, int, int){loadNotes(typeId, true);});
m_modelId = modelManager->registerModelProxy();
+ m_acceptedFeatures = supportedFeatures();
- modelManager->announceFeatures(Constants::QML_JS_RANGE_FEATURES | 1 << ProfileMemory,
+ modelManager->announceFeatures(m_acceptedFeatures,
[this](const QmlEvent &event, const QmlEventType &type) {
loadEvent(event, type);
}, [this](){
@@ -63,7 +69,7 @@ FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager,
void FlameGraphModel::clear()
{
beginResetModel();
- m_stackBottom = FlameGraphData(0, -1, 1);
+ m_stackBottom = FlameGraphData(0, -1, 0);
m_callStack.clear();
m_compileStack.clear();
m_callStack.append(QmlEvent());
@@ -98,7 +104,8 @@ void FlameGraphModel::loadNotes(int typeIndex, bool emitSignal)
void FlameGraphModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
{
- Q_UNUSED(type);
+ if (!(m_acceptedFeatures & (1ULL << type.feature())))
+ return;
if (m_stackBottom.children.isEmpty())
beginResetModel();
@@ -150,6 +157,31 @@ void FlameGraphModel::onModelManagerStateChanged()
clear();
}
+void FlameGraphModel::restrictToFeatures(quint64 visibleFeatures)
+{
+ visibleFeatures = visibleFeatures & supportedFeatures();
+ if (visibleFeatures == m_acceptedFeatures)
+ return;
+
+ m_acceptedFeatures = visibleFeatures;
+ if (m_modelManager->state() != QmlProfilerModelManager::Done)
+ return;
+
+ clear();
+ beginResetModel();
+ if (!m_modelManager->replayEvents(m_modelManager->traceTime()->startTime(),
+ m_modelManager->traceTime()->endTime(),
+ std::bind(&FlameGraphModel::loadEvent,
+ this, std::placeholders::_1,
+ std::placeholders::_2))) {
+ emit m_modelManager->error(tr("Could not re-read events from temporary trace file."));
+ endResetModel();
+ clear();
+ } else {
+ finalize();
+ }
+}
+
static QString nameForType(RangeType typeNumber)
{
switch (typeNumber) {
diff --git a/src/plugins/qmlprofiler/flamegraphmodel.h b/src/plugins/qmlprofiler/flamegraphmodel.h
index 9fcc6e674c..587de41cf7 100644
--- a/src/plugins/qmlprofiler/flamegraphmodel.h
+++ b/src/plugins/qmlprofiler/flamegraphmodel.h
@@ -91,6 +91,7 @@ public slots:
void loadEvent(const QmlEvent &event, const QmlEventType &type);
void finalize();
void onModelManagerStateChanged();
+ void restrictToFeatures(quint64 visibleFeatures);
void loadNotes(int typeId, bool emitSignal);
void clear();
@@ -105,6 +106,7 @@ private:
FlameGraphData *m_callStackTop;
FlameGraphData *m_compileStackTop;
+ quint64 m_acceptedFeatures;
int m_modelId;
QmlProfilerModelManager *m_modelManager;
diff --git a/src/plugins/qmlprofiler/flamegraphview.cpp b/src/plugins/qmlprofiler/flamegraphview.cpp
index 12cffd84d3..d26d4747a3 100644
--- a/src/plugins/qmlprofiler/flamegraphview.cpp
+++ b/src/plugins/qmlprofiler/flamegraphview.cpp
@@ -80,13 +80,7 @@ void FlameGraphView::selectByTypeId(int typeIndex)
void FlameGraphView::onVisibleFeaturesChanged(quint64 features)
{
- int rangeTypeMask = 0;
- for (int rangeType = 0; rangeType < MaximumRangeType; ++rangeType) {
- if (features & (1ULL << featureFromRangeType(RangeType(rangeType))))
- rangeTypeMask |= (1 << rangeType);
- }
- if (m_content->rootObject())
- m_content->rootObject()->setProperty("visibleRangeTypes", rangeTypeMask);
+ m_model->restrictToFeatures(features);
}
void FlameGraphView::contextMenuEvent(QContextMenuEvent *ev)
diff --git a/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml b/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml
index 2de3ec9422..34bca26cfa 100644
--- a/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml
+++ b/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml
@@ -36,7 +36,6 @@ ScrollView {
signal gotoSourceLocation(string filename, int line, int column)
property int selectedTypeId: -1
- property int visibleRangeTypes: -1
property int sizeRole: QmlProfilerFlameGraphModel.DurationRole
readonly property var trRoleNames: [
@@ -86,11 +85,9 @@ ScrollView {
property int typeId: FlameGraph.data(QmlProfilerFlameGraphModel.TypeIdRole) || -1
property bool isBindingLoop: parent.checkBindingLoop(typeId)
- property bool rangeTypeVisible:
- root.visibleRangeTypes & (1 << FlameGraph.data(QmlProfilerFlameGraphModel.RangeTypeRole))
- itemHeight: rangeTypeVisible ? flamegraph.delegateHeight : 0
- isSelected: typeId !== -1 && typeId === root.selectedTypeId && rangeTypeVisible
+ itemHeight: flamegraph.delegateHeight
+ isSelected: typeId !== -1 && typeId === root.selectedTypeId
borderColor: {
if (isSelected)
diff --git a/src/plugins/qmlprofiler/qmlprofiler.qbs b/src/plugins/qmlprofiler/qmlprofiler.qbs
index 8bf7b5147b..02a08fb656 100644
--- a/src/plugins/qmlprofiler/qmlprofiler.qbs
+++ b/src/plugins/qmlprofiler/qmlprofiler.qbs
@@ -92,6 +92,7 @@ QtcPlugin {
"qmlprofilerbindingloopsrenderpass_test.h",
"qmlprofilerclientmanager_test.cpp", "qmlprofilerclientmanager_test.h",
"qmlprofilerconfigwidget_test.cpp", "qmlprofilerconfigwidget_test.h",
+ "qmlprofilertraceview_test.cpp", "qmlprofilertraceview_test.h",
]
}
}
diff --git a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
index ea89b6b6dc..23dcfaf3f4 100644
--- a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
@@ -48,6 +48,7 @@
#include "tests/qmlprofilerbindingloopsrenderpass_test.h"
#include "tests/qmlprofilerclientmanager_test.h"
#include "tests/qmlprofilerconfigwidget_test.h"
+#include "tests/qmlprofilertraceview_test.h"
// Force QML Debugging to be enabled, so that we can selftest the profiler
#define QT_QML_DEBUG_NO_WARNING
@@ -141,6 +142,7 @@ QList<QObject *> QmlProfiler::Internal::QmlProfilerPlugin::createTestObjects() c
tests << new QmlProfilerBindingLoopsRenderPassTest;
tests << new QmlProfilerClientManagerTest;
tests << new QmlProfilerConfigWidgetTest;
+ tests << new QmlProfilerTraceViewTest;
tests << new QQmlEngine; // Trigger debug connector to be started
#endif
diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
index f009a99429..90608cbb1f 100644
--- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
@@ -23,20 +23,15 @@
**
****************************************************************************/
-#include "qmlprofilerclientmanager.h"
#include "qmlprofilerruncontrol.h"
-#include "qmlprofilertool.h"
-#include "qmlprofilerplugin.h"
-#include <debugger/analyzer/analyzermanager.h>
+#include "qmlprofilerclientmanager.h"
+#include "qmlprofilertool.h"
#include <coreplugin/icore.h>
#include <coreplugin/helpmanager.h>
-#include <projectexplorer/devicesupport/idevice.h>
-#include <projectexplorer/environmentaspect.h>
#include <projectexplorer/kitinformation.h>
-#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectexplorericons.h>
#include <projectexplorer/runconfiguration.h>
@@ -47,18 +42,13 @@
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtsupportconstants.h>
-#include <qmldebug/qmloutputparser.h>
#include <qmldebug/qmldebugcommandlinearguments.h>
#include <utils/qtcassert.h>
+#include <utils/qtcfallthrough.h>
-#include <QApplication>
-#include <QMainWindow>
#include <QMessageBox>
-#include <QPushButton>
-#include <QTimer>
-using namespace Debugger;
using namespace Core;
using namespace ProjectExplorer;
using namespace QmlProfiler::Internal;
@@ -75,7 +65,6 @@ class QmlProfilerRunner::QmlProfilerRunnerPrivate
{
public:
QmlProfilerStateManager *m_profilerState = 0;
- QTimer m_noDebugOutputTimer;
};
//
@@ -89,14 +78,6 @@ QmlProfilerRunner::QmlProfilerRunner(RunControl *runControl)
setDisplayName("QmlProfilerRunner");
runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR);
setSupportsReRunning(false);
-
- // Only wait 4 seconds for the 'Waiting for connection' on application output, then just try to connect
- // (application output might be redirected / blocked)
- d->m_noDebugOutputTimer.setSingleShot(true);
- d->m_noDebugOutputTimer.setInterval(4000);
- connect(&d->m_noDebugOutputTimer, &QTimer::timeout, this, [this]() {
- notifyRemoteSetupDone(Utils::Port());
- });
}
QmlProfilerRunner::~QmlProfilerRunner()
@@ -113,13 +94,45 @@ void QmlProfilerRunner::start()
QUrl serverUrl = this->serverUrl();
+ QmlProfilerClientManager *clientManager = Internal::QmlProfilerTool::clientManager();
+
+ connect(clientManager, &QmlProfilerClientManager::connectionFailed,
+ this, [this, clientManager] {
+ QMessageBox *infoBox = new QMessageBox(ICore::mainWindow());
+ infoBox->setIcon(QMessageBox::Critical);
+ infoBox->setWindowTitle(QmlProfilerTool::tr("Qt Creator"));
+ infoBox->setText(QmlProfilerTool::tr("Could not connect to the in-process QML profiler.\n"
+ "Do you want to retry?"));
+ infoBox->setStandardButtons(QMessageBox::Retry | QMessageBox::Cancel | QMessageBox::Help);
+ infoBox->setDefaultButton(QMessageBox::Retry);
+ infoBox->setModal(true);
+
+ connect(infoBox, &QDialog::finished, this, [clientManager, this](int result) {
+ switch (result) {
+ case QMessageBox::Retry:
+ clientManager->retryConnect();
+ break;
+ case QMessageBox::Help:
+ HelpManager::handleHelpRequest(
+ "qthelp://org.qt-project.qtcreator/doc/creator-debugging-qml.html");
+ Q_FALLTHROUGH();
+ case QMessageBox::Cancel:
+ // The actual error message has already been logged.
+ QmlProfilerTool::logState(QmlProfilerTool::tr("Failed to connect."));
+ cancelProcess();
+ break;
+ }
+ });
+
+ infoBox->show();
+ });
+
+ clientManager->setServerUrl(serverUrl);
if (serverUrl.port() != -1) {
- QmlProfilerClientManager *clientManager = Internal::QmlProfilerTool::clientManager();
- clientManager->setServerUrl(serverUrl);
clientManager->connectToTcpServer();
+ } else {
+ clientManager->startLocalServer();
}
- else if (serverUrl.path().isEmpty())
- d->m_noDebugOutputTimer.start();
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning);
@@ -137,6 +150,7 @@ void QmlProfilerRunner::stop()
case QmlProfilerStateManager::AppStopRequested:
// Pressed "stop" a second time. Kill the application without collecting data
d->m_profilerState->setCurrentState(QmlProfilerStateManager::Idle);
+ reportStopped();
break;
case QmlProfilerStateManager::Idle:
case QmlProfilerStateManager::AppDying:
@@ -149,7 +163,6 @@ void QmlProfilerRunner::stop()
}
break;
}
- reportStopped();
}
void QmlProfilerRunner::notifyRemoteFinished()
@@ -190,53 +203,6 @@ void QmlProfilerRunner::cancelProcess()
runControl()->initiateStop();
}
-void QmlProfilerRunner::notifyRemoteSetupFailed(const QString &errorMessage)
-{
- QMessageBox *infoBox = new QMessageBox(ICore::mainWindow());
- infoBox->setIcon(QMessageBox::Critical);
- infoBox->setWindowTitle(tr("Qt Creator"));
- //: %1 is detailed error message
- infoBox->setText(tr("Could not connect to the in-process QML debugger:\n%1")
- .arg(errorMessage));
- infoBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Help);
- infoBox->setDefaultButton(QMessageBox::Ok);
- infoBox->setModal(true);
-
- connect(infoBox, &QDialog::finished,
- this, &QmlProfilerRunner::wrongSetupMessageBoxFinished);
-
- infoBox->show();
-
- // KILL
- d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying);
- d->m_noDebugOutputTimer.stop();
-}
-
-void QmlProfilerRunner::wrongSetupMessageBoxFinished(int button)
-{
- if (button == QMessageBox::Help) {
- HelpManager::handleHelpRequest(QLatin1String("qthelp://org.qt-project.qtcreator/doc/creator-debugging-qml.html"
- "#setting-up-qml-debugging"));
- }
-}
-
-void QmlProfilerRunner::notifyRemoteSetupDone(Utils::Port port)
-{
- d->m_noDebugOutputTimer.stop();
-
- QUrl serverUrl = this->serverUrl();
- if (!port.isValid())
- port = Utils::Port(serverUrl.port());
-
- if (port.isValid()) {
- serverUrl.setPort(port.number());
- auto clientManager = Internal::QmlProfilerTool::clientManager();
- clientManager->setServerUrl(serverUrl);
- clientManager->connectToTcpServer();
- reportStarted();
- }
-}
-
void QmlProfilerRunner::registerProfilerStateManager( QmlProfilerStateManager *profilerState )
{
// disconnect old
@@ -256,7 +222,7 @@ void QmlProfilerRunner::profilerStateChanged()
{
switch (d->m_profilerState->currentState()) {
case QmlProfilerStateManager::Idle:
- d->m_noDebugOutputTimer.stop();
+ reportStopped();
break;
default:
break;
@@ -302,13 +268,17 @@ LocalQmlProfilerSupport::LocalQmlProfilerSupport(RunControl *runControl)
}
LocalQmlProfilerSupport::LocalQmlProfilerSupport(RunControl *runControl, const QUrl &serverUrl)
- : RunWorker(runControl)
+ : SimpleTargetRunner(runControl)
{
setDisplayName("LocalQmlProfilerSupport");
m_profiler = new QmlProfilerRunner(runControl);
m_profiler->setServerUrl(serverUrl);
- m_profiler->addDependency(this);
+
+ addStopDependency(m_profiler);
+ // We need to open the local server before the application tries to connect.
+ // In the TCP case, it doesn't hurt either to start the profiler before.
+ addStartDependency(m_profiler);
StandardRunnable debuggee = runnable().as<StandardRunnable>();
QString arguments = QmlDebug::qmlDebugArguments(QmlDebug::QmlProfilerServices, serverUrl);
@@ -319,21 +289,7 @@ LocalQmlProfilerSupport::LocalQmlProfilerSupport(RunControl *runControl, const Q
debuggee.commandLineArguments = arguments;
debuggee.runMode = ApplicationLauncher::Gui;
- m_profilee = new SimpleTargetRunner(runControl);
- m_profilee->setRunnable(debuggee);
- addDependency(m_profilee);
-}
-
-void LocalQmlProfilerSupport::start()
-{
- reportStarted();
- emit localRunnerStarted();
-}
-
-void LocalQmlProfilerSupport::stop()
-{
- reportStopped();
- emit localRunnerStopped();
+ setRunnable(debuggee);
}
} // namespace QmlProfiler
diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.h b/src/plugins/qmlprofiler/qmlprofilerruncontrol.h
index 5d782e2d14..de423c7e77 100644
--- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.h
+++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.h
@@ -50,8 +50,6 @@ public:
void registerProfilerStateManager( QmlProfilerStateManager *profilerState );
- void notifyRemoteSetupDone(Utils::Port port);
- void notifyRemoteSetupFailed(const QString &errorMessage);
void cancelProcess();
void notifyRemoteFinished();
@@ -59,14 +57,13 @@ private:
void start() override;
void stop() override;
- void wrongSetupMessageBoxFinished(int);
void profilerStateChanged();
class QmlProfilerRunnerPrivate;
QmlProfilerRunnerPrivate *d;
};
-class LocalQmlProfilerSupport : public ProjectExplorer::RunWorker
+class LocalQmlProfilerSupport : public ProjectExplorer::SimpleTargetRunner
{
Q_OBJECT
@@ -75,15 +72,7 @@ public:
LocalQmlProfilerSupport(ProjectExplorer::RunControl *runControl,
const QUrl &serverUrl);
- void start() override;
- void stop() override;
-
-signals:
- void localRunnerStarted();
- void localRunnerStopped();
-
private:
- ProjectExplorer::SimpleTargetRunner *m_profilee;
QmlProfilerRunner *m_profiler;
};
diff --git a/src/plugins/qmlprofiler/qmlprofilerstatisticsview.cpp b/src/plugins/qmlprofiler/qmlprofilerstatisticsview.cpp
index 428b98b2d2..b603def7ba 100644
--- a/src/plugins/qmlprofiler/qmlprofilerstatisticsview.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerstatisticsview.cpp
@@ -578,9 +578,8 @@ void QmlProfilerStatisticsMainView::updateNotes(int typeIndex)
item->setToolTip(it.value());
} else if (stats.durationRecursive > 0) {
item->setBackground(colors()->noteBackground);
- item->setToolTip(tr("%1 / %2% of total in recursive calls")
- .arg(Timeline::formatTime(stats.durationRecursive))
- .arg(stats.durationRecursive * 100l / stats.duration));
+ item->setToolTip(tr("+%1 in recursive calls")
+ .arg(Timeline::formatTime(stats.durationRecursive)));
} else if (!item->toolTip().isEmpty()){
item->setBackground(colors()->defaultBackground);
item->setToolTip(QString());
@@ -619,8 +618,9 @@ void QmlProfilerStatisticsMainView::parseModel()
}
if (d->m_fieldShown[TotalTime]) {
- newRow << new StatisticsViewItem(Timeline::formatTime(stats.duration),
- stats.duration);
+ newRow << new StatisticsViewItem(
+ Timeline::formatTime(stats.duration - stats.durationRecursive),
+ stats.duration - stats.durationRecursive);
}
if (d->m_fieldShown[SelfTimeInPercent]) {
diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp
index e246bf885c..423b8c655a 100644
--- a/src/plugins/qmlprofiler/qmlprofilertool.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp
@@ -139,8 +139,6 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
d->m_profilerState = new QmlProfilerStateManager(this);
connect(d->m_profilerState, &QmlProfilerStateManager::stateChanged,
this, &QmlProfilerTool::profilerStateChanged);
- connect(d->m_profilerState, &QmlProfilerStateManager::clientRecordingChanged,
- this, &QmlProfilerTool::clientRecordingChanged);
connect(d->m_profilerState, &QmlProfilerStateManager::serverRecordingChanged,
this, &QmlProfilerTool::serverRecordingChanged);
connect(d->m_profilerState, &QmlProfilerStateManager::recordedFeaturesChanged,
@@ -206,8 +204,6 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
connect(d->m_recordFeaturesMenu, &QMenu::triggered,
this, &QmlProfilerTool::toggleRequestedFeature);
- setRecording(d->m_profilerState->clientRecording());
-
d->m_clearButton = new QToolButton;
d->m_clearButton->setIcon(Utils::Icons::CLEAN_TOOLBAR.icon());
d->m_clearButton->setToolTip(tr("Discard data"));
@@ -240,6 +236,7 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
d->m_timeLabel->setPalette(palette);
d->m_timeLabel->setIndent(10);
updateTimeDisplay();
+ connect(d->m_timeLabel, &QObject::destroyed, &d->m_recordingTimer, &QTimer::stop);
setAvailableFeatures(d->m_profilerModelManager->availableFeatures());
setRecordedFeatures(0);
@@ -296,6 +293,46 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
model->createMarks(this, fileName);
});
}
+
+ auto updateRecordButton = [this]() {
+ const bool recording =
+ d->m_profilerState->currentState() != QmlProfilerStateManager::AppRunning
+ ? d->m_profilerState->clientRecording() : d->m_profilerState->serverRecording();
+
+ const static QIcon recordOn = Debugger::Icons::RECORD_ON.icon();
+ const static QIcon recordOff = Debugger::Icons::RECORD_OFF.icon();
+
+ // update display
+ d->m_recordButton->setToolTip(recording ? tr("Disable Profiling") : tr("Enable Profiling"));
+ d->m_recordButton->setIcon(recording ? recordOn : recordOff);
+ d->m_recordButton->setChecked(recording);
+
+ switch (d->m_profilerModelManager->state()) {
+ case QmlProfilerModelManager::Empty:
+ case QmlProfilerModelManager::AcquiringData:
+ case QmlProfilerModelManager::Done:
+ // Don't change the recording button if the application cannot react to it.
+ d->m_recordButton->setEnabled(d->m_profilerState->currentState()
+ != QmlProfilerStateManager::AppStopRequested
+ && d->m_profilerState->currentState()
+ != QmlProfilerStateManager::AppDying);
+ break;
+ case QmlProfilerModelManager::ProcessingData:
+ case QmlProfilerModelManager::ClearingData:
+ d->m_recordButton->setEnabled(false);
+ break;
+ }
+ };
+
+ connect(d->m_profilerState, &QmlProfilerStateManager::stateChanged,
+ d->m_recordButton, updateRecordButton);
+ connect(d->m_profilerState, &QmlProfilerStateManager::serverRecordingChanged,
+ d->m_recordButton, updateRecordButton);
+ connect(d->m_profilerState, &QmlProfilerStateManager::clientRecordingChanged,
+ d->m_recordButton, updateRecordButton);
+ connect(d->m_profilerModelManager, &QmlProfilerModelManager::stateChanged,
+ d->m_recordButton, updateRecordButton);
+ updateRecordButton();
}
QmlProfilerTool::~QmlProfilerTool()
@@ -351,16 +388,6 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker)
updateRunActions();
runWorker->registerProfilerStateManager(d->m_profilerState);
- QmlProfilerClientManager *clientManager = d->m_profilerConnections;
-
- // FIXME: Check that there's something sensible in sp.connParams
- auto serverUrl = runWorker->serverUrl();
- clientManager->setServerUrl(serverUrl);
- if (!serverUrl.path().isEmpty()) {
- // That's the local socket case.
- // We open the server and the application connects to it, so let's do that right away.
- clientManager->startLocalServer();
- }
//
// Initialize m_projectFinder
@@ -369,37 +396,6 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker)
if (runConfiguration) {
d->m_profilerModelManager->populateFileFinder(runConfiguration);
}
-
- connect(clientManager, &QmlProfilerClientManager::connectionFailed,
- runWorker, [this, clientManager, runWorker]() {
- QMessageBox *infoBox = new QMessageBox(ICore::mainWindow());
- infoBox->setIcon(QMessageBox::Critical);
- infoBox->setWindowTitle(tr("Qt Creator"));
- infoBox->setText(tr("Could not connect to the in-process QML profiler.\n"
- "Do you want to retry?"));
- infoBox->setStandardButtons(QMessageBox::Retry | QMessageBox::Cancel | QMessageBox::Help);
- infoBox->setDefaultButton(QMessageBox::Retry);
- infoBox->setModal(true);
-
- connect(infoBox, &QDialog::finished, runWorker, [clientManager, runWorker](int result) {
- switch (result) {
- case QMessageBox::Retry:
- clientManager->retryConnect();
- break;
- case QMessageBox::Help:
- HelpManager::handleHelpRequest(
- "qthelp://org.qt-project.qtcreator/doc/creator-debugging-qml.html");
- Q_FALLTHROUGH();
- case QMessageBox::Cancel:
- // The actual error message has already been logged.
- logState(tr("Failed to connect."));
- runWorker->cancelProcess();
- break;
- }
- });
-
- infoBox->show();
- });
}
void QmlProfilerTool::recordingButtonChanged(bool recording)
@@ -425,28 +421,6 @@ void QmlProfilerTool::recordingButtonChanged(bool recording)
}
}
-void QmlProfilerTool::setRecording(bool recording)
-{
- const static QIcon recordOn = Debugger::Icons::RECORD_ON.icon();
- const static QIcon recordOff = Debugger::Icons::RECORD_OFF.icon();
-
- // update display
- d->m_recordButton->setToolTip( recording ? tr("Disable Profiling") : tr("Enable Profiling"));
- d->m_recordButton->setIcon(recording ? recordOn : recordOff);
-
- d->m_recordButton->setChecked(recording);
-
- // manage timer
- if (d->m_profilerState->currentState() == QmlProfilerStateManager::AppRunning) {
- if (recording) {
- d->m_recordingTimer.start();
- d->m_recordingElapsedTime.start();
- } else {
- d->m_recordingTimer.stop();
- }
- }
-}
-
void QmlProfilerTool::gotoSourceLocation(const QString &fileUrl, int lineNumber, int columnNumber)
{
if (lineNumber < 0 || fileUrl.isEmpty())
@@ -538,7 +512,7 @@ void QmlProfilerTool::clearTextMarks()
bool QmlProfilerTool::prepareTool()
{
- if (d->m_recordButton->isChecked()) {
+ if (d->m_profilerState->clientRecording()) {
if (checkForUnsavedNotes()) {
clearData(); // clear right away to suppress second warning on server recording change
return true;
@@ -794,28 +768,23 @@ void QmlProfilerTool::profilerDataModelStateChanged()
{
switch (d->m_profilerModelManager->state()) {
case QmlProfilerModelManager::Empty :
- d->m_recordButton->setEnabled(true);
setButtonsEnabled(true);
break;
case QmlProfilerModelManager::ClearingData :
clearTextMarks();
- d->m_recordButton->setEnabled(false);
setButtonsEnabled(false);
clearDisplay();
break;
case QmlProfilerModelManager::AcquiringData :
restoreFeatureVisibility();
- d->m_recordButton->setEnabled(true); // Press recording button to stop recording
setButtonsEnabled(false); // Other buttons disabled
break;
case QmlProfilerModelManager::ProcessingData :
- d->m_recordButton->setEnabled(false);
setButtonsEnabled(false);
break;
case QmlProfilerModelManager::Done :
showSaveOption();
updateTimeDisplay();
- d->m_recordButton->setEnabled(true);
setButtonsEnabled(true);
createTextMarks();
break;
@@ -866,13 +835,10 @@ void QmlProfilerTool::profilerStateChanged()
break;
}
case QmlProfilerStateManager::Idle :
- // when the app finishes, set recording display to client status
- setRecording(d->m_profilerState->clientRecording());
break;
case QmlProfilerStateManager::AppStopRequested:
// Don't allow toggling the recording while data is loaded when application quits
if (d->m_profilerState->serverRecording()) {
- d->m_recordButton->setEnabled(false);
// Turn off recording and wait for remaining data
d->m_profilerConnections->stopRecording();
} else {
@@ -886,14 +852,6 @@ void QmlProfilerTool::profilerStateChanged()
}
}
-void QmlProfilerTool::clientRecordingChanged()
-{
- // if application is running, display server record changes
- // if application is stopped, display client record changes
- if (d->m_profilerState->currentState() != QmlProfilerStateManager::AppRunning)
- setRecording(d->m_profilerState->clientRecording());
-}
-
void QmlProfilerTool::serverRecordingChanged()
{
showLoadOption();
@@ -911,19 +869,16 @@ void QmlProfilerTool::serverRecordingChanged()
QMessageBox::Save)
showSaveDialog();
- setRecording(true);
+ d->m_recordingTimer.start();
+ d->m_recordingElapsedTime.start();
if (!d->m_profilerModelManager->aggregateTraces() ||
d->m_profilerModelManager->state() == QmlProfilerModelManager::Done)
clearData();
d->m_profilerModelManager->startAcquiring();
} else {
- setRecording(false);
-
- // changes back once loading is finished, see profilerDataModelStateChanged()
- if (!d->m_profilerModelManager->aggregateTraces()) {
- d->m_recordButton->setEnabled(false);
+ d->m_recordingTimer.stop();
+ if (!d->m_profilerModelManager->aggregateTraces())
d->m_profilerModelManager->acquiringDone();
- }
}
} else if (d->m_profilerState->currentState() == QmlProfilerStateManager::AppStopRequested) {
d->m_profilerModelManager->acquiringDone();
diff --git a/src/plugins/qmlprofiler/qmlprofilertool.h b/src/plugins/qmlprofiler/qmlprofilertool.h
index 206c56930c..c50747e85b 100644
--- a/src/plugins/qmlprofiler/qmlprofilertool.h
+++ b/src/plugins/qmlprofiler/qmlprofilertool.h
@@ -69,14 +69,11 @@ public:
public slots:
void profilerStateChanged();
- void clientRecordingChanged();
void serverRecordingChanged();
void clientsDisconnected();
void setAvailableFeatures(quint64 features);
void setRecordedFeatures(quint64 features);
-
void recordingButtonChanged(bool recording);
- void setRecording(bool recording);
void gotoSourceLocation(const QString &fileUrl, int lineNumber, int columnNumber);
void selectType(int typeId);
diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp
index a2a00b4f98..a7bf3fe468 100644
--- a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp
@@ -115,13 +115,16 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, QmlProfilerViewManag
break;
case QmlProfilerModelManager::ClearingData:
d->m_zoomControl->clear();
- if (!d->m_suspendedModels.isEmpty())
- break; // Models are suspended already. AcquiringData was aborted.
Q_FALLTHROUGH();
case QmlProfilerModelManager::AcquiringData:
- // Temporarily remove the models, while we're changing them
- d->m_suspendedModels = d->m_modelProxy->models();
- d->m_modelProxy->setModels(QVariantList());
+ if (d->m_suspendedModels.isEmpty()) {
+ // Temporarily remove the models, while we're changing them
+ d->m_suspendedModels = d->m_modelProxy->models();
+ d->m_modelProxy->setModels(QVariantList());
+ }
+ // Otherwise models are suspended already. This can happen if either acquiring was
+ // aborted or we're doing a "restrict to range" which consists of a partial clearing and
+ // then re-acquiring of data.
break;
}
});
@@ -309,6 +312,11 @@ bool QmlProfilerTraceView::isUsable() const
#endif
}
+bool QmlProfilerTraceView::isSuspended() const
+{
+ return !d->m_suspendedModels.isEmpty();
+}
+
void QmlProfilerTraceView::changeEvent(QEvent *e)
{
if (e->type() == QEvent::EnabledChange) {
diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.h b/src/plugins/qmlprofiler/qmlprofilertraceview.h
index 2cc81c8536..79063ac261 100644
--- a/src/plugins/qmlprofiler/qmlprofilertraceview.h
+++ b/src/plugins/qmlprofiler/qmlprofilertraceview.h
@@ -53,6 +53,7 @@ public:
qint64 selectionEnd() const;
void showContextMenu(QPoint position);
bool isUsable() const;
+ bool isSuspended() const;
public slots:
void clear();
diff --git a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp
index 21bddf6f33..6275067d89 100644
--- a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp
+++ b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp
@@ -25,17 +25,13 @@
#include "localqmlprofilerrunner_test.h"
-#include "../qmlprofilerruncontrol.h"
-
#include <debugger/analyzer/analyzermanager.h>
-
#include <projectexplorer/runnables.h>
+#include <qmlprofiler/qmlprofilerruncontrol.h>
#include <QtTest>
#include <QTcpServer>
-using namespace ProjectExplorer;
-
namespace QmlProfiler {
namespace Internal {
@@ -43,83 +39,115 @@ LocalQmlProfilerRunnerTest::LocalQmlProfilerRunnerTest(QObject *parent) : QObjec
{
}
-void LocalQmlProfilerRunnerTest::start()
-{
- delete runControl;
- runControl = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
- runControl->setRunnable(debuggee);
- auto runner = new LocalQmlProfilerSupport(runControl, serverUrl);
-
- connect(runner, &LocalQmlProfilerSupport::localRunnerStarted, this, [this] {
- QVERIFY(!running);
- ++runCount;
- running = true;
- });
- connect(runner, &LocalQmlProfilerSupport::localRunnerStopped, this, [this] {
- QVERIFY(running);
- running = false;
- });
- runControl->initiateStart();
-}
-
void LocalQmlProfilerRunnerTest::testRunner()
{
+ QPointer<ProjectExplorer::RunControl> runControl;
+ QPointer<LocalQmlProfilerSupport> profiler;
+ ProjectExplorer::StandardRunnable debuggee;
+ QUrl serverUrl;
+
+ bool running = false;
+ bool started = false;
+ int startCount = 0;
+ int runCount = 0;
+ int stopCount = 0;
+
debuggee.executable = "\\-/|\\-/";
debuggee.environment = Utils::Environment::systemEnvironment();
// should not be used anywhere but cannot be empty
serverUrl.setPath("invalid");
- start();
+ runControl = new ProjectExplorer::RunControl(nullptr,
+ ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
+ runControl->setRunnable(debuggee);
+ profiler = new LocalQmlProfilerSupport(runControl, serverUrl);
+
+ auto connectRunner = [&]() {
+ connect(runControl, &ProjectExplorer::RunControl::aboutToStart, this, [&]() {
+ QVERIFY(!started);
+ QVERIFY(!running);
+ ++startCount;
+ started = true;
+ });
+ connect(runControl, &ProjectExplorer::RunControl::started, this, [&]() {
+ QVERIFY(started);
+ QVERIFY(!running);
+ ++runCount;
+ running = true;
+ });
+ connect(runControl, &ProjectExplorer::RunControl::stopped, this, [&]() {
+ QVERIFY(started);
+ ++stopCount;
+ running = false;
+ started = false;
+ });
+ connect(runControl, &ProjectExplorer::RunControl::finished, this, [&]() {
+ running = false;
+ started = false;
+ });
+ };
+
+ connectRunner();
- QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner1);
-}
+ runControl->initiateStart();
-void LocalQmlProfilerRunnerTest::testRunner1()
-{
- QTRY_COMPARE_WITH_TIMEOUT(runCount, 1, 10000);
- QTRY_VERIFY_WITH_TIMEOUT(!running, 10000);
+ QTRY_COMPARE_WITH_TIMEOUT(startCount, 1, 10000);
+ QTRY_VERIFY_WITH_TIMEOUT(!started, 10000);
+ QCOMPARE(stopCount, 1);
+ QCOMPARE(runCount, 0);
- serverUrl = urlFromLocalSocket();
+ runControl->initiateFinish();
+ QTRY_VERIFY(runControl.isNull());
+ QVERIFY(profiler.isNull());
+
+ serverUrl = ProjectExplorer::urlFromLocalSocket();
+ debuggee.executable = qApp->applicationFilePath();
- debuggee.executable = QCoreApplication::applicationFilePath();
// comma is used to specify a test function. In this case, an invalid one.
debuggee.commandLineArguments = QString("-test QmlProfiler,");
+ runControl = new ProjectExplorer::RunControl(nullptr,
+ ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
+ runControl->setRunnable(debuggee);
+ profiler = new LocalQmlProfilerSupport(runControl, serverUrl);
+ connectRunner();
+ runControl->initiateStart();
- start();
-
- QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner2);
-}
-
-void LocalQmlProfilerRunnerTest::testRunner2()
-{
- QTRY_COMPARE_WITH_TIMEOUT(runCount, 2, 10000);
+ QTRY_VERIFY_WITH_TIMEOUT(running, 10000);
QTRY_VERIFY_WITH_TIMEOUT(!running, 10000);
+ QCOMPARE(startCount, 2);
+ QCOMPARE(stopCount, 2);
+ QCOMPARE(runCount, 1);
- debuggee.commandLineArguments.clear();
- serverUrl = urlFromLocalHostAndFreePort();
-
- start();
+ runControl->initiateFinish();
+ QTRY_VERIFY(runControl.isNull());
+ QVERIFY(profiler.isNull());
- QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner3);
-}
+ debuggee.commandLineArguments.clear();
+ serverUrl.clear();
+ serverUrl = ProjectExplorer::urlFromLocalHostAndFreePort();
+ runControl = new ProjectExplorer::RunControl(nullptr,
+ ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
+ runControl->setRunnable(debuggee);
+ profiler = new LocalQmlProfilerSupport(runControl, serverUrl);
+ connectRunner();
+ runControl->initiateStart();
-void LocalQmlProfilerRunnerTest::testRunner3()
-{
- QTRY_COMPARE_WITH_TIMEOUT(runCount, 3, 10000);
+ QTRY_VERIFY_WITH_TIMEOUT(running, 10000);
runControl->initiateStop();
- QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner4);
-}
-
-void LocalQmlProfilerRunnerTest::testRunner4()
-{
QTRY_VERIFY_WITH_TIMEOUT(!running, 10000);
- delete runControl;
+ QCOMPARE(startCount, 3);
+ QCOMPARE(stopCount, 3);
+ QCOMPARE(runCount, 2);
+
+ runControl->initiateFinish();
+ QTRY_VERIFY(runControl.isNull());
+ QVERIFY(profiler.isNull());
}
void LocalQmlProfilerRunnerTest::testFindFreePort()
{
- QUrl serverUrl = urlFromLocalHostAndFreePort();
+ QUrl serverUrl = ProjectExplorer::urlFromLocalHostAndFreePort();
QVERIFY(serverUrl.port() != -1);
QVERIFY(!serverUrl.host().isEmpty());
QTcpServer server;
@@ -128,7 +156,7 @@ void LocalQmlProfilerRunnerTest::testFindFreePort()
void LocalQmlProfilerRunnerTest::testFindFreeSocket()
{
- QUrl serverUrl = urlFromLocalSocket();
+ QUrl serverUrl = ProjectExplorer::urlFromLocalSocket();
QString socket = serverUrl.path();
QVERIFY(!socket.isEmpty());
QVERIFY(!QFile::exists(socket));
diff --git a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.h b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.h
index 7b6bc60980..796f2ce3c4 100644
--- a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.h
+++ b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.h
@@ -43,19 +43,6 @@ private slots:
void testRunner();
void testFindFreePort();
void testFindFreeSocket();
-
-private:
- void start();
- void testRunner1();
- void testRunner2();
- void testRunner3();
- void testRunner4();
-
- bool running = false;
- int runCount = 0;
- ProjectExplorer::RunControl *runControl = nullptr;
- ProjectExplorer::StandardRunnable debuggee;
- QUrl serverUrl;
};
} // namespace Internal
diff --git a/src/plugins/qmlprofiler/tests/qmlprofilertraceview_test.cpp b/src/plugins/qmlprofiler/tests/qmlprofilertraceview_test.cpp
new file mode 100644
index 0000000000..a1ed887ce4
--- /dev/null
+++ b/src/plugins/qmlprofiler/tests/qmlprofilertraceview_test.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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 "qmlprofilertraceview_test.h"
+#include <QtTest>
+
+namespace QmlProfiler {
+namespace Internal {
+
+QmlProfilerTraceViewTest::QmlProfilerTraceViewTest(QObject *parent) :
+ QObject(parent), traceView(nullptr, nullptr, &modelManager)
+{
+}
+
+void QmlProfilerTraceViewTest::testStateChanges()
+{
+ // Standard acquire-process-clear work flow
+ modelManager.startAcquiring();
+ QVERIFY(traceView.isSuspended());
+ modelManager.acquiringDone();
+ QVERIFY(!traceView.isSuspended());
+ modelManager.clear();
+ QVERIFY(!traceView.isSuspended());
+
+ // Restrict to range
+ modelManager.startAcquiring();
+ QVERIFY(traceView.isSuspended());
+ modelManager.acquiringDone();
+ QVERIFY(!traceView.isSuspended());
+ modelManager.restrictToRange(10, 14);
+ QVERIFY(!traceView.isSuspended());
+ modelManager.restrictToRange(-1, -1);
+ QVERIFY(!traceView.isSuspended());
+ modelManager.clear();
+ QVERIFY(!traceView.isSuspended());
+
+ // Abort Acquiring
+ modelManager.startAcquiring();
+ QVERIFY(traceView.isSuspended());
+ modelManager.clear();
+ QVERIFY(!traceView.isSuspended());
+}
+
+} // namespace Internal
+} // namespace QmlProfiler
diff --git a/src/plugins/qmlprofiler/tests/qmlprofilertraceview_test.h b/src/plugins/qmlprofiler/tests/qmlprofilertraceview_test.h
new file mode 100644
index 0000000000..e4edd01938
--- /dev/null
+++ b/src/plugins/qmlprofiler/tests/qmlprofilertraceview_test.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <qmlprofiler/qmlprofilermodelmanager.h>
+#include <qmlprofiler/qmlprofilertraceview.h>
+
+#include <QObject>
+
+namespace QmlProfiler {
+namespace Internal {
+
+class QmlProfilerTraceViewTest : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QmlProfilerTraceViewTest(QObject *parent = nullptr);
+
+private slots:
+ void testStateChanges();
+
+private:
+ QmlProfilerModelManager modelManager;
+ QmlProfilerTraceView traceView;
+};
+
+} // namespace Internal
+} // namespace QmlProfiler
diff --git a/src/plugins/qmlprofiler/tests/tests.pri b/src/plugins/qmlprofiler/tests/tests.pri
index 6d976a2716..feeda0cc40 100644
--- a/src/plugins/qmlprofiler/tests/tests.pri
+++ b/src/plugins/qmlprofiler/tests/tests.pri
@@ -14,7 +14,8 @@ SOURCES += \
$$PWD/qmlprofilerattachdialog_test.cpp \
$$PWD/qmlprofilerbindingloopsrenderpass_test.cpp \
$$PWD/qmlprofilerclientmanager_test.cpp \
- $$PWD/qmlprofilerconfigwidget_test.cpp
+ $$PWD/qmlprofilerconfigwidget_test.cpp \
+ $$PWD/qmlprofilertraceview_test.cpp
HEADERS += \
$$PWD/debugmessagesmodel_test.h \
@@ -32,4 +33,5 @@ HEADERS += \
$$PWD/qmlprofilerattachdialog_test.h \
$$PWD/qmlprofilerbindingloopsrenderpass_test.h \
$$PWD/qmlprofilerclientmanager_test.h \
- $$PWD/qmlprofilerconfigwidget_test.h
+ $$PWD/qmlprofilerconfigwidget_test.h \
+ $$PWD/qmlprofilertraceview_test.h
diff --git a/src/plugins/qnx/qnxanalyzesupport.cpp b/src/plugins/qnx/qnxanalyzesupport.cpp
index 4a7d89ac63..f5e182a8e3 100644
--- a/src/plugins/qnx/qnxanalyzesupport.cpp
+++ b/src/plugins/qnx/qnxanalyzesupport.cpp
@@ -87,12 +87,12 @@ QnxQmlProfilerSupport::QnxQmlProfilerSupport(RunControl *runControl)
auto portsGatherer = new PortsGatherer(runControl);
auto debuggeeRunner = new QnxAnalyzeeRunner(runControl, portsGatherer);
- debuggeeRunner->addDependency(portsGatherer);
+ debuggeeRunner->addStartDependency(portsGatherer);
auto slog2InfoRunner = new Slog2InfoRunner(runControl);
- slog2InfoRunner->addDependency(debuggeeRunner);
+ slog2InfoRunner->addStartDependency(debuggeeRunner);
- addDependency(slog2InfoRunner);
+ addStartDependency(slog2InfoRunner);
// QmlDebug::QmlOutputParser m_outputParser;
// FIXME: m_outputParser needs to be fed with application output
diff --git a/src/plugins/qnx/qnxdebugsupport.cpp b/src/plugins/qnx/qnxdebugsupport.cpp
index 1832e1d3ab..e560ed285e 100644
--- a/src/plugins/qnx/qnxdebugsupport.cpp
+++ b/src/plugins/qnx/qnxdebugsupport.cpp
@@ -99,12 +99,12 @@ QnxDebugSupport::QnxDebugSupport(RunControl *runControl)
m_portsGatherer->setUseQmlServer(isQmlDebugging());
auto debuggeeRunner = new QnxDebuggeeRunner(runControl, m_portsGatherer);
- debuggeeRunner->addDependency(m_portsGatherer);
+ debuggeeRunner->addStartDependency(m_portsGatherer);
auto slog2InfoRunner = new Slog2InfoRunner(runControl);
- slog2InfoRunner->addDependency(debuggeeRunner);
+ slog2InfoRunner->addStartDependency(debuggeeRunner);
- addDependency(slog2InfoRunner);
+ addStartDependency(slog2InfoRunner);
}
void QnxDebugSupport::start()
diff --git a/src/plugins/qnx/qnxdevice.cpp b/src/plugins/qnx/qnxdevice.cpp
index 994f74a839..31a8d9064d 100644
--- a/src/plugins/qnx/qnxdevice.cpp
+++ b/src/plugins/qnx/qnxdevice.cpp
@@ -55,19 +55,25 @@ class QnxPortsGatheringMethod : public PortsGatheringMethod
{
// TODO: The command is probably needlessly complicated because the parsing method
// used to be fixed. These two can now be matched to each other.
- QByteArray commandLine(QAbstractSocket::NetworkLayerProtocol protocol) const
+ Runnable runnable(QAbstractSocket::NetworkLayerProtocol protocol) const override
{
Q_UNUSED(protocol);
- return "netstat -na "
+ StandardRunnable runnable;
+ // FIXME: Is this extra shell needed?
+ runnable.executable = "/bin/sh";
+ runnable.commandLineArguments = "-c \""
+ "netstat -na "
"| sed 's/[a-z]\\+\\s\\+[0-9]\\+\\s\\+[0-9]\\+\\s\\+\\(\\*\\|[0-9\\.]\\+\\)\\.\\([0-9]\\+\\).*/\\2/g' "
"| while read line; do "
"if [[ $line != udp* ]] && [[ $line != Active* ]]; then "
"printf '%x\n' $line; "
"fi; "
- "done";
+ "done"
+ "\"";
+ return runnable;
}
- QList<Port> usedPorts(const QByteArray &output) const
+ QList<Port> usedPorts(const QByteArray &output) const override
{
QList<Port> ports;
QList<QByteArray> portStrings = output.split('\n');
diff --git a/src/plugins/qnx/slog2inforunner.cpp b/src/plugins/qnx/slog2inforunner.cpp
index 3bde0d4301..527dc16ceb 100644
--- a/src/plugins/qnx/slog2inforunner.cpp
+++ b/src/plugins/qnx/slog2inforunner.cpp
@@ -46,11 +46,7 @@ Slog2InfoRunner::Slog2InfoRunner(RunControl *runControl)
auto qnxRunConfig = qobject_cast<QnxRunConfiguration *>(runControl->runConfiguration());
QTC_ASSERT(qnxRunConfig, return);
m_applicationId = FileName::fromString(qnxRunConfig->remoteExecutableFilePath()).fileName();
-}
-void Slog2InfoRunner::printMissingWarning()
-{
- appendMessage(tr("Warning: \"slog2info\" is not found on the device, debug output not available."), ErrorMessageFormat);
// See QTCREATORBUG-10712 for details.
// We need to limit length of ApplicationId to 63 otherwise it would not match one in slog2info.
m_applicationId.truncate(63);
@@ -69,6 +65,11 @@ void Slog2InfoRunner::printMissingWarning()
connect(m_logProcess, &DeviceProcess::finished, this, &Slog2InfoRunner::finished);
}
+void Slog2InfoRunner::printMissingWarning()
+{
+ appendMessage(tr("Warning: \"slog2info\" is not found on the device, debug output not available."), ErrorMessageFormat);
+}
+
void Slog2InfoRunner::start()
{
StandardRunnable r;
diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp
index 0e7abf6d5f..49185ee5a3 100644
--- a/src/plugins/qtsupport/baseqtversion.cpp
+++ b/src/plugins/qtsupport/baseqtversion.cpp
@@ -477,6 +477,11 @@ QSet<Id> BaseQtVersion::availableFeatures() const
if (qtVersion().matches(5, 8))
return features;
+ features.unite(versionedIds(Constants::FEATURE_QT_QUICK_PREFIX, 2, 9));
+
+ if (qtVersion().matches(5, 9))
+ return features;
+
return features;
}
diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp
index 1e6fe89993..0e783a1a19 100644
--- a/src/plugins/remotelinux/linuxdevice.cpp
+++ b/src/plugins/remotelinux/linuxdevice.cpp
@@ -35,6 +35,7 @@
#include <coreplugin/id.h>
#include <projectexplorer/devicesupport/sshdeviceprocesslist.h>
+#include <projectexplorer/runnables.h>
#include <ssh/sshremoteprocessrunner.h>
#include <utils/algorithm.h>
#include <utils/port.h>
@@ -122,7 +123,7 @@ private:
class LinuxPortsGatheringMethod : public PortsGatheringMethod
{
- QByteArray commandLine(QAbstractSocket::NetworkLayerProtocol protocol) const
+ Runnable runnable(QAbstractSocket::NetworkLayerProtocol protocol) const
{
// We might encounter the situation that protocol is given IPv6
// but the consumer of the free port information decides to open
@@ -135,7 +136,10 @@ class LinuxPortsGatheringMethod : public PortsGatheringMethod
Q_UNUSED(protocol)
// /proc/net/tcp* covers /proc/net/tcp and /proc/net/tcp6
- return "sed -e 's/.*: [[:xdigit:]]*:\\([[:xdigit:]]\\{4\\}\\).*/\\1/g' /proc/net/tcp*";
+ StandardRunnable runnable;
+ runnable.executable = "sed";
+ runnable.commandLineArguments = "-e 's/.*: [[:xdigit:]]*:\\([[:xdigit:]]\\{4\\}\\).*/\\1/g' /proc/net/tcp*";
+ return runnable;
}
QList<Utils::Port> usedPorts(const QByteArray &output) const
diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp
index 72a85f53e1..de1a9efde1 100644
--- a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp
+++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp
@@ -58,10 +58,15 @@ RemoteLinuxQmlProfilerSupport::RemoteLinuxQmlProfilerSupport(RunControl *runCont
setDisplayName("RemoteLinuxQmlProfilerSupport");
m_portsGatherer = new PortsGatherer(runControl);
- addDependency(m_portsGatherer);
+ addStartDependency(m_portsGatherer);
+
+ // The ports gatherer can safely be stopped once the process is running, even though it has to
+ // be started before.
+ addStopDependency(m_portsGatherer);
m_profiler = runControl->createWorker(runControl->runMode());
- m_profiler->addDependency(this);
+ m_profiler->addStartDependency(this);
+ addStopDependency(m_profiler);
}
void RemoteLinuxQmlProfilerSupport::start()
@@ -102,7 +107,7 @@ RemoteLinuxPerfSupport::RemoteLinuxPerfSupport(RunControl *runControl)
.join(' ');
auto toolRunner = runControl->createWorker(runControl->runMode());
- toolRunner->addDependency(this);
+ toolRunner->addStartDependency(this);
// connect(&m_outputGatherer, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
// this, &RemoteLinuxPerfSupport::remoteIsRunning);
diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
index 2d74283218..4ce28bbc16 100644
--- a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
+++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
@@ -57,9 +57,9 @@ LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl)
m_portsGatherer->setUseQmlServer(isQmlDebugging());
auto gdbServer = new GdbServerRunner(runControl, m_portsGatherer);
- gdbServer->addDependency(m_portsGatherer);
+ gdbServer->addStartDependency(m_portsGatherer);
- addDependency(gdbServer);
+ addStartDependency(gdbServer);
RunConfiguration *runConfig = runControl->runConfiguration();
if (auto rlrc = qobject_cast<RemoteLinuxRunConfiguration *>(runConfig))
diff --git a/src/plugins/scxmleditor/outputpane/errorwidget.cpp b/src/plugins/scxmleditor/outputpane/errorwidget.cpp
index 2e085c0328..455bd88e7b 100644
--- a/src/plugins/scxmleditor/outputpane/errorwidget.cpp
+++ b/src/plugins/scxmleditor/outputpane/errorwidget.cpp
@@ -203,7 +203,7 @@ QString ErrorWidget::modifyExportedValue(const QString &val)
void ErrorWidget::exportWarnings()
{
- QString fileName = QFileDialog::getSaveFileName(this, tr("Export To File"), QString(), tr("CSV files (*.csv)"));
+ QString fileName = QFileDialog::getSaveFileName(this, tr("Export to File"), QString(), tr("CSV files (*.csv)"));
if (fileName.isEmpty())
return;
diff --git a/src/plugins/scxmleditor/plugin_interface/scattributeitemmodel.cpp b/src/plugins/scxmleditor/plugin_interface/scattributeitemmodel.cpp
index 30d561a952..38fe97e667 100644
--- a/src/plugins/scxmleditor/plugin_interface/scattributeitemmodel.cpp
+++ b/src/plugins/scxmleditor/plugin_interface/scattributeitemmodel.cpp
@@ -117,8 +117,6 @@ QVariant SCAttributeItemModel::data(const QModelIndex &index, int role) const
return Qt::AlignHCenter;
else
break;
- case Qt::ForegroundRole:
- return bExtraRow ? QBrush(Qt::gray) : QBrush(Qt::black);
case DataTypeRole: {
if (m_tag->tagType() == Metadata || m_tag->tagType() == MetadataItem)
return (int)QVariant::String;
@@ -148,7 +146,7 @@ Qt::ItemFlags SCAttributeItemModel::flags(const QModelIndex &index) const
if (m_tag->tagType() <= MetadataItem || (index.column() == 1 && m_tag->info()->n_attributes > 0 && m_tag->info()->attributes[index.row()].editable))
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
- return Qt::NoItemFlags;
+ return index.column() == 0 ? Qt::ItemIsEnabled : Qt::NoItemFlags;
}
int SCAttributeItemModel::columnCount(const QModelIndex &parent) const
diff --git a/src/plugins/scxmleditor/plugin_interface/stateitem.cpp b/src/plugins/scxmleditor/plugin_interface/stateitem.cpp
index 532851632c..edc2562ccf 100644
--- a/src/plugins/scxmleditor/plugin_interface/stateitem.cpp
+++ b/src/plugins/scxmleditor/plugin_interface/stateitem.cpp
@@ -306,7 +306,7 @@ void StateItem::createContextMenu(QMenu *menu)
if (type() == ParallelType) {
data[Constants::C_SCXMLTAG_ACTIONTYPE] = TagUtils::Relayout;
- menu->addAction(tr("Relayout"))->setData(data);
+ menu->addAction(tr("Re-Layout"))->setData(data);
}
menu->addSeparator();
diff --git a/src/plugins/valgrind/memcheckengine.cpp b/src/plugins/valgrind/memcheckengine.cpp
index 4e25251e4b..8e80ef1165 100644
--- a/src/plugins/valgrind/memcheckengine.cpp
+++ b/src/plugins/valgrind/memcheckengine.cpp
@@ -97,7 +97,7 @@ MemcheckToolRunner::MemcheckToolRunner(RunControl *runControl, bool withGdb)
// We need a real address to connect to from the outside.
if (device()->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
- addDependency(new LocalAddressFinder(runControl, &m_localServerAddress));
+ addStartDependency(new LocalAddressFinder(runControl, &m_localServerAddress));
}
QString MemcheckToolRunner::progressTitle() const
diff --git a/src/plugins/winrt/winrtrunnerhelper.cpp b/src/plugins/winrt/winrtrunnerhelper.cpp
index a8986a8026..0b4c6653bb 100644
--- a/src/plugins/winrt/winrtrunnerhelper.cpp
+++ b/src/plugins/winrt/winrtrunnerhelper.cpp
@@ -185,6 +185,8 @@ void WinRtRunnerHelper::startWinRtRunner(const RunConf &conf)
if (m_device->type() == Constants::WINRT_DEVICE_TYPE_LOCAL)
QtcProcess::addArgs(&runnerArgs, QStringLiteral("--profile appx"));
+ else if (m_device->type() == Constants::WINRT_DEVICE_TYPE_PHONE)
+ QtcProcess::addArgs(&runnerArgs, QStringLiteral("--profile appxphone"));
QtcProcess::addArg(&runnerArgs, m_executableFilePath);
if (!m_arguments.isEmpty())
diff --git a/src/shared/qbs b/src/shared/qbs
-Subproject 998c69898058a7917a35875b7c7591bba6cf9f4
+Subproject 4b5803362114eaea3edbb57c9b47e03547ece20
diff --git a/src/tools/clangbackend/ipcsource/clangbackend_global.h b/src/tools/clangbackend/ipcsource/clangbackend_global.h
index 0dccaa87ad..d806afc98c 100644
--- a/src/tools/clangbackend/ipcsource/clangbackend_global.h
+++ b/src/tools/clangbackend/ipcsource/clangbackend_global.h
@@ -25,6 +25,8 @@
#pragma once
+#include <clang-c/Index.h>
+
namespace ClangBackEnd {
enum class PreferredTranslationUnit
@@ -34,4 +36,9 @@ enum class PreferredTranslationUnit
LastUninitialized,
};
+// CLANG-UPGRADE-CHECK: Remove IS_SUSPEND_SUPPORTED once we require clang >= 5.0
+#if defined(CINDEX_VERSION_HAS_BACKPORTED_SUSPEND) || CINDEX_VERSION_MINOR >= 41
+# define IS_SUSPEND_SUPPORTED
+#endif
+
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri b/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri
index 2207748065..c89d84c591 100644
--- a/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri
+++ b/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri
@@ -12,6 +12,7 @@ HEADERS += \
$$PWD/clangdocumentprocessor.h \
$$PWD/clangdocumentprocessors.h \
$$PWD/clangdocuments.h \
+ $$PWD/clangdocumentsuspenderresumer.h \
$$PWD/clangexceptions.h \
$$PWD/clangfilepath.h \
$$PWD/clangfilesystemwatcher.h \
@@ -25,8 +26,10 @@ HEADERS += \
$$PWD/clangreparsesupportivetranslationunitjob.h \
$$PWD/clangrequestdocumentannotationsjob.h \
$$PWD/clangrequestreferencesjob.h \
+ $$PWD/clangresumedocumentjob.h \
$$PWD/clangstring.h \
$$PWD/clangsupportivetranslationunitinitializer.h \
+ $$PWD/clangsuspenddocumentjob.h \
$$PWD/clangtranslationunit.h \
$$PWD/clangtranslationunits.h \
$$PWD/clangtranslationunitupdater.h \
@@ -64,6 +67,7 @@ SOURCES += \
$$PWD/clangdocumentprocessor.cpp \
$$PWD/clangdocumentprocessors.cpp \
$$PWD/clangdocuments.cpp \
+ $$PWD/clangdocumentsuspenderresumer.cpp \
$$PWD/clangexceptions.cpp \
$$PWD/clangfilepath.cpp \
$$PWD/clangfilesystemwatcher.cpp \
@@ -73,10 +77,12 @@ SOURCES += \
$$PWD/clangjobrequest.cpp \
$$PWD/clangjobs.cpp \
$$PWD/clangparsesupportivetranslationunitjob.cpp \
+ $$PWD/clangresumedocumentjob.cpp \
$$PWD/clangreferencescollector.cpp \
$$PWD/clangreparsesupportivetranslationunitjob.cpp \
$$PWD/clangrequestdocumentannotationsjob.cpp \
$$PWD/clangrequestreferencesjob.cpp \
+ $$PWD/clangsuspenddocumentjob.cpp \
$$PWD/clangsupportivetranslationunitinitializer.cpp \
$$PWD/clangtranslationunit.cpp \
$$PWD/clangtranslationunits.cpp \
diff --git a/src/tools/clangbackend/ipcsource/clangcodemodelserver.cpp b/src/tools/clangbackend/ipcsource/clangcodemodelserver.cpp
index d852c2a546..e18b1e736f 100644
--- a/src/tools/clangbackend/ipcsource/clangcodemodelserver.cpp
+++ b/src/tools/clangbackend/ipcsource/clangcodemodelserver.cpp
@@ -26,6 +26,7 @@
#include "clangcodemodelserver.h"
#include "clangdocuments.h"
+#include "clangdocumentsuspenderresumer.h"
#include "clangfilesystemwatcher.h"
#include "clangtranslationunits.h"
#include "codecompleter.h"
@@ -89,6 +90,7 @@ void ClangCodeModelServer::registerTranslationUnitsForEditor(const ClangBackEnd:
unsavedFiles.createOrUpdate(message.fileContainers());
documents.setUsedByCurrentEditor(message.currentEditorFilePath());
documents.setVisibleInEditors(message.visibleEditorFilePaths());
+ processSuspendResumeJobs(documents.documents());
processInitialJobsForDocuments(createdDocuments);
} catch (const std::exception &exception) {
@@ -290,6 +292,8 @@ void ClangCodeModelServer::updateVisibleTranslationUnits(const UpdateVisibleTran
try {
documents.setUsedByCurrentEditor(message.currentEditorFilePath());
documents.setVisibleInEditors(message.visibleEditorFilePaths());
+ processSuspendResumeJobs(documents.documents());
+
updateDocumentAnnotationsTimer.start(0);
} catch (const std::exception &exception) {
qWarning() << "Error in ClangCodeModelServer::updateVisibleTranslationUnits:" << exception.what();
@@ -373,6 +377,16 @@ void ClangCodeModelServer::processJobsForDirtyAndVisibleButNotCurrentDocuments()
addAndRunUpdateJobs(documents.dirtyAndVisibleButNotCurrentDocuments());
}
+void ClangCodeModelServer::processSuspendResumeJobs(const std::vector<Document> &documents)
+{
+ const SuspendResumeJobs suspendResumeJobs = createSuspendResumeJobs(documents);
+ for (const SuspendResumeJobsEntry &entry : suspendResumeJobs) {
+ DocumentProcessor processor = documentProcessors().processor(entry.document);
+ processor.addJob(entry.jobRequestType, entry.preferredTranslationUnit);
+ processor.process();
+ }
+}
+
void ClangCodeModelServer::processInitialJobsForDocuments(const std::vector<Document> &documents)
{
for (const auto &document : documents) {
diff --git a/src/tools/clangbackend/ipcsource/clangcodemodelserver.h b/src/tools/clangbackend/ipcsource/clangcodemodelserver.h
index 352eb1f932..b6c5619d8d 100644
--- a/src/tools/clangbackend/ipcsource/clangcodemodelserver.h
+++ b/src/tools/clangbackend/ipcsource/clangcodemodelserver.h
@@ -78,6 +78,7 @@ private:
void processJobsForDirtyCurrentDocument();
void processTimerForVisibleButNotCurrentDocuments();
void processJobsForDirtyAndVisibleButNotCurrentDocuments();
+ void processSuspendResumeJobs(const std::vector<Document> &documents);
void addAndRunUpdateJobs(std::vector<Document> documents);
diff --git a/src/tools/clangbackend/ipcsource/clangdocument.cpp b/src/tools/clangbackend/ipcsource/clangdocument.cpp
index 3cfcfabe09..a4f95d17b8 100644
--- a/src/tools/clangbackend/ipcsource/clangdocument.cpp
+++ b/src/tools/clangbackend/ipcsource/clangdocument.cpp
@@ -71,6 +71,8 @@ public:
uint documentRevision = 0;
+ TimePoint visibleTimePoint;
+
TimePoint isDirtyChangeTimePoint;
bool isDirty = false;
@@ -78,6 +80,7 @@ public:
bool isUsedByCurrentEditor = false;
bool isVisibleInEditor = false;
bool increaseResponsiveness = false;
+ bool isSuspended = false;
};
DocumentData::DocumentData(const Utf8String &filePath,
@@ -224,6 +227,20 @@ void Document::setResponsivenessIncreaseNeeded(bool responsivenessIncreaseNeeded
d->increaseResponsiveness = responsivenessIncreaseNeeded;
}
+bool Document::isSuspended() const
+{
+ checkIfNull();
+
+ return d->isSuspended;
+}
+
+void Document::setIsSuspended(bool isSuspended)
+{
+ checkIfNull();
+
+ d->isSuspended = isSuspended;
+}
+
bool Document::isUsedByCurrentEditor() const
{
checkIfNull();
@@ -245,13 +262,22 @@ bool Document::isVisibleInEditor() const
return d->isVisibleInEditor;
}
-void Document::setIsVisibleInEditor(bool isVisibleInEditor)
+void Document::setIsVisibleInEditor(bool isVisibleInEditor, const TimePoint &timePoint)
{
checkIfNull();
+ if (isVisibleInEditor)
+ d->visibleTimePoint = timePoint;
d->isVisibleInEditor = isVisibleInEditor;
}
+TimePoint Document::visibleTimePoint() const
+{
+ checkIfNull();
+
+ return d->visibleTimePoint;;
+}
+
bool Document::isDirty() const
{
checkIfNull();
diff --git a/src/tools/clangbackend/ipcsource/clangdocument.h b/src/tools/clangbackend/ipcsource/clangdocument.h
index 15555ace10..260705c135 100644
--- a/src/tools/clangbackend/ipcsource/clangdocument.h
+++ b/src/tools/clangbackend/ipcsource/clangdocument.h
@@ -93,11 +93,15 @@ public:
bool isResponsivenessIncreaseNeeded() const;
void setResponsivenessIncreaseNeeded(bool responsivenessIncreaseNeeded);
+ bool isSuspended() const;
+ void setIsSuspended(bool isSuspended);
+
bool isUsedByCurrentEditor() const;
void setIsUsedByCurrentEditor(bool isUsedByCurrentEditor);
bool isVisibleInEditor() const;
- void setIsVisibleInEditor(bool isVisibleInEditor);
+ void setIsVisibleInEditor(bool isVisibleInEditor, const TimePoint &timePoint);
+ TimePoint visibleTimePoint() const;
bool isDirty() const;
TimePoint isDirtyTimeChangePoint() const;
diff --git a/src/tools/clangbackend/ipcsource/clangdocuments.cpp b/src/tools/clangbackend/ipcsource/clangdocuments.cpp
index 7ae7106cc8..5fc8f294a7 100644
--- a/src/tools/clangbackend/ipcsource/clangdocuments.cpp
+++ b/src/tools/clangbackend/ipcsource/clangdocuments.cpp
@@ -117,8 +117,9 @@ void Documents::setUsedByCurrentEditor(const Utf8String &filePath)
void Documents::setVisibleInEditors(const Utf8StringVector &filePaths)
{
+ const TimePoint timePoint = Clock::now();
for (Document &document : documents_)
- document.setIsVisibleInEditor(filePaths.contains(document.filePath()));
+ document.setIsVisibleInEditor(filePaths.contains(document.filePath()), timePoint);
}
const Document &Documents::document(const Utf8String &filePath, const Utf8String &projectPartId) const
diff --git a/src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.cpp b/src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.cpp
new file mode 100644
index 0000000000..8edde48fd6
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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 "clangdocumentsuspenderresumer.h"
+
+#include "clangbackendipc_global.h"
+#include "clangdocumentprocessors.h"
+#include "clangdocuments.h"
+
+#include <utils/algorithm.h>
+
+#include <algorithm>
+
+namespace ClangBackEnd {
+
+constexpr int DefaultHotDocumentsSize = 7;
+
+void categorizeHotColdDocuments(int hotDocumentsSize,
+ const std::vector<Document> &inDocuments,
+ std::vector<Document> &hotDocuments,
+ std::vector<Document> &coldDocuments)
+{
+ // Sort documents, most recently used/visible at top
+ std::vector<Document> documents = inDocuments;
+ std::stable_sort(documents.begin(), documents.end(), [](const Document &a, const Document &b) {
+ return a.visibleTimePoint() > b.visibleTimePoint();
+ });
+
+ // Ensure that visible documents are always hot, otherwise not all visible
+ // documents will be resumed.
+ const auto isVisible = [](const Document &document) { return document.isVisibleInEditor(); };
+ const int visibleDocumentsSize = Utils::count(documents, isVisible);
+ hotDocumentsSize = std::max(hotDocumentsSize, visibleDocumentsSize);
+
+ if (documents.size() <= uint(hotDocumentsSize)) {
+ hotDocuments = documents;
+ coldDocuments.clear();
+ } else {
+ const auto firstColdIterator = documents.begin() + hotDocumentsSize;
+ hotDocuments = std::vector<Document>(documents.begin(), firstColdIterator);
+ coldDocuments = std::vector<Document>(firstColdIterator, documents.end());
+ }
+}
+
+#ifdef IS_SUSPEND_SUPPORTED
+static int hotDocumentsSize()
+{
+ static int hotDocuments = -1;
+ if (hotDocuments == -1) {
+ bool ok = false;
+ const int fromEnvironment = qEnvironmentVariableIntValue("QTC_CLANG_HOT_DOCUMENTS", &ok);
+ hotDocuments = ok && fromEnvironment >= 1 ? fromEnvironment : DefaultHotDocumentsSize;
+ }
+
+ return hotDocuments;
+}
+
+static SuspendResumeJobs createJobs(const Document &document, JobRequest::Type type)
+{
+ SuspendResumeJobs jobs;
+
+ jobs.append({document, type, PreferredTranslationUnit::RecentlyParsed});
+ if (document.isResponsivenessIncreased())
+ jobs.append({document, type, PreferredTranslationUnit::PreviouslyParsed});
+
+ return jobs;
+}
+
+static bool isFineDocument(const Document &document)
+{
+ return !document.isNull() && document.isIntact();
+}
+
+static bool isSuspendable(const Document &document)
+{
+ return isFineDocument(document)
+ && !document.isSuspended()
+ && !document.isVisibleInEditor();
+}
+
+static bool isResumable(const Document &document)
+{
+ return isFineDocument(document)
+ && document.isSuspended()
+ && document.isVisibleInEditor();
+}
+
+#endif // IS_SUSPEND_SUPPORTED
+
+SuspendResumeJobs createSuspendResumeJobs(const std::vector<Document> &documents,
+ int customHotDocumentSize)
+{
+ Q_UNUSED(documents);
+ Q_UNUSED(customHotDocumentSize);
+
+ SuspendResumeJobs jobs;
+
+#ifdef IS_SUSPEND_SUPPORTED
+ std::vector<Document> hotDocuments;
+ std::vector<Document> coldDocuments;
+
+ const int size = (customHotDocumentSize == -1) ? hotDocumentsSize() : customHotDocumentSize;
+ categorizeHotColdDocuments(size, documents, hotDocuments, coldDocuments);
+
+ // Cold documents should be suspended...
+ const std::vector<Document> toSuspend = Utils::filtered(coldDocuments, &isSuspendable);
+ for (const Document &document : toSuspend)
+ jobs += createJobs(document, JobRequest::Type::SuspendDocument);
+
+ // ...and hot documents that were suspended should be resumed
+ const std::vector<Document> toResume = Utils::filtered(hotDocuments, &isResumable);
+ for (const Document &document : toResume)
+ jobs += createJobs(document, JobRequest::Type::ResumeDocument);
+#endif // IS_SUSPEND_SUPPORTED
+
+ return jobs;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.h b/src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.h
new file mode 100644
index 0000000000..7e2bd8722d
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "clangdocument.h"
+#include "clangjobrequest.h"
+
+#include <vector>
+
+namespace ClangBackEnd {
+
+class SuspendResumeJobsEntry {
+public:
+ SuspendResumeJobsEntry() = default;
+ SuspendResumeJobsEntry(const Document &document,
+ JobRequest::Type jobRequestType,
+ PreferredTranslationUnit preferredTranslationUnit)
+ : document(document)
+ , jobRequestType(jobRequestType)
+ , preferredTranslationUnit(preferredTranslationUnit)
+ {
+ }
+
+ Document document;
+ JobRequest::Type jobRequestType = JobRequest::Type::SuspendDocument;
+ PreferredTranslationUnit preferredTranslationUnit = PreferredTranslationUnit::RecentlyParsed;
+};
+using SuspendResumeJobs = QVector<SuspendResumeJobsEntry>;
+
+SuspendResumeJobs createSuspendResumeJobs(const std::vector<Document> &documents,
+ int customHotDocumentCounts = -1);
+
+// for tests
+void categorizeHotColdDocuments(int hotDocumentsSize,
+ const std::vector<Document> &inDocuments,
+ std::vector<Document> &hotDocuments,
+ std::vector<Document> &coldDocuments);
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangiasyncjob.cpp b/src/tools/clangbackend/ipcsource/clangiasyncjob.cpp
index 4e4718ba3a..45fe842dda 100644
--- a/src/tools/clangbackend/ipcsource/clangiasyncjob.cpp
+++ b/src/tools/clangbackend/ipcsource/clangiasyncjob.cpp
@@ -27,11 +27,13 @@
#include "clangcompletecodejob.h"
#include "clangcreateinitialdocumentpreamblejob.h"
+#include "clangfollowsymboljob.h"
#include "clangparsesupportivetranslationunitjob.h"
#include "clangreparsesupportivetranslationunitjob.h"
#include "clangrequestdocumentannotationsjob.h"
#include "clangrequestreferencesjob.h"
-#include "clangfollowsymboljob.h"
+#include "clangresumedocumentjob.h"
+#include "clangsuspenddocumentjob.h"
#include "clangupdatedocumentannotationsjob.h"
Q_LOGGING_CATEGORY(jobsLog, "qtc.clangbackend.jobs");
@@ -57,6 +59,10 @@ IAsyncJob *IAsyncJob::create(JobRequest::Type type)
return new RequestReferencesJob();
case JobRequest::Type::FollowSymbol:
return new FollowSymbolJob();
+ case JobRequest::Type::SuspendDocument:
+ return new SuspendDocumentJob();
+ case JobRequest::Type::ResumeDocument:
+ return new ResumeDocumentJob();
}
return nullptr;
diff --git a/src/tools/clangbackend/ipcsource/clangjobqueue.cpp b/src/tools/clangbackend/ipcsource/clangjobqueue.cpp
index b4cc059aeb..8c9ace68e6 100644
--- a/src/tools/clangbackend/ipcsource/clangjobqueue.cpp
+++ b/src/tools/clangbackend/ipcsource/clangjobqueue.cpp
@@ -94,8 +94,9 @@ bool JobQueue::isJobRequestExpired(const JobRequest &jobRequest) const
{
const JobRequest::ExpirationReasons expirationReasons = jobRequest.expirationReasons;
const UnsavedFiles unsavedFiles = m_documents.unsavedFiles();
+ using ExpirationReason = JobRequest::ExpirationReason;
- if (expirationReasons.testFlag(JobRequest::UnsavedFilesChanged)) {
+ if (expirationReasons.testFlag(ExpirationReason::UnsavedFilesChanged)) {
if (jobRequest.unsavedFilesChangeTimePoint != unsavedFiles.lastChangeTimePoint()) {
qCDebug(jobsLog) << "Removing due to outdated unsaved files:" << jobRequest;
return true;
@@ -104,7 +105,7 @@ bool JobQueue::isJobRequestExpired(const JobRequest &jobRequest) const
bool projectCheckedAndItExists = false;
- if (expirationReasons.testFlag(JobRequest::DocumentClosed)) {
+ if (expirationReasons.testFlag(ExpirationReason::DocumentClosed)) {
if (!m_documents.hasDocument(jobRequest.filePath, jobRequest.projectPartId)) {
qCDebug(jobsLog) << "Removing due to already closed document:" << jobRequest;
return true;
@@ -123,7 +124,7 @@ bool JobQueue::isJobRequestExpired(const JobRequest &jobRequest) const
return true;
}
- if (expirationReasons.testFlag(JobRequest::DocumentRevisionChanged)) {
+ if (expirationReasons.testFlag(ExpirationReason::DocumentRevisionChanged)) {
if (document.documentRevision() > jobRequest.documentRevision) {
qCDebug(jobsLog) << "Removing due to changed document revision:" << jobRequest;
return true;
@@ -131,7 +132,7 @@ bool JobQueue::isJobRequestExpired(const JobRequest &jobRequest) const
}
}
- if (expirationReasons.testFlag(JobRequest::ProjectChanged)) {
+ if (expirationReasons.testFlag(ExpirationReason::ProjectChanged)) {
if (!projectCheckedAndItExists && !m_projectParts.hasProjectPart(jobRequest.projectPartId)) {
qCDebug(jobsLog) << "Removing due to already closed project:" << jobRequest;
return true;
@@ -173,6 +174,48 @@ void JobQueue::prioritizeRequests()
std::stable_sort(m_queue.begin(), m_queue.end(), lessThan);
}
+static bool passesPreconditions(const JobRequest &request, const Document &document)
+{
+ using Condition = JobRequest::Condition;
+ const JobRequest::Conditions conditions = request.conditions;
+
+ if (conditions.testFlag(Condition::DocumentSuspended) && !document.isSuspended()) {
+ qCDebug(jobsLog) << "Not choosing due to unsuspended document:" << request;
+ return false;
+ }
+
+ if (conditions.testFlag(Condition::DocumentUnsuspended) && document.isSuspended()) {
+ qCDebug(jobsLog) << "Not choosing due to suspended document:" << request;
+ return false;
+ }
+
+ if (conditions.testFlag(Condition::DocumentVisible) && !document.isVisibleInEditor()) {
+ qCDebug(jobsLog) << "Not choosing due to invisble document:" << request;
+ return false;
+ }
+
+ if (conditions.testFlag(Condition::DocumentNotVisible) && document.isVisibleInEditor()) {
+ qCDebug(jobsLog) << "Not choosing due to visble document:" << request;
+ return false;
+ }
+
+ if (conditions.testFlag(Condition::CurrentDocumentRevision)) {
+ if (document.isDirty()) {
+ // TODO: If the document is dirty due to a project update,
+ // references are processes later than ideal.
+ qCDebug(jobsLog) << "Not choosing due to dirty document:" << request;
+ return false;
+ }
+
+ if (request.documentRevision != document.documentRevision()) {
+ qCDebug(jobsLog) << "Not choosing due to revision mismatch:" << request;
+ return false;
+ }
+ }
+
+ return true;
+}
+
JobRequests JobQueue::takeJobRequestsToRunNow()
{
JobRequests jobsToRun;
@@ -187,7 +230,7 @@ JobRequests JobQueue::takeJobRequestsToRunNow()
const Document &document = m_documents.document(request.filePath,
request.projectPartId);
- if (!document.isUsedByCurrentEditor() && !document.isVisibleInEditor())
+ if (!passesPreconditions(request, document))
continue;
const Utf8String id = document.translationUnit(request.preferredTranslationUnit).id();
@@ -197,20 +240,6 @@ JobRequests JobQueue::takeJobRequestsToRunNow()
if (isJobRunningForTranslationUnit(id))
continue;
- if (request.conditions.testFlag(JobRequest::Condition::CurrentDocumentRevision)) {
- if (document.isDirty()) {
- // TODO: If the document is dirty due to a project update,
- // references are processes later than ideal.
- qCDebug(jobsLog) << "Not choosing due to dirty document:" << request;
- continue;
- }
-
- if (request.documentRevision != document.documentRevision()) {
- qCDebug(jobsLog) << "Not choosing due to revision mismatch:" << request;
- continue;
- }
- }
-
translationUnitsScheduledForThisRun.insert(id);
jobsToRun += request;
i.remove();
diff --git a/src/tools/clangbackend/ipcsource/clangjobrequest.cpp b/src/tools/clangbackend/ipcsource/clangjobrequest.cpp
index 204c66e750..800f576cb4 100644
--- a/src/tools/clangbackend/ipcsource/clangjobrequest.cpp
+++ b/src/tools/clangbackend/ipcsource/clangjobrequest.cpp
@@ -41,6 +41,8 @@ static const char *JobRequestTypeToText(JobRequest::Type type)
RETURN_TEXT_FOR_CASE(RequestDocumentAnnotations);
RETURN_TEXT_FOR_CASE(RequestReferences);
RETURN_TEXT_FOR_CASE(FollowSymbol);
+ RETURN_TEXT_FOR_CASE(SuspendDocument);
+ RETURN_TEXT_FOR_CASE(ResumeDocument);
}
return "UnhandledJobRequestType";
@@ -109,29 +111,37 @@ bool JobRequest::operator==(const JobRequest &other) const
JobRequest::ExpirationReasons JobRequest::expirationReasonsForType(Type type)
{
switch (type) {
- case JobRequest::Type::UpdateDocumentAnnotations:
- return JobRequest::ExpirationReasons(JobRequest::AnythingChanged);
- case JobRequest::Type::RequestReferences:
- case JobRequest::Type::RequestDocumentAnnotations:
- case JobRequest::Type::FollowSymbol:
- return JobRequest::ExpirationReasons(JobRequest::DocumentClosed
- |JobRequest::DocumentRevisionChanged);
- case JobRequest::Type::CompleteCode:
- case JobRequest::Type::CreateInitialDocumentPreamble:
- case JobRequest::Type::ParseSupportiveTranslationUnit:
- case JobRequest::Type::ReparseSupportiveTranslationUnit:
- return JobRequest::ExpirationReasons(JobRequest::DocumentClosed);
+ case Type::UpdateDocumentAnnotations:
+ return ExpirationReasons(ExpirationReason::AnythingChanged);
+ case Type::RequestReferences:
+ case Type::RequestDocumentAnnotations:
+ case Type::FollowSymbol:
+ return ExpirationReasons(ExpirationReason::DocumentClosed)
+ | ExpirationReasons(ExpirationReason::DocumentRevisionChanged);
+ default:
+ return ExpirationReason::DocumentClosed;
}
-
- return JobRequest::ExpirationReasons(JobRequest::DocumentClosed);
}
JobRequest::Conditions JobRequest::conditionsForType(JobRequest::Type type)
{
- if (type == JobRequest::Type::RequestReferences)
- return JobRequest::Conditions(JobRequest::Condition::CurrentDocumentRevision);
+ if (type == Type::SuspendDocument) {
+ return Conditions(Condition::DocumentUnsuspended)
+ | Conditions(Condition::DocumentNotVisible);
+ }
+
+ if (type == Type::ResumeDocument) {
+ return Conditions(Condition::DocumentSuspended)
+ | Conditions(Condition::DocumentVisible);
+ }
+
+ Conditions conditions = Conditions(Condition::DocumentUnsuspended)
+ | Conditions(Condition::DocumentVisible);
+
+ if (type == Type::RequestReferences)
+ conditions |= Condition::CurrentDocumentRevision;
- return JobRequest::Conditions(JobRequest::Condition::NoCondition);
+ return conditions;
}
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangjobrequest.h b/src/tools/clangbackend/ipcsource/clangjobrequest.h
index 2f096c0d9f..e0b7ed2d94 100644
--- a/src/tools/clangbackend/ipcsource/clangjobrequest.h
+++ b/src/tools/clangbackend/ipcsource/clangjobrequest.h
@@ -54,15 +54,22 @@ public:
RequestDocumentAnnotations,
RequestReferences,
FollowSymbol,
+
+ SuspendDocument,
+ ResumeDocument,
};
enum class Condition {
- NoCondition,
- CurrentDocumentRevision,
+ NoCondition = 1 << 0,
+ DocumentVisible = 1 << 1,
+ DocumentNotVisible = 1 << 2,
+ DocumentSuspended = 1 << 3,
+ DocumentUnsuspended = 1 << 4,
+ CurrentDocumentRevision = 1 << 5,
};
Q_DECLARE_FLAGS(Conditions, Condition)
- enum ExpirationReason {
+ enum class ExpirationReason {
Never = 1 << 0,
DocumentClosed = 1 << 1,
diff --git a/src/tools/clangbackend/ipcsource/clangresumedocumentjob.cpp b/src/tools/clangbackend/ipcsource/clangresumedocumentjob.cpp
new file mode 100644
index 0000000000..c628d4444a
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/clangresumedocumentjob.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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 "clangresumedocumentjob.h"
+
+#include <utils/qtcassert.h>
+
+namespace ClangBackEnd {
+
+void ResumeDocumentJob::finalizeAsyncRun()
+{
+ if (context().isDocumentOpen()) {
+ if (QTC_GUARD(asyncResult().updateResult.hasReparsed()))
+ m_pinnedDocument.setIsSuspended(false);
+ }
+
+ UpdateDocumentAnnotationsJob::finalizeAsyncRun();
+}
+
+bool ResumeDocumentJob::isExpectedJobRequestType(const JobRequest &jobRequest) const
+{
+ return jobRequest.type == JobRequest::Type::ResumeDocument;
+}
+
+TranslationUnitUpdateInput ResumeDocumentJob::createUpdateInput(const Document &document) const
+{
+ TranslationUnitUpdateInput input = UpdateDocumentAnnotationsJob::createUpdateInput(document);
+ input.reparseNeeded = true;
+ return input;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangresumedocumentjob.h b/src/tools/clangbackend/ipcsource/clangresumedocumentjob.h
new file mode 100644
index 0000000000..aff8e780f7
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/clangresumedocumentjob.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "clangasyncjob.h"
+#include "clangdocument.h"
+#include "clangupdatedocumentannotationsjob.h"
+
+namespace ClangBackEnd {
+
+class ResumeDocumentJob : public UpdateDocumentAnnotationsJob
+{
+public:
+ void finalizeAsyncRun() override;
+
+private:
+ bool isExpectedJobRequestType(const JobRequest &jobRequest) const override;
+ TranslationUnitUpdateInput createUpdateInput(const Document &document) const override;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.cpp b/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.cpp
new file mode 100644
index 0000000000..e3406fcf32
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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 "clangsuspenddocumentjob.h"
+
+#include <clangbackendipc/clangbackendipcdebugutils.h>
+
+#include <utils/qtcassert.h>
+
+namespace ClangBackEnd {
+
+static bool runAsyncHelper(const TranslationUnit &translationUnit)
+{
+ TIME_SCOPE_DURATION("SuspendDocumentJobRunner");
+
+ return translationUnit.suspend();
+}
+
+IAsyncJob::AsyncPrepareResult SuspendDocumentJob::prepareAsyncRun()
+{
+ const JobRequest jobRequest = context().jobRequest;
+ QTC_ASSERT(jobRequest.type == JobRequest::Type::SuspendDocument, return AsyncPrepareResult());
+
+ try {
+ m_pinnedDocument = context().documentForJobRequest();
+ m_pinnedFileContainer = m_pinnedDocument.fileContainer();
+
+ TranslationUnit translationUnit
+ = m_pinnedDocument.translationUnit(jobRequest.preferredTranslationUnit);
+ setRunner([translationUnit]() {
+ return runAsyncHelper(translationUnit);
+ });
+ return AsyncPrepareResult{translationUnit.id()};
+
+ } catch (const std::exception &exception) {
+ qWarning() << "Error in SuspendDocumentJob::prepareAsyncRun:" << exception.what();
+ return AsyncPrepareResult();
+ }
+}
+
+void SuspendDocumentJob::finalizeAsyncRun()
+{
+ if (context().isDocumentOpen()) {
+ const bool suspendSucceeded = asyncResult();
+ if (QTC_GUARD(suspendSucceeded)) {
+ m_pinnedDocument.setIsSuspended(true);
+ }
+ }
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.h b/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.h
new file mode 100644
index 0000000000..16d5b52a1e
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "clangasyncjob.h"
+#include "clangdocument.h"
+
+namespace ClangBackEnd {
+
+class SuspendDocumentJob : public AsyncJob<bool>
+{
+public:
+ AsyncPrepareResult prepareAsyncRun() override;
+ void finalizeAsyncRun() override;
+
+private:
+ Document m_pinnedDocument;
+ FileContainer m_pinnedFileContainer;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp b/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp
index ca95c5f190..0bc0509a5e 100644
--- a/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp
+++ b/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp
@@ -25,6 +25,7 @@
#include "clangtranslationunit.h"
+#include "clangbackend_global.h"
#include "clangreferencescollector.h"
#include "clangtranslationunitupdater.h"
@@ -38,6 +39,8 @@
#include <sourcelocation.h>
#include <sourcerange.h>
+#include <utils/qtcassert.h>
+
namespace ClangBackEnd {
TranslationUnit::TranslationUnit(const Utf8String &id,
@@ -100,6 +103,16 @@ TranslationUnitUpdateResult TranslationUnit::reparse(
return updater.update(TranslationUnitUpdater::UpdateMode::ForceReparse);
}
+bool TranslationUnit::suspend() const
+{
+#ifdef IS_SUSPEND_SUPPORTED
+ return clang_suspendTranslationUnit(cxTranslationUnit());
+#else
+ QTC_CHECK(false && "clang_suspendTranslationUnit() not supported.");
+ return false;
+#endif
+}
+
TranslationUnit::CodeCompletionResult TranslationUnit::complete(
UnsavedFiles &unsavedFiles,
uint line,
diff --git a/src/tools/clangbackend/ipcsource/clangtranslationunit.h b/src/tools/clangbackend/ipcsource/clangtranslationunit.h
index 5e6d28736a..cc398e9a72 100644
--- a/src/tools/clangbackend/ipcsource/clangtranslationunit.h
+++ b/src/tools/clangbackend/ipcsource/clangtranslationunit.h
@@ -71,6 +71,8 @@ public:
CXIndex &cxIndex() const;
CXTranslationUnit &cxTranslationUnit() const;
+ bool suspend() const;
+
TranslationUnitUpdateResult update(const TranslationUnitUpdateInput &parseInput) const;
TranslationUnitUpdateResult parse(const TranslationUnitUpdateInput &parseInput) const;
TranslationUnitUpdateResult reparse(const TranslationUnitUpdateInput &parseInput) const;
diff --git a/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.cpp b/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.cpp
index fee622964d..b4b56fe534 100644
--- a/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.cpp
+++ b/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.cpp
@@ -56,8 +56,7 @@ static UpdateDocumentAnnotationsJob::AsyncResult runAsyncHelper(
IAsyncJob::AsyncPrepareResult UpdateDocumentAnnotationsJob::prepareAsyncRun()
{
const JobRequest jobRequest = context().jobRequest;
- QTC_ASSERT(jobRequest.type == JobRequest::Type::UpdateDocumentAnnotations,
- return AsyncPrepareResult());
+ QTC_ASSERT(isExpectedJobRequestType(jobRequest), return AsyncPrepareResult());
try {
m_pinnedDocument = context().documentForJobRequest();
@@ -65,7 +64,7 @@ IAsyncJob::AsyncPrepareResult UpdateDocumentAnnotationsJob::prepareAsyncRun()
const TranslationUnit translationUnit
= m_pinnedDocument.translationUnit(jobRequest.preferredTranslationUnit);
- const TranslationUnitUpdateInput updateInput = m_pinnedDocument.createUpdateInput();
+ const TranslationUnitUpdateInput updateInput = createUpdateInput(m_pinnedDocument);
setRunner([translationUnit, updateInput]() {
return runAsyncHelper(translationUnit, updateInput);
});
@@ -87,6 +86,17 @@ void UpdateDocumentAnnotationsJob::finalizeAsyncRun()
}
}
+bool UpdateDocumentAnnotationsJob::isExpectedJobRequestType(const JobRequest &jobRequest) const
+{
+ return jobRequest.type == JobRequest::Type::UpdateDocumentAnnotations;
+}
+
+TranslationUnitUpdateInput
+UpdateDocumentAnnotationsJob::createUpdateInput(const Document &document) const
+{
+ return document.createUpdateInput();
+}
+
void UpdateDocumentAnnotationsJob::incorporateUpdaterResult(const AsyncResult &result)
{
m_pinnedDocument.incorporateUpdaterResult(result.updateResult);
diff --git a/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.h b/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.h
index 00fe3be311..fdbe9068a6 100644
--- a/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.h
+++ b/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.h
@@ -53,12 +53,18 @@ public:
AsyncPrepareResult prepareAsyncRun() override;
void finalizeAsyncRun() override;
+protected:
+ virtual bool isExpectedJobRequestType(const JobRequest &jobRequest) const;
+ virtual TranslationUnitUpdateInput createUpdateInput(const Document &document) const;
+
private:
void incorporateUpdaterResult(const AsyncResult &result);
void sendAnnotations(const AsyncResult &result);
-private:
+protected:
Document m_pinnedDocument;
+
+private:
FileContainer m_pinnedFileContainer;
};
diff --git a/src/tools/clangbackend/ipcsource/highlightingmark.cpp b/src/tools/clangbackend/ipcsource/highlightingmark.cpp
index bc918326a7..510192b6e7 100644
--- a/src/tools/clangbackend/ipcsource/highlightingmark.cpp
+++ b/src/tools/clangbackend/ipcsource/highlightingmark.cpp
@@ -165,7 +165,8 @@ void HighlightingMark::overloadedDeclRefKind(const Cursor &cursor)
// Workaround https://bugs.llvm.org//show_bug.cgi?id=33256 - SomeType in
// "using N::SomeType" is mistakenly considered as a CXCursor_OverloadedDeclRef.
if (cursor.overloadedDeclarationsCount() >= 1
- && cursor.overloadedDeclaration(0).kind() != CXCursor_FunctionDecl) {
+ && cursor.overloadedDeclaration(0).kind() != CXCursor_FunctionDecl
+ && cursor.overloadedDeclaration(0).kind() != CXCursor_FunctionTemplate) {
m_types.mainHighlightingType = HighlightingType::Type;
}
}
diff --git a/src/tools/qml2puppet/qml2puppet.qbs b/src/tools/qml2puppet/qml2puppet.qbs
index feaa14bb6b..bb3d0726d3 100644
--- a/src/tools/qml2puppet/qml2puppet.qbs
+++ b/src/tools/qml2puppet/qml2puppet.qbs
@@ -20,7 +20,10 @@ QtcTool {
condition: qbs.targetOS.contains("unix") && !qbs.targetOS.contains("bsd")
cpp.dynamicLibraries: base.concat("rt")
}
- bundle.embedInfoPlist: true
+ Properties {
+ condition: qbs.targetOS.contains("darwin")
+ bundle.embedInfoPlist: true
+ }
property path puppetDir: "../../../share/qtcreator/qml/qmlpuppet"
cpp.includePaths: base.concat([
diff --git a/src/tools/qtcdebugger/main.cpp b/src/tools/qtcdebugger/main.cpp
index 6dee4d966f..574edc5954 100644
--- a/src/tools/qtcdebugger/main.cpp
+++ b/src/tools/qtcdebugger/main.cpp
@@ -102,6 +102,8 @@ static bool parseArguments(const QStringList &args, QString *errorMessage)
optIsWow = true;
} else if (arg == QLatin1String("nogui")) {
noguiMode = true;
+ } else if (arg == QLatin1String("p")) {
+ // Ignore, see QTCREATORBUG-18194.
} else {
*errorMessage = QString::fromLatin1("Unexpected option: %1").arg(arg);
return false;
@@ -282,8 +284,13 @@ bool startCreatorAsDebugger(bool asClient, QString *errorMessage)
// Send to running Creator: Unstable with directly linked CDB engine.
if (asClient)
args << QLatin1String("-client");
- args << QLatin1String("-wincrashevent")
- << QString::fromLatin1("%1:%2").arg(argWinCrashEvent).arg(argProcessId);
+ if (argWinCrashEvent != 0) {
+ args << QLatin1String("-wincrashevent")
+ << QString::fromLatin1("%1:%2").arg(argWinCrashEvent).arg(argProcessId);
+ } else {
+ args << QLatin1String("-debug")
+ << QString::fromLatin1("%1").arg(argProcessId);
+ }
if (debug)
qDebug() << binary << args;
QProcess p;
diff --git a/tests/auto/json/json.qbs b/tests/auto/json/json.qbs
index de9a22fcf2..3b0a36e141 100644
--- a/tests/auto/json/json.qbs
+++ b/tests/auto/json/json.qbs
@@ -5,7 +5,7 @@ QtcAutotest {
Depends { name: "bundle" }
Depends { name: "qtcjson" }
- bundle.isBundle: false
+ consoleApplication: true
Group {
name: "test data"
diff --git a/tests/helper/README.txt b/tests/helper/README.txt
new file mode 100644
index 0000000000..64b0f3b38d
--- /dev/null
+++ b/tests/helper/README.txt
@@ -0,0 +1,3 @@
+These files are needed by the Squish tests in tests/system. They should be
+replaced by a better solution but for the time being, do not edit, move or
+delete them without the consent of those maintaining the Squish tests.
diff --git a/tests/helper/qmlapplicationviewer/qmlapplicationviewer.cpp b/tests/helper/qmlapplicationviewer/qmlapplicationviewer.cpp
new file mode 100644
index 0000000000..0a87431867
--- /dev/null
+++ b/tests/helper/qmlapplicationviewer/qmlapplicationviewer.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlapplicationviewer.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtDeclarative/QDeclarativeComponent>
+#include <QtDeclarative/QDeclarativeEngine>
+#include <QtDeclarative/QDeclarativeContext>
+#include <QtGui/QApplication>
+
+#include <qplatformdefs.h> // MEEGO_EDITION_HARMATTAN
+
+#ifdef HARMATTAN_BOOSTER
+#include <MDeclarativeCache>
+#endif
+
+#if defined(QMLJSDEBUGGER) && QT_VERSION < 0x040800
+
+#include <qt_private/qdeclarativedebughelper_p.h>
+
+#if !defined(NO_JSDEBUGGER)
+#include <jsdebuggeragent.h>
+#endif
+#if !defined(NO_QMLOBSERVER)
+#include <qdeclarativeviewobserver.h>
+#endif
+
+// Enable debugging before any QDeclarativeEngine is created
+struct QmlJsDebuggingEnabler
+{
+ QmlJsDebuggingEnabler()
+ {
+ QDeclarativeDebugHelper::enableDebugging();
+ }
+};
+
+// Execute code in constructor before first QDeclarativeEngine is instantiated
+static QmlJsDebuggingEnabler enableDebuggingHelper;
+
+#endif // QMLJSDEBUGGER
+
+class QmlApplicationViewerPrivate
+{
+ QmlApplicationViewerPrivate(QDeclarativeView *view_) : view(view_) {}
+
+ QString mainQmlFile;
+ QDeclarativeView *view;
+ friend class QmlApplicationViewer;
+ QString adjustPath(const QString &path);
+};
+
+QString QmlApplicationViewerPrivate::adjustPath(const QString &path)
+{
+#ifdef Q_OS_MAC
+ if (!QDir::isAbsolutePath(path))
+ return QString::fromLatin1("%1/../Resources/%2")
+ .arg(QCoreApplication::applicationDirPath(), path);
+#else
+ const QString pathInInstallDir =
+ QString::fromLatin1("%1/../%2").arg(QCoreApplication::applicationDirPath(), path);
+ if (QFileInfo(pathInInstallDir).exists())
+ return pathInInstallDir;
+#endif
+ return path;
+}
+
+QmlApplicationViewer::QmlApplicationViewer(QWidget *parent)
+ : QDeclarativeView(parent)
+ , d(new QmlApplicationViewerPrivate(this))
+{
+ connect(engine(), SIGNAL(quit()), SLOT(close()));
+ setResizeMode(QDeclarativeView::SizeRootObjectToView);
+ // Qt versions prior to 4.8.0 don't have QML/JS debugging services built in
+#if defined(QMLJSDEBUGGER) && QT_VERSION < 0x040800
+#if !defined(NO_JSDEBUGGER)
+ new QmlJSDebugger::JSDebuggerAgent(d->view->engine());
+#endif
+#if !defined(NO_QMLOBSERVER)
+ new QmlJSDebugger::QDeclarativeViewObserver(d->view, d->view);
+#endif
+#endif
+}
+
+QmlApplicationViewer::QmlApplicationViewer(QDeclarativeView *view, QWidget *parent)
+ : QDeclarativeView(parent)
+ , d(new QmlApplicationViewerPrivate(view))
+{
+ connect(view->engine(), SIGNAL(quit()), view, SLOT(close()));
+ view->setResizeMode(QDeclarativeView::SizeRootObjectToView);
+ // Qt versions prior to 4.8.0 don't have QML/JS debugging services built in
+#if defined(QMLJSDEBUGGER) && QT_VERSION < 0x040800
+#if !defined(NO_JSDEBUGGER)
+ new QmlJSDebugger::JSDebuggerAgent(d->view->engine());
+#endif
+#if !defined(NO_QMLOBSERVER)
+ new QmlJSDebugger::QDeclarativeViewObserver(d->view, d->view);
+#endif
+#endif
+}
+
+QmlApplicationViewer::~QmlApplicationViewer()
+{
+ delete d;
+}
+
+QmlApplicationViewer *QmlApplicationViewer::create()
+{
+#ifdef HARMATTAN_BOOSTER
+ return new QmlApplicationViewer(MDeclarativeCache::qDeclarativeView(), 0);
+#else
+ return new QmlApplicationViewer();
+#endif
+}
+
+void QmlApplicationViewer::setMainQmlFile(const QString &file)
+{
+ d->mainQmlFile = d->adjustPath(file);
+ d->view->setSource(QUrl::fromLocalFile(d->mainQmlFile));
+}
+
+void QmlApplicationViewer::addImportPath(const QString &path)
+{
+ d->view->engine()->addImportPath(d->adjustPath(path));
+}
+
+void QmlApplicationViewer::setOrientation(ScreenOrientation orientation)
+{
+#if defined(Q_OS_SYMBIAN)
+ // If the version of Qt on the device is < 4.7.2, that attribute won't work
+ if (orientation != ScreenOrientationAuto) {
+ const QStringList v = QString::fromAscii(qVersion()).split(QLatin1Char('.'));
+ if (v.count() == 3 && (v.at(0).toInt() << 16 | v.at(1).toInt() << 8 | v.at(2).toInt()) < 0x040702) {
+ qWarning("Screen orientation locking only supported with Qt 4.7.2 and above");
+ return;
+ }
+ }
+#endif // Q_OS_SYMBIAN
+
+ Qt::WidgetAttribute attribute;
+ switch (orientation) {
+#if QT_VERSION < 0x040702
+ // Qt < 4.7.2 does not yet have the Qt::WA_*Orientation attributes
+ case ScreenOrientationLockPortrait:
+ attribute = static_cast<Qt::WidgetAttribute>(128);
+ break;
+ case ScreenOrientationLockLandscape:
+ attribute = static_cast<Qt::WidgetAttribute>(129);
+ break;
+ default:
+ case ScreenOrientationAuto:
+ attribute = static_cast<Qt::WidgetAttribute>(130);
+ break;
+#else // QT_VERSION < 0x040702
+ case ScreenOrientationLockPortrait:
+ attribute = Qt::WA_LockPortraitOrientation;
+ break;
+ case ScreenOrientationLockLandscape:
+ attribute = Qt::WA_LockLandscapeOrientation;
+ break;
+ default:
+ case ScreenOrientationAuto:
+ attribute = Qt::WA_AutoOrientation;
+ break;
+#endif // QT_VERSION < 0x040702
+ };
+ setAttribute(attribute, true);
+}
+
+void QmlApplicationViewer::showExpanded()
+{
+#if defined(Q_OS_SYMBIAN) || defined(MEEGO_EDITION_HARMATTAN) || defined(Q_WS_SIMULATOR)
+ d->view->showFullScreen();
+#elif defined(Q_WS_MAEMO_5)
+ d->view->showMaximized();
+#else
+ d->view->show();
+#endif
+}
+
+QApplication *createApplication(int &argc, char **argv)
+{
+#ifdef HARMATTAN_BOOSTER
+ return MDeclarativeCache::qApplication(argc, argv);
+#else
+ return new QApplication(argc, argv);
+#endif
+}
diff --git a/tests/helper/qmlapplicationviewer/qmlapplicationviewer.h b/tests/helper/qmlapplicationviewer/qmlapplicationviewer.h
new file mode 100644
index 0000000000..724c2ff529
--- /dev/null
+++ b/tests/helper/qmlapplicationviewer/qmlapplicationviewer.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLAPPLICATIONVIEWER_H
+#define QMLAPPLICATIONVIEWER_H
+
+#include <QtDeclarative/QDeclarativeView>
+
+class QmlApplicationViewer : public QDeclarativeView
+{
+ Q_OBJECT
+
+public:
+ enum ScreenOrientation {
+ ScreenOrientationLockPortrait,
+ ScreenOrientationLockLandscape,
+ ScreenOrientationAuto
+ };
+
+ explicit QmlApplicationViewer(QWidget *parent = 0);
+ virtual ~QmlApplicationViewer();
+
+ static QmlApplicationViewer *create();
+
+ void setMainQmlFile(const QString &file);
+ void addImportPath(const QString &path);
+
+ // Note that this will only have an effect on Symbian and Fremantle.
+ void setOrientation(ScreenOrientation orientation);
+
+ void showExpanded();
+
+private:
+ explicit QmlApplicationViewer(QDeclarativeView *view, QWidget *parent);
+ class QmlApplicationViewerPrivate *d;
+};
+
+QApplication *createApplication(int &argc, char **argv);
+
+#endif // QMLAPPLICATIONVIEWER_H
diff --git a/tests/helper/qmlapplicationviewer/qmlapplicationviewer.pri b/tests/helper/qmlapplicationviewer/qmlapplicationviewer.pri
new file mode 100644
index 0000000000..6809b64463
--- /dev/null
+++ b/tests/helper/qmlapplicationviewer/qmlapplicationviewer.pri
@@ -0,0 +1,156 @@
+# This file was generated by the Qt Quick Application wizard of Qt Creator.
+# The code below adds the QmlApplicationViewer to the project and handles the
+# activation of QML debugging.
+# It is recommended not to modify this file, since newer versions of Qt Creator
+# may offer an updated version of it.
+
+QT += declarative
+
+SOURCES += $$PWD/qmlapplicationviewer.cpp
+HEADERS += $$PWD/qmlapplicationviewer.h
+INCLUDEPATH += $$PWD
+
+# Include JS debugger library if QMLJSDEBUGGER_PATH is set
+!isEmpty(QMLJSDEBUGGER_PATH) {
+ include($$QMLJSDEBUGGER_PATH/qmljsdebugger-lib.pri)
+} else {
+ DEFINES -= QMLJSDEBUGGER
+}
+
+contains(CONFIG,qdeclarative-boostable):contains(MEEGO_EDITION,harmattan) {
+ DEFINES += HARMATTAN_BOOSTER
+}
+# This file was generated by an application wizard of Qt Creator.
+# The code below handles deployment to Symbian and Maemo, aswell as copying
+# of the application data to shadow build directories on desktop.
+# It is recommended not to modify this file, since newer versions of Qt Creator
+# may offer an updated version of it.
+
+defineTest(qtcAddDeployment) {
+for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemsources = $${item}.sources
+ $$itemsources = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath= $$eval($${deploymentfolder}.target)
+ export($$itemsources)
+ export($$itempath)
+ DEPLOYMENT += $$item
+}
+
+MAINPROFILEPWD = $$_PRO_FILE_PWD_
+
+symbian {
+ isEmpty(ICON):exists($${TARGET}.svg):ICON = $${TARGET}.svg
+ isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x20000 0x2000000
+} else:win32 {
+ copyCommand =
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+ source = $$replace(source, /, \\)
+ sourcePathSegments = $$split(source, \\)
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments)
+ target = $$replace(target, /, \\)
+ target ~= s,\\\\\\.?\\\\,\\,
+ !isEqual(source,$$target) {
+ !isEmpty(copyCommand):copyCommand += &&
+ isEqual(QMAKE_DIR_SEP, \\) {
+ copyCommand += $(COPY_DIR) \"$$source\" \"$$target\"
+ } else {
+ source = $$replace(source, \\\\, /)
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
+ target = $$replace(target, \\\\, /)
+ copyCommand += test -d \"$$target\" || mkdir -p \"$$target\" && cp -r \"$$source\" \"$$target\"
+ }
+ }
+ }
+ !isEmpty(copyCommand) {
+ copyCommand = @echo Copying application data... && $$copyCommand
+ copydeploymentfolders.commands = $$copyCommand
+ first.depends = $(first) copydeploymentfolders
+ export(first.depends)
+ export(copydeploymentfolders.commands)
+ QMAKE_EXTRA_TARGETS += first copydeploymentfolders
+ }
+} else:unix {
+ maemo5 {
+ installPrefix = /opt/$${TARGET}
+ target.path = $${installPrefix}/bin
+ desktopfile.files = $${TARGET}.desktop
+ desktopfile.path = /usr/share/applications/hildon
+ icon.files = $${TARGET}64.png
+ icon.path = /usr/share/icons/hicolor/64x64/apps
+ } else:!isEmpty(MEEGO_VERSION_MAJOR) {
+ installPrefix = /opt/$${TARGET}
+ target.path = $${installPrefix}/bin
+ desktopfile.files = $${TARGET}_harmattan.desktop
+ desktopfile.path = /usr/share/applications
+ icon.files = $${TARGET}80.png
+ icon.path = /usr/share/icons/hicolor/80x80/apps
+ } else { # Assumed to be a Desktop Unix
+ installPrefix = $$desktopInstallPrefix
+ target.path = $${installPrefix}
+ sources.files = *.cpp *.h *.desktop *.png *.pro *.qml *.qmlproject *.svg
+ sources.path = $$desktopInstallPrefix
+ export(sources.files)
+ export(sources.path)
+ INSTALLS += sources
+ copyCommand =
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+ source = $$replace(source, \\\\, /)
+ macx {
+ target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target)
+ } else {
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
+ }
+ target = $$replace(target, \\\\, /)
+ sourcePathSegments = $$split(source, /)
+ targetFullPath = $$target/$$last(sourcePathSegments)
+ targetFullPath ~= s,/\\.?/,/,
+ !isEqual(source,$$targetFullPath) {
+ !isEmpty(copyCommand):copyCommand += &&
+ copyCommand += $(MKDIR) \"$$target\"
+ copyCommand += && $(COPY_DIR) \"$$source\" \"$$target\"
+ }
+ }
+ !isEmpty(copyCommand) {
+ copyCommand = @echo Copying application data... && $$copyCommand
+ copydeploymentfolders.commands = $$copyCommand
+ first.depends = $(first) copydeploymentfolders
+ export(first.depends)
+ export(copydeploymentfolders.commands)
+ QMAKE_EXTRA_TARGETS += first copydeploymentfolders
+ }
+ }
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ !isEmpty(desktopfile.path) {
+ export(icon.files)
+ export(icon.path)
+ export(desktopfile.files)
+ export(desktopfile.path)
+ INSTALLS += icon desktopfile
+ }
+
+ export(target.path)
+ INSTALLS += target
+}
+
+export (ICON)
+export (INSTALLS)
+export (DEPLOYMENT)
+export (TARGET.EPOCHEAPSIZE)
+export (TARGET.CAPABILITY)
+export (LIBS)
+export (QMAKE_EXTRA_TARGETS)
+}
diff --git a/tests/manual/debugger/python/README.md b/tests/manual/debugger/python/README.md
new file mode 100644
index 0000000000..0ed136ee40
--- /dev/null
+++ b/tests/manual/debugger/python/README.md
@@ -0,0 +1,4 @@
+
+- qtcreator -load PythonEditor ./python.pyqtc
+- Switch active runconfiguration to main.py
+- <F10>
diff --git a/tests/manual/debugger/python/math.py b/tests/manual/debugger/python/math.py
index 0bd111e386..3a1dd06891 100644
--- a/tests/manual/debugger/python/math.py
+++ b/tests/manual/debugger/python/math.py
@@ -1,6 +1,6 @@
import sys
-from PyQt4 import QtGui
+#from PyQt4 import QtGui
diff --git a/tests/manual/debugger/python/python.pyqtc b/tests/manual/debugger/python/python.pyqtc
new file mode 100644
index 0000000000..08389c2a46
--- /dev/null
+++ b/tests/manual/debugger/python/python.pyqtc
@@ -0,0 +1 @@
+math.py
diff --git a/tests/system/README b/tests/system/README
index 0e4526d183..6a62bb8d05 100644
--- a/tests/system/README
+++ b/tests/system/README
@@ -4,17 +4,54 @@ Squish tests inside this folder have several prerequisites to get them running.
First - and most important - you have to own a valid Squish license. Currently it's recommended to use Squish 6.0.
-Second - some of the test suites/test cases expect an installed Qt 4 SDK in its default location.
-On Linux/Mac this is ~/QtSDK, and on Windows this is C:\QtSDK.
-After installing the QtSDK you should use the package manager of the QtSDK (SDKMaintenanceTool) to add some more packages.
-You'll need at least Desktop Qt versions 4.7.4, 4.8.0, Harmattan stuff (except QEmu), Maemo Toolchain, Qt Examples, Simulator, Documentation files.
+Second - some of the test suites/test cases expect a build of Qt 4.8.7 to be available:
+ 1. Download the source code from:
+ * Windows: http://download.qt.io/official_releases/qt/4.8/4.8.7/qt-everywhere-opensource-src-4.8.7.zip
+ * Other: http://download.qt.io/official_releases/qt/4.8/4.8.7/qt-everywhere-opensource-src-4.8.7.tar.gz
+ 2. Extract the contents of the archive's directory qt-everywhere-opensource-src-4.8.7 to:
+ * Windows: C:\Qt\Qt4.8.7
+ * Other: $HOME/Qt4.8.7
+ 3. Apply the changes from patch.txt next to this README.
+ 4. In the directory you extracted the sources to, configure Qt:
+ * Windows (MSVC2013 32 bit):
+ .\configure.exe -opensource -developer-build -confirm-license -debug-and-release -nomake tests -nomake examples -nomake demos -no-webkit -no-phonon
+ * Linux (gcc < 6):
+ ./configure -opensource -developer-build -confirm-license -debug-and-release -nomake tests -nomake examples -nomake demos -no-webkit -no-phonon
+ * macOS:
+ ./configure -opensource -developer-build -confirm-license -debug-and-release -nomake tests -nomake examples -nomake demos -no-webkit -no-phonon -sdk <PATH_TO_INSTALLED_MACOSX_SDK>
+ 5. Make:
+ * Windows (do not use jom):
+ nmake
+ * Other:
+ make -j<number of available cores>
Third - some of the test suites/test cases expect Qt 5.3.1 (default toolchain), Qt 5.4.1 (gcc, Linux and Windows only) and Qt 5.6.1-1 (default toolchain)
installed in their default locations. On Linux/Mac this is ~/Qt5.x.1 and on Windows this is C:\Qt\Qt5.x.1. The default toolchains are gcc on Linux,
clang on Mac and MSVC2010 (Qt <= 5.5) or MSVC2013 (Qt > 5.5) on Windows. It's easiest to use default installations of the official opensource Qt packages.
+On macOS it might be necessary to tweak some files of the Qt installation - depending on the installed Xcode and its installed SDKs.
+If Xcode 8+ is installed you will need to update the file
+~/Qt5.3.1/5.3/clang_64/mkspecs/features/mac/default_pre.prf
+Change the line
+
+ isEmpty($$list($$system("/usr/bin/xcrun -find xcrun 2>/dev/null")))
+
+to
+
+ isEmpty($$list($$system("/usr/bin/xcrun -find xcodebuild 2>/dev/null")))
+
+Furthermore - depending on the installed SDK it might be necessary to update the file
+~/Qt5.3.1/5.3/clang_64/mkspecs/qdevice.pri
+Search for the following line
+
+ !host_build:QMAKE_MAC_SDK = macosx10.8
+
+Newer Xcode might miss the 10.8 SDK. Check
+/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
+which SDKs are installed and update the version number accordingly.
+
Fourth - you'll have to provide some additional repositories (and for the hooking into subprocesses even some more Squish bundles, see below).
-These additional repositories are located inside ~/QtSDK/src or C:\QtSDK\src (depending on the OS you're on).
+These additional repositories are located inside ~/squish-data or C:\Users\<user>\squish-data (depending on the OS you're on).
You can also just provide them inside a different folder and specify the folder with the environment variable SYSTEST_SRCPATH.
This folder must contain the following:
* a QtCreator repository (or source copy) of tag v4.2.2 named 'creator' including the submodule src/shared/qbs
@@ -30,6 +67,10 @@ Normally it should be okay to just install them as usual and add their executabl
Sixth - Qt Creator should be built with ClangCodeModel plugin. How to do so, see QTCREATOR_REPO/src/plugins/clangcodemodel/README. Without the
plugin, the tests for ClangCodeModel will be skipped but will not cause failures.
+On macOS make sure you are using the correct keyboard layout to avoid problems when using keyboard interaction. Tested and known to be
+working would be 'U.S. International - PC', while pure 'U.S.' had problems.
+Use the settings in System Preferences > Keyboard > Input Sources to install missing keyboard layouts and ensure you have set it as default.
+
Attention! If any of these prerequisites cannot be satisfied the tests will likely fail (or not run at all).
diff --git a/tests/system/patch.txt b/tests/system/patch.txt
new file mode 100644
index 0000000000..f541f32780
--- /dev/null
+++ b/tests/system/patch.txt
@@ -0,0 +1,17 @@
+--- src/gui/painting/qpaintengine_mac.cpp
++++ src/gui/painting/qpaintengine_mac.cpp
+@@ -340,13 +340,7 @@
+ }
+
+ // Get the color space from the display profile.
+- CGColorSpaceRef colorSpace = 0;
+- CMProfileRef displayProfile = 0;
+- CMError err = CMGetProfileByAVID((CMDisplayIDType)displayID, &displayProfile);
+- if (err == noErr) {
+- colorSpace = CGColorSpaceCreateWithPlatformColorSpace(displayProfile);
+- CMCloseProfile(displayProfile);
+- }
++ CGColorSpaceRef colorSpace = CGDisplayCopyColorSpace(displayID);
+
+ // Fallback: use generic DeviceRGB
+ if (colorSpace == 0)
diff --git a/tests/system/settings/mac/QtProject/qtcreator/profiles.xml b/tests/system/settings/mac/QtProject/qtcreator/profiles.xml
index 002250ea9f..3df47f6a77 100644
--- a/tests/system/settings/mac/QtProject/qtcreator/profiles.xml
+++ b/tests/system/settings/mac/QtProject/qtcreator/profiles.xml
@@ -8,31 +8,6 @@
<value type="bool" key="PE.Profile.AutoDetected">false</value>
<valuemap type="QVariantMap" key="PE.Profile.Data">
<value type="QString" key="Android.GdbServer.Information"></value>
- <value type="QString" key="Debugger.Information">{2f514661-b9f7-4f83-8822-a9a9d0699600}</value>
- <value type="QString" key="PE.Profile.Device">Desktop Device</value>
- <value type="QByteArray" key="PE.Profile.DeviceType">Desktop</value>
- <value type="QString" key="PE.Profile.SysRoot"></value>
- <value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Gcc:{c3f59b87-6997-4bd8-8067-ee04dc536371}</value>
- <valuemap type="QVariantMap" key="PE.Profile.ToolChains">
- <value type="QByteArray" key="C">{461bb8dc-22ff-461f-82fe-ebe8b21b697f}</value>
- <value type="QString" key="Cxx">ProjectExplorer.ToolChain.Gcc:{c3f59b87-6997-4bd8-8067-ee04dc536371}</value>
- </valuemap>
- <value type="QString" key="QtPM4.mkSpecInformation"></value>
- <value type="int" key="QtSupport.QtInformation">4</value>
- </valuemap>
- <value type="QString" key="PE.Profile.Icon">:///DESKTOP///</value>
- <value type="QString" key="PE.Profile.Id">{4d9ea3ed-a7f0-4b0e-885f-da3b82931988}</value>
- <valuelist type="QVariantList" key="PE.Profile.MutableInfo"/>
- <value type="QString" key="PE.Profile.Name">Desktop 474 GCC</value>
- <value type="bool" key="PE.Profile.SDK">false</value>
- </valuemap>
- </data>
- <data>
- <variable>Profile.1</variable>
- <valuemap type="QVariantMap">
- <value type="bool" key="PE.Profile.AutoDetected">false</value>
- <valuemap type="QVariantMap" key="PE.Profile.Data">
- <value type="QString" key="Android.GdbServer.Information"></value>
<value type="QString" key="Debugger.Information">{70e26273-2c0b-4534-bbc0-eb6ca670821a}</value>
<value type="QString" key="PE.Profile.Device">{7c5a3673-e300-4286-9666-0f86d3e3dc38}</value>
<value type="QByteArray" key="PE.Profile.DeviceType">GenericLinuxOsType</value>
@@ -53,7 +28,7 @@
</valuemap>
</data>
<data>
- <variable>Profile.2</variable>
+ <variable>Profile.1</variable>
<valuemap type="QVariantMap">
<value type="bool" key="PE.Profile.AutoDetected">false</value>
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
@@ -80,7 +55,7 @@
</valuemap>
</data>
<data>
- <variable>Profile.3</variable>
+ <variable>Profile.2</variable>
<valuemap type="QVariantMap">
<value type="bool" key="PE.Profile.AutoDetected">false</value>
<valuemap type="QVariantMap" key="PE.Profile.Data">
@@ -100,12 +75,12 @@
<value type="QString" key="PE.Profile.Icon">:///DESKTOP///</value>
<value type="QString" key="PE.Profile.Id">{1dcb5509-1670-470d-80a5-8a988f36e4e2}</value>
<valuelist type="QVariantList" key="PE.Profile.MutableInfo"/>
- <value type="QString" key="PE.Profile.Name">Desktop 480 GCC</value>
+ <value type="QString" key="PE.Profile.Name">Desktop 487 default</value>
<value type="bool" key="PE.Profile.SDK">false</value>
</valuemap>
</data>
<data>
- <variable>Profile.4</variable>
+ <variable>Profile.3</variable>
<valuemap type="QVariantMap">
<value type="bool" key="PE.Profile.AutoDetected">false</value>
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
@@ -133,7 +108,7 @@
</data>
<data>
<variable>Profile.Count</variable>
- <value type="int">5</value>
+ <value type="int">4</value>
</data>
<data>
<variable>Profile.Default</variable>
diff --git a/tests/system/settings/mac/QtProject/qtcreator/qtversion.xml b/tests/system/settings/mac/QtProject/qtcreator/qtversion.xml
index ff94b4aa3b..77b68271ab 100644
--- a/tests/system/settings/mac/QtProject/qtcreator/qtversion.xml
+++ b/tests/system/settings/mac/QtProject/qtcreator/qtversion.xml
@@ -6,8 +6,8 @@
<variable>QtVersion.0</variable>
<valuemap type="QVariantMap">
<value type="int" key="Id">2</value>
- <value type="QString" key="Name">Desktop Qt 4.8 for GCC (Qt SDK)</value>
- <value type="QString" key="QMakePath">~/QtSDK/Desktop/Qt/4.8.0/gcc/bin/qmake</value>
+ <value type="QString" key="Name">Desktop Qt 4.8 for GCC</value>
+ <value type="QString" key="QMakePath">~/Qt4.8.7/bin/qmake</value>
<value type="QString" key="QtVersion.Type">Qt4ProjectManager.QtVersion.Desktop</value>
<value type="bool" key="isAutodetected">false</value>
</valuemap>
@@ -15,16 +15,6 @@
<data>
<variable>QtVersion.1</variable>
<valuemap type="QVariantMap">
- <value type="int" key="Id">4</value>
- <value type="QString" key="Name">Desktop Qt 4.7.4 for GCC (Qt SDK)</value>
- <value type="QString" key="QMakePath">~/QtSDK/Desktop/Qt/474/gcc/bin/qmake</value>
- <value type="QString" key="QtVersion.Type">Qt4ProjectManager.QtVersion.Desktop</value>
- <value type="bool" key="isAutodetected">false</value>
- </valuemap>
- </data>
- <data>
- <variable>QtVersion.2</variable>
- <valuemap type="QVariantMap">
<value type="int" key="Id">9</value>
<value type="QString" key="Name">Desktop Qt 5.6.1 (SQUISH_DEFAULT_COMPILER)</value>
<value type="QString" key="QMakePath">~/Qt5.6.1/5.6/SQUISH_DEFAULT_COMPILER/bin/qmake</value>
@@ -33,7 +23,7 @@
</valuemap>
</data>
<data>
- <variable>QtVersion.3</variable>
+ <variable>QtVersion.2</variable>
<valuemap type="QVariantMap">
<value type="int" key="Id">11</value>
<value type="QString" key="Name">Desktop Qt 5.3.1 (SQUISH_DEFAULT_COMPILER)</value>
diff --git a/tests/system/settings/unix/QtProject/qtcreator/profiles.xml b/tests/system/settings/unix/QtProject/qtcreator/profiles.xml
index 6914de5443..265a81a89b 100644
--- a/tests/system/settings/unix/QtProject/qtcreator/profiles.xml
+++ b/tests/system/settings/unix/QtProject/qtcreator/profiles.xml
@@ -9,27 +9,6 @@
<valuemap type="QVariantMap" key="PE.Profile.Data">
<value type="QString" key="Android.GdbServer.Information"></value>
<value type="QString" key="Debugger.Information">{70e26273-2c0b-4534-bbc0-eb6ca670821a}</value>
- <value type="QString" key="PE.Profile.Device">Desktop Device</value>
- <value type="QByteArray" key="PE.Profile.DeviceType">Desktop</value>
- <value type="QString" key="PE.Profile.SysRoot"></value>
- <value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Gcc:{c3f59b87-6997-4bd8-8067-ee04dc536371}</value>
- <value type="QString" key="QtPM4.mkSpecInformation"></value>
- <value type="int" key="QtSupport.QtInformation">4</value>
- </valuemap>
- <value type="QString" key="PE.Profile.Icon">:///DESKTOP///</value>
- <value type="QString" key="PE.Profile.Id">{4d9ea3ed-a7f0-4b0e-885f-da3b82931988}</value>
- <valuelist type="QVariantList" key="PE.Profile.MutableInfo"/>
- <value type="QString" key="PE.Profile.Name">Desktop 474 GCC</value>
- <value type="bool" key="PE.Profile.SDK">false</value>
- </valuemap>
- </data>
- <data>
- <variable>Profile.1</variable>
- <valuemap type="QVariantMap">
- <value type="bool" key="PE.Profile.AutoDetected">false</value>
- <valuemap type="QVariantMap" key="PE.Profile.Data">
- <value type="QString" key="Android.GdbServer.Information"></value>
- <value type="QString" key="Debugger.Information">{70e26273-2c0b-4534-bbc0-eb6ca670821a}</value>
<value type="QString" key="PE.Profile.Device">{7c5a3673-e300-4286-9666-0f86d3e3dc38}</value>
<value type="QByteArray" key="PE.Profile.DeviceType">GenericLinuxOsType</value>
<value type="QString" key="PE.Profile.SysRoot"></value>
@@ -39,7 +18,7 @@
<value type="QString" key="Cxx">ProjectExplorer.ToolChain.Gcc:{c3f59b87-6997-4bd8-8067-ee04dc536371}</value>
</valuemap>
<value type="QString" key="QtPM4.mkSpecInformation"></value>
- <value type="int" key="QtSupport.QtInformation">4</value>
+ <value type="int" key="QtSupport.QtInformation">2</value>
</valuemap>
<value type="QString" key="PE.Profile.Icon">:///DESKTOP///</value>
<value type="QString" key="PE.Profile.Id">{f16848fc-b615-43b5-b0cc-16a9f57fb573}</value>
@@ -49,7 +28,7 @@
</valuemap>
</data>
<data>
- <variable>Profile.2</variable>
+ <variable>Profile.1</variable>
<valuemap type="QVariantMap">
<value type="bool" key="PE.Profile.AutoDetected">false</value>
<valuemap type="QVariantMap" key="PE.Profile.Data">
@@ -65,12 +44,12 @@
<value type="QString" key="PE.Profile.Icon">:///DESKTOP///</value>
<value type="QString" key="PE.Profile.Id">{1dcb5509-1670-470d-80a5-8a988f36e4e2}</value>
<valuelist type="QVariantList" key="PE.Profile.MutableInfo"/>
- <value type="QString" key="PE.Profile.Name">Desktop 480 GCC</value>
+ <value type="QString" key="PE.Profile.Name">Desktop 487 default</value>
<value type="bool" key="PE.Profile.SDK">false</value>
</valuemap>
</data>
<data>
- <variable>Profile.3</variable>
+ <variable>Profile.2</variable>
<valuemap type="QVariantMap">
<value type="bool" key="PE.Profile.AutoDetected">false</value>
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
@@ -93,7 +72,7 @@
</valuemap>
</data>
<data>
- <variable>Profile.4</variable>
+ <variable>Profile.3</variable>
<valuemap type="QVariantMap">
<value type="bool" key="PE.Profile.AutoDetected">false</value>
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
@@ -117,7 +96,7 @@
</valuemap>
</data>
<data>
- <variable>Profile.5</variable>
+ <variable>Profile.4</variable>
<valuemap type="QVariantMap">
<value type="bool" key="PE.Profile.AutoDetected">false</value>
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
@@ -142,7 +121,7 @@
</data>
<data>
<variable>Profile.Count</variable>
- <value type="int">6</value>
+ <value type="int">5</value>
</data>
<data>
<variable>Profile.Default</variable>
diff --git a/tests/system/settings/unix/QtProject/qtcreator/qtversion.xml b/tests/system/settings/unix/QtProject/qtcreator/qtversion.xml
index 96f21e9f84..b6463a4f6e 100644
--- a/tests/system/settings/unix/QtProject/qtcreator/qtversion.xml
+++ b/tests/system/settings/unix/QtProject/qtcreator/qtversion.xml
@@ -6,8 +6,8 @@
<variable>QtVersion.0</variable>
<valuemap type="QVariantMap">
<value type="int" key="Id">2</value>
- <value type="QString" key="Name">Desktop Qt 4.8 for GCC (Qt SDK)</value>
- <value type="QString" key="QMakePath">~/QtSDK/Desktop/Qt/4.8.0/gcc/bin/qmake</value>
+ <value type="QString" key="Name">Desktop Qt 4.8 for GCC</value>
+ <value type="QString" key="QMakePath">~/Qt4.8.7/bin/qmake</value>
<value type="QString" key="QtVersion.Type">Qt4ProjectManager.QtVersion.Desktop</value>
<value type="bool" key="isAutodetected">false</value>
</valuemap>
@@ -15,16 +15,6 @@
<data>
<variable>QtVersion.1</variable>
<valuemap type="QVariantMap">
- <value type="int" key="Id">4</value>
- <value type="QString" key="Name">Desktop Qt 4.7.4 for GCC (Qt SDK)</value>
- <value type="QString" key="QMakePath">~/QtSDK/Desktop/Qt/474/gcc/bin/qmake</value>
- <value type="QString" key="QtVersion.Type">Qt4ProjectManager.QtVersion.Desktop</value>
- <value type="bool" key="isAutodetected">false</value>
- </valuemap>
- </data>
- <data>
- <variable>QtVersion.2</variable>
- <valuemap type="QVariantMap">
<value type="int" key="Id">11</value>
<value type="QString" key="Name">Qt 5.3.1 (SQUISH_DEFAULT_COMPILER)</value>
<value type="QString" key="QMakePath">~/Qt5.3.1/5.3/SQUISH_DEFAULT_COMPILER/bin/qmake</value>
@@ -33,7 +23,7 @@
</valuemap>
</data>
<data>
- <variable>QtVersion.3</variable>
+ <variable>QtVersion.2</variable>
<valuemap type="QVariantMap">
<value type="int" key="Id">13</value>
<value type="QString" key="Name">Qt %{Qt:Version} (SQUISH_DEFAULT_COMPILER)</value>
@@ -43,7 +33,7 @@
</valuemap>
</data>
<data>
- <variable>QtVersion.4</variable>
+ <variable>QtVersion.3</variable>
<valuemap type="QVariantMap">
<value type="int" key="Id">15</value>
<value type="QString" key="Name">Qt %{Qt:Version} (SQUISH_DEFAULT_COMPILER)</value>
diff --git a/tests/system/settings/windows/QtProject/qtcreator/profiles.xml b/tests/system/settings/windows/QtProject/qtcreator/profiles.xml
index b88210ec3e..8baf4c029a 100644
--- a/tests/system/settings/windows/QtProject/qtcreator/profiles.xml
+++ b/tests/system/settings/windows/QtProject/qtcreator/profiles.xml
@@ -9,43 +9,15 @@
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
<valuemap type="QVariantMap" key="PE.Profile.Data">
<value type="QString" key="Android.GdbServer.Information"></value>
- <value type="QString" key="Debugger.Information">{2f8a1f59-ddd7-49f0-ae61-1337223f56a3}</value>
- <value type="QString" key="PE.Profile.Device">Desktop Device</value>
- <value type="QByteArray" key="PE.Profile.DeviceType">Desktop</value>
- <valuelist type="QVariantList" key="PE.Profile.Environment"/>
- <value type="QString" key="PE.Profile.SysRoot"></value>
- <value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Mingw:{2729dd3e-84f5-42e1-aed1-6a27163346ce}</value>
- <valuemap type="QVariantMap" key="PE.Profile.ToolChains">
- <value type="QByteArray" key="C">{41d0a157-7cf1-4c83-bab8-d77b3f136b85}</value>
- <value type="QString" key="Cxx">ProjectExplorer.ToolChain.Mingw:{2729dd3e-84f5-42e1-aed1-6a27163346ce}</value>
- </valuemap>
- <value type="QString" key="QtPM4.mkSpecInformation"></value>
- <value type="int" key="QtSupport.QtInformation">8</value>
- </valuemap>
- <value type="QString" key="PE.Profile.Icon">:///DESKTOP///</value>
- <value type="QString" key="PE.Profile.Id">{897290fe-c35a-4e5e-b5e2-d8e448e2aed1}</value>
- <valuelist type="QVariantList" key="PE.Profile.MutableInfo"/>
- <value type="QString" key="PE.Profile.Name">Desktop 474 GCC</value>
- <value type="bool" key="PE.Profile.SDK">false</value>
- <valuelist type="QVariantList" key="PE.Profile.StickyInfo"/>
- </valuemap>
- </data>
- <data>
- <variable>Profile.1</variable>
- <valuemap type="QVariantMap">
- <value type="bool" key="PE.Profile.AutoDetected">false</value>
- <value type="QString" key="PE.Profile.AutoDetectionSource"></value>
- <valuemap type="QVariantMap" key="PE.Profile.Data">
- <value type="QString" key="Android.GdbServer.Information"></value>
<value type="QString" key="Debugger.Information">{1b25f20a-d584-4fb7-85b3-74dd15b82f6f}</value>
<value type="QString" key="PE.Profile.Device">Desktop Device</value>
<value type="QByteArray" key="PE.Profile.DeviceType">Desktop</value>
<valuelist type="QVariantList" key="PE.Profile.Environment"/>
<value type="QString" key="PE.Profile.SysRoot"></value>
- <value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Msvc:{1186dad9-c485-4f69-b7e1-aff54c89ecb2}</value>
+ <value type="QString" key="PE.Profile.ToolChain">{7ca0887f-a9a5-4251-aba6-560a15595d20}</value>
<valuemap type="QVariantMap" key="PE.Profile.ToolChains">
- <value type="QByteArray" key="C">{93e707bd-236f-4d8d-917d-814aa358024b}</value>
- <value type="QString" key="Cxx">ProjectExplorer.ToolChain.Msvc:{1186dad9-c485-4f69-b7e1-aff54c89ecb2}</value>
+ <value type="QByteArray" key="C">{d35e7a1a-5ab8-4fd6-8a2c-634846c669bb}</value>
+ <value type="QString" key="Cxx">{7ca0887f-a9a5-4251-aba6-560a15595d20}</value>
</valuemap>
<value type="QString" key="QtPM4.mkSpecInformation"></value>
<value type="int" key="QtSupport.QtInformation">2</value>
@@ -53,13 +25,13 @@
<value type="QString" key="PE.Profile.Icon">:///DESKTOP///</value>
<value type="QString" key="PE.Profile.Id">{9b35bbe6-25a7-4cce-ba07-487c795f5265}</value>
<valuelist type="QVariantList" key="PE.Profile.MutableInfo"/>
- <value type="QString" key="PE.Profile.Name">Desktop 480 MSVC2010</value>
+ <value type="QString" key="PE.Profile.Name">Desktop 487 default</value>
<value type="bool" key="PE.Profile.SDK">false</value>
<valuelist type="QVariantList" key="PE.Profile.StickyInfo"/>
</valuemap>
</data>
<data>
- <variable>Profile.2</variable>
+ <variable>Profile.1</variable>
<valuemap type="QVariantMap">
<value type="bool" key="PE.Profile.AutoDetected">false</value>
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
@@ -87,7 +59,7 @@
</valuemap>
</data>
<data>
- <variable>Profile.3</variable>
+ <variable>Profile.2</variable>
<valuemap type="QVariantMap">
<value type="bool" key="PE.Profile.AutoDetected">false</value>
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
@@ -115,7 +87,7 @@
</valuemap>
</data>
<data>
- <variable>Profile.4</variable>
+ <variable>Profile.3</variable>
<valuemap type="QVariantMap">
<value type="bool" key="PE.Profile.AutoDetected">false</value>
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
@@ -144,7 +116,7 @@
</data>
<data>
<variable>Profile.Count</variable>
- <value type="int">5</value>
+ <value type="int">4</value>
</data>
<data>
<variable>Profile.Default</variable>
diff --git a/tests/system/settings/windows/QtProject/qtcreator/qtversion.xml b/tests/system/settings/windows/QtProject/qtcreator/qtversion.xml
index 73d1c52694..713c9acea6 100644
--- a/tests/system/settings/windows/QtProject/qtcreator/qtversion.xml
+++ b/tests/system/settings/windows/QtProject/qtcreator/qtversion.xml
@@ -6,8 +6,8 @@
<variable>QtVersion.0</variable>
<valuemap type="QVariantMap">
<value type="int" key="Id">2</value>
- <value type="QString" key="Name">Qt 4.8 for Desktop - MSVC2010 (Qt SDK)</value>
- <value type="QString" key="QMakePath">C:/QtSDK/Desktop/Qt/4.8.0/msvc2010/bin/qmake.exe</value>
+ <value type="QString" key="Name">Qt 4.8 for Desktop - MSVC2013</value>
+ <value type="QString" key="QMakePath">C:/Qt/Qt4.8.7/bin/qmake.exe</value>
<value type="QString" key="QtVersion.Type">Qt4ProjectManager.QtVersion.Desktop</value>
<value type="bool" key="isAutodetected">false</value>
</valuemap>
@@ -15,16 +15,6 @@
<data>
<variable>QtVersion.1</variable>
<valuemap type="QVariantMap">
- <value type="int" key="Id">8</value>
- <value type="QString" key="Name">Qt 4.7.4 for Desktop - MinGW 4.4 (Qt SDK)</value>
- <value type="QString" key="QMakePath">c:/qtsdk/desktop/qt/4.7.4/mingw/bin/qmake.exe</value>
- <value type="QString" key="QtVersion.Type">Qt4ProjectManager.QtVersion.Desktop</value>
- <value type="bool" key="isAutodetected">false</value>
- </valuemap>
- </data>
- <data>
- <variable>QtVersion.2</variable>
- <valuemap type="QVariantMap">
<value type="int" key="Id">20</value>
<value type="QString" key="Name">Qt 5.3.1 (msvc2010_opengl)</value>
<value type="QString" key="QMakePath">C:/Qt/Qt5.3.1/5.3/msvc2010_opengl/bin/qmake.exe</value>
@@ -33,7 +23,7 @@
</valuemap>
</data>
<data>
- <variable>QtVersion.3</variable>
+ <variable>QtVersion.2</variable>
<valuemap type="QVariantMap">
<value type="int" key="Id">22</value>
<value type="QString" key="Name">Qt %{Qt:Version} (mingw491_32)</value>
@@ -43,7 +33,7 @@
</valuemap>
</data>
<data>
- <variable>QtVersion.4</variable>
+ <variable>QtVersion.3</variable>
<valuemap type="QVariantMap">
<value type="int" key="Id">24</value>
<value type="QString" key="Name">Qt %{Qt:Version} (msvc2013)</value>
diff --git a/tests/system/settings/windows/QtProject/qtcreator/toolchains.xml b/tests/system/settings/windows/QtProject/qtcreator/toolchains.xml
index bbb2ad2a90..0db49a0028 100644
--- a/tests/system/settings/windows/QtProject/qtcreator/toolchains.xml
+++ b/tests/system/settings/windows/QtProject/qtcreator/toolchains.xml
@@ -5,21 +5,6 @@
<data>
<variable>ToolChain.0</variable>
<valuemap type="QVariantMap">
- <value type="QString" key="ProjectExplorer.GccToolChain.Path">C:/QtSDK/mingw/bin/g++.exe</value>
- <valuelist type="QVariantList" key="ProjectExplorer.GccToolChain.PlatformCodeGenFlags"/>
- <valuelist type="QVariantList" key="ProjectExplorer.GccToolChain.PlatformLinkerFlags"/>
- <valuelist type="QVariantList" key="ProjectExplorer.GccToolChain.SupportedAbis">
- <value type="QString">x86-windows-msys-pe-32bit</value>
- </valuelist>
- <value type="QString" key="ProjectExplorer.GccToolChain.TargetAbi">x86-windows-msys-pe-32bit</value>
- <value type="bool" key="ProjectExplorer.ToolChain.Autodetect">false</value>
- <value type="QString" key="ProjectExplorer.ToolChain.DisplayName">MinGW 4.4</value>
- <value type="QString" key="ProjectExplorer.ToolChain.Id">ProjectExplorer.ToolChain.Mingw:{2729dd3e-84f5-42e1-aed1-6a27163346ce}</value>
- </valuemap>
- </data>
- <data>
- <variable>ToolChain.1</variable>
- <valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2010-pe-32bit</value>
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">c:/Program Files (x86)/Microsoft Visual Studio 10.0/VC/vcvarsall.bat</value>
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBatArg">x86</value>
@@ -29,7 +14,7 @@
</valuemap>
</data>
<data>
- <variable>ToolChain.2</variable>
+ <variable>ToolChain.1</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.GccToolChain.Path">C:/Qt/Qt5.4.1/Tools/mingw491_32/bin/g++.exe</value>
<valuelist type="QVariantList" key="ProjectExplorer.GccToolChain.PlatformCodeGenFlags"/>
@@ -44,7 +29,7 @@
</valuemap>
</data>
<data>
- <variable>ToolChain.3</variable>
+ <variable>ToolChain.2</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2010-pe-32bit</value>
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">C:/Program Files (x86)/Microsoft Visual Studio 10.0/VC/vcvarsall.bat</value>
@@ -56,7 +41,7 @@
</valuemap>
</data>
<data>
- <variable>ToolChain.4</variable>
+ <variable>ToolChain.3</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2013-pe-32bit</value>
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/vcvarsall.bat</value>
@@ -68,24 +53,7 @@
</valuemap>
</data>
<data>
- <variable>ToolChain.5</variable>
- <valuemap type="QVariantMap">
- <value type="QString" key="ProjectExplorer.GccToolChain.OriginalTargetTriple">mingw32</value>
- <value type="QString" key="ProjectExplorer.GccToolChain.Path">C:/QtSDK/mingw/bin/gcc.exe</value>
- <valuelist type="QVariantList" key="ProjectExplorer.GccToolChain.PlatformCodeGenFlags"/>
- <valuelist type="QVariantList" key="ProjectExplorer.GccToolChain.PlatformLinkerFlags"/>
- <valuelist type="QVariantList" key="ProjectExplorer.GccToolChain.SupportedAbis">
- <value type="QString">x86-windows-msys-pe-32bit</value>
- </valuelist>
- <value type="QString" key="ProjectExplorer.GccToolChain.TargetAbi">x86-windows-msys-pe-32bit</value>
- <value type="bool" key="ProjectExplorer.ToolChain.Autodetect">false</value>
- <value type="QString" key="ProjectExplorer.ToolChain.DisplayName">MinGW 4.4</value>
- <value type="QString" key="ProjectExplorer.ToolChain.Id">ProjectExplorer.ToolChain.Mingw:{41d0a157-7cf1-4c83-bab8-d77b3f136b85}</value>
- <value type="int" key="ProjectExplorer.ToolChain.Language">1</value>
- </valuemap>
- </data>
- <data>
- <variable>ToolChain.6</variable>
+ <variable>ToolChain.4</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.GccToolChain.OriginalTargetTriple">i686-w64-mingw32</value>
<value type="QString" key="ProjectExplorer.GccToolChain.Path">C:/Qt/Qt5.4.1/Tools/mingw491_32/bin/gcc.exe</value>
@@ -102,7 +70,7 @@
</valuemap>
</data>
<data>
- <variable>ToolChain.7</variable>
+ <variable>ToolChain.5</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2013-pe-32bit</value>
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/vcvarsall.bat</value>
@@ -114,7 +82,7 @@
</data>
<data>
<variable>ToolChain.Count</variable>
- <value type="int">8</value>
+ <value type="int">6</value>
</data>
<data>
<variable>Version</variable>
diff --git a/tests/system/shared/classes.py b/tests/system/shared/classes.py
index 0cc851960b..47c6012c9f 100644
--- a/tests/system/shared/classes.py
+++ b/tests/system/shared/classes.py
@@ -28,10 +28,9 @@ import operator
# for easier re-usage (because Python hasn't an enum type)
class Targets:
- ALL_TARGETS = tuple(map(lambda x: 2 ** x , range(6)))
+ ALL_TARGETS = tuple(map(lambda x: 2 ** x , range(5)))
- (DESKTOP_474_GCC,
- DESKTOP_480_DEFAULT,
+ (DESKTOP_487_DEFAULT,
EMBEDDED_LINUX,
DESKTOP_531_DEFAULT,
DESKTOP_541_GCC,
@@ -55,18 +54,12 @@ class Targets:
@staticmethod
def qt4Classes():
- return (Targets.DESKTOP_474_GCC | Targets.DESKTOP_480_DEFAULT
- | Targets.EMBEDDED_LINUX)
+ return (Targets.DESKTOP_487_DEFAULT | Targets.EMBEDDED_LINUX)
@staticmethod
def getStringForTarget(target):
- if target == Targets.DESKTOP_474_GCC:
- return "Desktop 474 GCC"
- elif target == Targets.DESKTOP_480_DEFAULT:
- if platform.system() in ('Windows', 'Microsoft'):
- return "Desktop 480 MSVC2010"
- else:
- return "Desktop 480 GCC"
+ if target == Targets.DESKTOP_487_DEFAULT:
+ return "Desktop 487 default"
elif target == Targets.EMBEDDED_LINUX:
return "Embedded Linux"
elif target == Targets.DESKTOP_531_DEFAULT:
diff --git a/tests/system/shared/debugger.py b/tests/system/shared/debugger.py
index 49a83b1ca2..301ff108de 100644
--- a/tests/system/shared/debugger.py
+++ b/tests/system/shared/debugger.py
@@ -253,16 +253,3 @@ def verifyBreakPoint(bpToVerify):
else:
test.fatal("Expected a dict for bpToVerify - got '%s'" % className(bpToVerify))
return False
-
-# this function removes the compiled qml-debug library from QtSDK (only necessary for Qt < 4.8)
-def removeQmlDebugFolderIfExists():
- paths = [os.path.join(sdkPath, "Desktop", "Qt", "474", "gcc", "qtc-qmldbg"),
- os.path.join(sdkPath, "Desktop", "Qt", "4.7.4", "mingw", "qtc-qmldbg"),
- os.path.join(sdkPath, "Desktop", "Qt", "4.7.4", "msvc2008", "qtc-qmldbg")
- ]
- for path in paths:
- if os.path.exists(path):
- try:
- shutil.rmtree(path)
- except:
- test.warning("Error while removing '%s'" % path)
diff --git a/tests/system/shared/editor_utils.py b/tests/system/shared/editor_utils.py
index 32200de040..51b2fdf4d9 100644
--- a/tests/system/shared/editor_utils.py
+++ b/tests/system/shared/editor_utils.py
@@ -344,7 +344,10 @@ def validateSearchResult(expectedCount):
def invokeContextMenuItem(editorArea, command1, command2 = None):
ctxtMenu = openContextMenuOnTextCursorPosition(editorArea)
snooze(1)
- activateItem(waitForObjectItem(objectMap.realName(ctxtMenu), command1, 2000))
+ item1 = waitForObjectItem(objectMap.realName(ctxtMenu), command1, 2000)
+ if command2 and platform.system() == 'Darwin':
+ mouseMove(item1)
+ activateItem(item1)
if command2:
activateItem(waitForObjectItem("{title='%s' type='QMenu' visible='1' window=%s}"
% (command1, objectMap.realName(ctxtMenu)), command2, 2000))
diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py
index d3f47b73e5..00135f668b 100644
--- a/tests/system/shared/project.py
+++ b/tests/system/shared/project.py
@@ -73,7 +73,7 @@ def openCmakeProject(projectPath, buildDir):
invokeMenuItem("File", "Open File or Project...")
selectFromFileDialog(projectPath)
__chooseTargets__([]) # uncheck all
- __chooseTargets__([Targets.DESKTOP_480_DEFAULT], additionalFunc=additionalFunction)
+ __chooseTargets__([Targets.DESKTOP_487_DEFAULT], additionalFunc=additionalFunction)
clickButton(waitForObject(":Qt Creator.Configure Project_QPushButton"))
return True
@@ -205,7 +205,7 @@ def __modifyAvailableTargets__(available, requiredQt, asStrings=False):
# so the least required version is 4.8, but 4.7.4 will be still listed
if not (requiredQtVersion == "480" and found.group(0) == "474"):
available.remove(currentItem)
- if requiredQtVersion > "480":
+ if requiredQtVersion > "487":
toBeRemoved = [Targets.EMBEDDED_LINUX]
if asStrings:
toBeRemoved = Targets.getTargetsAsStrings(toBeRemoved)
@@ -349,7 +349,7 @@ def createEmptyQtProject(workingDir=None, projectName=None, targets=Targets.desk
__createProjectHandleLastPage__()
return projectName, checkedTargets
-def createNewNonQtProject(workingDir=None, projectName=None, target=[Targets.DESKTOP_474_GCC],
+def createNewNonQtProject(workingDir=None, projectName=None, target=[Targets.DESKTOP_487_DEFAULT],
plainC=False, cmake=False, qbs=False):
if plainC:
template = "Plain C Application"
@@ -378,7 +378,7 @@ def createNewNonQtProject(workingDir=None, projectName=None, target=[Targets.DES
return projectName
def createNewCPPLib(projectDir = None, projectName = None, className = None, fromWelcome = False,
- target = [Targets.DESKTOP_474_GCC], isStatic = False, modules = ["QtCore"]):
+ target = [Targets.DESKTOP_487_DEFAULT], isStatic = False, modules = ["QtCore"]):
available = __createProjectOrFileSelectType__(" Library", "C++ Library", fromWelcome, True)
if isStatic:
libType = LibType.STATIC
@@ -396,7 +396,7 @@ def createNewCPPLib(projectDir = None, projectName = None, className = None, fro
return checkedTargets, projectName, className
def createNewQtPlugin(projectDir=None, projectName=None, className=None, fromWelcome=False,
- target=[Targets.DESKTOP_474_GCC], baseClass="QGenericPlugin"):
+ target=[Targets.DESKTOP_487_DEFAULT], baseClass="QGenericPlugin"):
available = __createProjectOrFileSelectType__(" Library", "C++ Library", fromWelcome, True)
if projectDir == None:
projectDir = tempDir()
@@ -414,7 +414,7 @@ def createNewQtPlugin(projectDir=None, projectName=None, className=None, fromWel
# parameter additionalFunc function to be executed inside the detailed view of each chosen kit
# if present, 'Details' button will be clicked, function will be executed,
# 'Details' button will be clicked again
-def __chooseTargets__(targets=[Targets.DESKTOP_474_GCC], availableTargets=None, additionalFunc=None):
+def __chooseTargets__(targets=[Targets.DESKTOP_487_DEFAULT], availableTargets=None, additionalFunc=None):
if availableTargets != None:
available = availableTargets
else:
@@ -653,8 +653,7 @@ def __getSupportedPlatforms__(text, templateName, getAsStrings=False):
result = []
if 'Desktop' in supports:
if version == None or version < "5.0":
- result.append(Targets.DESKTOP_474_GCC)
- result.append(Targets.DESKTOP_480_DEFAULT)
+ result.append(Targets.DESKTOP_487_DEFAULT)
if platform.system() in ("Linux", "Darwin"):
result.append(Targets.EMBEDDED_LINUX)
result.extend([Targets.DESKTOP_531_DEFAULT, Targets.DESKTOP_561_DEFAULT])
diff --git a/tests/system/shared/qtcreator.py b/tests/system/shared/qtcreator.py
index 71efd63f42..2599a33581 100644
--- a/tests/system/shared/qtcreator.py
+++ b/tests/system/shared/qtcreator.py
@@ -308,16 +308,18 @@ def copySettingsToTmpDir(destination=None, omitFiles=[]):
# current dir is directory holding qtcreator.py
origSettingsDir = os.path.abspath(os.path.join(os.getcwd(), "..", "..", "settings"))
-sdkPath = os.path.expanduser("~/QtSDK")
+qt4Path = os.path.expanduser("~/Qt4.8.7")
if platform.system() in ('Windows', 'Microsoft'):
- sdkPath = "C:\\QtSDK"
+ qt4Path = "C:\\Qt\\Qt4.8.7"
origSettingsDir = os.path.join(origSettingsDir, "windows")
elif platform.system() == 'Darwin':
origSettingsDir = os.path.join(origSettingsDir, "mac")
else:
origSettingsDir = os.path.join(origSettingsDir, "unix")
-srcPath = os.getenv("SYSTEST_SRCPATH", os.path.join(sdkPath, "src"))
+
+qt4examplePath = os.path.join(qt4Path, "examples")
+srcPath = os.getenv("SYSTEST_SRCPATH", os.path.expanduser(os.path.join("~", "squish-data")))
overrideStartApplication()
diff --git a/tests/system/suite_APTW/tst_APTW03/test.py b/tests/system/suite_APTW/tst_APTW03/test.py
index 1b8090fcdc..d1ef6a5f80 100644
--- a/tests/system/suite_APTW/tst_APTW03/test.py
+++ b/tests/system/suite_APTW/tst_APTW03/test.py
@@ -81,14 +81,13 @@ def main():
# Qt Plugin needs Qt4.8 for QGenericPlugin which is tested by default
targets = Targets.desktopTargetClasses()
- targets.remove(Targets.DESKTOP_474_GCC)
checkedTargets, projectName, className = createNewQtPlugin(tempDir(), "SampleApp3", "MyPlugin",
target=targets)
virtualFunctionsAdded = False
for kit, config in iterateBuildConfigs(len(checkedTargets), "Debug"):
- is480Kit = "480" in Targets.getStringForTarget(checkedTargets[kit])
+ is487Kit = "487" in Targets.getStringForTarget(checkedTargets[kit])
verifyBuildConfig(len(checkedTargets), kit, config, True, True)
- if virtualFunctionsAdded and platform.system() in ('Microsoft', 'Windows') and is480Kit:
+ if virtualFunctionsAdded and platform.system() in ('Microsoft', 'Windows') and is487Kit:
test.warning("Skipping building of Qt4.8 targets because of QTCREATORBUG-12251.")
continue
invokeMenuItem('Build', 'Build Project "%s"' % projectName)
@@ -126,12 +125,12 @@ def main():
addReturn(editor, "QObject \*%s::create.*" % className, "0")
virtualFunctionsAdded = True
invokeMenuItem('File', 'Save All')
- if platform.system() in ('Microsoft', 'Windows') and is480Kit: # QTCREATORBUG-12251
+ if platform.system() in ('Microsoft', 'Windows') and is487Kit: # QTCREATORBUG-12251
test.warning("Skipping building of Qt4.8 targets because of QTCREATORBUG-12251.")
continue
invokeMenuItem('Build', 'Rebuild Project "%s"' % projectName)
waitForCompile(10000)
- if platform.system() == "Darwin" and is480Kit:
+ if platform.system() == "Darwin" and is487Kit:
test.log("Skipping compile check (gcc on OSX is only clang with gcc frontend nowadays)")
continue
checkCompile()
diff --git a/tests/system/suite_CCOM/tst_CCOM01/test.py b/tests/system/suite_CCOM/tst_CCOM01/test.py
index 99d1d33f76..8e336c8567 100755
--- a/tests/system/suite_CCOM/tst_CCOM01/test.py
+++ b/tests/system/suite_CCOM/tst_CCOM01/test.py
@@ -41,8 +41,7 @@ def main():
return
# open example project, supports only Qt 5
targets = Targets.desktopTargetClasses()
- targets.remove(Targets.DESKTOP_474_GCC)
- targets.remove(Targets.DESKTOP_480_DEFAULT)
+ targets.remove(Targets.DESKTOP_487_DEFAULT)
checkedTargets = openQmakeProject(examplePath, targets)
# build and wait until finished - on all build configurations
availableConfigs = iterateBuildConfigs(len(checkedTargets))
diff --git a/tests/system/suite_CSUP/tst_CSUP04/test.py b/tests/system/suite_CSUP/tst_CSUP04/test.py
index d9cf3c84f5..482a616f6d 100644
--- a/tests/system/suite_CSUP/tst_CSUP04/test.py
+++ b/tests/system/suite_CSUP/tst_CSUP04/test.py
@@ -28,8 +28,8 @@ source("../../shared/qtcreator.py")
# entry of test
def main():
# prepare example project
- sourceExample = os.path.abspath(sdkPath + "/Examples/4.7/declarative/animation/basics/property-animation")
- proFile = "propertyanimation.pro"
+ sourceExample = os.path.abspath(qt4examplePath + "/declarative/animation/basics/property-animation")
+ proFile = "property-animation.pro"
if not neededFilePresent(os.path.join(sourceExample, proFile)):
return
# copy example project to temp directory
@@ -44,7 +44,7 @@ def main():
progressBarWait(30000)
checkCodeModelSettings(useClang)
# open .cpp file in editor
- if not openDocument("propertyanimation.Sources.main\\.cpp"):
+ if not openDocument("property-animation.Sources.main\\.cpp"):
test.fatal("Could not open main.cpp")
invokeMenuItem("File", "Exit")
return
@@ -58,12 +58,12 @@ def main():
return
# wait until search finished and verify search results
waitForSearchResults()
- validateSearchResult(14)
+ validateSearchResult(21)
result = re.search("QmlApplicationViewer", str(editorWidget.plainText))
test.verify(result, "Verifying if: The list of all usages of the selected text is displayed in Search Results. "
"File with used text is opened.")
# move cursor to the other word and test Find Usages function by pressing Ctrl+Shift+U.
- openDocument("propertyanimation.Sources.main\\.cpp")
+ openDocument("property-animation.Sources.main\\.cpp")
if not placeCursorToLine(editorWidget, "viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);"):
return
for i in range(4):
diff --git a/tests/system/suite_CSUP/tst_CSUP05/test.py b/tests/system/suite_CSUP/tst_CSUP05/test.py
index 54f8e4b783..3b9409c56c 100644
--- a/tests/system/suite_CSUP/tst_CSUP05/test.py
+++ b/tests/system/suite_CSUP/tst_CSUP05/test.py
@@ -28,8 +28,8 @@ source("../../shared/qtcreator.py")
# entry of test
def main():
# prepare example project
- sourceExample = os.path.abspath(sdkPath + "/Examples/4.7/declarative/animation/basics/property-animation")
- proFile = "propertyanimation.pro"
+ sourceExample = os.path.abspath(qt4examplePath + "/declarative/animation/basics/property-animation")
+ proFile = "property-animation.pro"
if not neededFilePresent(os.path.join(sourceExample, proFile)):
return
# copy example project to temp directory
@@ -44,7 +44,7 @@ def main():
progressBarWait(30000)
checkCodeModelSettings(useClang)
# open .cpp file in editor
- if not openDocument("propertyanimation.Sources.main\\.cpp"):
+ if not openDocument("property-animation.Sources.main\\.cpp"):
test.fatal("Could not open main.cpp")
invokeMenuItem("File", "Exit")
return
diff --git a/tests/system/suite_CSUP/tst_CSUP06/test.py b/tests/system/suite_CSUP/tst_CSUP06/test.py
index 56588aefde..7d2a31c39a 100644
--- a/tests/system/suite_CSUP/tst_CSUP06/test.py
+++ b/tests/system/suite_CSUP/tst_CSUP06/test.py
@@ -105,20 +105,20 @@ def checkSymbolCompletion(editor, isClangCodeModel):
"Dummy::Internal::":["DOUBLE", "one"]
}
missing = ["Dummy::s", "Dummy::P", "dummy.b", "dummy.bla(", "internal.o", "freefunc2",
- "using namespace st", "afun"]
+ "afun"]
expectedResults = {"dummy.":"dummy.foo(", "Dummy::s":"Dummy::sfunc()",
"Dummy::P":"Dummy::PI", "dummy.b":"dummy.bla(", "dummy.bla(":"dummy.bla(",
"internal.o":"internal.one", "freefunc2":"freefunc2(",
"using namespace st":"using namespace std", "afun":"afunc()"}
- if not isClangCodeModel:
- expectedSuggestion["using namespace st"] = ["std", "st"]
- missing.remove("using namespace st")
- else:
+ if isClangCodeModel:
missing.remove("internal.o")
expectedSuggestion["internal.o"] = ["one", "operator="]
if platform.system() in ('Microsoft', 'Windows'):
expectedSuggestion["using namespace st"] = ["std", "stdext"]
- missing.remove("using namespace st")
+ else:
+ expectedSuggestion["using namespace st"] = ["std", "struct ", "struct template"]
+ else:
+ expectedSuggestion["using namespace st"] = ["std", "st"]
# define test function to perform the _real_ auto completion test on the current line
def testSymb(currentLine, *args):
missing, expectedSug, expectedRes = args
diff --git a/tests/system/suite_HELP/tst_HELP02/test.py b/tests/system/suite_HELP/tst_HELP02/test.py
index f246a41b6c..e3fc68cb40 100755
--- a/tests/system/suite_HELP/tst_HELP02/test.py
+++ b/tests/system/suite_HELP/tst_HELP02/test.py
@@ -91,8 +91,14 @@ def setKeyboardShortcutForAboutQtC():
expected = 'Ctrl+Alt+A'
if platform.system() == 'Darwin':
expected = 'Ctrl+Opt+A'
- test.verify(waitFor("str(findObject(shortcut).text) == expected", 5000),
- "Expected key sequence is displayed.")
+
+ shortcutMatches = waitFor("str(findObject(shortcut).text) == expected", 5000)
+ if not shortcutMatches and platform.system() == 'Darwin':
+ test.warning("Squish Issue: shortcut was set to %s - entering it manually now"
+ % waitForObject(shortcut).text)
+ replaceEditorContent(shortcut, expected)
+ else:
+ test.verify(shortcutMatches, "Expected key sequence is displayed.")
clickButton(waitForObject(":Options.OK_QPushButton"))
def main():
diff --git a/tests/system/suite_HELP/tst_HELP04/test.py b/tests/system/suite_HELP/tst_HELP04/test.py
index 7f046e76a4..344d3e20e4 100755
--- a/tests/system/suite_HELP/tst_HELP04/test.py
+++ b/tests/system/suite_HELP/tst_HELP04/test.py
@@ -28,8 +28,8 @@ import re
# test search in help mode and advanced search
searchKeywordDictionary={ "deployment":True, "deplmint":False, "build":True, "bld":False }
-urlDictionary = { "deployment":"qthelp://com.trolltech.qt.481/qdoc/gettingstarted-develop.html",
- "build":"qthelp://com.trolltech.qt.481/qdoc/sql-driver.html" }
+urlDictionary = { "deployment":"qthelp://com.trolltech.qt.487/qdoc/gettingstarted-develop.html",
+ "build":"qthelp://com.trolltech.qt.487/qdoc/sql-driver.html" }
def __getSelectedText__():
@@ -84,12 +84,11 @@ def verifyUrl(expected):
return test.compare(expected, __getUrl__(), "Expected URL loaded?")
def main():
- global sdkPath
noMatch = "Your search did not match any documents."
startApplication("qtcreator" + SettingsPath)
if not startedWithoutPluginError():
return
- addHelpDocumentation([os.path.join(sdkPath, "Documentation", "qt.qch")])
+ addHelpDocumentation([os.path.join(qt4Path, "doc", "qch", "qt.qch")])
# switch to help mode
switchViewTo(ViewConstants.HELP)
# verify that search widget is accessible
@@ -160,12 +159,12 @@ def main():
type(resultsView, "<Tab>")
type(resultsView, "<Return>")
verifySelection("printing")
- verifyUrl("qthelp://com.trolltech.qt.481/qdoc/overviews.html")
+ verifyUrl("qthelp://com.trolltech.qt.487/qdoc/overviews.html")
for i in range(2):
type(resultsView, "<Tab>")
type(resultsView, "<Return>")
verifySelection("sql")
- verifyUrl("qthelp://com.trolltech.qt.481/qdoc/best-practices.html")
+ verifyUrl("qthelp://com.trolltech.qt.487/qdoc/best-practices.html")
# verify if simple search is properly disabled
test.verify(not searchLineEdit.enabled,
"Verifying if simple search is not active in advanced mode.")
diff --git a/tests/system/suite_debugger/tst_simple_analyze/test.py b/tests/system/suite_debugger/tst_simple_analyze/test.py
index f8ed64a3b2..89c5fe3091 100644
--- a/tests/system/suite_debugger/tst_simple_analyze/test.py
+++ b/tests/system/suite_debugger/tst_simple_analyze/test.py
@@ -167,9 +167,3 @@ def safeClickTab(tab):
pass
test.fatal("Tab %s is not being shown." % tab)
return False
-
-def init():
- removeQmlDebugFolderIfExists()
-
-def cleanup():
- removeQmlDebugFolderIfExists()
diff --git a/tests/system/suite_debugger/tst_simple_debug/test.py b/tests/system/suite_debugger/tst_simple_debug/test.py
index f20069cd2a..54b0d652ee 100644
--- a/tests/system/suite_debugger/tst_simple_debug/test.py
+++ b/tests/system/suite_debugger/tst_simple_debug/test.py
@@ -31,7 +31,6 @@ def main():
return
# Requires Qt 4.8
targets = Targets.desktopTargetClasses()
- targets.remove(Targets.DESKTOP_474_GCC)
# using a temporary directory won't mess up a potentially existing
workingDir = tempDir()
checkedTargets, projectName = createNewQtQuickApplication(workingDir, targets=targets)
@@ -94,9 +93,3 @@ def main():
else:
test.fatal("Setting breakpoints failed - leaving without testing.")
invokeMenuItem("File", "Exit")
-
-def init():
- removeQmlDebugFolderIfExists()
-
-def cleanup():
- removeQmlDebugFolderIfExists()
diff --git a/tests/system/suite_editors/tst_memberoperator/test.py b/tests/system/suite_editors/tst_memberoperator/test.py
index 36db7f6618..4582268c70 100644
--- a/tests/system/suite_editors/tst_memberoperator/test.py
+++ b/tests/system/suite_editors/tst_memberoperator/test.py
@@ -49,11 +49,7 @@ def main():
waitFor("object.exists(':popupFrame_TextEditor::GenericProposalWidget')", 1500)
found = str(lineUnderCursor(cppwindow)).strip()
exp = testData.field(record, "expected")
- if (useClang and exp.endswith("->") and JIRA.isBugStillOpen(16336)
- and platform.system() in ('Windows', 'Microsoft')):
- test.xcompare(found, exp)
- else:
- test.compare(found, exp)
+ test.compare(found, exp)
invokeMenuItem("File", 'Revert "main.cpp" to Saved')
clickButton(waitForObject(":Revert to Saved.Proceed_QPushButton"))
snooze(1)
diff --git a/tests/system/suite_general/tst_build_speedcrunch/test.py b/tests/system/suite_general/tst_build_speedcrunch/test.py
index d66524001c..34be2beafa 100644
--- a/tests/system/suite_general/tst_build_speedcrunch/test.py
+++ b/tests/system/suite_general/tst_build_speedcrunch/test.py
@@ -42,7 +42,7 @@ def main():
startApplication("qtcreator" + SettingsPath)
if not startedWithoutPluginError():
return
- checkedTargets = openQmakeProject(SpeedCrunchPath, [Targets.DESKTOP_480_DEFAULT])
+ checkedTargets = openQmakeProject(SpeedCrunchPath, [Targets.DESKTOP_487_DEFAULT])
progressBarWait(30000)
fancyToolButton = waitForObject(":*Qt Creator_Core::Internal::FancyToolButton")
diff --git a/tests/system/suite_general/tst_openqt_creator/test.py b/tests/system/suite_general/tst_openqt_creator/test.py
index 8fe0b03847..aa4a73d78f 100644
--- a/tests/system/suite_general/tst_openqt_creator/test.py
+++ b/tests/system/suite_general/tst_openqt_creator/test.py
@@ -36,7 +36,7 @@ def main():
return
runButton = findObject(':*Qt Creator.Run_Core::Internal::FancyToolButton')
- openQmakeProject(pathSpeedcrunch, [Targets.DESKTOP_480_DEFAULT])
+ openQmakeProject(pathSpeedcrunch, [Targets.DESKTOP_487_DEFAULT])
# Wait for parsing to complete
waitFor("runButton.enabled", 30000)
# Starting before opening, because this is where Creator froze (QTCREATORBUG-10733)
diff --git a/tests/system/suite_general/tst_session_handling/test.py b/tests/system/suite_general/tst_session_handling/test.py
index 03a9114263..4e626232af 100644
--- a/tests/system/suite_general/tst_session_handling/test.py
+++ b/tests/system/suite_general/tst_session_handling/test.py
@@ -148,6 +148,3 @@ def checkForSessionFile(sessionName, proFiles):
proFile = proFile.replace('\\', '/')
test.verify(proFile in content, "Verifying whether expected .pro file (%s) is listed "
"inside session file." % proFile)
-
-def init():
- removeQmlDebugFolderIfExists()
diff --git a/tests/system/suite_tools/tst_git_local/test.py b/tests/system/suite_tools/tst_git_local/test.py
index daface7a97..0206885fa2 100644
--- a/tests/system/suite_tools/tst_git_local/test.py
+++ b/tests/system/suite_tools/tst_git_local/test.py
@@ -172,19 +172,19 @@ def main():
% os.path.join(srcPath, projectName, ".git").replace("\\", "/") in str(vcsLog),
"Has initialization of repo been logged:\n%s " % vcsLog)
createLocalGitConfig(os.path.join(srcPath, projectName, ".git"))
- commitMessages = [commit("Initial Commit", "Committed 5 file(s).")]
+ commitMessages = [commit("Initial Commit", "Committed 5 files.")]
clickButton(waitForObject(":*Qt Creator.Clear_QToolButton"))
headerName = "pointless_header.h"
addCPlusPlusFile(headerName, "C++ Header File", projectName + ".pro",
addToVCS="Git", expectedHeaderName=headerName)
- commitMessages.insert(0, commit("Added pointless header file", "Committed 2 file(s)."))
+ commitMessages.insert(0, commit("Added pointless header file", "Committed 2 files."))
readmeName = "README.txt"
addEmptyFileOutsideProject(readmeName)
replaceEditorContent(waitForObject(":Qt Creator_TextEditor::TextEditorWidget"),
"Some important advice in the README")
invokeMenuItem("File", "Save All")
commitsInProject = list(commitMessages) # deep copy
- commitOutsideProject = commit("Added README file", "Committed 2 file(s).", True) # QTCREATORBUG-11074
+ commitOutsideProject = commit("Added README file", "Committed 2 files.", True) # QTCREATORBUG-11074
commitMessages.insert(0, commitOutsideProject)
invokeMenuItem('Tools', 'Git', 'Current File', 'Log of "%s"' % readmeName)
@@ -208,7 +208,7 @@ def main():
# test for QTCREATORBUG-15051
addEmptyFileOutsideProject("anotherFile.txt")
fakeIdCommitMessage = "deadbeefdeadbeefdeadbeef is not a commit id"
- commit(fakeIdCommitMessage, "Committed 1 file(s).")
+ commit(fakeIdCommitMessage, "Committed 1 files.")
invokeMenuItem("Tools", "Git", "Local Repository", "Log")
gitEditor = waitForObject(":Qt Creator_Git::Internal::GitEditor")
waitFor("len(str(gitEditor.plainText)) > 0 and str(gitEditor.plainText) != 'Working...'", 20000)
diff --git a/tests/unit/unittest/clangasyncjob-base.cpp b/tests/unit/unittest/clangasyncjob-base.cpp
index cb7f5d742a..c3695d9639 100644
--- a/tests/unit/unittest/clangasyncjob-base.cpp
+++ b/tests/unit/unittest/clangasyncjob-base.cpp
@@ -52,6 +52,7 @@ JobRequest ClangAsyncJobTest::createJobRequest(const Utf8String &filePath,
JobRequest jobRequest;
jobRequest.type = type;
jobRequest.expirationReasons = JobRequest::expirationReasonsForType(type);
+ jobRequest.conditions = JobRequest::conditionsForType(type);
jobRequest.filePath = filePath;
jobRequest.projectPartId = projectPartId;
jobRequest.unsavedFilesChangeTimePoint = unsavedFiles.lastChangeTimePoint();
diff --git a/tests/unit/unittest/clangdocumentsuspenderresumer-test.cpp b/tests/unit/unittest/clangdocumentsuspenderresumer-test.cpp
new file mode 100644
index 0000000000..8ab78ebded
--- /dev/null
+++ b/tests/unit/unittest/clangdocumentsuspenderresumer-test.cpp
@@ -0,0 +1,295 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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 "googletest.h"
+
+#include "dummyclangipcclient.h"
+
+#include <clangclock.h>
+#include <clangdocument.h>
+#include <clangdocumentprocessors.h>
+#include <clangdocuments.h>
+#include <clangdocumentsuspenderresumer.h>
+#include <clangtranslationunits.h>
+#include <projects.h>
+#include <unsavedfiles.h>
+#include <utf8string.h>
+
+#include <utils/algorithm.h>
+
+#include <clang-c/Index.h>
+
+using ClangBackEnd::Clock;
+using ClangBackEnd::Document;
+using ClangBackEnd::JobRequest;
+using ClangBackEnd::PreferredTranslationUnit;
+using ClangBackEnd::SuspendResumeJobs;
+using ClangBackEnd::SuspendResumeJobsEntry;
+using ClangBackEnd::TimePoint;
+
+using testing::ContainerEq;
+using testing::ElementsAre;
+using testing::IsEmpty;
+
+namespace ClangBackEnd {
+
+bool operator==(const SuspendResumeJobsEntry &a, const SuspendResumeJobsEntry &b)
+{
+ return a.document == b.document
+ && a.jobRequestType == b.jobRequestType
+ && a.preferredTranslationUnit == b.preferredTranslationUnit;
+}
+
+} // ClangBackEnd
+
+namespace {
+
+class DocumentSuspenderResumer : public ::testing::Test
+{
+protected:
+ void SetUp() override;
+ Document getDocument(const Utf8String &filePath);
+ void categorizeDocuments(int hotDocumentsSize);
+ SuspendResumeJobs createSuspendResumeJobs(int hotDocumentsSize = -1);
+
+protected:
+ ClangBackEnd::ProjectParts projects;
+ ClangBackEnd::UnsavedFiles unsavedFiles;
+ ClangBackEnd::Documents documents{projects, unsavedFiles};
+ DummyIpcClient dummyIpcClient;
+ ClangBackEnd::DocumentProcessors documentProcessors{documents, unsavedFiles, projects,
+ dummyIpcClient};
+
+ const Utf8String projectPartId = Utf8StringLiteral("projectPartId");
+
+ const Utf8String filePath1 = Utf8StringLiteral(TESTDATA_DIR"/empty1.cpp");
+ const ClangBackEnd::FileContainer fileContainer1{filePath1, projectPartId, Utf8String(), true};
+
+ const Utf8String filePath2 = Utf8StringLiteral(TESTDATA_DIR"/empty2.cpp");
+ const ClangBackEnd::FileContainer fileContainer2{filePath2, projectPartId, Utf8String(), true};
+
+ const Utf8String filePath3 = Utf8StringLiteral(TESTDATA_DIR"/empty3.cpp");
+ const ClangBackEnd::FileContainer fileContainer3{filePath3, projectPartId, Utf8String(), true};
+
+ std::vector<Document> hotDocuments;
+ std::vector<Document> coldDocuments;
+};
+
+TEST_F(DocumentSuspenderResumer, CategorizeNoDocuments)
+{
+ categorizeDocuments(99);
+
+ ASSERT_THAT(hotDocuments, IsEmpty());
+ ASSERT_THAT(coldDocuments, IsEmpty());
+}
+
+TEST_F(DocumentSuspenderResumer, CategorizeSingleDocument)
+{
+ documents.create({fileContainer1});
+
+ categorizeDocuments(99);
+
+ ASSERT_THAT(hotDocuments, ElementsAre(getDocument(filePath1)));
+ ASSERT_THAT(coldDocuments, IsEmpty());
+}
+
+TEST_F(DocumentSuspenderResumer, CategorizeKeepsStableOrder)
+{
+ documents.create({fileContainer1, fileContainer2});
+
+ categorizeDocuments(99);
+
+ ASSERT_THAT(hotDocuments, ElementsAre(getDocument(filePath1),
+ getDocument(filePath2)));
+}
+
+TEST_F(DocumentSuspenderResumer, CategorizePutsLastVisibleToTopOfHotDocuments)
+{
+ documents.create({fileContainer1, fileContainer2});
+ documents.setVisibleInEditors({filePath1});
+ documents.setVisibleInEditors({filePath2});
+
+ categorizeDocuments(99);
+
+ ASSERT_THAT(hotDocuments, ElementsAre(getDocument(filePath2),
+ getDocument(filePath1)));
+}
+
+TEST_F(DocumentSuspenderResumer, CategorizeWithLessDocumentsThanWeCareFor)
+{
+ documents.create({fileContainer1});
+
+ categorizeDocuments(2);
+
+ ASSERT_THAT(hotDocuments, ElementsAre(getDocument(filePath1)));
+ ASSERT_THAT(coldDocuments, IsEmpty());
+}
+
+TEST_F(DocumentSuspenderResumer, CategorizeWithZeroHotDocuments)
+{
+ documents.create({fileContainer1});
+
+ categorizeDocuments(0);
+
+ ASSERT_THAT(hotDocuments, IsEmpty());
+ ASSERT_THAT(coldDocuments, ElementsAre(getDocument(filePath1)));
+}
+
+TEST_F(DocumentSuspenderResumer, CategorizeWithMoreVisibleDocumentsThanHotDocuments)
+{
+ const TimePoint timePoint = Clock::now();
+ Document document1 = documents.create({fileContainer1})[0];
+ document1.setIsVisibleInEditor(true, timePoint);
+ Document document2 = documents.create({fileContainer2})[0];
+ document2.setIsVisibleInEditor(true, timePoint);
+
+ categorizeDocuments(1);
+
+ ASSERT_THAT(hotDocuments, ElementsAre(getDocument(filePath1), getDocument(filePath2)));
+ ASSERT_THAT(coldDocuments, IsEmpty());
+}
+
+TEST_F(DocumentSuspenderResumer, CreateSuspendJobForInvisible)
+{
+ Document document = documents.create({fileContainer1})[0];
+ document.setIsSuspended(false);
+ document.setIsVisibleInEditor(false, Clock::now());
+ const SuspendResumeJobs expectedJobs = {
+ {document, JobRequest::Type::SuspendDocument, PreferredTranslationUnit::RecentlyParsed}
+ };
+
+ const SuspendResumeJobs jobs = createSuspendResumeJobs(/*hotDocumentsSize=*/ 0);
+
+ ASSERT_THAT(jobs, ContainerEq(expectedJobs));
+}
+
+TEST_F(DocumentSuspenderResumer, DoNotCreateSuspendJobForVisible)
+{
+ Document document = documents.create({fileContainer1})[0];
+ document.setIsSuspended(false);
+ document.setIsVisibleInEditor(true, Clock::now());
+
+ const SuspendResumeJobs jobs = createSuspendResumeJobs(/*hotDocumentsSize=*/ 0);
+
+ ASSERT_THAT(jobs, ContainerEq(SuspendResumeJobs()));
+}
+
+TEST_F(DocumentSuspenderResumer, CreateSuspendJobsForDocumentWithSupportiveTranslationUnit)
+{
+ Document document = documents.create({fileContainer1})[0];
+ document.setIsSuspended(false);
+ document.setIsVisibleInEditor(false, Clock::now());
+ document.translationUnits().createAndAppend(); // Add supportive translation unit
+ const SuspendResumeJobs expectedJobs = {
+ {document, JobRequest::Type::SuspendDocument, PreferredTranslationUnit::RecentlyParsed},
+ {document, JobRequest::Type::SuspendDocument, PreferredTranslationUnit::PreviouslyParsed},
+ };
+
+ const SuspendResumeJobs jobs = createSuspendResumeJobs(/*hotDocumentsSize=*/ 0);
+
+ ASSERT_THAT(jobs, ContainerEq(expectedJobs));
+}
+
+TEST_F(DocumentSuspenderResumer, CreateResumeJob)
+{
+ Document document = documents.create({fileContainer1})[0];
+ document.setIsSuspended(true);
+ document.setIsVisibleInEditor(true, Clock::now());
+ const SuspendResumeJobs expectedJobs = {
+ {document, JobRequest::Type::ResumeDocument, PreferredTranslationUnit::RecentlyParsed}
+ };
+
+ const SuspendResumeJobs jobs = createSuspendResumeJobs();
+
+ ASSERT_THAT(jobs, ContainerEq(expectedJobs));
+}
+
+TEST_F(DocumentSuspenderResumer, DoNotCreateResumeJobForInvisible)
+{
+ Document document = documents.create({fileContainer1})[0];
+ document.setIsSuspended(true);
+ document.setIsVisibleInEditor(false, Clock::now());
+
+ const SuspendResumeJobs jobs = createSuspendResumeJobs(/*hotDocumentsSize=*/ 0);
+
+ ASSERT_THAT(jobs, ContainerEq(SuspendResumeJobs()));
+}
+
+TEST_F(DocumentSuspenderResumer, CreateResumeJobsForDocumentWithSupportiveTranslationUnit)
+{
+ Document document = documents.create({fileContainer1})[0];
+ document.setIsSuspended(true);
+ document.setIsVisibleInEditor(true, Clock::now());
+ document.translationUnits().createAndAppend(); // Add supportive translation unit
+ const SuspendResumeJobs expectedJobs = {
+ {document, JobRequest::Type::ResumeDocument, PreferredTranslationUnit::RecentlyParsed},
+ {document, JobRequest::Type::ResumeDocument, PreferredTranslationUnit::PreviouslyParsed},
+ };
+
+ const SuspendResumeJobs jobs = createSuspendResumeJobs();
+
+ ASSERT_THAT(jobs, ContainerEq(expectedJobs));
+}
+
+TEST_F(DocumentSuspenderResumer, CreateSuspendAndResumeJobs)
+{
+ Document hotDocument = documents.create({fileContainer1})[0];
+ hotDocument.setIsSuspended(true);
+ Document coldDocument = documents.create({fileContainer2})[0];
+ coldDocument.setIsSuspended(false);
+ documents.setVisibleInEditors({filePath1});
+ const SuspendResumeJobs expectedJobs = {
+ {coldDocument, JobRequest::Type::SuspendDocument, PreferredTranslationUnit::RecentlyParsed},
+ {hotDocument, JobRequest::Type::ResumeDocument, PreferredTranslationUnit::RecentlyParsed},
+ };
+
+ const SuspendResumeJobs jobs = createSuspendResumeJobs(/*hotDocumentsSize=*/ 1);
+
+ ASSERT_THAT(jobs, ContainerEq(expectedJobs));
+}
+
+void DocumentSuspenderResumer::SetUp()
+{
+ projects.createOrUpdate({ClangBackEnd::ProjectPartContainer(projectPartId)});
+}
+
+ClangBackEnd::Document DocumentSuspenderResumer::getDocument(const Utf8String &filePath)
+{
+ return documents.document(filePath, projectPartId);
+}
+
+void DocumentSuspenderResumer::categorizeDocuments(int hotDocumentsSize)
+{
+ categorizeHotColdDocuments(hotDocumentsSize, documents.documents(), hotDocuments,
+ coldDocuments);
+}
+
+ClangBackEnd::SuspendResumeJobs
+DocumentSuspenderResumer::createSuspendResumeJobs(int hotDocumentsSize)
+{
+ return ClangBackEnd::createSuspendResumeJobs(documents.documents(), hotDocumentsSize);
+}
+
+} // anonymous
diff --git a/tests/unit/unittest/clangjobqueue-test.cpp b/tests/unit/unittest/clangjobqueue-test.cpp
index 22af7aa01a..ea786e87f1 100644
--- a/tests/unit/unittest/clangjobqueue-test.cpp
+++ b/tests/unit/unittest/clangjobqueue-test.cpp
@@ -65,9 +65,6 @@ protected:
JobRequest::Type type,
PreferredTranslationUnit preferredTranslationUnit
= PreferredTranslationUnit::RecentlyParsed) const;
- JobRequest createJobRequestWithConditions(const Utf8String &filePath,
- JobRequest::Type type,
- JobRequest::Conditions conditions) const;
void updateDocumentRevision();
void updateUnsavedFiles();
@@ -415,9 +412,7 @@ TEST_F(JobQueue, RequestCompleteCodeOutdatableByDocumentRevisionChange)
TEST_F(JobQueue, RequestReferencesRunsForCurrentDocumentRevision)
{
- jobQueue.add( createJobRequestWithConditions(filePath1,
- JobRequest::Type::RequestReferences,
- JobRequest::Condition::CurrentDocumentRevision));
+ jobQueue.add(createJobRequest(filePath1, JobRequest::Type::RequestReferences));
const JobRequests jobsToStart = jobQueue.processQueue();
@@ -426,9 +421,7 @@ TEST_F(JobQueue, RequestReferencesRunsForCurrentDocumentRevision)
TEST_F(JobQueue, RequestReferencesOutdatableByDocumentClose)
{
- jobQueue.add(createJobRequestWithConditions(filePath1,
- JobRequest::Type::RequestReferences,
- JobRequest::Condition::CurrentDocumentRevision));
+ jobQueue.add(createJobRequest(filePath1, JobRequest::Type::RequestReferences));
removeDocument();
const JobRequests jobsToStart = jobQueue.processQueue();
@@ -437,6 +430,28 @@ TEST_F(JobQueue, RequestReferencesOutdatableByDocumentClose)
ASSERT_THAT(jobQueue.size(), Eq(0));
}
+TEST_F(JobQueue, RequestReferencesDoesNotRunOnSuspendedDocument)
+{
+ jobQueue.add(createJobRequest(filePath1, JobRequest::Type::RequestReferences));
+ document.setIsSuspended(true);
+
+ const JobRequests jobsToStart = jobQueue.processQueue();
+
+ ASSERT_THAT(jobsToStart.size(), Eq(0));
+ ASSERT_THAT(jobQueue.size(), Eq(1));
+}
+
+TEST_F(JobQueue, ResumeDocumentDoesNotRunOnUnsuspended)
+{
+ jobQueue.add(createJobRequest(filePath1, JobRequest::Type::ResumeDocument));
+ document.setIsSuspended(false);
+
+ const JobRequests jobsToStart = jobQueue.processQueue();
+
+ ASSERT_THAT(jobsToStart.size(), Eq(0));
+ ASSERT_THAT(jobQueue.size(), Eq(1));
+}
+
void JobQueue::SetUp()
{
projects.createOrUpdate({ProjectPartContainer(projectPartId)});
@@ -477,6 +492,7 @@ JobRequest JobQueue::createJobRequest(
JobRequest jobRequest;
jobRequest.type = type;
jobRequest.expirationReasons = JobRequest::expirationReasonsForType(type);
+ jobRequest.conditions = JobRequest::conditionsForType(type);
jobRequest.filePath = filePath;
jobRequest.projectPartId = projectPartId;
jobRequest.unsavedFilesChangeTimePoint = unsavedFiles.lastChangeTimePoint();
@@ -487,18 +503,6 @@ JobRequest JobQueue::createJobRequest(
return jobRequest;
}
-JobRequest JobQueue::createJobRequestWithConditions(const Utf8String &filePath,
- JobRequest::Type type,
- JobRequest::Conditions conditions) const
-{
- JobRequest jobRequest = createJobRequest(filePath,
- type,
- PreferredTranslationUnit::RecentlyParsed);
- jobRequest.conditions = conditions;
-
- return jobRequest;
-}
-
void JobQueue::updateDocumentRevision()
{
documents.update({FileContainer(filePath1, projectPartId, Utf8String(), true, 1)});
diff --git a/tests/unit/unittest/clangresumedocumentjob-test.cpp b/tests/unit/unittest/clangresumedocumentjob-test.cpp
new file mode 100644
index 0000000000..11a9e49072
--- /dev/null
+++ b/tests/unit/unittest/clangresumedocumentjob-test.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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 "clangasyncjob-base.h"
+
+#include <clangresumedocumentjob.h>
+
+using namespace ClangBackEnd;
+
+using testing::_;
+
+namespace {
+
+class ResumeDocumentJob : public ClangAsyncJobTest
+{
+protected:
+ void SetUp() override { BaseSetUp(JobRequest::Type::ResumeDocument, job); }
+ void suspendDocument()
+ {
+ document.parse();
+ document.translationUnit().suspend();
+ document.setIsSuspended(true);
+ }
+
+protected:
+ ClangBackEnd::ResumeDocumentJob job;
+};
+
+TEST_F(ResumeDocumentJob, PrepareAsyncRun)
+{
+ job.setContext(jobContext);
+
+ ASSERT_TRUE(job.prepareAsyncRun());
+}
+
+TEST_F(ResumeDocumentJob, RunAsync)
+{
+ suspendDocument();
+ job.setContext(jobContext);
+ job.prepareAsyncRun();
+
+ job.runAsync();
+
+ ASSERT_TRUE(waitUntilJobFinished(job));
+}
+
+TEST_F(ResumeDocumentJob, DocumentIsResumedAfterRun)
+{
+ suspendDocument();
+ job.setContext(jobContext);
+ job.prepareAsyncRun();
+
+ job.runAsync();
+ ASSERT_TRUE(waitUntilJobFinished(job));
+
+ ASSERT_FALSE(document.isSuspended());
+}
+
+TEST_F(ResumeDocumentJob, SendsAnnotationsAfterResume)
+{
+ suspendDocument();
+ job.setContext(jobContextWithMockClient);
+ job.prepareAsyncRun();
+ EXPECT_CALL(mockIpcClient, documentAnnotationsChanged(_)).Times(1);
+
+ job.runAsync();
+ ASSERT_TRUE(waitUntilJobFinished(job));
+}
+
+} // anonymous
diff --git a/tests/unit/unittest/clangsuspenddocumentjob-test.cpp b/tests/unit/unittest/clangsuspenddocumentjob-test.cpp
new file mode 100644
index 0000000000..b9f92f3beb
--- /dev/null
+++ b/tests/unit/unittest/clangsuspenddocumentjob-test.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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 "clangasyncjob-base.h"
+
+#include <clangsuspenddocumentjob.h>
+
+using namespace ClangBackEnd;
+
+namespace {
+
+class SuspendDocumentJob : public ClangAsyncJobTest
+{
+protected:
+ void SetUp() override { BaseSetUp(JobRequest::Type::SuspendDocument, job); }
+
+protected:
+ ClangBackEnd::SuspendDocumentJob job;
+};
+
+TEST_F(SuspendDocumentJob, PrepareAsyncRun)
+{
+ job.setContext(jobContext);
+
+ ASSERT_TRUE(job.prepareAsyncRun());
+}
+
+TEST_F(SuspendDocumentJob, RunAsync)
+{
+ document.parse();
+ job.setContext(jobContext);
+ job.prepareAsyncRun();
+
+ job.runAsync();
+
+ ASSERT_TRUE(waitUntilJobFinished(job));
+}
+
+TEST_F(SuspendDocumentJob, DocumentIsSuspendedAfterRun)
+{
+ document.parse();
+ job.setContext(jobContext);
+ job.prepareAsyncRun();
+
+ job.runAsync();
+ ASSERT_TRUE(waitUntilJobFinished(job));
+
+ ASSERT_TRUE(document.isSuspended());
+}
+
+} // anonymous
diff --git a/tests/unit/unittest/data/empty1.cpp b/tests/unit/unittest/data/empty1.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/unit/unittest/data/empty1.cpp
diff --git a/tests/unit/unittest/data/empty2.cpp b/tests/unit/unittest/data/empty2.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/unit/unittest/data/empty2.cpp
diff --git a/tests/unit/unittest/data/empty3.cpp b/tests/unit/unittest/data/empty3.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/unit/unittest/data/empty3.cpp
diff --git a/tests/unit/unittest/data/highlightingmarks.cpp b/tests/unit/unittest/data/highlightingmarks.cpp
index 5b3374d582..860dbddc70 100644
--- a/tests/unit/unittest/data/highlightingmarks.cpp
+++ b/tests/unit/unittest/data/highlightingmarks.cpp
@@ -579,3 +579,6 @@ void f32()
NonConstPointerArgument(x.getter());
}
+
+namespace N { template <typename T> void SizeIs(); }
+using N::SizeIs;
diff --git a/tests/unit/unittest/highlightingmarks-test.cpp b/tests/unit/unittest/highlightingmarks-test.cpp
index 8592bb67be..cbedd9d844 100644
--- a/tests/unit/unittest/highlightingmarks-test.cpp
+++ b/tests/unit/unittest/highlightingmarks-test.cpp
@@ -1033,19 +1033,16 @@ TEST_F(HighlightingMarks, ConstPointerArgument)
TEST_F(HighlightingMarks, NonConstPointerGetterAsArgument)
{
- const auto infos = translationUnit.highlightingMarksInRange(sourceRange(580, 41));
+ const auto infos = translationUnit.highlightingMarksInRange(sourceRange(580, 42));
- ASSERT_THAT(infos,
- ElementsAre(_,
- _,
- HasMixin(HighlightingType::OutputArgument),
- HasMixin(HighlightingType::OutputArgument),
- HasMixin(HighlightingType::OutputArgument),
- HasMixin(HighlightingType::OutputArgument),
- HasMixin(HighlightingType::OutputArgument),
- _,
- _,
- _));
+ infos[1];
+
+ ASSERT_THAT(infos[2] ,HasMixin(HighlightingType::OutputArgument));
+ ASSERT_THAT(infos[3], HasMixin(HighlightingType::OutputArgument));
+ ASSERT_THAT(infos[4], HasMixin(HighlightingType::OutputArgument));
+ ASSERT_THAT(infos[5], HasMixin(HighlightingType::OutputArgument));
+ ASSERT_THAT(infos[6], HasMixin(HighlightingType::OutputArgument));
+ ASSERT_THAT(infos[7], Not(HasMixin(HighlightingType::OutputArgument)));
}
TEST_F(HighlightingMarks, NonConstReferenceArgumentCallInsideCall)
@@ -1180,6 +1177,13 @@ TEST_F(HighlightingMarks, DISABLED_VariableInOperatorFunctionCall)
ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::LocalVariable));
}
+TEST_F(HighlightingMarks, UsingTemplateFunction)
+{
+ const auto infos = translationUnit.highlightingMarksInRange(sourceRange(584, 17));
+
+ ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Function));
+}
+
Data *HighlightingMarks::d;
void HighlightingMarks::SetUpTestCase()
diff --git a/tests/unit/unittest/matchingtext-test.cpp b/tests/unit/unittest/matchingtext-test.cpp
index d5bfcaddef..c07bfec49a 100644
--- a/tests/unit/unittest/matchingtext-test.cpp
+++ b/tests/unit/unittest/matchingtext-test.cpp
@@ -256,4 +256,11 @@ TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotBeforeNestedName
ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{"));
}
+TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotWithinString)
+{
+ const Document document("\"a@b\"");
+
+ ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{"));
+}
+
} // anonymous
diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro
index be7632ecd5..67226416af 100644
--- a/tests/unit/unittest/unittest.pro
+++ b/tests/unit/unittest/unittest.pro
@@ -84,6 +84,7 @@ SOURCES += \
clangdocumentprocessors-test.cpp \
clangdocumentprocessor-test.cpp \
clangdocuments-test.cpp \
+ clangdocumentsuspenderresumer-test.cpp \
clangdocument-test.cpp \
clangfixitoperation-test.cpp \
clangisdiagnosticrelatedtolocation-test.cpp \
@@ -94,8 +95,10 @@ SOURCES += \
clangreparsesupportivetranslationunitjob-test.cpp \
clangrequestdocumentannotationsjob-test.cpp \
clangrequestreferencesjob-test.cpp \
+ clangresumedocumentjob-test.cpp \
clangstring-test.cpp \
clangsupportivetranslationunitinitializer-test.cpp \
+ clangsuspenddocumentjob-test.cpp \
clangtranslationunits-test.cpp \
clangtranslationunit-test.cpp \
clangupdatedocumentannotationsjob-test.cpp \