diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 202c71a50db..42254415db5 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -82,8 +82,11 @@ jobs: # Add to PATH environment variable file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/${cmake_dir}" cmake_dir) - message("::add-path::$ENV{GITHUB_WORKSPACE}") - message("::add-path::${cmake_dir}") + set(path_separator ":") + if ("${{ runner.os }}" STREQUAL "Windows") + set(path_separator ";") + endif() + file(APPEND "$ENV{GITHUB_PATH}" "$ENV{GITHUB_WORKSPACE}${path_separator}${cmake_dir}") if (NOT "${{ runner.os }}" STREQUAL "Windows") execute_process( diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake index 4e8b7ba5336..9bb27649591 100644 --- a/cmake/QtCreatorAPI.cmake +++ b/cmake/QtCreatorAPI.cmake @@ -65,7 +65,7 @@ endfunction() function(add_qtc_library name) cmake_parse_arguments(_arg "STATIC;OBJECT;SKIP_TRANSLATION;BUILD_BY_DEFAULT;ALLOW_ASCII_CASTS;UNVERSIONED" - "DESTINATION;COMPONENT" + "DESTINATION;COMPONENT;SOURCES_PREFIX" "DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;PUBLIC_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES" ${ARGN} ) @@ -94,6 +94,20 @@ function(add_qtc_library name) endif() endif() + # TODO copied from extend_qtc_target. + # Instead require CMake 3.11 and use extend_qtc_target for setting SOURCES. + # Requiring cmake 3.11 is necessary because before that add_library requires + # at least one source file. + if (_arg_SOURCES_PREFIX) + foreach(source IN LISTS _arg_SOURCES) + list(APPEND prefixed_sources "${_arg_SOURCES_PREFIX}/${source}") + endforeach() + if (NOT IS_ABSOLUTE ${_arg_SOURCES_PREFIX}) + set(_arg_SOURCES_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/${_arg_SOURCES_PREFIX}") + endif() + set(_arg_SOURCES ${prefixed_sources}) + endif() + compare_sources_with_existing_disk_files(${name} "${_arg_SOURCES}") set(library_type SHARED) @@ -114,6 +128,11 @@ function(add_qtc_library name) add_library(${IDE_CASED_ID}::${name} ALIAS ${name}) set_public_headers(${name} "${_arg_SOURCES}") + # TODO remove, see above + if (_arg_SOURCES_PREFIX) + target_include_directories(${name} PRIVATE $) + endif() + if (${name} MATCHES "^[^0-9-]+$") string(TOUPPER "${name}_LIBRARY" EXPORT_SYMBOL) endif() @@ -134,15 +153,18 @@ function(add_qtc_library name) EXTRA_TRANSLATIONS ${_arg_EXTRA_TRANSLATIONS} ) - get_filename_component(public_build_interface_dir "${CMAKE_CURRENT_SOURCE_DIR}/.." ABSOLUTE) - file(RELATIVE_PATH include_dir_relative_path ${PROJECT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/..") - target_include_directories(${name} - PRIVATE - "$" - PUBLIC - "$" - "$" - ) + # everything is different with SOURCES_PREFIX + if (NOT _arg_SOURCES_PREFIX) + get_filename_component(public_build_interface_dir "${CMAKE_CURRENT_SOURCE_DIR}/.." ABSOLUTE) + file(RELATIVE_PATH include_dir_relative_path ${PROJECT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/..") + target_include_directories(${name} + PRIVATE + "$" + PUBLIC + "$" + "$" + ) + endif() set(skip_translation OFF) if (_arg_SKIP_TRANSLATION) @@ -244,7 +266,7 @@ function(add_qtc_plugin target_name) cmake_parse_arguments(_arg "EXPERIMENTAL;SKIP_DEBUG_CMAKE_FILE_CHECK;SKIP_INSTALL;INTERNAL_ONLY;SKIP_TRANSLATION" "VERSION;COMPAT_VERSION;PLUGIN_JSON_IN;PLUGIN_PATH;PLUGIN_NAME;OUTPUT_NAME;BUILD_DEFAULT" - "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;PUBLIC_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PLUGIN_DEPENDS;PLUGIN_RECOMMENDS" + "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;PUBLIC_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PLUGIN_DEPENDS;PLUGIN_RECOMMENDS;PROPERTIES" ${ARGN} ) diff --git a/cmake/QtCreatorAPIInternal.cmake b/cmake/QtCreatorAPIInternal.cmake index 5404680da0f..6105c9f00e8 100644 --- a/cmake/QtCreatorAPIInternal.cmake +++ b/cmake/QtCreatorAPIInternal.cmake @@ -360,7 +360,8 @@ function(enable_pch target) endif() unset(PCH_TARGET) - if ("Qt5::Widgets" IN_LIST dependencies) + if ("Qt5::Widgets" IN_LIST dependencies OR + "Qt5::Gui" IN_LIST dependencies) set(PCH_TARGET QtCreatorPchGui) elseif ("Qt5::Core" IN_LIST dependencies) set(PCH_TARGET QtCreatorPchConsole) diff --git a/dist/changes-4.14.0.md b/dist/changes-4.14.0.md new file mode 100644 index 00000000000..4d5eaa0822d --- /dev/null +++ b/dist/changes-4.14.0.md @@ -0,0 +1,186 @@ +Qt Creator 4.14 +=============== + +Qt Creator version 4.14 contains bug fixes and new features. + +The most important changes are listed in this document. For a complete +list of changes, see the Git log for the Qt Creator sources that +you can check out from the public Git repository. For example: + + git clone git://code.qt.io/qt-creator/qt-creator.git + git log --cherry-pick --pretty=oneline origin/4.13..v4.14.0 + +General +------- + +* Added option for asking for confirmation before closing (QTCREATORBUG-7637) + +Help +---- + +* Made `litehtml` rendering backend the default + +Editing +------- + +* Added option to adjust line spacing (QTCREATORBUG-13727) + +### C++ + +* Added refactoring action that creates getters and setters for all class members + (QTCREATORBUG-14504) +* Added refactoring action that generates member from class member initialization + (QTCREATORBUG-11842) +* Added refactoring action that creates implementations for all member functions + (QTCREATORBUG-12164) +* Added refactoring action for removing `using namespace` directives (QTCREATORBUG-24392) +* Added auto-completion of existing namespaces and classes to `New Class` wizard + (QTCREATORBUG-10066) +* Added action for showing function arguments hint (QTCREATORBUG-19394) +* Added option for after how many characters auto-completion may trigger (QTCREATORBUG-19920) +* Restricted completion for second argument of `connect` calls to signals (QTCREATORBUG-13558) +* Fixed duplicate items appearing in include completion (QTCREATORBUG-24515) +* Fixed missing namespace when generating getters and setters (QTCREATORBUG-14886) +* Fixed missing `inline` when generating method definitions in header files + (QTCREATORBUG-15052) +* Fixed that `Follow Symbol Under Cursor` on declarations and definitions did not offer items + in subclasses (QTCREATORBUG-10160) +* Fixed that `RESET` function was not generated for `Q_PROPERTY`s (QTCREATORBUG-11809) +* Fixed that `Insert virtual functions of base class` refactoring action added already + implemented operators (QTCREATORBUG-12218) +* Fixed that `Complete switch statement` indents unrelated code (QTCREATORBUG-12445) +* Fixed that `Apply function signature change` removed return values from `std::function` + arguments (QTCREATORBUG-13698) +* Fixed handling of multiple inheritance in `Insert Virtual Functions` (QTCREATORBUG-12223) +* Fixed auto-indentation for lambdas with trailing return type (QTCREATORBUG-18497) +* Fixed indentation when starting new line in documentation comments (QTCREATORBUG-11749) +* Fixed that auto-indentation was applied within multiline string literals + (QTCREATORBUG-20180) +* Fixed sorting in `Outline` view (QTCREATORBUG-12714) +* Fixed that renaming files did not adapt include guards in headers (QTCREATORBUG-4686) + +### Language Client + +* Improved outline for hierarchical symbols + +### QML + +* Fixed issues with `Move Component into Separate File` (QTCREATORBUG-21091) +* Fixed crash with malformed `property` (QTCREATORBUG-24587) + +### GLSL + +* Updated language specification (QTCREATORBUG-24068) + +Projects +-------- + +* Renamed `CurrentProject:*` variables to `CurrentDocument:Project:*` (QTCREATORBUG-12724, + QTCREATORBUG-24606) +* Fixed issue when environment changes after appending or prepending path (QTCREATORBUG-24105) +* Fixed `Embedding of the UI Class` option for widget applications (QTCREATORBUG-24422) +* Fixed shell used for console applications (QTCREATORBUG-24659) + +### Wizards + +* Fixed creation of form editor class with namespace (QTCREATORBUG-24723) + +### CMake + +* Added option to unselect multiple configuration variables simultaneously + (QTCREATORBUG-22659) + +### Meson + +* Fixed updating of introspection data after reconfiguration + +Debugging +--------- + +* Fixed disabling and enabling breakpoints (QTCREATORBUG-24669) + +Analyzer +-------- + +### Clang + +* Re-added automatic analyzation of files on save +* Added multi-selection in diagnostics view (QTCREATORBUG-24396) + +Version Control Systems +----------------------- + +* Improved removal of multiple files (QTCREATORBUG-24385) +* Added option to add file when creating it from locator (QTCREATORBUG-24168) + +### Git + +* Added option to show file at specified revision (QTCREATORBUG-24689) + +### Gerrit + +* Added suggestion for local branch name when checking out patch set (QTCREATORBUG-24006) +* Fixed commit list in `Push to Gerrit` (QTCREATORBUG-24436) + +Test Integration +---------------- + +* Made it easier to re-run failed tests + +Platforms +--------- + +### macOS + +* Fixed type display when debugging with newest LLDB + +### Android + +* Improved manifest editor + * Added support for `xhdpi`, `xxhdpi` and `xxxhdpi` icons and splashscreens + * Added support for setting preferred screen orientation +* Added missing Android variables to completion in `.pro` and `.pri` files +* Fixed passing command line arguments to application (QTCREATORBUG-23712) + +Credits for these changes go to: +-------------------------------- +Alessandro Portale +Alexander Mishin +Alexis Jeandet +Andre Hartmann +André Pönitz +Antonio Di Monaco +Asit Dhal +Assam Boudjelthia +Christian Kandeler +Christian Stenger +Cristian Adam +David Schulz +Denis Shienkov +Eike Ziller +Fabio Falsini +Fawzi Mohamed +Federico Guerinoni +Henning Gruendl +Jeremy Ephron +Kai Köhne +Knud Dollereder +Lars Knoll +Leander Schulten +Leena Miettinen +Lukasz Ornatek +Mahmoud Badri +Martin Kampas +Michael Weghorn +Miikka Heikkinen +Miklós Márton +Morten Johan Sørvig +Orgad Shaneh +Robert Löhning +Tasuku Suzuki +Thiago Macieira +Thomas Hartmann +Tobias Hunger +Vikas Pachdha +Volodymyr Zibarov +Wojciech Smigaj diff --git a/doc/qtcreator/images/qml-code-completion.png b/doc/qtcreator/images/qml-code-completion.png index 61b24adb00c..227100907cb 100644 Binary files a/doc/qtcreator/images/qml-code-completion.png and b/doc/qtcreator/images/qml-code-completion.png differ diff --git a/doc/qtcreator/images/qml-code-snippet.png b/doc/qtcreator/images/qml-code-snippet.png index 65fcd04d706..805d252777e 100644 Binary files a/doc/qtcreator/images/qml-code-snippet.png and b/doc/qtcreator/images/qml-code-snippet.png differ diff --git a/doc/qtcreator/images/qml-snippet-editor.png b/doc/qtcreator/images/qml-snippet-editor.png index 31d58040f34..91befb0cec5 100644 Binary files a/doc/qtcreator/images/qml-snippet-editor.png and b/doc/qtcreator/images/qml-snippet-editor.png differ diff --git a/doc/qtcreator/images/qmldesigner-code-completion.png b/doc/qtcreator/images/qmldesigner-code-completion.png index f374766e054..9a73bd018b2 100644 Binary files a/doc/qtcreator/images/qmldesigner-code-completion.png and b/doc/qtcreator/images/qmldesigner-code-completion.png differ diff --git a/doc/qtcreator/images/qtcreator-codecompletion.png b/doc/qtcreator/images/qtcreator-codecompletion.png index 1d3b5600a9b..2a9ebe49f8a 100644 Binary files a/doc/qtcreator/images/qtcreator-codecompletion.png and b/doc/qtcreator/images/qtcreator-codecompletion.png differ diff --git a/doc/qtcreator/images/qtcreator-context-sensitive-help.png b/doc/qtcreator/images/qtcreator-context-sensitive-help.png index fb5720bb4af..5b732f0bdbf 100644 Binary files a/doc/qtcreator/images/qtcreator-context-sensitive-help.png and b/doc/qtcreator/images/qtcreator-context-sensitive-help.png differ diff --git a/doc/qtcreator/images/qtcreator-edit-code-snippets.png b/doc/qtcreator/images/qtcreator-edit-code-snippets.png index 91e50ce5ba1..03777dcdc5b 100644 Binary files a/doc/qtcreator/images/qtcreator-edit-code-snippets.png and b/doc/qtcreator/images/qtcreator-edit-code-snippets.png differ diff --git a/doc/qtcreator/images/qtcreator-help-add-bookmark-dlg.png b/doc/qtcreator/images/qtcreator-help-add-bookmark-dlg.png index bec770fe986..9a808c522fa 100644 Binary files a/doc/qtcreator/images/qtcreator-help-add-bookmark-dlg.png and b/doc/qtcreator/images/qtcreator-help-add-bookmark-dlg.png differ diff --git a/doc/qtcreator/images/qtcreator-help-filters.png b/doc/qtcreator/images/qtcreator-help-filters.png index 73af52f158e..ab60d0edd81 100644 Binary files a/doc/qtcreator/images/qtcreator-help-filters.png and b/doc/qtcreator/images/qtcreator-help-filters.png differ diff --git a/doc/qtcreator/images/qtcreator-help-search.png b/doc/qtcreator/images/qtcreator-help-search.png index ca29bd6593f..40772692032 100644 Binary files a/doc/qtcreator/images/qtcreator-help-search.png and b/doc/qtcreator/images/qtcreator-help-search.png differ diff --git a/doc/qtcreator/images/qtcreator-options-environment-system.png b/doc/qtcreator/images/qtcreator-options-environment-system.png index e9d5b1dea44..bc7ccc8ee8c 100644 Binary files a/doc/qtcreator/images/qtcreator-options-environment-system.png and b/doc/qtcreator/images/qtcreator-options-environment-system.png differ diff --git a/doc/qtcreator/images/qtcreator-options-texteditor-behavior-file-encodings.png b/doc/qtcreator/images/qtcreator-options-texteditor-behavior-file-encodings.png new file mode 100644 index 00000000000..3fc01471952 Binary files /dev/null and b/doc/qtcreator/images/qtcreator-options-texteditor-behavior-file-encodings.png differ diff --git a/doc/qtcreator/images/qtcreator-options-texteditor-completion.png b/doc/qtcreator/images/qtcreator-options-texteditor-completion.png new file mode 100644 index 00000000000..b501035e836 Binary files /dev/null and b/doc/qtcreator/images/qtcreator-options-texteditor-completion.png differ diff --git a/doc/qtcreator/images/qtcreator-snippet-modifiers.png b/doc/qtcreator/images/qtcreator-snippet-modifiers.png index 9d6f3657f7d..1fa3d3169f6 100644 Binary files a/doc/qtcreator/images/qtcreator-snippet-modifiers.png and b/doc/qtcreator/images/qtcreator-snippet-modifiers.png differ diff --git a/doc/qtcreator/src/editors/creator-code-completion.qdoc b/doc/qtcreator/src/editors/creator-code-completion.qdoc index 7d7b627eb32..c635776fb5b 100644 --- a/doc/qtcreator/src/editors/creator-code-completion.qdoc +++ b/doc/qtcreator/src/editors/creator-code-completion.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -31,7 +31,7 @@ \title Completing Code As you write code, \QC suggests properties, IDs, and code snippets to - complete the code. It provides a list of context-sensitive suggestions to + complete the code. It provides a list of suggestions to the statement currently under your cursor. Press \key Tab or \key Enter to accept the selected suggestion and complete the code. @@ -48,17 +48,39 @@ To open the list of suggestions at any time, press \key {Ctrl+Space}. If only one option is available, \QC inserts it automatically. - When completion is invoked manually, \QC completes the common prefix of the - list of suggestions. This is especially useful for classes with several - similarly named members. To disable this functionality, uncheck - \uicontrol {Autocomplete common prefix} in the code completion preferences. - Select \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} - > \uicontrol Completion. + \section1 Specifying Completion Settings + + To specify settings for code completion, select \uicontrol Tools > + \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Completion. + + \image qtcreator-options-texteditor-completion.png "Text Editor Completion options" By default, code completion does not consider case. To apply full or first-letter case-sensitivity, select \uicontrol Full or \uicontrol {First Letter} in the \uicontrol {Case-sensitivity} field. + By default, code completion is always invoked, but you can change this + behavior in the \uicontrol {Activate completion} field to invoke + it \uicontrol Manually or \uicontrol {When Triggered}. + + You can set a timeout in milliseconds for code completion in the + \uicontrol {Timeout in ms} field. + + In the \uicontrol {Character threshold} field, specify the number of + characters you need to enter before code completion is triggered. + + When completion is invoked manually, \QC completes the common prefix of the + list of suggestions. This is especially useful for classes with several + similarly named members. To disable this functionality, deselect the + \uicontrol {Autocomplete common prefix} check box. + + Select the \uicontrol {Automatically split strings} check box to split + a string to two lines by adding an end quote at the cursor position when + you press \key Enter and a start quote at the beginning of the next line, + before the rest of the string. In addition, pressing \key {Shift+Enter} + inserts an escape character at the cursor position and moves the rest of + the string to the next line. + \section1 Summary of Available Types The following table lists available types for code completion and icon used diff --git a/doc/qtcreator/src/editors/creator-code-refactoring.qdoc b/doc/qtcreator/src/editors/creator-code-refactoring.qdoc index ab8145b5f72..2f65b3568f5 100644 --- a/doc/qtcreator/src/editors/creator-code-refactoring.qdoc +++ b/doc/qtcreator/src/editors/creator-code-refactoring.qdoc @@ -507,6 +507,19 @@ be \c {public}, \c {protected}, \c {private}, \c {public slot}, \c {protected slot}, or \c {private slot}. \li Function name + \row + \li Add Class Member + \li Adds a member declaration for the class member being + initialized if it is not yet declared. You must enter + the data type of the member. + \li Identifier + \row + \li Create Implementations for Member Functions + \li Creates implementations for all member functions in one go. + In the \uicontrol {Member Function Implementations} dialog, + you can specify whether the member functions are generated + inline or outside the class. + \li Function name \row \li Switch with Next/Previous Parameter \li Moves a parameter down or up one position in a parameter list. @@ -795,6 +808,17 @@ Also, the coding style for pointers and references is not respected yet. \li Stack Variable + \row + \li Remove \c {using namespace} and Adjust Type Names Accordingly + \li Remove occurrences of \c {using namespace} in the local scope + and adjust type names accordingly. + \li \c using directive + \row + \li Remove All Occurrences of \c {using namespace} in Global Scope + and Adjust Type Names Accordingly + \li Remove all occurrences of \c {using namespace} in the global + scope and adjust type names accordingly. + \li \c using directive \row \li Convert connect() to Qt 5 Style \li Converts a Qt 4 QObject::connect() to Qt 5 style. diff --git a/doc/qtcreator/src/editors/creator-editors-options-text.qdoc b/doc/qtcreator/src/editors/creator-editors-options-text.qdoc index bfee108f3c4..8414fe8cfe2 100644 --- a/doc/qtcreator/src/editors/creator-editors-options-text.qdoc +++ b/doc/qtcreator/src/editors/creator-editors-options-text.qdoc @@ -97,11 +97,10 @@ \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Behavior, and then select a suitable option in \uicontrol {Default encoding}. - Qt 5 requires UTF-8 encoded source files, and therefore the default encoding - was changed from \uicontrol System to \uicontrol UTF-8 in \QC version 2.6. - However, the \uicontrol {Default encoding} field still displays the value - \uicontrol System if the default system encoding is set to UTF-8. + \image qtcreator-options-texteditor-behavior-file-encodings.png "File encoding options" + Qt 5 and Qt 6 require UTF-8 encoded source files, and therefore the default + encoding is set to \uicontrol UTF-8. Detecting the correct encoding is tricky, so \QC will not try to do so. Instead, it displays the following error message when you try to edit a file that is not UTF-8 encoded: \uicontrol {Error: Could not decode "filename" with diff --git a/doc/qtcreator/src/howto/creator-help.qdoc b/doc/qtcreator/src/howto/creator-help.qdoc index 1ed54048667..af152620c38 100644 --- a/doc/qtcreator/src/howto/creator-help.qdoc +++ b/doc/qtcreator/src/howto/creator-help.qdoc @@ -47,6 +47,9 @@ is not available, the tooltip displays type information for the symbol. + \li To display tooltips for function signatures regardless of the + cursor position in the function call, press \key {Ctrl+Shift+D}. + \li To display the full help on a Qt class or function, press \key F1 or select \uicontrol {Context Help} in the context menu. The documentation is displayed in a @@ -75,24 +78,11 @@ To switch to the editor context when you close the last help page, select the \uicontrol {Return to editor on closing the last page} check box. - \section1 Selecting the Help Viewer Backend - The help viewer backend determines the style sheet that is used to display - the help files. A help viewer backend that is based on the \l {QTextBrowser} - is used by default. However, it has several issues that have been fixed when - using litehtml as the help viewer backend. - - On \macos, you can also use a help viewer backend that is based on the - system WebView component. - - To switch the help viewer backend: - - \list 1 - \li Select \uicontrol Tools > \uicontrol Options > \uicontrol Help > - \uicontrol General. - \li In the \uicontrol {Viewer backend} field, select a viewer backend. - \li Reload the help page to take the new backend to use. - \endlist + the help files. The default help viewer backend that is based on litehtml + is recommended for viewing Qt documentation. You can choose another help + viewer backend in the \uicontrol {Viewer backend} field. To take the new + backend to use, reload the help page. \section1 Viewing Function Tooltips diff --git a/doc/qtcreator/src/howto/creator-keyboard-shortcuts.qdoc b/doc/qtcreator/src/howto/creator-keyboard-shortcuts.qdoc index d5546a80a4b..31ba7cf46b8 100644 --- a/doc/qtcreator/src/howto/creator-keyboard-shortcuts.qdoc +++ b/doc/qtcreator/src/howto/creator-keyboard-shortcuts.qdoc @@ -283,6 +283,12 @@ \li Esc \row \li Exit \QC + + By default, \QC exits without asking for confirmation, unless + there are unsaved changes in open files. To always be asked, + select the \uicontrol {Ask for confirmation before exiting} + check box in \uicontrol Tools > \uicontrol Options > + \uicontrol Environment > \uicontrol System. \li Ctrl+Q \endtable @@ -304,6 +310,10 @@ \row \li Trigger a completion in this scope \li Ctrl+Space + \row + \li Display tooltips for function signatures regardless of the + cursor position in the function call + \li Ctrl+Shift+D \row \li Copy line \li Ctrl+Ins diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc index 13080a27efd..d4d9a5600c6 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc @@ -373,7 +373,8 @@ The wizard supports namespaces. To use a namespace, enter a qualified class name in the \uicontrol {Class name} field. For example: - MyNamespace::MySubNamespace::MyClass. + \c MyNamespace::MySubNamespace::MyClass. The wizard suggests + existing namespaces and class names as you type. \image qtcreator-cpp-class-wizard.png "Enter Class Name dialog" diff --git a/share/qtcreator/debugger/misctypes.py b/share/qtcreator/debugger/misctypes.py index 85926535518..cb162677375 100644 --- a/share/qtcreator/debugger/misctypes.py +++ b/share/qtcreator/debugger/misctypes.py @@ -36,36 +36,42 @@ import re def qdump____m128(d, value): d.putEmptyValue() + d.putExpandable() if d.isExpanded(): d.putArrayData(value.address(), 4, d.lookupType('float')) def qdump____m256(d, value): d.putEmptyValue() + d.putExpandable() if d.isExpanded(): d.putArrayData(value.address(), 8, d.lookupType('float')) def qdump____m512(d, value): d.putEmptyValue() + d.putExpandable() if d.isExpanded(): d.putArrayData(value.address(), 16, d.lookupType('float')) def qdump____m128d(d, value): d.putEmptyValue() + d.putExpandable() if d.isExpanded(): d.putArrayData(value.address(), 2, d.lookupType('double')) def qdump____m256d(d, value): d.putEmptyValue() + d.putExpandable() if d.isExpanded(): d.putArrayData(value.address(), 4, d.lookupType('double')) def qdump____m512d(d, value): d.putEmptyValue() + d.putExpandable() if d.isExpanded(): d.putArrayData(value.address(), 8, d.lookupType('double')) @@ -73,6 +79,7 @@ def qdump____m512d(d, value): def qdump____m128i(d, value): data = d.hexencode(value.data(16)) d.putValue(':'.join('%04x' % int(data[i:i + 4], 16) for i in range(0, 32, 4))) + d.putExpandable() if d.isExpanded(): with Children(d): addr = value.address() @@ -85,6 +92,7 @@ def qdump____m128i(d, value): def qdump____m256i(d, value): data = d.hexencode(value.data(32)) d.putValue(':'.join('%04x' % int(data[i:i + 4], 16) for i in range(0, 64, 4))) + d.putExpandable() if d.isExpanded(): with Children(d): addr = value.address() @@ -98,6 +106,7 @@ def qdump____m512i(d, value): data = d.hexencode(value.data(64)) d.putValue(':'.join('%04x' % int(data[i:i + 4], 16) for i in range(0, 64, 4)) + ', ' + ':'.join('%04x' % int(data[i:i + 4], 16) for i in range(64, 128, 4))) + d.putExpandable() if d.isExpanded(): with Children(d): d.putArrayItem('uint32x16', value.address(), 16, 'unsigned int') diff --git a/share/qtcreator/qmldesigner/qt4mcu/metadata.qml b/share/qtcreator/qmldesigner/qt4mcu/metadata.qml new file mode 100644 index 00000000000..09c612ab401 --- /dev/null +++ b/share/qtcreator/qmldesigner/qt4mcu/metadata.qml @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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. +** +****************************************************************************/ + +//list of files in the current system +Metadata { + id: metadataFile + + defaultVersion: v14 + + VersionData { + id: v14 + name: "QUL 1.4" + path: "qul-14.qml" + } +} diff --git a/share/qtcreator/qmldesigner/qt4mcu/qul-14.qml b/share/qtcreator/qmldesigner/qt4mcu/qul-14.qml new file mode 100644 index 00000000000..8b9ffed3b88 --- /dev/null +++ b/share/qtcreator/qmldesigner/qt4mcu/qul-14.qml @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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. +** +****************************************************************************/ + +VersionData { + name: "QUL 1.4" + + bannedItems: ["QtQuick.AnimatedImage", + "QtQuick.BorderImage", + "QtQuick.FocusScope", + "QtQuick.TextInput", + "QtQuick.TextEdit", + "QtQuick.Flow", + "QtQuick.Grid", + "QtQuick.GridView", + "QtQuick.PathView", + "QtQuick.Controls", + "QtQuick.Controls.BusyIndicator", + "QtQuick.Controls.ButtonGroup", + "QtQuick.Controls.CheckDelegate", + "QtQuick.Controls.Container", + "QtQuick.Controls.ComboBox", + "QtQuick.Controls.DelayButton", + "QtQuick.Controls.Frame", + "QtQuick.Controls.GroupBox", + "QtQuick.Controls.ItemDelegate", + "QtQuick.Controls.Label", + "QtQuick.Controls.Page", + "QtQuick.Controls.PageIndicator", + "QtQuick.Controls.Pane", + "QtQuick.Controls.RadioDelegate", + "QtQuick.Controls.RangeSlider", + "QtQuick.Controls.RoundButton", + "QtQuick.Controls.ScrollView", + "QtQuick.Controls.SpinBox", + "QtQuick.Controls.StackView", + "QtQuick.Controls.SwipeDelegate", + "QtQuick.Controls.SwitchDelegate", + "QtQuick.Controls.ToolBar", + "QtQuick.Controls.ToolButton", + "QtQuick.Controls.TabBar", + "QtQuick.Controls.TabButton", + "QtQuick.Controls.TextArea", + "QtQuick.Controls.TextField", + "QtQuick.Controls.ToolSeparator", + "QtQuick.Controls.Tumbler"] + + allowedImports: ["QtQuick", + "QtQuick.Controls", + "QtQuick.Timeline"] + + bannedImports: ["FlowView"] + + //ComplexProperty is not a type, it's just a way to handle bigger props + ComplexProperty { + prefix: "font" + bannedProperties: ["wordSpacing", "letterSpacing", "hintingPreference", + "kerning", "preferShaping", "capitalization", + "strikeout", "underline", "styleName"] + } + + QtQuick.Item { + bannedProperties: ["layer", "opacity", "gradient", "smooth", "antialiasing", + "border", "baselineOffset", "focus", "activeFocusOnTab", + "rotation", "scale", "transformOrigin"] + } + + QtQuick.Flickable { + bannedProperties: ["boundsBehavior", "boundsMovement", "flickDeceleration", + "flickableDirection", "leftMargin", "rightMargin", "bottomMargin", "topMargin", + "originX", "originY", "pixelAligned", "pressDelay", "synchronousDrag"] + } + + QtQuick.MouseArea { + bannedProperties: ["propagateComposedEvents", "preventStealing", "cursorShape", + "scrollGestureEnabled", "drag", "acceptedButtons", "hoverEnabled"] + } + + QtQuick.Image { + allowChildren: false + allowedProperties: ["rotation", "scale", "transformOrigin"] + bannedProperties: ["mirror", "mipmap", "cache", "autoTransform", "asynchronous", + "sourceSize", "smooth"] + } + + QtQuick.Text { + allowChildren: false + allowedProperties: ["rotation", "scale", "transformOrigin"] + bannedProperties: ["elide", "lineHeight", "lineHeightMode", "wrapMode", "style", + "styleColor", "minimumPointSize", "minimumPixelSize", "styleColor", + "fontSizeMode", "renderType", "textFormat", "maximumLineCount"] + } + + //Padding is not an actual item, but rather set of properties in Text + Padding { + bannedProperties: ["bottomPadding", "topPadding", "leftPadding", "rightPadding"] + } + + QtQuick.Column { + bannedProperties: ["layoutDirection"] + } + + QtQuick.Row { + bannedProperties: ["layoutDirection"] + } + + QtQuick.ListView { + bannedProperties: ["cacheBuffer", "highlightRangeMode", "highlightMoveDuration", + "highlightResizeDuration", "preferredHighlightBegin", "layoutDirection", + "preferredHighlightEnd", "highlightFollowsCurrentItem", "keyNavigationWraps", + "snapMode", "highlightMoveVelocity", "highlightResizeVelocity"] + } + + QtQuick.Animation { + bannedProperties: ["paused"] + } + + //Quick Controls2 Items and properties: + + QtQuick.Controls.Control { + bannedProperties: ["focusPolicy", "hoverEnabled", "wheelEnabled"] + } + + QtQuick.Controls.AbstractButton { + bannedProperties: ["display", "autoExclusive"] + } + + QtQuick.Controls.ProgressBar { + bannedProperties: ["indeterminate"] + } + + QtQuick.Controls.Slider { + bannedProperties: ["live", "snapMode", "touchDragThreshold"] + } +} diff --git a/src/libs/3rdparty/cplusplus/CMakeLists.txt b/src/libs/3rdparty/cplusplus/CMakeLists.txt index 11ba09cab62..b8a8607a8c3 100644 --- a/src/libs/3rdparty/cplusplus/CMakeLists.txt +++ b/src/libs/3rdparty/cplusplus/CMakeLists.txt @@ -1,7 +1,6 @@ add_qtc_library(3rd_cplusplus OBJECT PUBLIC_DEPENDS Qt5::Core Utils DEFINES CPLUSPLUS_BUILD_LIB - INCLUDES "${PROJECT_SOURCE_DIR}/src/libs" SOURCES AST.cpp AST.h ASTClone.cpp diff --git a/src/libs/cplusplus/CMakeLists.txt b/src/libs/cplusplus/CMakeLists.txt index 829534acd40..9ca49291d4c 100644 --- a/src/libs/cplusplus/CMakeLists.txt +++ b/src/libs/cplusplus/CMakeLists.txt @@ -6,7 +6,6 @@ add_qtc_library(CPlusPlus DEPENDS Utils Qt5::Concurrent DEFINES CPLUSPLUS_BUILD_LIB PUBLIC_DEPENDS 3rd_cplusplus Qt5::Gui - PUBLIC_INCLUDES src/libs/3rdparty SOURCES ASTParent.cpp ASTParent.h ASTPath.cpp ASTPath.h diff --git a/src/libs/sqlite/CMakeLists.txt b/src/libs/sqlite/CMakeLists.txt index 33abce755f8..30e5edf12fc 100644 --- a/src/libs/sqlite/CMakeLists.txt +++ b/src/libs/sqlite/CMakeLists.txt @@ -17,6 +17,7 @@ add_qtc_library(Sqlite ../3rdparty/sqlite SOURCES ../3rdparty/sqlite/sqlite3.c + ../3rdparty/sqlite/sqlite3.h ../3rdparty/sqlite/carray.c constraints.h createtablesqlstatementbuilder.cpp createtablesqlstatementbuilder.h @@ -25,6 +26,7 @@ add_qtc_library(Sqlite sqlitecolumn.h sqlitedatabase.cpp sqlitedatabase.h sqlitedatabasebackend.cpp sqlitedatabasebackend.h + sqlitedatabaseinterface.h sqliteexception.cpp sqliteexception.h sqliteglobal.cpp sqliteglobal.h sqliteindex.h @@ -34,10 +36,12 @@ add_qtc_library(Sqlite sqlitesessions.cpp sqlitesessions.h sqlitetable.h sqlitetransaction.h - sqlitewritestatement.cpp sqlitewritestatement.h + sqlitetransaction.h sqlitevalue.h + sqlitewritestatement.cpp sqlitewritestatement.h sqlstatementbuilder.cpp sqlstatementbuilder.h sqlstatementbuilderexception.h + tableconstraints.h utf8string.cpp utf8string.h utf8stringvector.cpp utf8stringvector.h ) diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index 71628e51269..217a3abfa70 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -886,8 +886,10 @@ void SelectionAspect::addToLayout(LayoutBuilder &builder) d->m_buttons.append(button); d->m_buttonGroup->addButton(button); connect(button, &QAbstractButton::clicked, this, [this, i] { - d->m_value = i; - emit changed(); + if (d->m_value != i) { + d->m_value = i; + emit changed(); + } }); } break; @@ -899,7 +901,12 @@ void SelectionAspect::addToLayout(LayoutBuilder &builder) for (int i = 0, n = d->m_options.size(); i < n; ++i) d->m_comboBox->addItem(d->m_options.at(i).displayName); connect(d->m_comboBox.data(), QOverload::of(&QComboBox::activated), this, - [this](int index) { d->m_value = index; emit changed(); }); + [this](int index) { + if (d->m_value != index) { + d->m_value = index; + emit changed(); + } + }); d->m_comboBox->setCurrentIndex(d->m_value); builder.addItems({d->m_label.data(), d->m_comboBox.data()}); break; diff --git a/src/libs/utils/images/download.png b/src/libs/utils/images/download.png new file mode 100644 index 00000000000..c95b062add5 Binary files /dev/null and b/src/libs/utils/images/download.png differ diff --git a/src/libs/utils/images/download@2x.png b/src/libs/utils/images/download@2x.png new file mode 100644 index 00000000000..2fe43f05ccd Binary files /dev/null and b/src/libs/utils/images/download@2x.png differ diff --git a/src/libs/utils/images/download_arrow.png b/src/libs/utils/images/download_arrow.png deleted file mode 100644 index c73bf628f4b..00000000000 Binary files a/src/libs/utils/images/download_arrow.png and /dev/null differ diff --git a/src/libs/utils/images/download_arrow@2x.png b/src/libs/utils/images/download_arrow@2x.png deleted file mode 100644 index aabf6fce787..00000000000 Binary files a/src/libs/utils/images/download_arrow@2x.png and /dev/null differ diff --git a/src/libs/utils/images/download_base.png b/src/libs/utils/images/download_base.png deleted file mode 100644 index 25163bef64c..00000000000 Binary files a/src/libs/utils/images/download_base.png and /dev/null differ diff --git a/src/libs/utils/images/download_base@2x.png b/src/libs/utils/images/download_base@2x.png deleted file mode 100644 index a5e7405ac3d..00000000000 Binary files a/src/libs/utils/images/download_base@2x.png and /dev/null differ diff --git a/src/libs/utils/utils.qrc b/src/libs/utils/utils.qrc index 180c5e5b43b..da1778f08ad 100644 --- a/src/libs/utils/utils.qrc +++ b/src/libs/utils/utils.qrc @@ -231,10 +231,8 @@ images/dir.png images/online.png images/online@2x.png - images/download_arrow.png - images/download_arrow@2x.png - images/download_base.png - images/download_base@2x.png + images/download.png + images/download@2x.png ../3rdparty/xdg/freedesktop.org.xml diff --git a/src/libs/utils/utilsicons.cpp b/src/libs/utils/utilsicons.cpp index 04d35829626..3fa626551b8 100644 --- a/src/libs/utils/utilsicons.cpp +++ b/src/libs/utils/utilsicons.cpp @@ -203,8 +203,7 @@ const Icon ONLINE({ const Icon ONLINE_TOOLBAR({ {QLatin1String(":/utils/images/online.png"), Theme::IconsBaseColor}}); const Icon DOWNLOAD({ - {QLatin1String(":/utils/images/download_arrow.png"), Theme::IconsRunColor}, - {QLatin1String(":/utils/images/download_base.png"), Theme::PanelTextColorDark}}, Icon::Tint); + {QLatin1String(":/utils/images/download.png"), Theme::PanelTextColorMid}}, Icon::Tint); const Icon WARNING({ {QLatin1String(":/utils/images/warningfill.png"), Theme::BackgroundColorNormal}, diff --git a/src/plugins/autotest/testresultmodel.cpp b/src/plugins/autotest/testresultmodel.cpp index 386c22c73c3..f91ad9e097b 100644 --- a/src/plugins/autotest/testresultmodel.cpp +++ b/src/plugins/autotest/testresultmodel.cpp @@ -395,7 +395,7 @@ int TestResultModel::resultTypeCount(ResultType type) const { int result = 0; - for (const auto &id : m_reportedSummary.keys()) { + for (const auto &id : m_testResultCount.keys()) { // if we got a result count from the framework prefer that over our counted results int reported = m_reportedSummary[id].value(type); result += reported != 0 ? reported : m_testResultCount.value(id).value(type); diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 0853a46d93e..931d7835236 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -3228,7 +3228,7 @@ public: : CppQuickFixOperation(interface), m_class(theClass), m_member(member), m_type(type) { setDescription(QCoreApplication::translate("CppTools::Quickfix", - "Add class member \"%1\"").arg(m_member)); + "Add Class Member \"%1\"").arg(m_member)); } private: @@ -3238,7 +3238,7 @@ private: if (type.isEmpty()) { type = QInputDialog::getText( Core::ICore::dialogParent(), - QCoreApplication::translate("CppTools::Quickfix","Please provide the type"), + QCoreApplication::translate("CppTools::Quickfix","Provide the type"), QCoreApplication::translate("CppTools::Quickfix","Data type:"), QLineEdit::Normal); } @@ -7568,13 +7568,13 @@ public: if (m_removeAllAtGlobalScope) { setDescription(QApplication::translate( "CppTools::QuickFix", - "Remove all occurrences of 'using namespace %1' at the global scope " - "and adjust type names accordingly") + "Remove All Occurrences of \"using namespace %1\" in Global Scope " + "and Adjust Type Names Accordingly") .arg(name)); } else { setDescription(QApplication::translate("CppTools::QuickFix", - "Remove 'using namespace %1' and " - "adjust type names accordingly") + "Remove \"using namespace %1\" and " + "Adjust Type Names Accordingly") .arg(name)); } } diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 80b1611b8d5..e8a4ecf844c 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -929,9 +929,14 @@ static bool isOnlyControlModifier(const Qt::KeyboardModifiers &mods) return (mods ^ ControlModifier) == Qt::NoModifier; } -static bool hasControlModifier(const Qt::KeyboardModifiers &mods) +static bool isAcceptableModifier(const Qt::KeyboardModifiers &mods) { - return mods.testFlag(ControlModifier); + if (mods & ControlModifier) { + // Generally, CTRL is not fine, except in combination with ALT. + // See QTCREATORBUG-24673 + return mods & AltModifier; + } + return true; } @@ -1106,7 +1111,7 @@ public: bool is(int c) const { - return m_xkey == c && !hasControlModifier(m_modifiers); + return m_xkey == c && isAcceptableModifier(m_modifiers); } bool isControl() const diff --git a/src/plugins/projectexplorer/buildstepspage.cpp b/src/plugins/projectexplorer/buildstepspage.cpp index 25685ea9933..cc642d0d934 100644 --- a/src/plugins/projectexplorer/buildstepspage.cpp +++ b/src/plugins/projectexplorer/buildstepspage.cpp @@ -224,32 +224,6 @@ BuildStepListWidget::~BuildStepListWidget() m_buildStepsData.clear(); } -void BuildStepListWidget::updateSummary() -{ - auto step = qobject_cast(sender()); - if (step) { - foreach (const BuildStepsWidgetData *s, m_buildStepsData) { - if (s->step == step) { - s->detailsWidget->setSummaryText(step->summaryText()); - break; - } - } - } -} - -void BuildStepListWidget::updateEnabledState() -{ - auto step = qobject_cast(sender()); - if (step) { - foreach (const BuildStepsWidgetData *s, m_buildStepsData) { - if (s->step == step) { - s->toolWidget->setBuildStepEnabled(step->enabled()); - break; - } - } - } -} - void BuildStepListWidget::updateAddBuildStepMenu() { QMenu *menu = m_addButton->menu(); @@ -285,11 +259,14 @@ void BuildStepListWidget::addBuildStep(int pos) m_vbox->insertWidget(pos, s->detailsWidget); - connect(s->step, &BuildStep::updateSummary, - this, &BuildStepListWidget::updateSummary); + connect(s->step, &BuildStep::updateSummary, this, [s] { + s->detailsWidget->setSummaryText(s->step->summaryText()); + }); + + connect(s->step, &BuildStep::enabledChanged, this, [s] { + s->toolWidget->setBuildStepEnabled(s->step->enabled()); + }); - connect(s->step, &BuildStep::enabledChanged, - this, &BuildStepListWidget::updateEnabledState); // Expand new build steps by default const bool expand = newStep->hasUserExpansionState() diff --git a/src/plugins/projectexplorer/buildstepspage.h b/src/plugins/projectexplorer/buildstepspage.h index 0f8ee879ec0..f23a0d2bdde 100644 --- a/src/plugins/projectexplorer/buildstepspage.h +++ b/src/plugins/projectexplorer/buildstepspage.h @@ -98,8 +98,6 @@ public: private: void updateAddBuildStepMenu(); void addBuildStep(int pos); - void updateSummary(); - void updateEnabledState(); void stepMoved(int from, int to); void removeBuildStep(int pos); diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp index 28f82017f29..33ecc6d0f33 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.cpp +++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp @@ -52,6 +52,12 @@ namespace ProjectExplorer { /*! \class ProjectExplorer::TerminalAspect + \inmodule QtCreator + + \brief The TerminalAspect class lets a user specify that an executable + should be run in a separate terminal. + + The initial value is provided as a hint from the build systems. */ TerminalAspect::TerminalAspect() @@ -64,6 +70,9 @@ TerminalAspect::TerminalAspect() this, &TerminalAspect::calculateUseTerminal); } +/*! + \reimp +*/ void TerminalAspect::addToLayout(LayoutBuilder &builder) { QTC_CHECK(!m_checkBox); @@ -77,6 +86,9 @@ void TerminalAspect::addToLayout(LayoutBuilder &builder) }); } +/*! + \reimp +*/ void TerminalAspect::fromMap(const QVariantMap &map) { if (map.contains(settingsKey())) { @@ -90,6 +102,9 @@ void TerminalAspect::fromMap(const QVariantMap &map) m_checkBox->setChecked(m_useTerminal); } +/*! + \reimp +*/ void TerminalAspect::toMap(QVariantMap &data) const { if (m_userSet) @@ -114,17 +129,26 @@ void TerminalAspect::calculateUseTerminal() m_checkBox->setChecked(m_useTerminal); } +/*! + Returns whether a separate terminal should be used. +*/ bool TerminalAspect::useTerminal() const { return m_useTerminal; } +/*! + Sets the initial value to \a hint. +*/ void TerminalAspect::setUseTerminalHint(bool hint) { m_useTerminalHint = hint; calculateUseTerminal(); } +/*! + Returns whether the user set the value. +*/ bool TerminalAspect::isUserSet() const { return m_userSet; @@ -132,6 +156,10 @@ bool TerminalAspect::isUserSet() const /*! \class ProjectExplorer::WorkingDirectoryAspect + \inmodule QtCreator + + \brief The WorkingDirectoryAspect class lets the user specify a + working directory for running the executable. */ WorkingDirectoryAspect::WorkingDirectoryAspect() @@ -141,6 +169,9 @@ WorkingDirectoryAspect::WorkingDirectoryAspect() setSettingsKey("RunConfiguration.WorkingDirectory"); } +/*! + \reimp +*/ void WorkingDirectoryAspect::addToLayout(LayoutBuilder &builder) { QTC_CHECK(!m_chooser); @@ -187,6 +218,9 @@ void WorkingDirectoryAspect::resetPath() m_chooser->setFilePath(m_defaultWorkingDirectory); } +/*! + \reimp +*/ void WorkingDirectoryAspect::fromMap(const QVariantMap &map) { m_workingDirectory = FilePath::fromString(map.value(settingsKey()).toString()); @@ -199,6 +233,9 @@ void WorkingDirectoryAspect::fromMap(const QVariantMap &map) m_chooser->setFilePath(m_workingDirectory.isEmpty() ? m_defaultWorkingDirectory : m_workingDirectory); } +/*! + \reimp +*/ void WorkingDirectoryAspect::toMap(QVariantMap &data) const { const QString wd = m_workingDirectory == m_defaultWorkingDirectory @@ -207,6 +244,11 @@ void WorkingDirectoryAspect::toMap(QVariantMap &data) const data.insert(keyForDefaultWd(), m_defaultWorkingDirectory.toString()); } +/*! + Returns the selected directory. + + Macros in the value are expanded using \a expander. +*/ FilePath WorkingDirectoryAspect::workingDirectory(const MacroExpander *expander) const { const Utils::Environment env = m_envAspect ? m_envAspect->environment() @@ -222,11 +264,19 @@ FilePath WorkingDirectoryAspect::defaultWorkingDirectory() const return m_defaultWorkingDirectory; } +/*! + Returns the selected directory. + + Macros in the value are not expanded. +*/ FilePath WorkingDirectoryAspect::unexpandedWorkingDirectory() const { return m_workingDirectory; } +/*! + Sets the default value to \a defaultWorkingDir. +*/ void WorkingDirectoryAspect::setDefaultWorkingDirectory(const FilePath &defaultWorkingDir) { if (defaultWorkingDir == m_defaultWorkingDirectory) @@ -244,6 +294,9 @@ void WorkingDirectoryAspect::setDefaultWorkingDirectory(const FilePath &defaultW } } +/*! + \internal +*/ PathChooser *WorkingDirectoryAspect::pathChooser() const { return m_chooser; @@ -252,6 +305,10 @@ PathChooser *WorkingDirectoryAspect::pathChooser() const /*! \class ProjectExplorer::ArgumentsAspect + \inmodule QtCreator + + \brief The ArgumentsAspect class lets a user specify command line + arguments for an executable. */ ArgumentsAspect::ArgumentsAspect() @@ -259,8 +316,14 @@ ArgumentsAspect::ArgumentsAspect() setDisplayName(tr("Arguments")); setId("ArgumentsAspect"); setSettingsKey("RunConfiguration.Arguments"); + m_labelText = tr("Command line arguments:"); } +/*! + Returns the main value of this aspect. + + Macros in the value are expanded using \a expander. +*/ QString ArgumentsAspect::arguments(const MacroExpander *expander) const { QTC_ASSERT(expander, return m_arguments); @@ -273,11 +336,19 @@ QString ArgumentsAspect::arguments(const MacroExpander *expander) const return expanded; } +/*! + Returns the main value of this aspect. + + Macros in the value are not expanded. +*/ QString ArgumentsAspect::unexpandedArguments() const { return m_arguments; } +/*! + Sets the main value of this aspect to \a arguments. +*/ void ArgumentsAspect::setArguments(const QString &arguments) { if (arguments != m_arguments) { @@ -290,11 +361,26 @@ void ArgumentsAspect::setArguments(const QString &arguments) m_multiLineChooser->setPlainText(arguments); } +/*! + Sets the displayes label text to \a labelText. +*/ +void ArgumentsAspect::setLabelText(const QString &labelText) +{ + m_labelText = labelText; +} + +/*! + Adds a button to reset the main value of this aspect to the value + computed by \a resetter. +*/ void ArgumentsAspect::setResetter(const std::function &resetter) { m_resetter = resetter; } +/*! + Resets the main value of this aspect. +*/ void ArgumentsAspect::resetArguments() { QString arguments; @@ -303,6 +389,9 @@ void ArgumentsAspect::resetArguments() setArguments(arguments); } +/*! + \reimp +*/ void ArgumentsAspect::fromMap(const QVariantMap &map) { QVariant args = map.value(settingsKey()); @@ -322,12 +411,18 @@ void ArgumentsAspect::fromMap(const QVariantMap &map) m_multiLineChooser->setPlainText(m_arguments); } +/*! + \reimp +*/ void ArgumentsAspect::toMap(QVariantMap &map) const { map.insert(settingsKey(), m_arguments); map.insert(settingsKey() + ".multi", m_multiLine); } +/*! + \internal +*/ QWidget *ArgumentsAspect::setupChooser() { if (m_multiLine) { @@ -348,10 +443,12 @@ QWidget *ArgumentsAspect::setupChooser() return m_chooser.data(); } +/*! + \reimp +*/ void ArgumentsAspect::addToLayout(LayoutBuilder &builder) { QTC_CHECK(!m_chooser && !m_multiLineChooser && !m_multiLineButton); - builder.addItem(tr("Command line arguments:")); const auto container = new QWidget; const auto containerLayout = new QHBoxLayout(container); @@ -394,11 +491,18 @@ void ArgumentsAspect::addToLayout(LayoutBuilder &builder) containerLayout->setAlignment(m_resetButton, Qt::AlignTop); } - builder.addItem(container); + builder.addItems({m_labelText, container}); } /*! \class ProjectExplorer::ExecutableAspect + \inmodule QtCreator + + \brief The ExecutableAspect class provides a building block to provide an + executable for a RunConfiguration. + + It combines a StringAspect that is typically updated automatically + by the build system's parsing results with an optional manual override. */ ExecutableAspect::ExecutableAspect() @@ -414,12 +518,21 @@ ExecutableAspect::ExecutableAspect() this, &ExecutableAspect::changed); } +/*! + \internal +*/ ExecutableAspect::~ExecutableAspect() { delete m_alternativeExecutable; m_alternativeExecutable = nullptr; } +/*! + Sets the display style of the paths to the default used on \a osType, + backslashes on Windows, forward slashes elsewhere. + + \sa Utils::StringAspect::setDisplayFilter() +*/ void ExecutableAspect::setExecutablePathStyle(OsType osType) { m_executable.setDisplayFilter([osType](const QString &pathName) { @@ -427,6 +540,11 @@ void ExecutableAspect::setExecutablePathStyle(OsType osType) }); } +/*! + Sets the settings key for history completion to \a historyCompleterKey. + + \sa Utils::PathChooser::setHistoryCompleter() +*/ void ExecutableAspect::setHistoryCompleter(const QString &historyCompleterKey) { m_executable.setHistoryCompleter(historyCompleterKey); @@ -434,6 +552,11 @@ void ExecutableAspect::setHistoryCompleter(const QString &historyCompleterKey) m_alternativeExecutable->setHistoryCompleter(historyCompleterKey); } +/*! + Sets the acceptable kind of path values to \a expectedKind. + + \sa Utils::PathChooser::setExpectedKind() +*/ void ExecutableAspect::setExpectedKind(const PathChooser::Kind expectedKind) { m_executable.setExpectedKind(expectedKind); @@ -441,6 +564,13 @@ void ExecutableAspect::setExpectedKind(const PathChooser::Kind expectedKind) m_alternativeExecutable->setExpectedKind(expectedKind); } +/*! + Sets the environment in which paths will be searched when the expected kind + of paths is chosen as PathChooser::Command or PathChooser::ExistingCommand + to \a env. + + \sa Utils::StringAspect::setEnvironment() +*/ void ExecutableAspect::setEnvironment(const Environment &env) { m_executable.setEnvironment(env); @@ -448,11 +578,25 @@ void ExecutableAspect::setEnvironment(const Environment &env) m_alternativeExecutable->setEnvironment(env); } +/*! + Sets the display \a style for aspect. + + \sa Utils::StringAspect::setDisplayStyle() +*/ void ExecutableAspect::setDisplayStyle(StringAspect::DisplayStyle style) { m_executable.setDisplayStyle(style); } +/*! + Makes an auto-detected executable overridable by the user. + + The \a overridingKey specifies the settings key for the user-provided executable, + the \a useOverridableKey the settings key for the fact that it + is actually overridden the user. + + \sa Utils::StringAspect::makeCheckable() +*/ void ExecutableAspect::makeOverridable(const QString &overridingKey, const QString &useOverridableKey) { QTC_ASSERT(!m_alternativeExecutable, return); @@ -466,6 +610,13 @@ void ExecutableAspect::makeOverridable(const QString &overridingKey, const QStri this, &ExecutableAspect::changed); } +/*! + Returns the path of the executable specified by this aspect. In case + the user selected a manual override this will be the value specified + by the user. + + \sa makeOverridable() + */ FilePath ExecutableAspect::executable() const { if (m_alternativeExecutable && m_alternativeExecutable->isChecked()) @@ -474,6 +625,9 @@ FilePath ExecutableAspect::executable() const return m_executable.filePath(); } +/*! + \reimp +*/ void ExecutableAspect::addToLayout(LayoutBuilder &builder) { m_executable.addToLayout(builder); @@ -481,28 +635,49 @@ void ExecutableAspect::addToLayout(LayoutBuilder &builder) m_alternativeExecutable->addToLayout(builder.finishRow()); } +/*! + Sets the label text for the main chooser to + \a labelText. + + \sa Utils::StringAspect::setLabelText() +*/ void ExecutableAspect::setLabelText(const QString &labelText) { m_executable.setLabelText(labelText); } +/*! + Sets the place holder text for the main chooser to + \a placeHolderText. + + \sa Utils::StringAspect::setPlaceHolderText() +*/ void ExecutableAspect::setPlaceHolderText(const QString &placeHolderText) { m_executable.setPlaceHolderText(placeHolderText); } +/*! + Sets the value of the main chooser to \a executable. +*/ void ExecutableAspect::setExecutable(const FilePath &executable) { m_executable.setFilePath(executable); m_executable.setShowToolTipOnLabel(true); } +/*! + Sets the settings key to \a key. +*/ void ExecutableAspect::setSettingsKey(const QString &key) { BaseAspect::setSettingsKey(key); m_executable.setSettingsKey(key); } +/*! + \reimp +*/ void ExecutableAspect::fromMap(const QVariantMap &map) { m_executable.fromMap(map); @@ -510,6 +685,9 @@ void ExecutableAspect::fromMap(const QVariantMap &map) m_alternativeExecutable->fromMap(map); } +/*! + \reimp +*/ void ExecutableAspect::toMap(QVariantMap &map) const { m_executable.toMap(map); @@ -520,6 +698,14 @@ void ExecutableAspect::toMap(QVariantMap &map) const /*! \class ProjectExplorer::UseLibraryPathsAspect + \inmodule QtCreator + + \brief The UseLibraryPathsAspect class lets a user specify whether build + library search paths should be added to the relevant environment + variables. + + This modifies DYLD_LIBRARY_PATH and DYLD_FRAMEWORK_PATH on Mac, PATH + on Windows and LD_LIBRARY_PATH everywhere else. */ UseLibraryPathsAspect::UseLibraryPathsAspect() @@ -538,8 +724,13 @@ UseLibraryPathsAspect::UseLibraryPathsAspect() setValue(ProjectExplorerPlugin::projectExplorerSettings().addLibraryPathsToRunEnv); } + /*! \class ProjectExplorer::UseDyldSuffixAspect + \inmodule QtCreator + + \brief The UseDyldSuffixAspect class lets a user specify whether the + DYLD_IMAGE_SUFFIX environment variable should be used on Mac. */ UseDyldSuffixAspect::UseDyldSuffixAspect() diff --git a/src/plugins/projectexplorer/runconfigurationaspects.h b/src/plugins/projectexplorer/runconfigurationaspects.h index 038341c4f6f..d76580698c6 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.h +++ b/src/plugins/projectexplorer/runconfigurationaspects.h @@ -81,7 +81,7 @@ public: Utils::FilePath workingDirectory(const Utils::MacroExpander *expander) const; Utils::FilePath defaultWorkingDirectory() const; Utils::FilePath unexpandedWorkingDirectory() const; - void setDefaultWorkingDirectory(const Utils::FilePath &defaultWorkingDir); + void setDefaultWorkingDirectory(const Utils::FilePath &defaultWorkingDirectory); Utils::PathChooser *pathChooser() const; private: @@ -111,6 +111,7 @@ public: QString unexpandedArguments() const; void setArguments(const QString &arguments); + void setLabelText(const QString &labelText); void setResetter(const std::function &resetter); void resetArguments(); @@ -121,6 +122,7 @@ private: QWidget *setupChooser(); QString m_arguments; + QString m_labelText; QPointer m_chooser; QPointer m_multiLineChooser; QPointer m_multiLineButton; diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index adc99837890..620b3645f70 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -52,6 +52,7 @@ #include #include +#include #include #include #include @@ -81,6 +82,17 @@ QMakeStep::QMakeStep(BuildStepList *bsl, Utils::Id id) : AbstractProcessStep(bsl, id) { setLowPriority(); + + auto updateSummary = [this] { + BaseQtVersion *qtVersion = QtKitAspect::qtVersion(target()->kit()); + if (!qtVersion) + return tr("qmake: No Qt version set. Cannot run qmake."); + const QString program = qtVersion->qmakeCommand().fileName(); + return tr("qmake: %1 %2").arg(program, project()->projectFilePath().fileName()); + }; + setSummaryUpdater(updateSummary); + + connect(target(), &Target::kitChanged, this, updateSummary); } QmakeBuildConfiguration *QMakeStep::qmakeBuildConfiguration() const @@ -532,23 +544,14 @@ QWidget *QMakeStep::createConfigWidget() abisListWidget = new QListWidget(widget); qmakeAdditonalArgumentsLineEdit->setText(m_userArgs); - auto formLayout = new QFormLayout(widget); - formLayout->addRow(label_0, buildConfigurationWidget); - formLayout->addRow(qmakeArgsLabel, qmakeAdditonalArgumentsLineEdit); - formLayout->addRow(label, qmakeArgumentsEdit); - formLayout->addRow(abisLabel, abisListWidget); + LayoutBuilder builder(widget); + builder.addRow({label_0, buildConfigurationWidget}); + builder.addRow({qmakeArgsLabel, qmakeAdditonalArgumentsLineEdit}); + builder.addRow({label, qmakeArgumentsEdit}); + builder.addRow({abisLabel, abisListWidget}); qmakeBuildConfigChanged(); - auto updateSummary = [this] { - BaseQtVersion *qtVersion = QtKitAspect::qtVersion(target()->kit()); - if (!qtVersion) - return tr("qmake: No Qt version set. Cannot run qmake."); - const QString program = qtVersion->qmakeCommand().fileName(); - return tr("qmake: %1 %2").arg(program, project()->projectFilePath().fileName()); - }; - setSummaryUpdater(updateSummary); - updateSummary(); updateAbiWidgets(); updateEffectiveQMakeCall(); @@ -557,24 +560,27 @@ QWidget *QMakeStep::createConfigWidget() this, &QMakeStep::qmakeArgumentsLineEdited); connect(buildConfigurationComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &QMakeStep::buildConfigurationSelected); + connect(qmakeBuildConfiguration(), &QmakeBuildConfiguration::qmlDebuggingChanged, - this, [this] { + widget, [this] { linkQmlDebuggingLibraryChanged(); askForRebuild(tr("QML Debugging")); }); + connect(project(), &Project::projectLanguagesUpdated, - this, &QMakeStep::linkQmlDebuggingLibraryChanged); + widget, [this] { linkQmlDebuggingLibraryChanged(); }); connect(target(), &Target::parsingFinished, - qmakeArgumentsEdit, [this]() { updateEffectiveQMakeCall(); }); + widget, [this] { updateEffectiveQMakeCall(); }); connect(qmakeBuildConfiguration(), &QmakeBuildConfiguration::useQtQuickCompilerChanged, - this, &QMakeStep::useQtQuickCompilerChanged); + widget, [this] { useQtQuickCompilerChanged(); }); connect(qmakeBuildConfiguration(), &QmakeBuildConfiguration::separateDebugInfoChanged, - this, &QMakeStep::separateDebugInfoChanged); + widget, [this] { separateDebugInfoChanged(); }); connect(qmakeBuildConfiguration(), &QmakeBuildConfiguration::qmakeBuildConfigurationChanged, - this, &QMakeStep::qmakeBuildConfigChanged); - connect(target(), &Target::kitChanged, this, &QMakeStep::qtVersionChanged); - connect(target(), &Target::kitChanged, this, updateSummary); - connect(abisListWidget, &QListWidget::itemChanged, this, [this]{ + widget, [this] { qmakeBuildConfigChanged(); }); + connect(target(), &Target::kitChanged, + widget, [this] { qtVersionChanged(); }); + + connect(abisListWidget, &QListWidget::itemChanged, this, [this] { abisChanged(); if (QmakeBuildConfiguration *bc = qmakeBuildConfiguration()) BuildManager::buildLists({bc->cleanSteps()}); diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 3d09bd2d193..11be30c80e1 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -1,3 +1,8 @@ +set(QmlDesignerPluginInstallPrefix "${IDE_PLUGIN_PATH}/qmldesigner") +if (APPLE) + set(QmlDesignerPluginInstallPrefix "${IDE_PLUGIN_PATH}/QmlDesigner") +endif() + add_qtc_plugin(QmlDesigner DEPENDS QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem @@ -25,21 +30,17 @@ add_qtc_plugin(QmlDesigner settingspage.cpp settingspage.h settingspage.ui shortcutmanager.cpp shortcutmanager.h switchsplittabwidget.cpp switchsplittabwidget.h + designermcumanager.cpp designermcumanager.h EXPLICIT_MOC components/propertyeditor/propertyeditorvalue.h components/connectioneditor/connectionviewwidget.h SKIP_DEBUG_CMAKE_FILE_CHECK EXTRA_TRANSLATIONS "${PROJECT_SOURCE_DIR}/share/qtcreator/qmldesigner" + PROPERTIES + QMLDESIGNER_PLUGIN_PATH "${QmlDesignerPluginInstallPrefix}" ) -set(QmlDesignerPluginInstallPrefix "${IDE_PLUGIN_PATH}/qmldesigner") -if (APPLE) - set(QmlDesignerPluginInstallPrefix "${IDE_PLUGIN_PATH}/QmlDesigner") -endif() - -extend_qtc_plugin(QmlDesigner PROPERTIES QMLDESIGNER_PLUGIN_PATH "${QmlDesignerPluginInstallPrefix}") - add_qtc_plugin(assetexporterplugin CONDITION TARGET QmlDesigner DEPENDS Core ProjectExplorer QmlDesigner Utils Qt5::Qml diff --git a/src/plugins/qmldesigner/components/importmanager/importswidget.cpp b/src/plugins/qmldesigner/components/importmanager/importswidget.cpp index d69511acd67..283a0501150 100644 --- a/src/plugins/qmldesigner/components/importmanager/importswidget.cpp +++ b/src/plugins/qmldesigner/components/importmanager/importswidget.cpp @@ -29,6 +29,7 @@ #include #include +#include #include @@ -94,20 +95,20 @@ void ImportsWidget::setPossibleImports(QList possibleImports) Utils::sort(possibleImports, importLess); m_addImportComboBox->clear(); - const DesignDocument *designDocument = QmlDesignerPlugin::instance()->currentDesignDocument(); - const bool isQtForMCUs = designDocument && designDocument->isQtForMCUsProject(); + const DesignerMcuManager &mcuManager = DesignerMcuManager::instance(); + const bool isQtForMCUs = mcuManager.isMCUProject(); QList filteredImports; - const QStringList mcuPostiveList = {"QtQuick", "QtQuick.Controls", "QtQuick.Timeline"}; - const QStringList mcuNegativeList = {"FlowView"}; + const QStringList mcuAllowedList = mcuManager.allowedImports(); + const QStringList mcuBannedList = mcuManager.bannedImports(); if (isQtForMCUs) { filteredImports = Utils::filtered(possibleImports, - [mcuPostiveList, mcuNegativeList](const Import &import) { - return (mcuPostiveList.contains(import.url()) + [mcuAllowedList, mcuBannedList](const Import &import) { + return (mcuAllowedList.contains(import.url()) || !import.url().startsWith("Qt")) - && !mcuNegativeList.contains(import.url()); + && !mcuBannedList.contains(import.url()); }); } else { filteredImports = possibleImports; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index 7f09bc0b493..a01ce38fc72 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -200,52 +201,12 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model) forceVisiblity = isItem; } - DesignDocument *designDocument = QmlDesignerPlugin::instance() - ->documentManager() - .currentDesignDocument(); + const DesignerMcuManager &mcuManager = DesignerMcuManager::instance(); - if (designDocument && designDocument->isQtForMCUsProject()) { - const QList blockTypes = {"QtQuick.AnimatedImage", - "QtQuick.BorderImage", - "QtQuick.FocusScope", - "QtQuick.TextInput", - "QtQuick.TextEdit", - "QtQuick.Flow", - "QtQuick.Grid", - "QtQuick.GridView", - "QtQuick.PathView", - "QtQuick.Controls", - "QtQuick.Controls.BusyIndicator", - "QtQuick.Controls.ButtonGroup", - "QtQuick.Controls.CheckDelegate", - "QtQuick.Controls.Container", - "QtQuick.Controls.ComboBox", - "QtQuick.Controls.DelayButton", - "QtQuick.Controls.Frame", - "QtQuick.Controls.GroupBox", - "QtQuick.Controls.ItemDelegate", - "QtQuick.Controls.Label", - "QtQuick.Controls.Page", - "QtQuick.Controls.PageIndicator", - "QtQuick.Controls.Pane", - "QtQuick.Controls.RadioDelegate", - "QtQuick.Controls.RangeSlider", - "QtQuick.Controls.RoundButton", - "QtQuick.Controls.ScrollView", - "QtQuick.Controls.SpinBox", - "QtQuick.Controls.StackView", - "QtQuick.Controls.SwipeDelegate", - "QtQuick.Controls.SwitchDelegate", - "QtQuick.Controls.ToolBar", - "QtQuick.Controls.ToolButton", - "QtQuick.Controls.TabBar", - "QtQuick.Controls.TabButton", - "QtQuick.Controls.TextArea", - "QtQuick.Controls.TextField", - "QtQuick.Controls.ToolSeparator", - "QtQuick.Controls.Tumbler"}; + if (mcuManager.isMCUProject()) { + const QSet blockTypes = mcuManager.bannedItems(); - if (blockTypes.contains(entry.typeName())) + if (blockTypes.contains(QString::fromUtf8(entry.typeName()))) valid = false; } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 8526e8a1f51..45e56011351 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -351,8 +352,9 @@ void ItemLibraryWidget::reloadQmlSource() void ItemLibraryWidget::setupImportTagWidget() { QTC_ASSERT(m_model, return); - const DesignDocument *designDocument = QmlDesignerPlugin::instance()->currentDesignDocument(); - const bool isQtForMCUs = designDocument && designDocument->isQtForMCUsProject(); + + const DesignerMcuManager &mcuManager = DesignerMcuManager::instance(); + const bool isQtForMCUs = mcuManager.isMCUProject(); const QStringList imports = m_model->metaInfo().itemLibraryInfo()->showTagsForImports(); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index 56a17e3d11c..dd507df5ea7 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include @@ -261,76 +263,12 @@ bool PropertyEditorValue::isTranslated() const return false; } -static bool itemOrImage(const QmlDesigner::NodeMetaInfo &metaInfo) +static bool isAllowedSubclassType(const QString &type, const QmlDesigner::NodeMetaInfo &metaInfo) { if (!metaInfo.isValid()) return false; - if (metaInfo.isSubclassOf("QtQuick.Image") || metaInfo.isSubclassOf("QtQuick.Text")) - return true; - - return false; -} - -static QList prepareNonMcuProperties() -{ - QList result; - - //Builtins: - const QList itemProperties = {"layer", "opacity", "gradient", "smooth", "antialiasing", - "border", "baselineOffset", "focus", "activeFocusOnTab"}; - const QList mouseAreaProperties = {"propagateComposedEvents", "preventStealing", "cursorShape", - "scrollGestureEnabled", "drag", "acceptedButtons", "hoverEnabled"}; - const QList flickableProperties = {"boundsBehavior", "boundsMovement", - "flickDeceleration", "flickableDirection", - "leftMargin", "rightMargin", "bottomMargin", "topMargin", - "originX", "originY", - "pixelAligned", "pressDelay", "synchronousDrag"}; - const QList imageProperties = {"mirror", "mipmap", "cache", "autoTransform", "asynchronous", - "sourceSize", "smooth"}; - const QList textProperties = {"elide", "lineHeight", "lineHeightMode", "wrapMode", "style", - "styleColor", "minimumPointSize", "minimumPixelSize", "styleColor", - "fontSizeMode", "renderType", "textFormat", "maximumLineCount"}; - const QList paddingProperties = {"bottomPadding", "topPadding", "leftPadding", "rightPadding"}; - const QList columnRowProperties = {"layoutDirection"}; - const QList listViewProperties = {"cacheBuffer", "highlightRangeMode", "highlightMoveDuration", - "highlightResizeDuration", "preferredHighlightBegin", "layoutDirection", - "preferredHighlightEnd", "highlightFollowsCurrentItem", "keyNavigationWraps", - "snapMode", "highlightMoveVelocity", "highlightResizeVelocity"}; - //Animations: - const QList animationProperties = {"paused"}; - - //QtQuick.Controls: - const QList controlProperties = {"focusPolicy", "hoverEnabled", "wheelEnabled"}; - const QList abstractButtonProperties = {"display", "autoExclusive"}; - const QList buttonProperties = {"flat", "highlighted"}; - const QList dialProperties = {}; //nothing in propeditor - const QList progressBarProperties = {"indeterminate"}; - const QList radioButton = {}; //nothing in propeditor - const QList sliderProperties = {"live", "snapMode", "touchDragThreshold"}; - const QList swipeViewProperties = {}; //nothing in propeditor - const QList switchProperties = {}; //nothing in propeditor - - result.append(itemProperties); - result.append(mouseAreaProperties); - result.append(flickableProperties); - result.append(imageProperties); - result.append(textProperties); - result.append(paddingProperties); - result.append(columnRowProperties); - result.append(listViewProperties); - result.append(animationProperties); - result.append(controlProperties); - result.append(abstractButtonProperties); - result.append(buttonProperties); - result.append(dialProperties); - result.append(progressBarProperties); - result.append(radioButton); - result.append(sliderProperties); - result.append(swipeViewProperties); - result.append(switchProperties); - - return result; + return (metaInfo.isSubclassOf(type.toUtf8())); } bool PropertyEditorValue::isAvailable() const @@ -338,31 +276,46 @@ bool PropertyEditorValue::isAvailable() const if (!m_modelNode.isValid()) return true; - const QList nonMcuProperties = prepareNonMcuProperties(); + const QmlDesigner::DesignerMcuManager &mcuManager = QmlDesigner::DesignerMcuManager::instance(); - const QByteArray fontPrefix = {"font"}; - const QList nonMcuFontProperties = {"wordSpacing", "letterSpacing", "hintingPreference", - "kerning", "preferShaping", "capitalization", - "strikeout", "underline", "styleName"}; + if (mcuManager.isMCUProject()) { + const QSet nonMcuProperties = mcuManager.bannedProperties(); + const auto mcuAllowedItemProperties = mcuManager.allowedItemProperties(); + const auto mcuBannedComplexProperties = mcuManager.bannedComplexProperties(); - const QList mcuTransformProperties = {"rotation", "scale", "transformOrigin"}; + const QList list = name().split('.'); + const QByteArray pureName = list.constFirst(); + const QString pureNameStr = QString::fromUtf8(pureName); - const QList list = name().split('.'); - const QByteArray pureName = list.constFirst(); + const QByteArray ending = list.constLast(); + const QString endingStr = QString::fromUtf8(ending); - QmlDesigner::DesignDocument *designDocument = QmlDesigner::QmlDesignerPlugin::instance() - ->documentManager() - .currentDesignDocument(); + //allowed item properties: + const auto itemTypes = mcuAllowedItemProperties.keys(); + for (const auto &itemType : itemTypes) { + if (isAllowedSubclassType(itemType, m_modelNode.metaInfo())) { + const QmlDesigner::DesignerMcuManager::ItemProperties allowedItemProps = + mcuAllowedItemProperties.value(itemType); + if (allowedItemProps.properties.contains(pureNameStr)) { + if (QmlDesigner::QmlItemNode::isValidQmlItemNode(m_modelNode)) { + const bool itemHasChildren = QmlDesigner::QmlItemNode(m_modelNode).hasChildren(); - if (designDocument && designDocument->isQtForMCUsProject()) { - if (pureName == fontPrefix) { - if (nonMcuFontProperties.contains(list.constLast())) - return false; + if (allowedItemProps.allowChildren == itemHasChildren) + return true; + } + } + } } - if (nonMcuProperties.contains(pureName)) + + //banned properties: + //with prefixes: + if (mcuBannedComplexProperties.value(pureNameStr).contains(endingStr)) return false; - if (mcuTransformProperties.contains(pureName) && !itemOrImage(m_modelNode.metaInfo())) + + //general group: + if (nonMcuProperties.contains(pureNameStr)) return false; + } return true; diff --git a/src/plugins/qmldesigner/designermcumanager.cpp b/src/plugins/qmldesigner/designermcumanager.cpp new file mode 100644 index 00000000000..d173ab6766c --- /dev/null +++ b/src/plugins/qmldesigner/designermcumanager.cpp @@ -0,0 +1,267 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 "designermcumanager.h" +#include "qmldesignerconstants.h" +#include "qmldesignerplugin.h" +#include "designersettings.h" +#include "designdocument.h" + +#include + +#include + +namespace QmlDesigner { + +static QString readProperty(const QString property, const QmlJS::SimpleReaderNode::Ptr &node) +{ + const QVariant propertyVar = node->property(property); + + if (!propertyVar.isNull() && propertyVar.isValid()) + return propertyVar.value(); + + return {}; +} + +static QStringList readPropertyList(const QString &property, const QmlJS::SimpleReaderNode::Ptr &node) +{ + const QVariant propertyVar = node->property(property); + + if (!propertyVar.isNull() && propertyVar.isValid()) + return propertyVar.value(); + + return {}; +} + +DesignerMcuManager &DesignerMcuManager::instance() +{ + static DesignerMcuManager instance; + + return instance; +} + +QString DesignerMcuManager::mcuResourcesPath() +{ + return Core::ICore::resourcePath() + QStringLiteral("/qmldesigner/qt4mcu"); +} + +bool DesignerMcuManager::isMCUProject() const +{ + QmlDesigner::DesignDocument *designDocument = QmlDesigner::QmlDesignerPlugin::instance() + ->documentManager().currentDesignDocument(); + if (designDocument) + return designDocument->isQtForMCUsProject(); + + return false; +} + +void DesignerMcuManager::readMetadata() +{ + const QString mainMetadataFileName = "metadata.qml"; + + m_defaultVersion = {}; + m_versionsList.clear(); + + QmlJS::SimpleReader reader; + const QmlJS::SimpleReaderNode::Ptr metadata = + reader.readFile(mcuResourcesPath() + "/" + mainMetadataFileName); + if (!metadata) { + qWarning() << "Designer MCU metadata:" << reader.errors(); + return; + } + + const QmlJS::SimpleReaderNode::List versions = metadata->children(); + + if (versions.isEmpty()) { + qWarning() << "Designer MCU metadata: metadata list is empty"; + return; + } + + const QVariant defaultVersion = metadata->property("defaultVersion"); + if (!defaultVersion.isNull() && defaultVersion.isValid()) { + for (const auto& version : versions) { + Version newVersion; + + const QVariant vId = version->property("id"); + if (vId.isNull() || !vId.isValid()) + continue; + + const QVariant vName = version->property("name"); + if (!vName.isNull() && vName.isValid()) + newVersion.name = vName.value(); + else + continue; + + const QVariant vPath = version->property("path"); + if (!vPath.isNull() && vPath.isValid()) + newVersion.fileName = vPath.value(); + else + continue; + + m_versionsList.push_back(newVersion); + + if (vId == defaultVersion) + m_defaultVersion = newVersion; + } + } +} + +void DesignerMcuManager::readVersionData(const DesignerMcuManager::Version &version) +{ + m_currentVersion = {}; + m_bannedItems.clear(); + m_allowedImports.clear(); + m_bannedImports.clear(); + m_bannedProperties.clear(); + m_allowedItemProperties.clear(); + m_bannedComplexProperties.clear(); + + QmlJS::SimpleReader reader; + const QmlJS::SimpleReaderNode::Ptr versionData = + reader.readFile(mcuResourcesPath() + "/" + version.fileName); + if (!versionData) { + qWarning() << "Designer MCU metadata:" << reader.errors(); + return; + } + + const QmlJS::SimpleReaderNode::List info = versionData->children(); + + if (info.isEmpty()) { + qWarning() << "Designer MCU metadata: metadata list is empty"; + return; + } + + for (const auto& child : info) { + //handling specific item types: + if (child->name() == "ComplexProperty") { + if (child->propertyNames().contains("prefix") + && child->propertyNames().contains("bannedProperties")) { + const QString complexPropPrefix(readProperty("prefix", child)); + const QStringList complexPropBans(readPropertyList("bannedProperties", child)); + + if (!complexPropPrefix.isEmpty() && !complexPropBans.isEmpty()) + m_bannedComplexProperties.insert(complexPropPrefix, complexPropBans); + } + + continue; + } + + //handling allowed properties: + if (child->propertyNames().contains("allowedProperties")) { + ItemProperties allowedProperties; + + const QVariant childrenPropertyVar = child->property("allowChildren"); + + if (!childrenPropertyVar.isNull() && childrenPropertyVar.isValid()) + allowedProperties.allowChildren = childrenPropertyVar.toBool(); + + allowedProperties.properties = readPropertyList("allowedProperties", child); + + if (!allowedProperties.properties.isEmpty()) + m_allowedItemProperties.insert(child->name(), allowedProperties); + } + + //handling banned properties: + const QStringList bannedProperties = readPropertyList("bannedProperties", child); + +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + m_bannedProperties.unite(QSet(bannedProperties.begin(), bannedProperties.end())); +#elif + m_bannedProperties.unite(QSet::fromList(bannedProperties)); +#endif + + } + + const QList bannedItems = readPropertyList("bannedItems", versionData); + +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + m_bannedItems = QSet(bannedItems.begin(), bannedItems.end()); +#elif + m_bannedItems = QSet::fromList(bannedItems); +#endif + + m_allowedImports = readPropertyList("allowedImports", versionData); + m_bannedImports = readPropertyList("bannedImports", versionData); + m_currentVersion = version; +} + +DesignerMcuManager::Version DesignerMcuManager::currentVersion() const +{ + return m_currentVersion; +} + +DesignerMcuManager::Version DesignerMcuManager::defaultVersion() const +{ + return m_defaultVersion; +} + +DesignerMcuManager::VersionsList DesignerMcuManager::versions() const +{ + return m_versionsList; +} + +QSet DesignerMcuManager::bannedItems() const +{ + return m_bannedItems; +} + +QSet DesignerMcuManager::bannedProperties() const +{ + return m_bannedProperties; +} + +QStringList DesignerMcuManager::allowedImports() const +{ + return m_allowedImports; +} + +QStringList DesignerMcuManager::bannedImports() const +{ + return m_bannedImports; +} + +QHash DesignerMcuManager::allowedItemProperties() const +{ + return m_allowedItemProperties; +} + +QHash DesignerMcuManager::bannedComplexProperties() const +{ + return m_bannedComplexProperties; +} + +DesignerMcuManager::DesignerMcuManager() +{ + readMetadata(); + + readVersionData(m_defaultVersion); +} + +DesignerMcuManager::~DesignerMcuManager() +{ + +} + +} // QmlDesigner diff --git a/src/plugins/qmldesigner/designermcumanager.h b/src/plugins/qmldesigner/designermcumanager.h new file mode 100644 index 00000000000..74f578afae2 --- /dev/null +++ b/src/plugins/qmldesigner/designermcumanager.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 + +#include +#include +#include +#include + +namespace QmlDesigner { + +class DesignerMcuManager +{ +public: + struct Version { + QString name; + QString fileName; + }; + using VersionsList = QList; + + struct ItemProperties { + QStringList properties; + bool allowChildren = true; + }; + + static DesignerMcuManager& instance(); + + static QString mcuResourcesPath(); + + bool isMCUProject() const; + + void readMetadata(); + void readVersionData(const DesignerMcuManager::Version &version); + + DesignerMcuManager::Version currentVersion() const; + DesignerMcuManager::Version defaultVersion() const; + DesignerMcuManager::VersionsList versions() const; + + QSet bannedItems() const; + QSet bannedProperties() const; + + QStringList allowedImports() const; + QStringList bannedImports() const; + + QHash allowedItemProperties() const; + QHash bannedComplexProperties() const; + + DesignerMcuManager(DesignerMcuManager const&) = delete; + void operator=(DesignerMcuManager const&) = delete; + +private: + DesignerMcuManager(); + ~DesignerMcuManager(); + +private: + DesignerMcuManager::Version m_currentVersion; + DesignerMcuManager::Version m_defaultVersion; + + QSet m_bannedItems; + QSet m_bannedProperties; + QStringList m_allowedImports; + QStringList m_bannedImports; + QHash m_allowedItemProperties; + QHash m_bannedComplexProperties; + + DesignerMcuManager::VersionsList m_versionsList; + +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pri b/src/plugins/qmldesigner/qmldesignerplugin.pri index 9eba4c9a811..8c99395c58d 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.pri +++ b/src/plugins/qmldesigner/qmldesignerplugin.pri @@ -10,7 +10,8 @@ HEADERS += $$PWD/qmldesignerconstants.h \ $$PWD/documentmanager.h \ $$PWD/documentwarningwidget.h \ $$PWD/qmldesignericons.h \ - $$PWD/openuiqmlfiledialog.h + $$PWD/openuiqmlfiledialog.h \ + $$PWD/designermcumanager.h SOURCES += $$PWD/qmldesignerplugin.cpp \ $$PWD/shortcutmanager.cpp \ @@ -22,7 +23,8 @@ SOURCES += $$PWD/qmldesignerplugin.cpp \ $$PWD/designmodecontext.cpp \ $$PWD/documentmanager.cpp \ $$PWD/documentwarningwidget.cpp \ - $$PWD/openuiqmlfiledialog.cpp + $$PWD/openuiqmlfiledialog.cpp \ + $$PWD/designermcumanager.cpp FORMS += $$PWD/settingspage.ui \ $$PWD/openuiqmlfiledialog.ui diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs index f95f853c7d6..ea57599bd08 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs @@ -928,6 +928,8 @@ Project { "settingspage.ui", "shortcutmanager.cpp", "shortcutmanager.h", + "designermcumanager.cpp", + "designermcumanager.h", ] } } diff --git a/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewactions.cpp b/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewactions.cpp index 616678d8557..75d26a02155 100644 --- a/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewactions.cpp +++ b/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewactions.cpp @@ -217,6 +217,8 @@ SwitchLanguageComboboxAction::SwitchLanguageComboboxAction(QObject *parent) QWidget *SwitchLanguageComboboxAction::createWidget(QWidget *parent) { QPointer comboBox = new QComboBox(parent); + // FIXME: this combobox does not work at the moment + comboBox->setDisabled(true); const QString toolTip(tr("Switch the language used by preview.")); comboBox->setToolTip(toolTip); comboBox->addItem(tr("Default")); diff --git a/src/plugins/qmlpreview/qmldebugtranslationclient.cpp b/src/plugins/qmlpreview/qmldebugtranslationclient.cpp index d62d3d0d204..6ebc13d8f8a 100644 --- a/src/plugins/qmlpreview/qmldebugtranslationclient.cpp +++ b/src/plugins/qmlpreview/qmldebugtranslationclient.cpp @@ -36,24 +36,24 @@ QmlDebugTranslationClient::QmlDebugTranslationClient(QmlDebug::QmlDebugConnectio { } -void QmlDebugTranslationClient::changeLanguage(const QUrl &url, const QString &locale) +void QmlDebugTranslationClient::changeLanguage(const QUrl &url, const QString &localeIsoCode) { QmlDebug::QPacket packet(dataStreamVersion()); - packet << static_cast(ChangeLanguage) << url << locale; + packet << static_cast(Command::ChangeLanguage) << url << localeIsoCode; sendMessage(packet.data()); } void QmlDebugTranslationClient::changeWarningColor(const QColor &warningColor) { QmlDebug::QPacket packet(dataStreamVersion()); - packet << static_cast(ChangeWarningColor) << warningColor; + packet << static_cast(Command::ChangeWarningColor) << warningColor; sendMessage(packet.data()); } void QmlDebugTranslationClient::changeElidedTextWarningString(const QString &warningString) { QmlDebug::QPacket packet(dataStreamVersion()); - packet << static_cast(ChangeElidedTextWarningString) << warningString; + packet << static_cast(Command::ChangeElidedTextWarningString) << warningString; sendMessage(packet.data()); } @@ -68,21 +68,21 @@ void QmlDebugTranslationClient::changeElideWarning(bool elideWarning) void QmlDebugTranslationClient::setDebugTranslationServiceLogFile(const QString &logFilePath) { QmlDebug::QPacket packet(dataStreamVersion()); - packet << static_cast(SetDebugTranslationServiceLogFile) << logFilePath; + packet << static_cast(Command::SetDebugTranslationServiceLogFile) << logFilePath; sendMessage(packet.data()); } void QmlDebugTranslationClient::enableElidedTextWarning() { QmlDebug::QPacket packet(dataStreamVersion()); - packet << static_cast(EnableElidedTextWarning); + packet << static_cast(Command::EnableElidedTextWarning); sendMessage(packet.data()); } void QmlDebugTranslationClient::disableElidedTextWarning() { QmlDebug::QPacket packet(dataStreamVersion()); - packet << static_cast(DisableElidedTextWarning); + packet << static_cast(Command::DisableElidedTextWarning); sendMessage(packet.data()); } @@ -91,7 +91,7 @@ void QmlDebugTranslationClient::messageReceived(const QByteArray &data) QmlDebug::QPacket packet(dataStreamVersion(), data); qint8 command; packet >> command; - qDebug() << "invalid command" << command; + qDebug() << Q_FUNC_INFO << "invalid command" << command; } void QmlDebugTranslationClient::stateChanged(QmlDebug::QmlDebugClient::State state) diff --git a/src/plugins/qmlpreview/qmldebugtranslationclient.h b/src/plugins/qmlpreview/qmldebugtranslationclient.h index 2b69e99b0a6..db00b6f0056 100644 --- a/src/plugins/qmlpreview/qmldebugtranslationclient.h +++ b/src/plugins/qmlpreview/qmldebugtranslationclient.h @@ -35,19 +35,20 @@ class QMLPREVIEW_EXPORT QmlDebugTranslationClient : public QmlDebug::QmlDebugCli Q_OBJECT public: //needs to be in sync with QQmlDebugTranslationClient in qtdeclarative/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h - enum Command { + enum class Command { ChangeLanguage, + MissingTranslationsChecked, + EnableElidedTextWarning, + DisableElidedTextWarning, ChangeWarningColor, ChangeElidedTextWarningString, SetDebugTranslationServiceLogFile, - EnableElidedTextWarning, - DisableElidedTextWarning, TestAllLanguages }; explicit QmlDebugTranslationClient(QmlDebug::QmlDebugConnection *connection); - void changeLanguage(const QUrl &url, const QString &locale); + void changeLanguage(const QUrl &url, const QString &localeIsoCode); void changeWarningColor(const QColor &warningColor); void changeElidedTextWarningString(const QString &warningString); //is QByteArray better here? void changeElideWarning(bool elideWarning); diff --git a/src/plugins/qmlpreview/qmldebugtranslationwidget.cpp b/src/plugins/qmlpreview/qmldebugtranslationwidget.cpp index b9d289a0106..d1c7c9f2891 100644 --- a/src/plugins/qmlpreview/qmldebugtranslationwidget.cpp +++ b/src/plugins/qmlpreview/qmldebugtranslationwidget.cpp @@ -91,8 +91,9 @@ QObject *getPreviewPlugin() namespace QmlPreview { -QmlDebugTranslationWidget::QmlDebugTranslationWidget(QWidget *parent) +QmlDebugTranslationWidget::QmlDebugTranslationWidget(QWidget *parent, TestLanguageGetter languagesGetterMethod) : QWidget(parent) + , m_testLanguagesGetter(languagesGetterMethod) { auto mainLayout = new QVBoxLayout(this); @@ -124,6 +125,7 @@ QmlDebugTranslationWidget::QmlDebugTranslationWidget(QWidget *parent) layout()->addWidget(elideWarningCheckBox); connect(elideWarningCheckBox, &QCheckBox::stateChanged, [this] (int state) { m_elideWarning = (state == Qt::Checked); + }); auto controlLayout = new QHBoxLayout; @@ -232,6 +234,7 @@ void QmlDebugTranslationWidget::updateStartupProjectTranslations() void QmlDebugTranslationWidget::updateCurrentTranslations(ProjectExplorer::Project *project) { + m_testLanguages.clear(); for (int i = m_selectLanguageLayout->count()-1; i >= 0; --i) { auto layoutItem = m_selectLanguageLayout->takeAt(i); delete layoutItem->widget(); @@ -244,28 +247,23 @@ void QmlDebugTranslationWidget::updateCurrentTranslations(ProjectExplorer::Proje connect(multiLanguageAspect, &QmlProjectManager::QmlMultiLanguageAspect::changed, this, &QmlDebugTranslationWidget::updateStartupProjectTranslations, Qt::UniqueConnection); + auto languageLabel = new QLabel(); + languageLabel->setText(tr("Select which language should be tested:")); + m_selectLanguageLayout->addWidget(languageLabel); if (multiLanguageAspect->value()) { - m_selectLanguageLayout->addWidget(new QLabel( - tr("Current language is \'%1\' can be changed in the 'Translation' tab.") - .arg(multiLanguageAspect->currentLocale()))); - m_testLanguages.clear(); - m_testLanguages.append(multiLanguageAspect->currentLocale()); - } else { - m_selectLanguageLayout->addWidget(new QLabel(tr("Select which language should be tested:"))); - QString errorMessage; - for (auto language : project->availableQmlPreviewTranslations(&errorMessage)) { - auto languageCheckBox = new QCheckBox(language); - m_selectLanguageLayout->addWidget(languageCheckBox); - connect(languageCheckBox, &QCheckBox::stateChanged, [this, language] (int state) { - if (state == Qt::Checked) - m_testLanguages.append(language); - else - m_testLanguages.removeAll(language); + addLanguageCheckBoxes({multiLanguageAspect->currentLocale()}); + if (m_testLanguagesGetter) { + auto addTestLanguages = new QPushButton(tr("Add Test Languages")); + m_selectLanguageLayout->addWidget(addTestLanguages); + connect(addTestLanguages, &QPushButton::clicked, [this]() { + addLanguageCheckBoxes(m_testLanguagesGetter()); }); - languageCheckBox->setChecked(true); } - m_selectLanguageLayout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + } else { + QString errorMessage; + addLanguageCheckBoxes(project->availableQmlPreviewTranslations(&errorMessage)); } + m_selectLanguageLayout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); } } @@ -298,14 +296,16 @@ void QmlDebugTranslationWidget::runTest() int timerCounter = 1; const auto testLanguageList = m_testLanguages; + if (m_elideWarning) + previewPlugin->changeElideWarning(true); + auto testLanguages = [previewPlugin, runControl, testLanguageList](int timerCounter, const QString &previewedFile) { - qDebug() << "testLanguages" << previewedFile; for (auto language : testLanguageList) { QTimer::singleShot(timerCounter * 1000, previewPlugin, [previewPlugin, runControl, language, previewedFile]() { if (runControl && runControl->isRunning()) { if (!previewedFile.isEmpty()) previewPlugin->setPreviewedFile(previewedFile); - previewPlugin->setLocale(language); + previewPlugin->setLocaleIsoCode(language); } }); } @@ -319,7 +319,7 @@ void QmlDebugTranslationWidget::runTest() //delete m_currentRunControl; // who deletes the runcontrol? m_currentRunControl = nullptr; if (auto previewPlugin = qobject_cast(getPreviewPlugin())) - previewPlugin->setLocale(m_lastUsedLanguageBeforeTest); + previewPlugin->setLocaleIsoCode(m_lastUsedLanguageBeforeTest); }); connect(runControl, &ProjectExplorer::RunControl::appendMessage, @@ -332,7 +332,7 @@ void QmlDebugTranslationWidget::runTest() if (auto runConfiguration = target->activeRunConfiguration()) { runControl->setRunConfiguration(runConfiguration); if (runControl->createMainWorker()) { - previewPlugin->setLocale(QString()); + previewPlugin->setLocaleIsoCode(QString()); runControl->initiateStart(); } } @@ -399,7 +399,7 @@ void QmlDebugTranslationWidget::appendMessage(const QString &message, Utils::Out return; } const QString serviceSeperator = ": QQmlDebugTranslationService: "; - if (!message.contains(serviceSeperator) || message.contains("DebugTranslation service - language changed")) + if (!message.contains(serviceSeperator)) return; QString locationString = message; locationString = locationString.split(serviceSeperator).first(); @@ -449,4 +449,19 @@ QString QmlDebugTranslationWidget::runButtonText(bool isRunning) return tr("Run language tests"); } +void QmlDebugTranslationWidget::addLanguageCheckBoxes(const QStringList &languages) +{ + for (auto language : languages) { + auto languageCheckBox = new QCheckBox(language); + m_selectLanguageLayout->addWidget(languageCheckBox); + connect(languageCheckBox, &QCheckBox::stateChanged, [this, language] (int state) { + if (state == Qt::Checked) + m_testLanguages.append(language); + else + m_testLanguages.removeAll(language); + }); + languageCheckBox->setChecked(true); + } +} + } // namespace QmlPreview diff --git a/src/plugins/qmlpreview/qmldebugtranslationwidget.h b/src/plugins/qmlpreview/qmldebugtranslationwidget.h index 944c7a59b93..7ea0760ac0f 100644 --- a/src/plugins/qmlpreview/qmldebugtranslationwidget.h +++ b/src/plugins/qmlpreview/qmldebugtranslationwidget.h @@ -51,11 +51,13 @@ namespace QmlPreview { class ProjectFileSelectionsWidget; + class QMLPREVIEW_EXPORT QmlDebugTranslationWidget : public QWidget { + using TestLanguageGetter = std::function; Q_OBJECT public: - explicit QmlDebugTranslationWidget(QWidget *parent = nullptr); + explicit QmlDebugTranslationWidget(QWidget *parent = nullptr, TestLanguageGetter languagesGetterMethod = {}); ~QmlDebugTranslationWidget() override; void setCurrentFile(const Utils::FilePath &filepath); @@ -75,6 +77,7 @@ private: QString singleFileButtonText(const QString &filePath); QString runButtonText(bool isRunning = false); + void addLanguageCheckBoxes(const QStringList &languages); QStringList m_testLanguages; QString m_lastUsedLanguageBeforeTest; @@ -94,6 +97,7 @@ private: QString m_lastDir; QHBoxLayout *m_selectLanguageLayout; + TestLanguageGetter m_testLanguagesGetter; }; } // namespace QmlPreview diff --git a/src/plugins/qmlpreview/qmlpreviewclient.cpp b/src/plugins/qmlpreview/qmlpreviewclient.cpp index ae89d75d4aa..6580833810c 100644 --- a/src/plugins/qmlpreview/qmlpreviewclient.cpp +++ b/src/plugins/qmlpreview/qmlpreviewclient.cpp @@ -56,13 +56,6 @@ void QmlPreviewClient::zoom(float zoomFactor) sendMessage(packet.data()); } -void QmlPreviewClient::language(const QUrl &context, const QString &locale) -{ - QmlDebug::QPacket packet(dataStreamVersion()); - packet << static_cast(Language) << context << locale; - sendMessage(packet.data()); -} - void QmlPreviewClient::announceFile(const QString &path, const QByteArray &contents) { QmlDebug::QPacket packet(dataStreamVersion()); diff --git a/src/plugins/qmlpreview/qmlpreviewclient.h b/src/plugins/qmlpreview/qmlpreviewclient.h index 4e84f6b3ee5..fdb7e3cd63e 100644 --- a/src/plugins/qmlpreview/qmlpreviewclient.h +++ b/src/plugins/qmlpreview/qmlpreviewclient.h @@ -43,8 +43,7 @@ public: Directory, ClearCache, Zoom, - Fps, - Language + Fps }; struct FpsInfo { @@ -64,7 +63,6 @@ public: void loadUrl(const QUrl &url); void rerun(); void zoom(float zoomFactor); - void language(const QUrl &context, const QString &locale); void announceFile(const QString &path, const QByteArray &contents); void announceDirectory(const QString &path, const QStringList &entries); void announceError(const QString &path); diff --git a/src/plugins/qmlpreview/qmlpreviewconnectionmanager.cpp b/src/plugins/qmlpreview/qmlpreviewconnectionmanager.cpp index 7da4bdea13f..ca125908ad3 100644 --- a/src/plugins/qmlpreview/qmlpreviewconnectionmanager.cpp +++ b/src/plugins/qmlpreview/qmlpreviewconnectionmanager.cpp @@ -36,16 +36,14 @@ namespace QmlPreview { namespace Internal { -QmlPreviewConnectionManager::~QmlPreviewConnectionManager() -{ -} - QmlPreviewConnectionManager::QmlPreviewConnectionManager(QObject *parent) : QmlDebug::QmlDebugConnectionManager(parent) { setTarget(nullptr); } +QmlPreviewConnectionManager::~QmlPreviewConnectionManager() = default; + void QmlPreviewConnectionManager::setTarget(ProjectExplorer::Target *target) { QtSupport::BaseQtVersion::populateQmlFileFinder(&m_projectFileFinder, target); @@ -117,13 +115,11 @@ void QmlPreviewConnectionManager::createDebugTranslationClient() { m_qmlDebugTranslationClient = new QmlDebugTranslationClient(connection()); connect(this, &QmlPreviewConnectionManager::language, - m_qmlDebugTranslationClient.data(), [this](const QString &locale) { - - if (m_lastLoadedUrl.isEmpty()) { - // findValidI18nDirectoryAsUrl does not work if we didn't load any file - m_initLocale = locale; - } else { - // service expects a context URL. + m_qmlDebugTranslationClient, [this](const QString &locale) { + m_lastUsedLanguage = locale; + // findValidI18nDirectoryAsUrl does not work if we didn't load any file + // service expects a context URL. + if (!m_lastLoadedUrl.isEmpty()) { // Search the parent directories of the last loaded URL for i18n files. m_qmlDebugTranslationClient->changeLanguage(findValidI18nDirectoryAsUrl(locale), locale); } @@ -159,10 +155,9 @@ void QmlPreviewConnectionManager::createPreviewClient() m_lastLoadedUrl = m_targetFileFinder.findUrl(filename); m_qmlPreviewClient->loadUrl(m_lastLoadedUrl); - if (!m_initLocale.isEmpty()) { - emit language(m_initLocale); - m_initLocale.clear(); - } + // emit language after a file was loaded and do it every time, + // because this also triggers the check for missing translations + emit language(m_lastUsedLanguage); }); connect(this, &QmlPreviewConnectionManager::rerun, @@ -171,19 +166,6 @@ void QmlPreviewConnectionManager::createPreviewClient() connect(this, &QmlPreviewConnectionManager::zoom, m_qmlPreviewClient.data(), &QmlPreviewClient::zoom); - connect(this, &QmlPreviewConnectionManager::language, - m_qmlPreviewClient.data(), [this](const QString &locale) { - - if (m_lastLoadedUrl.isEmpty()) { - // findValidI18nDirectoryAsUrl does not work if we didn't load any file - m_initLocale = locale; - } else { - // service expects a context URL. - // Search the parent directories of the last loaded URL for i18n files. - m_qmlPreviewClient->language(findValidI18nDirectoryAsUrl(locale), locale); - } - }); - connect(m_qmlPreviewClient.data(), &QmlPreviewClient::pathRequested, this, [this](const QString &path) { const bool found = m_projectFileFinder.findFileOrDirectory( diff --git a/src/plugins/qmlpreview/qmlpreviewconnectionmanager.h b/src/plugins/qmlpreview/qmlpreviewconnectionmanager.h index 7693eda6950..c63db57343c 100644 --- a/src/plugins/qmlpreview/qmlpreviewconnectionmanager.h +++ b/src/plugins/qmlpreview/qmlpreviewconnectionmanager.h @@ -76,10 +76,10 @@ private: QPointer m_qmlDebugTranslationClient; Utils::FileSystemWatcher m_fileSystemWatcher; QUrl m_lastLoadedUrl; + QString m_lastUsedLanguage; QmlPreviewFileLoader m_fileLoader = nullptr; QmlPreviewFileClassifier m_fileClassifier = nullptr; QmlPreviewFpsHandler m_fpsHandler = nullptr; - QString m_initLocale; }; } // namespace Internal diff --git a/src/plugins/qmlpreview/qmlpreviewplugin.cpp b/src/plugins/qmlpreview/qmlpreviewplugin.cpp index ffae9a1815a..f331d96b502 100644 --- a/src/plugins/qmlpreview/qmlpreviewplugin.cpp +++ b/src/plugins/qmlpreview/qmlpreviewplugin.cpp @@ -150,8 +150,8 @@ public: QmlPreview::QmlPreviewFileClassifier m_fileClassifer = nullptr; float m_zoomFactor = -1.0; QmlPreview::QmlPreviewFpsHandler m_fpsHandler = nullptr; - QString m_locale; - bool elideWarning = false; + QString m_localeIsoCode; + bool m_translationElideWarning = false; QPointer m_qmlDebugTranslationWidget; RunWorkerFactory localRunWorkerFactory{ @@ -163,8 +163,15 @@ public: RunWorkerFactory runWorkerFactory{ [this](RunControl *runControl) { - QmlPreviewRunner *runner = new QmlPreviewRunner(runControl, m_fileLoader, m_fileClassifer, - m_fpsHandler, m_zoomFactor); + QmlPreviewRunner *runner = new QmlPreviewRunner(QmlPreviewRunnerSetting{ + runControl, + m_fileLoader, + m_fileClassifer, + m_fpsHandler, + m_zoomFactor, + m_localeIsoCode, + m_translationElideWarning + }); connect(q, &QmlPreviewPlugin::updatePreviews, runner, &QmlPreviewRunner::loadFile); connect(q, &QmlPreviewPlugin::rerunPreviews, @@ -173,7 +180,7 @@ public: this, &QmlPreviewPluginPrivate::previewCurrentFile); connect(q, &QmlPreviewPlugin::zoomFactorChanged, runner, &QmlPreviewRunner::zoom); - connect(q, &QmlPreviewPlugin::localeChanged, + connect(q, &QmlPreviewPlugin::localeIsoCodeChanged, runner, &QmlPreviewRunner::language); connect(q, &QmlPreviewPlugin::elideWarningChanged, runner, &QmlPreviewRunner::changeElideWarning); @@ -207,7 +214,7 @@ QmlPreviewPluginPrivate::QmlPreviewPluginPrivate(QmlPreviewPlugin *parent) &QAction::setEnabled); connect(action, &QAction::triggered, this, [this]() { if (auto multiLanguageAspect = QmlProjectManager::QmlMultiLanguageAspect::current()) - m_locale = multiLanguageAspect->currentLocale(); + m_localeIsoCode = multiLanguageAspect->currentLocale(); ProjectExplorerPlugin::runStartupProject(Constants::QML_PREVIEW_RUN_MODE); }); @@ -387,30 +394,31 @@ void QmlPreviewPlugin::setFpsHandler(QmlPreviewFpsHandler fpsHandler) emit fpsHandlerChanged(d->m_fpsHandler); } -QString QmlPreviewPlugin::locale() const +QString QmlPreviewPlugin::localeIsoCode() const { - return d->m_locale; + return d->m_localeIsoCode; } -void QmlPreviewPlugin::setLocale(const QString &locale) +void QmlPreviewPlugin::setLocaleIsoCode(const QString &localeIsoCode) { if (auto multiLanguageAspect = QmlProjectManager::QmlMultiLanguageAspect::current()) - multiLanguageAspect->setCurrentLocale(locale); - if (d->m_locale == locale) + multiLanguageAspect->setCurrentLocale(localeIsoCode); + if (d->m_localeIsoCode == localeIsoCode) return; - d->m_locale = locale; - emit localeChanged(d->m_locale); + d->m_localeIsoCode = localeIsoCode; + emit localeIsoCodeChanged(d->m_localeIsoCode); } bool QmlPreviewPlugin::elideWarning() const { - return d->elideWarning; + return d->m_translationElideWarning; } void QmlPreviewPlugin::changeElideWarning(bool elideWarning) { - d->elideWarning = elideWarning; + d->m_translationElideWarning = elideWarning; + emit elideWarningChanged(elideWarning); } void QmlPreviewPlugin::setFileLoader(QmlPreviewFileLoader fileLoader) diff --git a/src/plugins/qmlpreview/qmlpreviewplugin.h b/src/plugins/qmlpreview/qmlpreviewplugin.h index 13146105ac9..b2455b10773 100644 --- a/src/plugins/qmlpreview/qmlpreviewplugin.h +++ b/src/plugins/qmlpreview/qmlpreviewplugin.h @@ -58,7 +58,7 @@ class QmlPreviewPlugin : public ExtensionSystem::IPlugin Q_PROPERTY(QmlPreview::QmlPreviewFpsHandler fpsHandler READ fpsHandler WRITE setFpsHandler NOTIFY fpsHandlerChanged) Q_PROPERTY(float zoomFactor READ zoomFactor WRITE setZoomFactor NOTIFY zoomFactorChanged) - Q_PROPERTY(QString locale READ locale WRITE setLocale NOTIFY localeChanged) + Q_PROPERTY(QString localeIsoCode READ localeIsoCode WRITE setLocaleIsoCode NOTIFY localeIsoCodeChanged) Q_PROPERTY(bool elideWarning READ elideWarning WRITE changeElideWarning NOTIFY elideWarningChanged) public: @@ -84,8 +84,8 @@ public: QmlPreview::QmlPreviewFpsHandler fpsHandler() const; void setFpsHandler(QmlPreview::QmlPreviewFpsHandler fpsHandler); - QString locale() const; - void setLocale(const QString &locale); + QString localeIsoCode() const; + void setLocaleIsoCode(const QString &localeIsoCode); bool elideWarning() const; void changeElideWarning(bool elideWarning); @@ -103,7 +103,7 @@ signals: void fpsHandlerChanged(QmlPreview::QmlPreviewFpsHandler fpsHandler); void zoomFactorChanged(float zoomFactor); - void localeChanged(const QString &locale); + void localeIsoCodeChanged(const QString &localeIsoCode); void elideWarningChanged(bool elideWarning); private: diff --git a/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp b/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp index 518e33794fb..a1b667b78b2 100644 --- a/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp +++ b/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp @@ -45,17 +45,13 @@ namespace QmlPreview { static const QString QmlServerUrl = "QmlServerUrl"; -QmlPreviewRunner::QmlPreviewRunner(ProjectExplorer::RunControl *runControl, - QmlPreviewFileLoader fileLoader, - QmlPreviewFileClassifier fileClassifier, - QmlPreviewFpsHandler fpsHandler, - float initialZoom) - : RunWorker(runControl) +QmlPreviewRunner::QmlPreviewRunner(const QmlPreviewRunnerSetting &settings) + : RunWorker(settings.runControl) { setId("QmlPreviewRunner"); - m_connectionManager.setFileLoader(fileLoader); - m_connectionManager.setFileClassifier(fileClassifier); - m_connectionManager.setFpsHandler(fpsHandler); + m_connectionManager.setFileLoader(settings.fileLoader); + m_connectionManager.setFileClassifier(settings.fileClassifier); + m_connectionManager.setFpsHandler(settings.fpsHandler); connect(this, &QmlPreviewRunner::loadFile, &m_connectionManager, &Internal::QmlPreviewConnectionManager::loadFile); @@ -70,24 +66,29 @@ QmlPreviewRunner::QmlPreviewRunner(ProjectExplorer::RunControl *runControl, &m_connectionManager, &Internal::QmlPreviewConnectionManager::changeElideWarning); connect(&m_connectionManager, &Internal::QmlPreviewConnectionManager::connectionOpened, - this, [this, initialZoom]() { - if (initialZoom > 0) - emit zoom(initialZoom); + this, [this, settings]() { + if (settings.zoom > 0) + emit zoom(settings.zoom); + if (!settings.language.isEmpty()) + emit language(settings.language); + if (settings.translationElideWarning) + emit changeElideWarning(true); + emit ready(); }); connect(&m_connectionManager, &Internal::QmlPreviewConnectionManager::restart, - runControl, [this, runControl]() { - if (!runControl->isRunning()) + runControl(), [this]() { + if (!runControl()->isRunning()) return; - this->connect(runControl, &ProjectExplorer::RunControl::stopped, runControl, [runControl]() { + this->connect(runControl(), &ProjectExplorer::RunControl::stopped, [this]() { ProjectExplorer::ProjectExplorerPlugin::runRunConfiguration( - runControl->runConfiguration(), + runControl()->runConfiguration(), ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE, true); }); - runControl->initiateStop(); + runControl()->initiateStop(); }); } diff --git a/src/plugins/qmlpreview/qmlpreviewruncontrol.h b/src/plugins/qmlpreview/qmlpreviewruncontrol.h index 38740b31a39..c5171e22488 100644 --- a/src/plugins/qmlpreview/qmlpreviewruncontrol.h +++ b/src/plugins/qmlpreview/qmlpreviewruncontrol.h @@ -32,14 +32,22 @@ namespace QmlPreview { +struct QmlPreviewRunnerSetting { + ProjectExplorer::RunControl *runControl = nullptr; + QmlPreviewFileLoader fileLoader; + QmlPreviewFileClassifier fileClassifier; + QmlPreviewFpsHandler fpsHandler; + float zoom = 1.0; + QString language; + bool translationElideWarning = false; +}; + class QmlPreviewRunner : public ProjectExplorer::RunWorker { Q_OBJECT public: - QmlPreviewRunner(ProjectExplorer::RunControl *runControl, QmlPreviewFileLoader fileLoader, - QmlPreviewFileClassifier fileClassifier, QmlPreviewFpsHandler fpsHandler, - float initialZoom); + QmlPreviewRunner(const QmlPreviewRunnerSetting &settings); void setServerUrl(const QUrl &serverUrl); QUrl serverUrl() const; diff --git a/src/plugins/qmlpreview/tests/qmlpreviewclient_test.cpp b/src/plugins/qmlpreview/tests/qmlpreviewclient_test.cpp index 12d8f317288..9aec2d6cc66 100644 --- a/src/plugins/qmlpreview/tests/qmlpreviewclient_test.cpp +++ b/src/plugins/qmlpreview/tests/qmlpreviewclient_test.cpp @@ -91,24 +91,6 @@ void QmlPreviewClientTest::testZoom() QVERIFY(packet.atEnd()); } -void QmlPreviewClientTest::testLanguate() -{ - TestableQmlPreviewClient client; - QUrl url("file:///some/file.qml"); - QString locale("qt_QT"); - client.language(url, locale); - QCOMPARE(client.messages.count(), 1); - QmlDebug::QPacket packet(client.dataStreamVersion(), client.messages.takeFirst()); - qint8 command; - QUrl resultUrl; - QString resultLocale; - packet >> command >> resultUrl >> resultLocale; - QCOMPARE(static_cast(command), QmlPreviewClient::Language); - QCOMPARE(resultUrl, url); - QCOMPARE(resultLocale, locale); - QVERIFY(packet.atEnd()); -} - void QmlPreviewClientTest::testMessageReceived() { TestableQmlPreviewClient client; diff --git a/src/plugins/qmlpreview/tests/qmlpreviewclient_test.h b/src/plugins/qmlpreview/tests/qmlpreviewclient_test.h index e5e1ad089e6..43ae0030036 100644 --- a/src/plugins/qmlpreview/tests/qmlpreviewclient_test.h +++ b/src/plugins/qmlpreview/tests/qmlpreviewclient_test.h @@ -36,7 +36,6 @@ private slots: void testLoadFile(); void testAnnounceFile(); void testZoom(); - void testLanguate(); void testMessageReceived(); }; diff --git a/src/plugins/qmlpreview/tests/qmlpreviewplugin_test.cpp b/src/plugins/qmlpreview/tests/qmlpreviewplugin_test.cpp index 9ca2f38b08d..0e3306f15df 100644 --- a/src/plugins/qmlpreview/tests/qmlpreviewplugin_test.cpp +++ b/src/plugins/qmlpreview/tests/qmlpreviewplugin_test.cpp @@ -78,21 +78,6 @@ void QmlPreviewPluginTest::testZoomFactorProperty() QCOMPARE(spy.count(), 2); } -void QmlPreviewPluginTest::testLocaleProperty() -{ - ExtensionSystem::IPlugin *plugin = getPlugin(); - QVERIFY(plugin); - - QSignalSpy spy(plugin, SIGNAL(localeChanged(QString))); - - QCOMPARE(plugin->property("locale").toString(), QString()); - plugin->setProperty("locale", "de_DE"); - QCOMPARE(plugin->property("locale").toString(), QString("de_DE")); - plugin->setProperty("locale", "qt_QT"); - QCOMPARE(plugin->property("locale").toString(), QString("qt_QT")); - QCOMPARE(spy.count(), 2); -} - void QmlPreviewPluginTest::testFpsHandlerProperty() { ExtensionSystem::IPlugin *plugin = getPlugin(); diff --git a/src/plugins/qmlpreview/tests/qmlpreviewplugin_test.h b/src/plugins/qmlpreview/tests/qmlpreviewplugin_test.h index ce3cef1dfcc..8ceeb6669ca 100644 --- a/src/plugins/qmlpreview/tests/qmlpreviewplugin_test.h +++ b/src/plugins/qmlpreview/tests/qmlpreviewplugin_test.h @@ -42,7 +42,6 @@ public: private slots: void testFileLoaderProperty(); void testZoomFactorProperty(); - void testLocaleProperty(); void testFpsHandlerProperty(); }; diff --git a/src/tools/icons/qtcreatoricons.svg b/src/tools/icons/qtcreatoricons.svg index 93915b03bcd..d1fbb86a153 100644 --- a/src/tools/icons/qtcreatoricons.svg +++ b/src/tools/icons/qtcreatoricons.svg @@ -3821,7 +3821,7 @@ sodipodi:nodetypes="cccccc" /> + id="src/libs/utils/images/download"> - - - diff --git a/src/tools/qml2puppet/CMakeLists.txt b/src/tools/qml2puppet/CMakeLists.txt index 36be18f8297..7d1d32c19b9 100644 --- a/src/tools/qml2puppet/CMakeLists.txt +++ b/src/tools/qml2puppet/CMakeLists.txt @@ -5,19 +5,58 @@ if (APPLE) string(APPEND DESTDIR "/qmldesigner") endif() -add_qtc_executable(qml2puppet +add_qtc_library(qml2puppet_static + STATIC DEPENDS - Qt5::CorePrivate Qt5::Widgets Qt5::QmlPrivate - Qt5::QuickPrivate Qt5::Network Qt5::GuiPrivate + Qt5::CorePrivate Qt5::Gui + PUBLIC_INCLUDES "${SRCDIR}/interfaces" + SOURCES_PREFIX "${SRCDIR}/interfaces" SOURCES - "${SRCDIR}/qml2puppet/qml2puppetmain.cpp" - "${SRCDIR}/qmlpuppet.qrc" - DESTINATION ${DESTDIR} + commondefines.h + nodeinstanceclientinterface.h + nodeinstanceglobal.h + nodeinstanceserverinterface.cpp nodeinstanceserverinterface.h ) -extend_qtc_executable(qml2puppet +extend_qtc_library(qml2puppet_static + PUBLIC_INCLUDES "${SRCDIR}/types" + SOURCES "${SRCDIR}/types/enumeration.h" +) + +extend_qtc_library(qml2puppet_static + PUBLIC_INCLUDES "${SRCDIR}/container" + SOURCES_PREFIX "${SRCDIR}/container" + SOURCES + addimportcontainer.cpp addimportcontainer.h + idcontainer.cpp idcontainer.h + imagecontainer.cpp imagecontainer.h + informationcontainer.cpp informationcontainer.h + instancecontainer.cpp instancecontainer.h + mockuptypecontainer.cpp mockuptypecontainer.h + propertyabstractcontainer.cpp propertyabstractcontainer.h + propertybindingcontainer.cpp propertybindingcontainer.h + propertyvaluecontainer.cpp propertyvaluecontainer.h + reparentcontainer.cpp reparentcontainer.h + sharedmemory.h +) + +extend_qtc_library(qml2puppet_static + CONDITION UNIX + SOURCES_PREFIX "${SRCDIR}/container" + SOURCES + sharedmemory_unix.cpp +) + +extend_qtc_library(qml2puppet_static + CONDITION NOT UNIX + SOURCES_PREFIX "${SRCDIR}/container" + SOURCES + sharedmemory_qt.cpp +) + +extend_qtc_library(qml2puppet_static + PUBLIC_INCLUDES "${SRCDIR}/commands" SOURCES_PREFIX "${SRCDIR}/commands" - INCLUDES "${PROJECT_SOURCE_DIR}/src/libs" SOURCES changeauxiliarycommand.cpp changeauxiliarycommand.h changebindingscommand.cpp changebindingscommand.h @@ -57,38 +96,21 @@ extend_qtc_executable(qml2puppet scenecreatedcommand.h ) -extend_qtc_executable(qml2puppet - SOURCES_PREFIX "${SRCDIR}/container" +add_qtc_executable(qml2puppet + DEPENDS + Qt5::CorePrivate Qt5::Widgets Qt5::QmlPrivate + Qt5::QuickPrivate Qt5::Network Qt5::GuiPrivate + qml2puppet_static SOURCES - addimportcontainer.cpp addimportcontainer.h - idcontainer.cpp idcontainer.h - imagecontainer.cpp imagecontainer.h - informationcontainer.cpp informationcontainer.h - instancecontainer.cpp instancecontainer.h - mockuptypecontainer.cpp mockuptypecontainer.h - propertyabstractcontainer.cpp propertyabstractcontainer.h - propertybindingcontainer.cpp propertybindingcontainer.h - propertyvaluecontainer.cpp propertyvaluecontainer.h - reparentcontainer.cpp reparentcontainer.h - sharedmemory.h + "${SRCDIR}/qml2puppet/qml2puppetmain.cpp" + "${SRCDIR}/qmlpuppet.qrc" + DESTINATION ${DESTDIR} ) -extend_qtc_executable(qml2puppet - CONDITION UNIX - SOURCES_PREFIX "${SRCDIR}/container" - SOURCES - sharedmemory_unix.cpp -) extend_qtc_executable(qml2puppet CONDITION UNIX AND (NOT APPLE) DEPENDS rt ) -extend_qtc_executable(qml2puppet - CONDITION NOT UNIX - SOURCES_PREFIX "${SRCDIR}/container" - SOURCES - sharedmemory_qt.cpp -) extend_qtc_executable(qml2puppet SOURCES_PREFIX "${SRCDIR}/instances" @@ -115,15 +137,6 @@ extend_qtc_executable(qml2puppet icongizmoimageprovider.cpp icongizmoimageprovider.h ) -extend_qtc_executable(qml2puppet - SOURCES_PREFIX "${SRCDIR}/interfaces" - SOURCES - commondefines.h - nodeinstanceclientinterface.h - nodeinstanceglobal.h - nodeinstanceserverinterface.cpp nodeinstanceserverinterface.h -) - extend_qtc_executable(qml2puppet SOURCES_PREFIX "${SRCDIR}/qml2puppet/iconrenderer" SOURCES diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 9fb89cf807e..1ca3131caf4 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -668,7 +668,7 @@ struct Check6 : Check }; struct Profile { - Profile(const QByteArray &contents) : contents(contents) {} + Profile(const QByteArray &contents) : contents(contents + '\n') {} QByteArray includes; QByteArray contents; @@ -1466,6 +1466,8 @@ void tst_Dumpers::dumper() projectFile.write("DEFINES += _GLIBCXX_DEBUG\n"); if (m_debuggerEngine == GdbEngine && m_debuggerVersion < 70500) projectFile.write("QMAKE_CXXFLAGS += -gdwarf-3\n"); + if (m_debuggerEngine == CdbEngine) + projectFile.write("CONFIG += utf8_source\n"); projectFile.write(data.profileExtra.toUtf8()); } else { projectFile.write(data.allProfile.toUtf8()); @@ -3769,12 +3771,7 @@ void tst_Dumpers::dumper_data() "const wchar_t *w = L\"aöa\";\n" "#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)\n" - "QString s7;\n" - "if (sizeof(wchar_t) == 4)\n" - " s7 = QString::fromUcs4((uint *)w);\n" - "else\n" - " s7 = QString::fromUtf16((ushort *)w);\n" - + "QString s7 = QString::fromWCharArray(w);\n" "QStringRef s8(&str, 1, 2);\n" "QStringRef s9;\n" "#else\n" @@ -5673,16 +5670,13 @@ void tst_Dumpers::dumper_data() "&s, &t, &w, &ch, &wch") - + CheckType("s", "char [5]") % NoCdbEngine - + CheckType("s", "char [4]") % CdbEngine + + CheckType("s", "char [5]") + Check("s.0", "[0]", "97", "char") - + CheckType("t", "char [6]") % NoCdbEngine - + CheckType("t", "char [5]") % CdbEngine + + CheckType("t", "char [6]") + Check("t.0", "[0]", "97", "char") + CheckType("w", "wchar_t [4]") + Check("ch.0", "[0]", "97", TypeDef("char", "CHAR")) - + CheckType("ch", "CHAR [5]") % NoCdbEngine - + CheckType("ch", "char [4]") % CdbEngine + + CheckType("ch", TypeDef("char [5]", "CHAR [5]")) + Check("wch.0", "[0]", "97", TypeDef("wchar_t", "WCHAR")) + CheckType("wch", TypeDef("wchar_t[4]", "WCHAR [4]")); diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index 6c0c9c52b4e..d9b55f6eead 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -507,7 +507,7 @@ def __getSupportedPlatforms__(text, templateName, getAsStrings=False): if templateName.startswith("Qt Quick Application - "): result = set([Targets.DESKTOP_5_10_1_DEFAULT, Targets.DESKTOP_5_14_1_DEFAULT]) elif 'Supported Platforms' in text: - supports = text[text.find('Supported Platforms'):].split(":")[1].strip().split(" ") + supports = text[text.find('Supported Platforms'):].split(":")[1].strip().split("\n") result = set() if 'Desktop' in supports: if (version == None or version < "5.0") and not templateName.startswith("Qt Quick 2"): diff --git a/tests/unit/unittest/unittest.qbs b/tests/unit/unittest/unittest.qbs index a25c2ee4f44..5ceb723b220 100644 --- a/tests/unit/unittest/unittest.qbs +++ b/tests/unit/unittest/unittest.qbs @@ -84,7 +84,6 @@ Project { "QT_RESTRICTED_CAST_FROM_ASCII", "QT_USE_FAST_OPERATOR_PLUS", "QT_USE_FAST_CONCATENATION", - "CLANG_UNIT_TESTS", "CLANGPCHMANAGER_STATIC_LIB", "CLANGSUPPORT_BUILD_STATIC_LIB", "CLANGTOOLS_STATIC_LIBRARY", @@ -101,8 +100,11 @@ Project { FileInfo.joinPaths(project.sourceDirectory, "share", "qtcreator")) + '"', 'CPPTOOLS_JSON="' + FileInfo.joinPaths(destinationDirectory, "CppTools.json") + '"', ]; - if (libclang.present && libclang.toolingEnabled) - defines = defines.concat(libclang.llvmToolingDefines); + if (libclang.present) { + defines.push("CLANG_UNIT_TESTS"); + if (libclang.toolingEnabled) + defines = defines.concat(libclang.llvmToolingDefines); + } return defines; } cpp.cxxFlags: {