diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index cc9a25788f4..45d9c8144f1 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -4,7 +4,7 @@ on: [push, pull_request] env: QT_VERSION: 5.15.1 - CLANG_VERSION: 100 + CLANG_VERSION: 110 ELFUTILS_VERSION: 0.175 CMAKE_VERSION: 3.18.3 NINJA_VERSION: 1.10.1 @@ -34,7 +34,7 @@ jobs: } - { name: "Ubuntu Latest GCC", artifact: "Linux", - os: ubuntu-latest, + os: ubuntu-20.04, cc: "gcc", cxx: "g++" } - { @@ -251,7 +251,7 @@ jobs: set(libclang "libclang-release_${clang_version}-based-windows-vs2019_32.7z") endif() elseif ("${{ runner.os }}" STREQUAL "Linux") - set(libclang "libclang-release_${clang_version}-based-linux-Ubuntu18.04-gcc9.2-x86_64.7z") + set(libclang "libclang-release_${clang_version}-based-linux-Ubuntu20.04-gcc9.3-x86_64.7z") elseif ("${{ runner.os }}" STREQUAL "macOS") set(libclang "libclang-release_${clang_version}-based-mac.7z") endif() diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake index 2e1183c75ed..ccba5909d3f 100644 --- a/cmake/QtCreatorAPI.cmake +++ b/cmake/QtCreatorAPI.cmake @@ -774,19 +774,6 @@ function(finalize_qtc_gtest test_name exclude_sources_regex) endforeach() endfunction() -# This is the CMake equivalent of "RESOURCES = $$files()" from qmake -function(qtc_glob_resources) - cmake_parse_arguments(_arg "" "QRC_FILE;ROOT;GLOB" "" ${ARGN}) - - file(GLOB_RECURSE fileList RELATIVE "${_arg_ROOT}" "${_arg_ROOT}/${_arg_GLOB}") - set(qrcData "\n") - foreach(file IN LISTS fileList) - string(APPEND qrcData " ${_arg_ROOT}/${file}\n") - endforeach() - string(APPEND qrcData "") - file(WRITE "${_arg_QRC_FILE}" "${qrcData}") -endfunction() - function(qtc_copy_to_builddir custom_target_name) cmake_parse_arguments(_arg "CREATE_SUBDIRS" "DESTINATION" "FILES;DIRECTORIES" ${ARGN}) set(timestampFiles) @@ -838,3 +825,84 @@ function(qtc_copy_to_builddir custom_target_name) add_custom_target("${custom_target_name}" ALL DEPENDS ${timestampFiles}) endfunction() + +function(qtc_add_resources target resourceName) + cmake_parse_arguments(rcc "" "PREFIX;LANG;BASE" "FILES;OPTIONS" ${ARGN}) + + string(REPLACE "/" "_" resourceName ${resourceName}) + string(REPLACE "." "_" resourceName ${resourceName}) + + # Apply base to all files + if (rcc_BASE) + foreach(file IN LISTS rcc_FILES) + set(resource_file "${rcc_BASE}/${file}") + file(TO_CMAKE_PATH ${resource_file} resource_file) + list(APPEND resource_files ${resource_file}) + endforeach() + else() + set(resource_files ${rcc_FILES}) + endif() + + set(newResourceName ${resourceName}) + set(resources ${resource_files}) + + set(generatedResourceFile "${CMAKE_CURRENT_BINARY_DIR}/.rcc/generated_${newResourceName}.qrc") + set(generatedSourceCode "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qrc_${newResourceName}.cpp") + + # Generate .qrc file: + + # + set(qrcContents "\n \n") + + set(resource_dependencies) + foreach(file IN LISTS resources) + set(file_resource_path ${file}) + + if (NOT IS_ABSOLUTE ${file}) + set(file "${CMAKE_CURRENT_SOURCE_DIR}/${file}") + endif() + + ### FIXME: escape file paths to be XML conform + # ... + string(APPEND qrcContents " ") + string(APPEND qrcContents "${file}\n") + list(APPEND files "${file}") + list(APPEND resource_dependencies ${file}) + target_sources(${target} PRIVATE "${file}") + set_property(SOURCE "${file}" PROPERTY HEADER_FILE_ONLY ON) + endforeach() + + # + string(APPEND qrcContents " \n\n") + + file(WRITE "${generatedResourceFile}.in" "${qrcContents}") + configure_file("${generatedResourceFile}.in" "${generatedResourceFile}") + + set_property(TARGET ${target} APPEND PROPERTY _qt_generated_qrc_files "${generatedResourceFile}") + + set(rccArgs --name "${newResourceName}" + --output "${generatedSourceCode}" "${generatedResourceFile}") + if(rcc_OPTIONS) + list(APPEND rccArgs ${rcc_OPTIONS}) + endif() + + # Process .qrc file: + add_custom_command(OUTPUT "${generatedSourceCode}" + COMMAND Qt5::rcc ${rccArgs} + DEPENDS + ${resource_dependencies} + ${generatedResourceFile} + "Qt5::rcc" + COMMENT "RCC ${newResourceName}" + VERBATIM) + + target_sources(${target} PRIVATE "${generatedSourceCode}") + set_property(SOURCE "${generatedSourceCode}" PROPERTY SKIP_AUTOGEN ON) +endfunction() diff --git a/cmake/QtCreatorIDEBranding.cmake b/cmake/QtCreatorIDEBranding.cmake index 3f5164ebb07..473c6fdaf62 100644 --- a/cmake/QtCreatorIDEBranding.cmake +++ b/cmake/QtCreatorIDEBranding.cmake @@ -1,5 +1,3 @@ -#PROJECT_USER_FILE_EXTENSION = .user - set(IDE_VERSION "4.13.82") # The IDE version. set(IDE_VERSION_COMPAT "4.13.82") # The IDE Compatibility version. set(IDE_VERSION_DISPLAY "4.14.0-beta1") # The IDE display version. @@ -11,3 +9,7 @@ set(IDE_DISPLAY_NAME "Qt Creator") # The IDE display name. set(IDE_ID "qtcreator") # The IDE id (no spaces, lowercase!) set(IDE_CASED_ID "QtCreator") # The cased IDE id (no spaces!) set(IDE_BUNDLE_IDENTIFIER "org.qt-project.${IDE_ID}") # The macOS application bundle identifier. + +set(PROJECT_USER_FILE_EXTENSION .user) +set(IDE_DOC_FILE "qtcreator/qtcreator.qdocconf") +set(IDE_DOC_FILE_ONLINE "qtcreator/qtcreator-online.qdocconf") diff --git a/dist/changes-4.14.0.md b/dist/changes-4.14.0.md index 3cc8c567eca..4da0dab84ae 100644 --- a/dist/changes-4.14.0.md +++ b/dist/changes-4.14.0.md @@ -37,6 +37,7 @@ Editing (QTCREATORBUG-10066) * Added action for showing function arguments hint (QTCREATORBUG-19394) * Added option for after how many characters auto-completion may trigger (QTCREATORBUG-19920) +* Added highlighting for structured bindings (QTCREATORBUG-24769) * Restricted completion for second argument of `connect` calls to signals (QTCREATORBUG-13558) * Fixed crash of backend with multiline `Q_PROPERTY` declarations (QTCREATORBUG-24746) * Fixed duplicate items appearing in include completion (QTCREATORBUG-24515) @@ -50,9 +51,11 @@ Editing implemented operators (QTCREATORBUG-12218) * Fixed that `Complete switch statement` indents unrelated code (QTCREATORBUG-12445) * Fixed `Complete switch statement` with templates (QTCREATORBUG-24752) +* Fixed `Complete switch statement` for enum classes (QTCREATORBUG-20475) * 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 issue with `Convert to Camel Case` (QTCREATORBUG-16560) * 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 @@ -85,6 +88,7 @@ Projects ### qmake * Added option to not execute `system` directives (QTCREATORBUG-24551) +* Fixed deployment with wildcards (QTCREATORBUG-24695) ### Wizards @@ -135,6 +139,7 @@ Test Integration ---------------- * Made it easier to re-run failed tests +* Added support for `QTest::addRow()` (QTCREATORBUG-24777) Platforms --------- diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index c453903cf09..8425aa50241 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -32,7 +32,7 @@ function(_find_all_includes _ret_includes _ret_framework_paths) endfunction() if (WITH_DOCS) - add_qtc_documentation("qtcreator/qtcreator.qdocconf") + add_qtc_documentation(${IDE_DOC_FILE}) if (BUILD_DEVELOPER_DOCS) _find_all_includes(_all_includes _framework_paths) add_qtc_documentation("qtcreatordev/qtcreator-dev.qdocconf" @@ -42,7 +42,7 @@ if (WITH_DOCS) endif() endif() if(WITH_ONLINE_DOCS) - add_qtc_documentation("qtcreator/qtcreator-online.qdocconf") + add_qtc_documentation(${IDE_DOC_FILE_ONLINE}) if (BUILD_DEVELOPER_DOCS) _find_all_includes(_all_includes _framework_paths) add_qtc_documentation("qtcreatordev/qtcreator-dev-online.qdocconf" diff --git a/doc/qtcreator/config/qtcreator-project.qdocconf b/doc/qtcreator/config/qtcreator-project.qdocconf index e2f5c9b5278..cff09e5c3bc 100644 --- a/doc/qtcreator/config/qtcreator-project.qdocconf +++ b/doc/qtcreator/config/qtcreator-project.qdocconf @@ -32,6 +32,7 @@ imagedirs = ../images \ ../../../src/plugins/qmldesigner/components/formeditor \ ../../../src/plugins/qmldesigner/components/navigator \ ../../../src/plugins/qmldesigner/components/timelineeditor/images \ + ../../../src/plugins/qmldesigner/componentsplugin/images \ ../../../src/plugins/qmldesigner/qmlpreviewplugin/images \ ../../../src/plugins/qmldesigner/qtquickplugin/images \ ../../../src/plugins/scxmleditor/common/images \ diff --git a/doc/qtcreator/images/icons/frame-icon16.png b/doc/qtcreator/images/icons/frame-icon16.png new file mode 100644 index 00000000000..e5b65ad53bb Binary files /dev/null and b/doc/qtcreator/images/icons/frame-icon16.png differ diff --git a/doc/qtcreator/images/icons/groupbox-icon16.png b/doc/qtcreator/images/icons/groupbox-icon16.png new file mode 100644 index 00000000000..9cf4324819f Binary files /dev/null and b/doc/qtcreator/images/icons/groupbox-icon16.png differ diff --git a/doc/qtcreator/images/icons/label-icon16.png b/doc/qtcreator/images/icons/label-icon16.png new file mode 100644 index 00000000000..b68d3845685 Binary files /dev/null and b/doc/qtcreator/images/icons/label-icon16.png differ diff --git a/doc/qtcreator/images/icons/page-icon16.png b/doc/qtcreator/images/icons/page-icon16.png new file mode 100644 index 00000000000..bc6810b6053 Binary files /dev/null and b/doc/qtcreator/images/icons/page-icon16.png differ diff --git a/doc/qtcreator/images/icons/pageindicator-icon16.png b/doc/qtcreator/images/icons/pageindicator-icon16.png new file mode 100644 index 00000000000..0fb8967564c Binary files /dev/null and b/doc/qtcreator/images/icons/pageindicator-icon16.png differ diff --git a/doc/qtcreator/images/icons/pane-icon16.png b/doc/qtcreator/images/icons/pane-icon16.png new file mode 100644 index 00000000000..2b8048441c3 Binary files /dev/null and b/doc/qtcreator/images/icons/pane-icon16.png differ diff --git a/doc/qtcreator/images/qtquick-layout-grid-properties.png b/doc/qtcreator/images/qtquick-layout-grid-properties.png new file mode 100644 index 00000000000..d7f51216b7e Binary files /dev/null and b/doc/qtcreator/images/qtquick-layout-grid-properties.png differ diff --git a/doc/qtcreator/images/qtquick-positioner-column-properties.png b/doc/qtcreator/images/qtquick-positioner-column-properties.png new file mode 100644 index 00000000000..0783872c513 Binary files /dev/null and b/doc/qtcreator/images/qtquick-positioner-column-properties.png differ diff --git a/doc/qtcreator/images/qtquick-positioner-flow-properties.png b/doc/qtcreator/images/qtquick-positioner-flow-properties.png new file mode 100644 index 00000000000..4b1e613c78b Binary files /dev/null and b/doc/qtcreator/images/qtquick-positioner-flow-properties.png differ diff --git a/doc/qtcreator/images/qtquick-positioner-grid-properties.png b/doc/qtcreator/images/qtquick-positioner-grid-properties.png new file mode 100644 index 00000000000..cd93830d365 Binary files /dev/null and b/doc/qtcreator/images/qtquick-positioner-grid-properties.png differ diff --git a/doc/qtcreator/src/analyze/creator-clang-static-analyzer.qdoc b/doc/qtcreator/src/analyze/creator-clang-static-analyzer.qdoc index 4f1ce5a8bd9..8fe248fa21b 100644 --- a/doc/qtcreator/src/analyze/creator-clang-static-analyzer.qdoc +++ b/doc/qtcreator/src/analyze/creator-clang-static-analyzer.qdoc @@ -188,7 +188,7 @@ \li In the \uicontrol {Topic Filter} field, select a topic to view only checks related to that area in the \uicontrol Checks field. - \li To view all checks again, select \uicontrol {Reset to All}. + \li To view all checks again, select \uicontrol {Reset Filter}. \li To view more information about the checks online, select the \uicontrol {Web Page} links next to them. diff --git a/doc/qtcreator/src/overview/creator-acknowledgements.qdoc b/doc/qtcreator/src/overview/creator-acknowledgements.qdoc index a49a2540282..9a02f948692 100644 --- a/doc/qtcreator/src/overview/creator-acknowledgements.qdoc +++ b/doc/qtcreator/src/overview/creator-acknowledgements.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 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. @@ -58,23 +58,7 @@ Copyright (c) 2008-2015 Jesse Beder. - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. + \include license-mit.qdocinc \li \b{Syntax highlighting engine for Kate syntax definitions} @@ -83,29 +67,285 @@ text rendering (e.g. as HTML), supporting both integration with a custom editor as well as a ready-to-use QSyntaxHighlighter sub-class. - Distributed under the: - \badcode - MIT License + The following files are part of KDE's kate project, kdelibs/kate: - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: + \list + \li \b alert.xml - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. + Author: Dominik Haumann (dhaumann@kde.org). - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - \endcode + Distributed under the MIT license. + + \include license-mit.qdocinc + + \li \b bash.xml + + Copyright (c) 2004 by Wilbert Berendsen (wilbert@kde.nl). + + Changes by: Matthew Woehlke (mw_triad@users.sourceforge.net), + Sebastian Pipping (webmaster@hartwork.org), and + Luiz Angelo Daros de Luca (luizluca@gmail.com). + + Released under the \l{https://www.gnu.org/licenses/lgpl-2.1.html} + {GNU Lesser General Public License Version 2.1 (LGPLv2.1)}. + + \li \b cmake.xml + + Copyright 2004 Alexander Neundorf (neundorf@kde.org). + + Copyright 2005 Dominik Haumann (dhdev@gmx.de). + + Copyright 2007,2008,2013,2014 Matthew Woehlke (mw_triad@users.sourceforge.net). + + Copyright 2013-2015,2017-2020 Alex Turbov (i.zaufi@gmail.com). + + Released under the \l{https://www.gnu.org/licenses/lgpl-2.1.html} + {GNU Lesser General Public License Version 2.1 (LGPLv2.1)} or later. + + \badcode + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + \endcode + + \li \b css.xml + + Author: Wilbert Berendsen (wilbert@kde.nl). + + Changes: + Version 7 and 8 by Jonathan Poelen, + Version 2.13 and 4 by Guo Yunhe (guoyunhebrave@gmail.com), + Version 2.08 by Joseph Wenninger, + Version 2.06 by Mte90, + Version 2.03 by Milian Wolff. + + Released under the \l{https://www.gnu.org/licenses/lgpl-2.1.html} + {GNU Lesser General Public License Version 2.1 (LGPLv2.1)}. + + \li \b doxygen.xml + + Author: Dominik Haumann (dhaumann@kde.org). + + Distributed under the MIT license. + + \include license-mit.qdocinc + + \li \b dtd.xml + + Author: Andriy Lesyuk (s-andy@in.if.ua). + + Released under the \l{https://www.gnu.org/licenses/lgpl-2.1.html} + {GNU Lesser General Public License Version 2.1 (LGPLv2.1)}. + + \li \b html.xml + + Author: Wilbert Berendsen (wilbert@kde.nl). + + Released under the \l{https://www.gnu.org/licenses/lgpl-2.1.html} + {GNU Lesser General Public License Version 2.1 (LGPLv2.1)}. + + \li \b ini.xml + + Author: Jan Janssen (medhefgo@web.de). + + Released under the \l{https://www.gnu.org/licenses/lgpl-2.1.html} + {GNU Lesser General Public License Version 2.1 (LGPLv2.1)}. + + \li \b java.xml + + Author: Alfredo Luiz Foltran Fialho (alfoltran@ig.com.br). + + Released under the \l{https://www.gnu.org/licenses/lgpl-2.1.html} + {GNU Lesser General Public License Version 2.1 (LGPLv2.1)}. + + \li \b javadoc.xml + + Author: Alfredo Luiz Foltran Fialho (alfoltran@ig.com.br). + + Released under the \l{https://www.gnu.org/licenses/lgpl-2.1.html} + {GNU Lesser General Public License Version 2.1 (LGPLv2.1)}. + + \li \b json.xml + + Author: Sebastian Pipping (sebastian@pipping.org). + + Released under the \l{https://www.gnu.org/licenses/gpl-3.0.html} + {GNU General Public License Version 3 (GPLv3)} or later. + + \li \b makefile.xml + + Author: v0.9 by Per Wigren (wigren@home.se). + + Changes: Joseph Wenninger (jowenn@kde.org), + Rui Santana (santana.rui@gmail.com), + v2.0 by Andreas Nordal (andreas.nordal@gmail.com), + v2.1 by Alex Turbov (i.zaufi@gmail.com), + v4 by Alex Richardson (arichardson.kde@gmail.com). + + \li \b markdown.xml + + Copyright 2008 Darrin Yeager (http://www.dyeager.org/). + + Dual-licensed under both the \l{https://www.gnu.org/licenses/gpl-2.0.html} + {GNU General Public License Version 2 (GPLv2)} BSD licenses. + + Extended 2009 Claes Holmerson (http://github.com/claes/kate-markdown/). + + Extended 2019 Nibaldo Gonz\unicode{0x00E1}lez S. (nibgonz@gmail.com). + Changes under MIT license. + + \badcode + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + \endcode + + \include license-mit.qdocinc + + \li \b modelines.xml + + Author: Alex Turbov (i.zaufi@gmail.com). + + Distributed under the MIT license. + + \include license-mit.qdocinc + + \li \b perl.xml + + Copyright (C) 2001, 2002, 2003, 2004 Anders Lund (anders@alweb.dk). + + \badcode + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + \endcode + + \li \b perl6.xml + + Author: Jonathan Poelen (jonathan.poelen@gmail.com). + + Distributed under the MIT license. + + \include license-mit.qdocinc + + \li \b powershell.xml + + Authors: Motoki Kashihara (motoki8791@gmail.com), + Michael Lombardi (Michael.T.Lombardi@outlook.com). + + Distributed under the MIT license. + + \include license-mit.qdocinc + + \li \b python.xml + + Author: Michael Bueker + + Changes: v0.9 by Per Wigren, + v1.9 by Michael Bueker, + v1.97 by Paul Giannaros, + v1.99 by Primoz Anzur, + v2.01 by Paul Giannaros. + + \li \b qdocconf.xml + + Author: Volker Krause (vkrause@kde.org). + + Distributed under the MIT license. + + \include license-mit.qdocinc + + \li \b ruby.xml + + Copyright (C) 2004 by Sebastian Vuorinen (sebastian dot vuorinen at helsinki dot fi). + + Copyright (C) 2004 by Stefan Lang (langstefan@gmx.at). + + Copyright (C) 2008 by Robin Pedersen (robinpeder@gmail.com). + + Copyright (C) 2011 by Miquel Sabat\unicode{0xe9} (mikisabate@gmail.com). + + \badcode + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + \endcode + + \li \b valgrind-suppression.xml + + Author: Milian Wolff (mail@milianw.de). + + Released under the \l{https://www.gnu.org/licenses/lgpl-2.1.html} + {GNU Lesser General Public License Version 2.1 (LGPLv2.1)}. + + \li \b xml.xml + + Author: Wilbert Berendsen (wilbert@kde.nl). + + Released under the \l{https://www.gnu.org/licenses/lgpl-2.1.html} + {GNU Lesser General Public License Version 2.1 (LGPLv2.1)}. + + \li \b yacc.xml + + YACC.XML supports syntax highlighting for Yacc/Bison source under Kate. + + Copyright (C) 2004, Jan Villat (jan.villat@net2000.ch). + + Changes by: Nibaldo Gonz\unicode{0x00E1}lez (nibgonz@gmail.com), + Sebastian Pipping (webmaster@hartwork.org). + + Released under the \l{https://www.gnu.org/licenses/lgpl-2.1.html} + {GNU Lesser General Public License Version 2.1 (LGPLv2.1)}. + + \endlist The source code of KSyntaxHighlighting can be found here: diff --git a/doc/qtcreator/src/overview/license-mit.qdocinc b/doc/qtcreator/src/overview/license-mit.qdocinc new file mode 100644 index 00000000000..0f563093e60 --- /dev/null +++ b/doc/qtcreator/src/overview/license-mit.qdocinc @@ -0,0 +1,22 @@ + \badcode + MIT License + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + \endcode diff --git a/doc/qtcreator/src/qtcreator-toc.qdoc b/doc/qtcreator/src/qtcreator-toc.qdoc index 0715d02a063..3df326a6ef9 100644 --- a/doc/qtcreator/src/qtcreator-toc.qdoc +++ b/doc/qtcreator/src/qtcreator-toc.qdoc @@ -103,6 +103,7 @@ \endlist \li \l{Managing Item Hierarchy} \li \l{Specifying Item Properties} + \li \l{Positioning Items} \li \l{Using Custom Fonts} \li \l{Annotating Designs} \li \l{Loading Placeholder Data} diff --git a/doc/qtcreator/src/qtquick/qtquick-buttons.qdoc b/doc/qtcreator/src/qtquick/qtquick-buttons.qdoc index 578f5dfb841..4b6d73a4e44 100644 --- a/doc/qtcreator/src/qtquick/qtquick-buttons.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-buttons.qdoc @@ -274,7 +274,7 @@ and set the button text for each button instance, for example. For more information about positioning buttons on screens, see - \l{Positioning Items in UIs}. + \l{Positioning Items}. \image qmldesigner-borderimage.png "Button preview as part of a screen" */ diff --git a/doc/qtcreator/src/qtquick/qtquick-components.qdoc b/doc/qtcreator/src/qtquick/qtquick-components.qdoc index ce288751d88..67c2001ed76 100644 --- a/doc/qtcreator/src/qtquick/qtquick-components.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-components.qdoc @@ -180,279 +180,6 @@ \l{SwipeDelegate}{Swipe Delegate} delegate components are also available in \uicontrol Library. - \section1 Positioning Items in UIs - - The position of an item in the UI can be either absolute or - relative to other items. If you are designing a static UI, - \l{Important Concepts In Qt Quick - Positioning#manual-positioning} - {manual positioning} provides the most efficient form of positioning - items. For a dynamic UI, you can employ the following positioning - methods provided by Qt Quick: - - \list - \li \l{Setting Bindings} - \li \l{Setting Anchors and Margins} - \li \l{Aligning and Distributing Items} - \li \l{Using Positioners} - \li \l{Using Layouts} - \li \l{Organizing Items} - \endlist - - \section2 Setting Bindings - - \l{Positioning with Bindings} {Property binding} is a declarative way of - specifying the value of a property. Binding allows a property value to be - expressed as a JavaScript expression that defines the value relative to - other property values or data accessible in the application. The property - value is automatically kept up to date if the other properties or data - values change. - - Property bindings are created implicitly in QML whenever a property is - assigned a JavaScript expression. To set JavaScript expressions as values - of properties in the Design mode, select the - \inlineimage icons/action-icon.png - (\uicontrol Actions) menu next to a property, and then select - \uicontrol {Set Binding}. - - \image qmldesigner-set-expression.png "Type properties context menu" - - In \uicontrol {Binding Editor}, select an item and a property from - lists of available items and their properties. - - \image qmldesigner-binding-editor.png "Binding Editor" - - Alternatively, start typing a - string and press \key Ctrl+Space to display a list of properties, IDs, and - code snippets. When you enter a period (.) after a property name, a list of - available values is displayed. Press \key Enter to accept the first - suggestion in the list and to complete the code. - - When a binding is set, the \uicontrol Actions menu icon changes to - \inlineimage icons/action-icon-binding - . To remove bindings, select \uicontrol Actions > \uicontrol Reset. - - You can set bindings also in the \uicontrol Connections view. For more - information, see \l {Adding Bindings Between Properties}. - - For more information on the JavaScript environment provided by QML, see - \l{Integrating QML and JavaScript}. - - Bindings are a black box for the Design mode and using them might have a - negative impact on performance, so consider setting anchors and margins for - items, instead. For example, instead of setting \c {parent.width} for an - item, you could anchor the item to its sibling items on the left and the - right. - - \section2 Setting Anchors and Margins - - In an \l{Important Concepts In Qt Quick - Positioning#anchors} - {anchor-based} layout, each QML type can be thought of as having a set of - invisible \e anchor lines: top, bottom, left, right, fill, horizontal - center, vertical center, and baseline. - - In the \uicontrol Layout tab you can set anchors and margins for items. To - set the anchors of an item, click the anchor buttons. You can combine the - top/bottom, left/right, and horizontal/vertical anchors to anchor items in - the corners of the parent item or center them horizontally or vertically - within the parent item. - - \image qmldesigner-anchor-buttons.png "Anchor buttons" - - For convenience, you can click the \inlineimage anchor-fill.png - (\uicontrol {Fill to Parent}) toolbar button to apply fill anchors to an - item and the \inlineimage qtcreator-anchors-reset-icon.png - (\uicontrol {Reset Anchors}) button to reset the anchors to their saved - state. - - You can specify the baseline anchor in \uicontrol {Text Editor} in the - Design mode. - - For performance reasons, you can only anchor an item to its siblings - and direct parent. By default, an item is anchored to its parent when - you use the anchor buttons. Select a sibling of the item in the - \uicontrol Target field to anchor to it, instead. - - Arbitrary anchoring is not supported. For example, you cannot specify: - \c {anchor.left: parent.right}. You have to specify: - \c {anchor.left: parent.left}. When you use the anchor buttons, anchors to - the parent item are always specified to the same side. However, anchors to - sibling items are specified to the opposite side: - \c {anchor.left: sibling.right}. This allows you to keep sibling items - together. - - In the following image, \uicontrol{Rectangle 2} is anchored to - \uicontrol {Rectangle 1} on its left and to the bottom of its parent. - - \image qmldesigner-anchors.png "Anchoring sibling items" - - The anchors for \uicontrol{Rectangle 2} are specified as follows in code: - - \qml - Rectangle { - id: rectangle2 - anchors.left: rectangle1.right - anchors.leftMargin: 10 - anchors.bottom: parent.bottom - anchors.bottomMargin: 10 - // - } - \endqml - - Margins specify the amount of empty space to leave to the outside of an - item. Margins only have meaning for anchors. They do not take any effect - when using layouts or absolute positioning. - - \section2 Aligning and Distributing Items - - When you're working with a group of items, you can select them to align - and distribute them evenly. As the positions of the items are fixed, you - cannot apply these functions to anchored items. For scalability, you can - anchor the aligned and distributed items when your design is ready. - - \image qmldesigner-alignment.png "Aligning sibling items" - - Select the buttons in the \uicontrol Align group to align the top/bottom - or left/right edges of the items in the group to the one farthest away from - the center of the group. For example, when left-aligning, the items are - aligned to the leftmost item. You can also align the horizontal/vertical - centers of items, or both, as in the image above. - - In the \uicontrol {Align to} field, select whether to align the items in - respect to the selection, the root item, or a \e {key object} that you - select in the \uicontrol {Key object} field. The key object must be a part - of the selection. - - You can distribute either \e objects or the \e spacing between them. If the - objects or spacing cannot be distributed to equal pixel values without - ending up with half pixels, you receive a notification. You can either allow - \QDS to distribute objects or spacing using the closest values possible or - tweak your design so that the objects and spacing can be distributed - perfectly. - - When distributing objects, you can select whether the distance between - them is calculated from their top/bottom or left/right edges or their - horizontal/vertical center. - - \image qmldesigner-distribute-objects.png "Distribute objects buttons" - - You can distribute spacing either evenly within a target area or at - specified distances, calculated from a starting point. - - You can select the orientation in which the objects are distributed evenly - within the target area: horizontally along the x axis or vertically along - the y axis. - - \image qmldesigner-distribute-spacing-evenly.png "Distribute spacing evenly" - - Alternatively, you can distribute spacing in pixels by selecting one of the - starting point buttons: left/right or top/bottom edge of the target area, - or its horizontal/vertical center. Note that some items might end up outside - the target area. - - \image qmldesigner-distribute-spacing-pixels.png "Distribute spacing in pixels" - - You can set the space between objects in pixels. You can - disable the distribution of spacing in pixels by clicking - the \inlineimage qmldesigner-distribute-spacing-x.png - button. - - \section2 Using Positioners - - \l{Important Concepts In Qt Quick - Positioning#positioners} - {Positioner items} are container items that manage the positions of items - in a declarative user interface. Positioners behave in a similar way to - the layout managers used with standard Qt widgets, except that they are - also containers in their own right. - - You can use the following positioners to arrange items in UIs: - - \list - \li \l[QtQuick] {Column} arranges its child items vertically. - \li \l[QtQuick] {Row} arranges its child items horizontally. - \li \l[QtQuick] {Grid} - arranges its child items so that they are aligned in a grid and - are not overlapping. - \li \l[QtQuick] {Flow} - arranges its child items side by side, wrapping as necessary. - \endlist - - To position several items in a \uicontrol Column, \uicontrol Row, - \uicontrol Grid, or \uicontrol Flow, select the items in - \uicontrol {Form Editor}, and then select \uicontrol Position in - the context menu. - - \section2 Using Layouts - - Since Qt 5.1, you can use QML types in the \l{qtquicklayouts-index.html} - {Qt Quick Layouts} module to arrange Qt Quick items in UIs. Unlike - positioners, they manage both the positions and sizes of items in a - declarative interface. They are well suited for resizable UIs. - - You can use the following layout types to arrange items in UIs: - - \list - \li \l{ColumnLayout}{Column Layout} provides a grid layout with only - one column. - \li \l{RowLayout}{Row Layout} provides a grid layout with only one row. - \li \l{GridLayout}{Grid Layout} provides a way of dynamically arranging - items in a grid. - \li \l{StackLayout}{Stack Layout} provides a stack of items where only - one item is visible at a time. - \endlist - - To lay out several items in a column, row, grid, or - \uicontrol {Stack Layout}, select the items in \uicontrol {Form Editor}, - and then select \uicontrol Layout in the context menu. - - You can also click the \inlineimage column.png - (\uicontrol {Column Layout}), \inlineimage row.png - (\uicontrol {Row Layout}), and \inlineimage grid.png - (\uicontrol {Grid Layout}) toolbar buttons to apply - layouts to the selected items. - - To make an item within a layout as wide as possible while respecting the - given constraints, select the item in \uicontrol {Form Editor}, and then - select \uicontrol Layout > \uicontrol {Fill Width} in the context menu. To - make the item as high as possible, select \uicontrol {Fill Height}. - - \section2 Editing Stack Layouts - - \image qtquick-designer-stacked-view.png - - To add items to a \uicontrol {Stack Layout}, select the - \inlineimage plus.png - button next to the type name in \uicontrol {Form Editor}. To move - between items, select the \inlineimage prev.png - (\uicontrol Previous) and \inlineimage next.png - (\uicontrol Next) buttons. - - To add a tab bar to a stack layout, select \uicontrol {Stacked Container} > - \uicontrol {Add Tab Bar}. - - To raise or lower the stacking order of an item, select - \uicontrol {Stacked Container} > \uicontrol {Increase Index} or - \uicontrol {Decrease Index}. - - \section2 Organizing Items - - Since Qt 5.7, you can use the following \l{Qt Quick Controls} types to - organize items in UIs: - - \list - \li \l [QtQuickControls]{Frame} places a logical group of controls - within a visual frame. - \li \l [QtQuickControls]{GroupBox}{Group Box} is used to lay out a - logical group of controls together, within a titled visual frame. - \li \l [QtQuickControls]{Label} is a text label with inherited styling - and font. - \li \l [QtQuickControls]{Page} provides a styled page control with - support for a header and footer. - \li \l [QtQuickControls]{PageIndicator}{Page Indicator} indicates the - currently active page. - \li \l [QtQuickControls]{Pane} provides a background matching with the - application style and theme. - \endlist - \section1 User Interaction Methods You can use the following QML types to add basic interaction methods to diff --git a/doc/qtcreator/src/qtquick/qtquick-fonts.qdoc b/doc/qtcreator/src/qtquick/qtquick-fonts.qdoc index ccaef797f2c..cbfaa2a9ece 100644 --- a/doc/qtcreator/src/qtquick/qtquick-fonts.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-fonts.qdoc @@ -24,7 +24,7 @@ ****************************************************************************/ /*! - \previouspage qtquick-properties.html + \previouspage qtquick-positioning.html \page qtquick-fonts.html \nextpage qtquick-annotations.html diff --git a/doc/qtcreator/src/qtquick/qtquick-positioning.qdoc b/doc/qtcreator/src/qtquick/qtquick-positioning.qdoc new file mode 100644 index 00000000000..7c1f07537e5 --- /dev/null +++ b/doc/qtcreator/src/qtquick/qtquick-positioning.qdoc @@ -0,0 +1,466 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Creator documentation. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** +****************************************************************************/ + +/*! + \page qtquick-positioning.html + \previouspage qtquick-properties.html + \nextpage qtquick-fonts.html + + \title Positioning Items + + The position of an item in a UI can be either absolute or relative to + other items. The visual types exist at a particular location in the screen + coordinate system at any instant in time. The x and y coordinates of a + visual item are relative to those of its visual parent, with the top-left + corner having the coordinate (0, 0). + + If you are designing a static UI, + \l{Important Concepts In Qt Quick - Positioning#manual-positioning} + {manual positioning} provides the most efficient form of positioning + items. For a dynamic UI, you can employ the following positioning + methods: + + \list + \li \l{Setting Bindings} + \li \l{Setting Anchors and Margins} + \li \l{Aligning and Distributing Items} + \li \l{Using Positioners} + \li \l{Using Layouts} + \li \l{Organizing Items} + \endlist + + \section2 Setting Bindings + + \l{Positioning with Bindings} {Property binding} is a declarative way of + specifying the value of a property. Binding allows a property value to be + expressed as a JavaScript expression that defines the value relative to + other property values or data accessible in the application. The property + value is automatically kept up to date if the other properties or data + values change. + + Property bindings are created implicitly in QML whenever a property is + assigned a JavaScript expression. To set JavaScript expressions as values + of properties in the \uicontrol Properties view, select the + \inlineimage icons/action-icon.png + (\uicontrol Actions) menu next to a property, and then select + \uicontrol {Set Binding}. + + \image qmldesigner-set-expression.png "Type properties context menu" + + In \uicontrol {Binding Editor}, select an item and a property from + lists of available items and their properties. + + \image qmldesigner-binding-editor.png "Binding Editor" + + Alternatively, start typing a + string and press \key Ctrl+Space to display a list of properties, IDs, and + code snippets. When you enter a period (.) after a property name, a list of + available values is displayed. Press \key Enter to accept the first + suggestion in the list and to complete the code. + + When a binding is set, the \uicontrol Actions menu icon changes to + \inlineimage icons/action-icon-binding + . To remove bindings, select \uicontrol Actions > \uicontrol Reset. + + You can set bindings also in the \uicontrol Connections view. For more + information, see \l {Adding Bindings Between Properties}. + + For more information on the JavaScript environment provided by QML, see + \l{Integrating QML and JavaScript}. + + Bindings are a black box for \QC and using them might have a + negative impact on performance, so consider setting anchors and margins for + items, instead. For example, instead of setting \c {parent.width} for an + item, you could anchor the item to its sibling items on the left and the + right. + + \section2 Setting Anchors and Margins + + In an \l{Important Concepts In Qt Quick - Positioning#anchors} + {anchor-based} layout, each QML type can be thought of as having a set of + invisible \e anchor lines: top, bottom, left, right, fill, horizontal + center, vertical center, and baseline. + + In the \uicontrol Layout tab you can set anchors and margins for items. To + set the anchors of an item, click the anchor buttons. You can combine the + top/bottom, left/right, and horizontal/vertical anchors to anchor items in + the corners of the parent item or center them horizontally or vertically + within the parent item. + + \image qmldesigner-anchor-buttons.png "Anchor buttons" + + For convenience, you can click the \inlineimage anchor-fill.png + (\uicontrol {Fill to Parent}) toolbar button to apply fill anchors to an + item and the \inlineimage qtcreator-anchors-reset-icon.png + (\uicontrol {Reset Anchors}) button to reset the anchors to their saved + state. + + You can specify the baseline anchor in \uicontrol {Text Editor}. + + For performance reasons, you can only anchor an item to its siblings + and direct parent. By default, an item is anchored to its parent when + you use the anchor buttons. Select a sibling of the item in the + \uicontrol Target field to anchor to it, instead. + + Arbitrary anchoring is not supported. For example, you cannot specify: + \c {anchor.left: parent.right}. You have to specify: + \c {anchor.left: parent.left}. When you use the anchor buttons, anchors to + the parent item are always specified to the same side. However, anchors to + sibling items are specified to the opposite side: + \c {anchor.left: sibling.right}. This allows you to keep sibling items + together. + + In the following image, \uicontrol{Rectangle 2} is anchored to + \uicontrol {Rectangle 1} on its left and to the bottom of its parent. + + \image qmldesigner-anchors.png "Anchoring sibling items" + + The anchors for \uicontrol{Rectangle 2} are specified as follows in code: + + \qml + Rectangle { + id: rectangle2 + anchors.left: rectangle1.right + anchors.leftMargin: 10 + anchors.bottom: parent.bottom + anchors.bottomMargin: 10 + // + } + \endqml + + Margins specify the amount of empty space to leave to the outside of an + item. Margins only have meaning for anchors. They do not take any effect + when using layouts or absolute positioning. + + \section2 Aligning and Distributing Items + + When you're working with a group of items, you can select them to align + and distribute them evenly. As the positions of the items are fixed, you + cannot apply these functions to anchored items. For scalability, you can + anchor the aligned and distributed items when your design is ready. + + \image qmldesigner-alignment.png "Aligning sibling items" + + Select the buttons in the \uicontrol Align group to align the top/bottom + or left/right edges of the items in the group to the one farthest away from + the center of the group. For example, when left-aligning, the items are + aligned to the leftmost item. You can also align the horizontal/vertical + centers of items, or both, as in the image above. + + In the \uicontrol {Align to} field, select whether to align the items in + respect to the selection, the root item, or a \e {key object} that you + select in the \uicontrol {Key object} field. The key object must be a part + of the selection. + + You can distribute either \e objects or the \e spacing between them. If the + objects or spacing cannot be distributed to equal pixel values without + ending up with half pixels, you receive a notification. You can either allow + \QDS to distribute objects or spacing using the closest values possible or + tweak your design so that the objects and spacing can be distributed + perfectly. + + When distributing objects, you can select whether the distance between + them is calculated from their top/bottom or left/right edges or their + horizontal/vertical center. + + \image qmldesigner-distribute-objects.png "Distribute objects buttons" + + You can distribute spacing either evenly within a target area or at + specified distances, calculated from a starting point. + + You can select the orientation in which the objects are distributed evenly + within the target area: horizontally along the x axis or vertically along + the y axis. + + \image qmldesigner-distribute-spacing-evenly.png "Distribute spacing evenly" + + Alternatively, you can distribute spacing in pixels by selecting one of the + starting point buttons: left/right or top/bottom edge of the target area, + or its horizontal/vertical center. Note that some items might end up outside + the target area. + + \image qmldesigner-distribute-spacing-pixels.png "Distribute spacing in pixels" + + You can set the space between objects in pixels. You can + disable the distribution of spacing in pixels by clicking + the \inlineimage qmldesigner-distribute-spacing-x.png + button. + + \section2 Using Positioners + + Positioner items are container items that manage the positions of + items. For many use cases, the best positioner to use is a simple + column, row, flow, or grid. You can use the QML types available in + the \uicontrol {Qt Quick - Positioner} section of \uicontrol Library + to position the children of an item in these formations in the most + efficient manner possible. + + To position several items in a \uicontrol Column, \uicontrol Row, + \uicontrol Flow, or \uicontrol Grid, select the items in + \uicontrol {Form Editor}, and then select \uicontrol Position in + the context menu. + + \section3 Column Positioner + + A \uicontrol Column positions its child items along a single column. + It can be used as a convenient way to vertically position a series of + items without using anchors. + + \image qtquick-positioner-column-properties.png "Column properties" + + For all positioners, you can specify the spacing between the child + items that they contain in the \uicontrol Spacing field. + + In addition, you can specify the vertical and horizontal padding between + content and the left, right, top, and bottom edges of items as values of + the fields in the \uicontrol Padding group. + + \section3 Row and Flow Positioners + + A \uicontrol Row positions its child items along a single row. It can be + used as a convenient way to horizontally position a series of items without + using anchors. + + The \uicontrol Flow type positions its child items like words on a page, + wrapping them to create rows or columns of items. + + \image qtquick-positioner-flow-properties.png "Flow properties" + + For flow and row positioners, you can also set the direction of a flow to + either left-to-right or top-to-bottom in the \uicontrol Flow field. + Items are positioned next to to each other according to the value you set + in the \uicontrol {Layout direction} field until the width or height of the + Flow item is exceeded, then wrapped to the next row or column. + + You can set the layout direction to either \uicontrol LeftToRight or + \uicontrol RightToLeft in the \uicontrol {Layout direction} field. If + the width of the row is explicitly set, the left anchor remains to the + left of the row and the right anchor remains to the right of it. + + \section3 Grid Positioner + + A \uicontrol Grid creates a grid of cells that is large enough to hold all + of its child items, and places these items in the cells from left to right + and top to bottom. Each item is positioned at the top-left corner of its + cell with position (0, 0). + + \QC generates the grid based on the positions of the child items in + \uicontrol {Form Editor}. You can modify the number of rows and columns + in the \uicontrol Rows and \uicontrol Columns fields. + + \image qtquick-positioner-grid-properties.png "Grid properties" + + In addition to the flow and layout direction, you can set the horizontal + and vertical alignment of grid items. By default, grid items are vertically + aligned to the top. Horizontal alignment follows the value of the + \uicontrol {Layout direction} field. For example, when layout direction is + set to \uicontrol LeftToRight, the items are aligned on the left. + + To mirror the layout, set the layout direction to \uicontrol RightToLeft. + To also mirror the horizontal alignment of items, select + \uicontrol AlignRight in the \uicontrol {Horizontal item alignment} field. + + \section3 Summary of Positioners + + The following table lists the positioners that you can use to arrange items + in UIs. They are available in the \uicontrol {Qt Quick - Positioner} section + of \uicontrol Library. + + \table + \header + \li Icon + \li Name + \li Purpose + \row + \li \inlineimage column-positioner-icon-16px.png + \li \l[QtQuick] {Column} + \li Arranges its child items vertically. + \row + \li \inlineimage row-positioner-icon-16px.png + \li \l[QtQuick] {Row} + \li Arranges its child items horizontally. + \row + \li \inlineimage grid-positioner-icon-16px.png + \li \l[QtQuick] {Grid} + \li Arranges its child items so that they are aligned in a grid and + are not overlapping. + \row + \li \inlineimage flow-positioner-icon-16px.png + \li \l[QtQuick] {Flow} + \li Arranges its child items side by side, wrapping as necessary. + \endtable + + \section2 Using Layouts + + \if defined(qtcreator) + Since Qt 5.1, you can use QML types in the \l{qtquicklayouts-index.html} + {Qt Quick Layouts} module to arrange items in UIs. + \else + You can use the QML types available in the \uicontrol {Qt Quick - Layouts} + section of \uicontrol Library to arrange items in UIs. + \endif + Unlike positioners, layouts manage both the positions and sizes of their + child items, and are therefore well suited for dynamic and resizable UIs. + However, this means that you should not specify fixed positions and sizes + for the child items in the \uicontrol Geometry group in their properties, + unless their implicit sizes are not satisfactory. + + You can use anchors or the width and height properties of the layout itself + to specify its size in respect to its non-layout parent item. However, do + not anchor the child items within layouts. + + To arrange several items in a column, row, grid, or + \uicontrol {Stack Layout}, select the items in \uicontrol {Form Editor}, + and then select \uicontrol Layout in the context menu. + + You can also click the \inlineimage column.png + (\uicontrol {Column Layout}), \inlineimage row.png + (\uicontrol {Row Layout}), and \inlineimage grid.png + (\uicontrol {Grid Layout}) toolbar buttons to apply + layouts to the selected items. + + To make an item within a layout as wide as possible while respecting the + given constraints, select the item in \uicontrol {Form Editor}, and then + select \uicontrol Layout > \uicontrol {Fill Width} in the context menu. To + make the item as high as possible, select \uicontrol {Fill Height}. + + \section3 Layout Properties + + A \uicontrol {Grid Layout} type provides a way of dynamically arranging + items in a grid. If the grid layout is resized, all its child items are + rearranged. If you want a layout with just one row or one column, use the + \uicontrol {Row Layout} or \uicontrol {Column Layout} type. + + The child items of row and column layout items are automatically positioned + either horizontally from left to right as rows or vertically from + top to bottom as columns. The number of the child items determines the width + of the row or the height of the column. You can specify the spacing between + the child items in the \uicontrol Spacing field. + + The child items of grid layout items are arranged according to the + \uicontrol Flow property. When the direction of a flow is set to + \uicontrol LeftToRight, child items are positioned next to to each + other until the the number of \uicontrol Columns is reached. Then, + the auto-positioning wraps back to the beginning of the next row. + + \image qtquick-layout-grid-properties.png "Grid Layout properties" + + If you set the direction of the flow to \uicontrol TopToBottom, child + items are auto-positioned vertically using the value of the \uicontrol Rows + field to determine the maximum number of rows. + + You can set the layout direction to either \uicontrol LeftToRight or + \uicontrol RightToLeft in the \uicontrol {Layout direction} field. + When you select \uicontrol RightToLeft, the alignment of the items + will be mirrored. + + You can specify the spacing between rows and columns in the + \uicontrol {Row spacing} and \uicontrol {Column spacing} fields. + + \section3 Stack Layout + + \image qtquick-designer-stacked-view.png + + To add items to a \uicontrol {Stack Layout}, select the + \inlineimage plus.png + button next to the type name in \uicontrol {Form Editor}. To move + between items, select the \inlineimage prev.png + (\uicontrol Previous) and \inlineimage next.png + (\uicontrol Next) buttons. + + To add a tab bar to a stack layout, select \uicontrol {Stacked Container} > + \uicontrol {Add Tab Bar}. + + To raise or lower the stacking order of an item, select + \uicontrol {Stacked Container} > \uicontrol {Increase Index} or + \uicontrol {Decrease Index}. + + \section3 Summary of Layouts + + The following table lists the layout types that you can use to arrange items + in UIs. They are available in the \uicontrol {Qt Quick - Layouts} section + of \uicontrol Library. + + \table + \header + \li Icon + \li Name + \li Purpose + \row + \li \inlineimage column-layouts-icon-16px.png + \li \l{ColumnLayout}{Column Layout} + \li Provides a grid layout with only one column. + \row + \li\inlineimage row-layouts-icon-16px.png + \li \l{RowLayout}{Row Layout} + \li Provides a grid layout with only one row. + \row + \li \inlineimage grid-layouts-icon-16px.png + \li \l{GridLayout}{Grid Layout} + \li Provides a way of dynamically arranging items in a grid. + \row + \li \inlineimage stack-layouts-icon-16px.png + \li \l{StackLayout}{Stack Layout} + \li Provides a stack of items where only one item is visible at a time. + \endtable + + + \section2 Organizing Items + + The following table lists the UI controls that you can use to + organize items in UIs (since Qt 5.7). They are available in the + \uicontrol {Qt Quick - Controls 2} section of \uicontrol Library. + + \table + \header + \li Icon + \li Name + \li Purpose + \row + \li \inlineimage icons/frame-icon16.png + \li \l [QtQuickControls]{Frame} + \li A visual frame around a group of controls. + \row + \li \inlineimage icons/groupbox-icon16.png + \li \l [QtQuickControls]{GroupBox}{Group Box} + \li A titled visual frame around a group of controls. + \row + \li \inlineimage icons/label-icon16.png + \li \l [QtQuickControls]{Label} + \li A text label with inherited styling and font. + \row + \li \inlineimage icons/page-icon16.png + \li \l [QtQuickControls]{Page} + \li A styled page control with support for a header and footer. + \row + \li \inlineimage icons/pageindicator-icon16.png + \li \l [QtQuickControls]{PageIndicator}{Page Indicator} + \li An indicator for the currently active page. + \row + \li \inlineimage icons/pane-icon16.png + \li \l [QtQuickControls]{Pane} + \li A background that matches the application style and theme. + \endtable +*/ diff --git a/doc/qtcreator/src/qtquick/qtquick-properties.qdoc b/doc/qtcreator/src/qtquick/qtquick-properties.qdoc index 02bb87582a5..dd7f3cb2a0d 100644 --- a/doc/qtcreator/src/qtquick/qtquick-properties.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-properties.qdoc @@ -26,7 +26,7 @@ /*! \page qtquick-properties.html \previouspage qtquick-navigator.html - \nextpage qtquick-fonts.html + \nextpage qtquick-positioning.html \title Specifying Item Properties @@ -235,7 +235,9 @@ \section2 Geometry In the \uicontrol Position group, you can set the position of an item on - the x and y axis. + the x and y axis. The position of an item in the UI can be either absolute + or relative to other items. For more information, see + \l{Positioning Items}. The z position of an item determines its position in relation to its sibling items in the type hierarchy. You can set it in the \uicontrol Z diff --git a/doc/qtdesignstudio/config/qtdesignstudio.qdocconf b/doc/qtdesignstudio/config/qtdesignstudio.qdocconf index 5bb27d9496e..dec1878602a 100644 --- a/doc/qtdesignstudio/config/qtdesignstudio.qdocconf +++ b/doc/qtdesignstudio/config/qtdesignstudio.qdocconf @@ -34,6 +34,7 @@ imagedirs = ../images \ ../../../src/plugins/qmldesigner/components/formeditor \ ../../../src/plugins/qmldesigner/components/navigator \ ../../../src/plugins/qmldesigner/components/timelineeditor/images \ + ../../../src/plugins/qmldesigner/componentsplugin/images \ ../../../src/plugins/qmldesigner/qmlpreviewplugin/images \ ../../../src/plugins/qmldesigner/qtquickplugin/images \ ../../../src/plugins/texteditor/images diff --git a/doc/qtdesignstudio/examples/doc/loginui2.qdoc b/doc/qtdesignstudio/examples/doc/loginui2.qdoc index 10c43839d2e..042f82c0e26 100644 --- a/doc/qtdesignstudio/examples/doc/loginui2.qdoc +++ b/doc/qtdesignstudio/examples/doc/loginui2.qdoc @@ -200,7 +200,7 @@ \section1 Next Steps To learn more about positioning items in \QDS, see - \l{Positioning Items in UIs}. + \l{Positioning Items}. To learn how to add a second page and move to it from the main page, see the next example in the series, \l {Log In UI - Part 3}. diff --git a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc index 966e2f3f3d6..5e46c894fae 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc @@ -83,6 +83,7 @@ \endlist \li \l{Managing Item Hierarchy} \li \l{Specifying Item Properties} + \li \l{Positioning Items} \li \l{Using Custom Fonts} \li \l{Annotating Designs} \li \l{Qt Quick UI Forms} diff --git a/doc/qtdesignstudio/src/qtdesignstudio.qdoc b/doc/qtdesignstudio/src/qtdesignstudio.qdoc index 3c2eba8e2c6..abf1ba7b7de 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio.qdoc @@ -62,7 +62,7 @@ \li \l{Creating Components} \li \l{Managing Item Hierarchy} \li \l{Specifying Item Properties} - \li \l{Using Custom Fonts} + \li \l{Positioning Items} \li \l{Annotating Designs} \endlist \li \b {\l{Adding Dynamics}} diff --git a/qbs/imports/QtcProduct.qbs b/qbs/imports/QtcProduct.qbs index 0509b79d784..829394d798f 100644 --- a/qbs/imports/QtcProduct.qbs +++ b/qbs/imports/QtcProduct.qbs @@ -29,6 +29,10 @@ Product { } } Depends { name: "Qt.core"; versionAtLeast: "5.14.0" } + Depends { + name: "Qt.core5compat" + condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 + } // TODO: Should fall back to what came from Qt.core for Qt < 5.7, but we cannot express that // atm. Conditionally pulling in a module that sets the property is also not possible, diff --git a/qtcreator.pri b/qtcreator.pri index 5879ded545a..5c586e2d76b 100644 --- a/qtcreator.pri +++ b/qtcreator.pri @@ -244,6 +244,7 @@ qt { QBSFILE = $$replace(_PRO_FILE_, \\.pro$, .qbs) exists($$QBSFILE):DISTFILES += $$QBSFILE +DISTFILES += $$_PRO_FILE_PWD_/CMakeLists.txt !isEmpty(QTC_PLUGIN_DEPENDS) { LIBS *= -L$$IDE_PLUGIN_PATH # plugin path from output directory diff --git a/qtcreator.pro b/qtcreator.pro index 7d055942ad6..cd3ae73669a 100644 --- a/qtcreator.pro +++ b/qtcreator.pro @@ -20,6 +20,7 @@ DISTFILES += dist/copyright_template.txt \ $$files(dist/changes-*) \ qtcreator.qbs \ $$files(qbs/*, true) \ + $$files(cmake/*) \ $$files(scripts/*.py) \ $$files(scripts/*.sh) \ $$files(scripts/*.pl) diff --git a/scripts/build.py b/scripts/build.py index 6fd8d976b28..50247030fdf 100755 --- a/scripts/build.py +++ b/scripts/build.py @@ -91,6 +91,10 @@ def get_arguments(): action='store_true', default=False) parser.add_argument('--with-tests', help='Enable building of tests', action='store_true', default=False) + parser.add_argument('--add-path', help='Prepends a CMAKE_PREFIX_PATH to the build', + action='append', dest='prefix_paths', default=[]) + parser.add_argument('--add-module-path', help='Prepends a CMAKE_MODULE_PATH to the build', + action='append', dest='module_paths', default=[]) parser.add_argument('--add-make-arg', help='Passes the argument to the make tool.', action='append', dest='make_args', default=[]) parser.add_argument('--add-config', help=('Adds the argument to the CMake configuration call. ' @@ -103,7 +107,7 @@ def get_arguments(): def build_qtcreator(args, paths): if not os.path.exists(paths.build): os.makedirs(paths.build) - prefix_paths = [paths.qt] + prefix_paths = [os.path.abspath(fp) for fp in args.prefix_paths] + [paths.qt] if paths.llvm: prefix_paths += [paths.llvm] if paths.elfutils: @@ -126,6 +130,10 @@ def build_qtcreator(args, paths): if args.python3: cmake_args += ['-DPYTHON_EXECUTABLE=' + args.python3] + if args.module_paths: + module_paths = [os.path.abspath(fp) for fp in args.module_paths] + cmake_args += ['-DCMAKE_MODULE_PATH=' + ';'.join(module_paths)] + # force MSVC on Windows, because it looks for GCC in the PATH first, # even if MSVC is first mentioned in the PATH... # TODO would be nicer if we only did this if cl.exe is indeed first in the PATH diff --git a/scripts/build_plugin.py b/scripts/build_plugin.py index 9df8c64f747..811713a969d 100755 --- a/scripts/build_plugin.py +++ b/scripts/build_plugin.py @@ -46,8 +46,10 @@ def get_arguments(): help='Path to Qt Creator installation including development package', required=True) parser.add_argument('--output-path', help='Output path for resulting 7zip files') - parser.add_argument('--add-path', help='Adds a CMAKE_PREFIX_PATH to the build', + parser.add_argument('--add-path', help='Prepends a CMAKE_PREFIX_PATH to the build', action='append', dest='prefix_paths', default=[]) + parser.add_argument('--add-make-arg', help='Passes the argument to the make tool.', + action='append', dest='make_args', default=[]) parser.add_argument('--add-config', help=('Adds the argument to the CMake configuration call. ' 'Use "--add-config=-DSOMEVAR=SOMEVALUE" if the argument begins with a dash.'), action='append', dest='config_args', default=[]) @@ -63,7 +65,7 @@ def build(args, paths): os.makedirs(paths.build) if not os.path.exists(paths.result): os.makedirs(paths.result) - prefix_paths = [paths.qt, paths.qt_creator] + [os.path.abspath(fp) for fp in args.prefix_paths] + prefix_paths = [os.path.abspath(fp) for fp in args.prefix_paths] + [paths.qt_creator, paths.qt] build_type = 'Debug' if args.debug else 'Release' cmake_args = ['cmake', '-DCMAKE_PREFIX_PATH=' + ';'.join(prefix_paths), @@ -92,7 +94,10 @@ def build(args, paths): cmake_args += args.config_args common.check_print_call(cmake_args + [paths.src], paths.build) - common.check_print_call(['cmake', '--build', '.'], paths.build) + build_args = ['cmake', '--build', '.'] + if args.make_args: + build_args += ['--'] + args.make_args + common.check_print_call(build_args, paths.build) if args.with_docs: common.check_print_call(['cmake', '--build', '.', '--target', 'docs'], paths.build) common.check_print_call(['cmake', '--install', '.', '--prefix', paths.install, '--strip'], diff --git a/scripts/common.py b/scripts/common.py index d033108648d..a828faca2de 100644 --- a/scripts/common.py +++ b/scripts/common.py @@ -133,16 +133,17 @@ def get_rpath(libfilepath, chrpath=None): chrpath = 'chrpath' try: output = subprocess.check_output([chrpath, '-l', libfilepath]).strip() + decoded_output = output.decode(encoding) if encoding else output except subprocess.CalledProcessError: # no RPATH or RUNPATH return [] marker = 'RPATH=' - index = output.decode(encoding).find(marker) + index = decoded_output.find(marker) if index < 0: marker = 'RUNPATH=' - index = output.find(marker) + index = decoded_output.find(marker) if index < 0: return [] - return output[index + len(marker):].split(':') + return decoded_output[index + len(marker):].split(':') def fix_rpaths(path, qt_deploy_path, qt_install_info, chrpath=None): if chrpath is None: @@ -155,12 +156,13 @@ def fix_rpaths(path, qt_deploy_path, qt_install_info, chrpath=None): if len(rpath) <= 0: return # remove previous Qt RPATH - new_rpath = filter(lambda path: not path.startswith(qt_install_prefix) and not path.startswith(qt_install_libs), - rpath) + new_rpath = list(filter(lambda path: not path.startswith(qt_install_prefix) and not path.startswith(qt_install_libs), + rpath)) # check for Qt linking lddOutput = subprocess.check_output(['ldd', filepath]) - if lddOutput.decode(encoding).find('libQt5') >= 0 or lddOutput.find('libicu') >= 0: + lddDecodedOutput = lddOutput.decode(encoding) if encoding else lddOutput + if lddDecodedOutput.find('libQt5') >= 0 or lddDecodedOutput.find('libicu') >= 0: # add Qt RPATH if necessary relative_path = os.path.relpath(qt_deploy_path, os.path.dirname(filepath)) if relative_path == '.': @@ -180,7 +182,7 @@ def fix_rpaths(path, qt_deploy_path, qt_install_info, chrpath=None): def is_unix_executable(filepath): # Whether a file is really a binary executable and not a script and not a symlink (unix only) if os.path.exists(filepath) and os.access(filepath, os.X_OK) and not os.path.islink(filepath): - with open(filepath) as f: + with open(filepath, 'rb') as f: return f.read(2) != "#!" def is_unix_library(filepath): diff --git a/scripts/deployqtHelper_mac.sh b/scripts/deployqtHelper_mac.sh index f91423accb9..b4b283289de 100755 --- a/scripts/deployqtHelper_mac.sh +++ b/scripts/deployqtHelper_mac.sh @@ -64,9 +64,7 @@ if [ -d "$assetimporterSrcDir" ]; then if [ ! -d "$assetimporterDestDir" ]; then echo "- Copying 3d assetimporter plugins" mkdir -p "$assetimporterDestDir" - for plugin in "$assetimporterSrcDir"/*.dylib; do - cp "$plugin" "$assetimporterDestDir"/ || exit 1 - done + find "$assetimporterSrcDir" -iname "*.dylib" -maxdepth 1 -exec cp {} "$assetimporterDestDir"/ \; fi fi diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorButton.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorButton.qml index e609297149d..afba6def0c7 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorButton.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorButton.qml @@ -201,6 +201,7 @@ Item { MouseArea { id: mapMouseArea anchors.fill: parent + preventStealing: true onPositionChanged: { if (pressed && mouse.buttons === Qt.LeftButton) { var xx = Math.max(0, Math.min(mouse.x, parent.width)) diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/licenses/LICENSE.GPLv2 b/src/libs/3rdparty/syntax-highlighting/data/syntax/licenses/LICENSE.GPLv2 new file mode 100644 index 00000000000..b9033aeae64 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/licenses/LICENSE.GPLv2 @@ -0,0 +1,282 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +Preamble + + The licenses for most software are designed to take away your freedom +to share and change it. By contrast, the GNU General Public License is +intended to guarantee your freedom to share and change free software +--to make sure the software is free for all its users. This General +Public License applies to most of the Free Software Foundation's +software and to any other program whose authors commit to using it. +(Some other Free Software Foundation software is covered by the GNU +Lesser General Public License instead.) You can apply it to your +programs, too. + +When we speak of free software, we are referring to freedom, not price. +Our General Public Licenses are designed to make sure that you have the +freedom to distribute copies of free software (and charge for this +service if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone +to deny you these rights or to ask you to surrender the rights. These +restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis + or for a fee, you must give the recipients all the rights that you +have. You must make sure that they, too, receive or can get the source +code. And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + +Finally, any free program is threatened constantly by software patents. +We wish to avoid the danger that redistributors of a free program will +individually obtain patent licenses, in effect making the program +proprietary. To prevent this, we have made it clear that any patent +must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and +modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a +notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of running +the Program is not restricted, and the output from the Program is +covered only if its contents constitute a work based on the Program +(independent of having been made by running the Program). Whether that +is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously +and appropriately publish on each copy an appropriate copyright notice +and disclaimer of warranty; keep intact all the notices that refer to +this License and to the absence of any warranty; and give any other +recipients of the Program a copy of this License along with the +Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of +it, thus forming a work based on the Program, and copy and distribute +such modifications or work under the terms of Section 1 above, provided +that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but does + not normally print such an announcement, your work based on the + Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of a +storage or distribution medium does not bring the other work under the +scope of this License. + +3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software + interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your cost + of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to control +compilation and installation of the executable. However, as a special +exception, the source code distributed need not include anything that +is normally distributed (in either source or binary form) with the +major components (compiler, kernel, and so on) of the operating system +on which the executable runs, unless that component itself accompanies +the executable. + +If distribution of executable or object code is made by offering access +to copy from a designated place, then offering equivalent access to +copy the source code from the same place counts as distribution of the +source code, even though third parties are not compelled to copy the +source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt otherwise +to copy, modify, sublicense or distribute the Program is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this License +will not have their licenses terminated so long as such parties remain +in full compliance. + +5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further restrictions +on the recipients' exercise of the rights granted herein. You are not +responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent license +would not permit royalty-free redistribution of the Program by all +those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain +entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License may +add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among countries +not thus excluded. In such case, this License incorporates the limitation +as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail +to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Program does not specify a version +number of this License, you may choose any version ever published by +the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the +author to ask for permission. For software which is copyrighted by +the Free Software Foundation, write to the Free Software Foundation; +we sometimes make exceptions for this. Our decision will be guided by +the two goals of preserving the free status of all derivatives of our +free software and of promoting the sharing and reuse of software +generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE +ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH +YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL +NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY +MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE +TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + +END OF TERMS AND CONDITIONS diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/licenses/LICENSE.GPLv3 b/src/libs/3rdparty/syntax-highlighting/data/syntax/licenses/LICENSE.GPLv3 new file mode 100644 index 00000000000..94a9ed024d3 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/licenses/LICENSE.GPLv3 @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/licenses/LICENSE.LGPLv21 b/src/libs/3rdparty/syntax-highlighting/data/syntax/licenses/LICENSE.LGPLv21 new file mode 100644 index 00000000000..ec3ce5f2b05 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/licenses/LICENSE.LGPLv21 @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/licenses/LICENSE.LGPLv3 b/src/libs/3rdparty/syntax-highlighting/data/syntax/licenses/LICENSE.LGPLv3 new file mode 100644 index 00000000000..eb332415518 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/licenses/LICENSE.LGPLv3 @@ -0,0 +1,163 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright © 2007 Free Software Foundation, Inc. +Everyone is permitted to copy and distribute verbatim copies of this +licensedocument, but changing it is not allowed. + +This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + +0. Additional Definitions. + + As used herein, “this License” refers to version 3 of the GNU Lesser +General Public License, and the “GNU GPL” refers to version 3 of the +GNU General Public License. + + “The Library” refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An “Application” is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A “Combined Work” is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the “Linked +Version”. + + The “Minimal Corresponding Source” for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The “Corresponding Application Code” for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + +1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + +2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort + to ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + +3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this + license document. + +4. Combined Works. + + You may convey a Combined Work under terms of your choice that, taken +together, effectively do not restrict modification of the portions of +the Library contained in the Combined Work and reverse engineering for +debugging such modifications, if you also do each of the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this + license document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of + this License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with + the Library. A suitable mechanism is one that (a) uses at run + time a copy of the Library already present on the user's + computer system, and (b) will operate properly with a modified + version of the Library that is interface-compatible with the + Linked Version. + + e) Provide Installation Information, but only if you would + otherwise be required to provide such information under section 6 + of the GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the Application + with a modified version of the Linked Version. (If you use option + 4d0, the Installation Information must accompany the Minimal + Corresponding Source and Corresponding Application Code. If you + use option 4d1, you must provide the Installation Information in + the manner specified by section 6 of the GNU GPL for conveying + Corresponding Source.) + +5. Combined Libraries. + + You may place library facilities that are a work based on the Library +side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities, conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of + it is a work based on the Library, and explaining where to find + the accompanying uncombined form of the same work. + +6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +as you received it specifies that a certain numbered version of the +GNU Lesser General Public License “or any later version” applies to +it, you have the option of following the terms and conditions either +of that published version or of any later version published by the +Free Software Foundation. If the Library as you received it does not +specify a version number of the GNU Lesser General Public License, +you may choose any version of the GNU Lesser General Public License +ever published by the Free Software Foundation. + +If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the Library. + diff --git a/src/libs/cplusplus/TypePrettyPrinter.cpp b/src/libs/cplusplus/TypePrettyPrinter.cpp index 193a00803c4..c85444a2287 100644 --- a/src/libs/cplusplus/TypePrettyPrinter.cpp +++ b/src/libs/cplusplus/TypePrettyPrinter.cpp @@ -383,6 +383,31 @@ static bool endsWithPtrOrRef(const QString &type) void TypePrettyPrinter::visit(Function *type) { + if (_overview->showTemplateParameters) { + QStringList nameParts = _name.split("::"); + int i = nameParts.length() - 1; + for (Scope *s = type->enclosingScope(); s && i >= 0; s = s->enclosingScope()) { + if (Template *templ = s->asTemplate()) { + QString &n = nameParts[i]; + n += '<'; + for (int index = 0; index < templ->templateParameterCount(); ++index) { + if (index) + n += QLatin1String(", "); + QString arg = _overview->prettyName(templ->templateParameterAt(index)->name()); + if (arg.isEmpty()) { + arg += 'T'; + arg += QString::number(index + 1); + } + n += arg; + } + n += '>'; + } + if (s->identifier()) + --i; + } + _name = nameParts.join("::"); + } + if (_needsParens) { _text.prepend(QLatin1Char('(')); if (! _name.isEmpty()) { @@ -417,7 +442,10 @@ void TypePrettyPrinter::visit(Function *type) if (TypenameArgument *typenameArg = param->asTypenameArgument()) { templateScope.append(QLatin1String(typenameArg->isClassDeclarator() ? "class " : "typename ")); - templateScope.append(_overview->prettyName(typenameArg->name())); + QString name = _overview->prettyName(typenameArg->name()); + if (name.isEmpty()) + name.append('T').append(QString::number(i + 1)); + templateScope.append(name); } else if (Argument *arg = param->asArgument()) { templateScope.append(operator()(arg->type(), _overview->prettyName(arg->name()))); diff --git a/src/libs/ssh/sshkeycreationdialog.cpp b/src/libs/ssh/sshkeycreationdialog.cpp index 9c4fe8db2b2..538315850a7 100644 --- a/src/libs/ssh/sshkeycreationdialog.cpp +++ b/src/libs/ssh/sshkeycreationdialog.cpp @@ -29,6 +29,7 @@ #include "sshsettings.h" #include +#include #include #include @@ -45,12 +46,7 @@ SshKeyCreationDialog::SshKeyCreationDialog(QWidget *parent) : QDialog(parent), m_ui(new Ui::SshKeyCreationDialog) { m_ui->setupUi(this); - // Not using Utils::PathChooser::browseButtonLabel to avoid dependency -#ifdef Q_OS_MAC - m_ui->privateKeyFileButton->setText(tr("Choose...")); -#else - m_ui->privateKeyFileButton->setText(tr("Browse...")); -#endif + m_ui->privateKeyFileButton->setText(Utils::PathChooser::browseButtonLabel()); const QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + QLatin1String("/.ssh/qtc_id"); setPrivateKeyFile(defaultPath); diff --git a/src/libs/tracing/tracing.qbs b/src/libs/tracing/tracing.qbs index 4705d9adc79..e037abb8281 100644 --- a/src/libs/tracing/tracing.qbs +++ b/src/libs/tracing/tracing.qbs @@ -9,6 +9,7 @@ Project { QtcLibrary { Depends { name: "Qt"; submodules: ["qml", "quick", "gui"] } + Depends { name: "Qt.testlib"; condition: project.withAutotests } Depends { name: "Utils" } Group { @@ -48,7 +49,7 @@ Project { Group { name: "Unit test utilities" - condition: qtc.testsEnabled + condition: project.withAutotests files: [ "runscenegraphtest.cpp", "runscenegraphtest.h" ] diff --git a/src/plugins/android/androidqtversion.cpp b/src/plugins/android/androidqtversion.cpp index 2f306671eb3..a5da746ccf8 100644 --- a/src/plugins/android/androidqtversion.cpp +++ b/src/plugins/android/androidqtversion.cpp @@ -171,9 +171,8 @@ int AndroidQtVersion::minimumNDK() const void AndroidQtVersion::parseMkSpec(ProFileEvaluator *evaluator) const { - if (supportsMultipleQtAbis()) - m_androidAbis = evaluator->values("ALL_ANDROID_ABIS"); - else + m_androidAbis = evaluator->values("ALL_ANDROID_ABIS"); + if (m_androidAbis.isEmpty()) m_androidAbis = QStringList{evaluator->value("ANDROID_TARGET_ARCH")}; const QString androidPlatform = evaluator->value("ANDROID_PLATFORM"); if (!androidPlatform.isEmpty()) { diff --git a/src/plugins/baremetal/CMakeLists.txt b/src/plugins/baremetal/CMakeLists.txt index 0a6721c4e76..046e0531c33 100644 --- a/src/plugins/baremetal/CMakeLists.txt +++ b/src/plugins/baremetal/CMakeLists.txt @@ -14,6 +14,7 @@ add_qtc_plugin(BareMetal debugserverprovidermanager.cpp debugserverprovidermanager.h debugserverproviderssettingspage.cpp debugserverproviderssettingspage.h debugservers/gdb/gdbserverprovider.cpp debugservers/gdb/gdbserverprovider.h + debugservers/gdb/genericgdbserverprovider.cpp debugservers/gdb/genericgdbserverprovider.h debugservers/gdb/openocdgdbserverprovider.cpp debugservers/gdb/openocdgdbserverprovider.h debugservers/gdb/stlinkutilgdbserverprovider.cpp debugservers/gdb/stlinkutilgdbserverprovider.h debugservers/gdb/jlinkgdbserverprovider.cpp debugservers/gdb/jlinkgdbserverprovider.h diff --git a/src/plugins/baremetal/baremetal.qbs b/src/plugins/baremetal/baremetal.qbs index c1942018002..f9631304500 100644 --- a/src/plugins/baremetal/baremetal.qbs +++ b/src/plugins/baremetal/baremetal.qbs @@ -42,6 +42,7 @@ QtcPlugin { prefix: "debugservers/gdb/" files: [ "gdbserverprovider.cpp", "gdbserverprovider.h", + "genericgdbserverprovider.cpp", "genericgdbserverprovider.h", "openocdgdbserverprovider.cpp", "openocdgdbserverprovider.h", "stlinkutilgdbserverprovider.cpp", "stlinkutilgdbserverprovider.h", "jlinkgdbserverprovider.cpp", "jlinkgdbserverprovider.h", diff --git a/src/plugins/baremetal/baremetalconstants.h b/src/plugins/baremetal/baremetalconstants.h index 816aa0a51a2..e446d77ed27 100644 --- a/src/plugins/baremetal/baremetalconstants.h +++ b/src/plugins/baremetal/baremetalconstants.h @@ -39,6 +39,7 @@ const char DEBUG_SERVER_PROVIDERS_SETTINGS_ID[] = "EE.BareMetal.DebugServerProvi // GDB Debugger Server Provider Ids. const char GDBSERVER_OPENOCD_PROVIDER_ID[] = "BareMetal.GdbServerProvider.OpenOcd"; const char GDBSERVER_JLINK_PROVIDER_ID[] = "BareMetal.GdbServerProvider.JLink"; +const char GDBSERVER_GENERIC_PROVIDER_ID[] = "BareMetal.GdbServerProvider.Generic"; const char GDBSERVER_STLINK_UTIL_PROVIDER_ID[] = "BareMetal.GdbServerProvider.STLinkUtil"; const char GDBSERVER_EBLINK_PROVIDER_ID[] = "BareMetal.GdbServerProvider.EBlink"; diff --git a/src/plugins/baremetal/debugserverprovidermanager.cpp b/src/plugins/baremetal/debugserverprovidermanager.cpp index 5081588783a..6ab84c02082 100644 --- a/src/plugins/baremetal/debugserverprovidermanager.cpp +++ b/src/plugins/baremetal/debugserverprovidermanager.cpp @@ -27,6 +27,7 @@ #include "idebugserverprovider.h" // GDB debug servers. +#include "debugservers/gdb/genericgdbserverprovider.h" #include "debugservers/gdb/openocdgdbserverprovider.h" #include "debugservers/gdb/stlinkutilgdbserverprovider.h" #include "debugservers/gdb/jlinkgdbserverprovider.h" @@ -61,7 +62,8 @@ static DebugServerProviderManager *m_instance = nullptr; DebugServerProviderManager::DebugServerProviderManager() : m_configFile(Utils::FilePath::fromString(Core::ICore::userResourcePath() + fileNameKeyC)) - , m_factories({new JLinkGdbServerProviderFactory, + , m_factories({new GenericGdbServerProviderFactory, + new JLinkGdbServerProviderFactory, new OpenOcdGdbServerProviderFactory, new StLinkUtilGdbServerProviderFactory, new EBlinkGdbServerProviderFactory, @@ -115,7 +117,13 @@ void DebugServerProviderManager::restoreProviders() if (!data.contains(key)) break; - const QVariantMap map = data.value(key).toMap(); + QVariantMap map = data.value(key).toMap(); + const QStringList keys = map.keys(); + for (const QString &key : keys) { + const int lastDot = key.lastIndexOf('.'); + if (lastDot != -1) + map[key.mid(lastDot + 1)] = map[key]; + } bool restored = false; for (IDebugServerProviderFactory *f : qAsConst(m_factories)) { if (f->canRestore(map)) { diff --git a/src/plugins/baremetal/debugservers/gdb/eblinkgdbserverprovider.cpp b/src/plugins/baremetal/debugservers/gdb/eblinkgdbserverprovider.cpp index bd6e3422852..8503bbf6c7f 100644 --- a/src/plugins/baremetal/debugservers/gdb/eblinkgdbserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/gdb/eblinkgdbserverprovider.cpp @@ -46,17 +46,17 @@ using namespace Utils; namespace BareMetal { namespace Internal { -const char executableFileKeyC[] = "BareMetal.EBlinkGdbServerProvider.ExecutableFile"; -const char verboseLevelKeyC[] = "BareMetal.EBlinkGdbServerProvider.VerboseLevel"; -const char deviceScriptC[] = "BareMetal.EBlinkGdbServerProvider.DeviceScript"; -const char interfaceTypeC[] = "BareMetal.EBlinkGdbServerProvider.InterfaceType"; -const char interfaceResetOnConnectC[] = "BareMetal.EBlinkGdbServerProvider.interfaceResetOnConnect"; -const char interfaceSpeedC[] = "BareMetal.EBlinkGdbServerProvider.InterfaceSpeed"; -const char interfaceExplicidDeviceC[] = "BareMetal.EBlinkGdbServerProvider.InterfaceExplicidDevice"; -const char targetNameC[] = "BareMetal.EBlinkGdbServerProvider.TargetName"; -const char targetDisableStackC[] = "BareMetal.EBlinkGdbServerProvider.TargetDisableStack"; -const char gdbShutDownAfterDisconnectC[] = "BareMetal.EBlinkGdbServerProvider.GdbShutDownAfterDisconnect"; -const char gdbNotUseCacheC[] = "BareMetal.EBlinkGdbServerProvider.GdbNotUseCache"; +const char executableFileKeyC[] = "ExecutableFile"; +const char verboseLevelKeyC[] = "VerboseLevel"; +const char deviceScriptC[] = "DeviceScript"; +const char interfaceTypeC[] = "InterfaceType"; +const char interfaceResetOnConnectC[] = "interfaceResetOnConnect"; +const char interfaceSpeedC[] = "InterfaceSpeed"; +const char interfaceExplicidDeviceC[] = "InterfaceExplicidDevice"; +const char targetNameC[] = "TargetName"; +const char targetDisableStackC[] = "TargetDisableStack"; +const char gdbShutDownAfterDisconnectC[] = "GdbShutDownAfterDisconnect"; +const char gdbNotUseCacheC[] = "GdbNotUseCache"; // EBlinkGdbServerProvider @@ -66,7 +66,6 @@ EBlinkGdbServerProvider::EBlinkGdbServerProvider() setInitCommands(defaultInitCommands()); setResetCommands(defaultResetCommands()); setChannel("127.0.0.1", 2331); - setSettingsKeyBase("BareMetal.EBlinkGdbServerProvider"); setTypeDisplayName(GdbServerProvider::tr("EBlink")); setConfigurationWidgetCreator([this] { return new EBlinkGdbServerProviderConfigWidget(this); }); } diff --git a/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp b/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp index 77dfee82ff3..e8287bcf474 100644 --- a/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp @@ -49,11 +49,11 @@ using namespace Utils; namespace BareMetal { namespace Internal { -const char startupModeKeyC[] = "BareMetal.GdbServerProvider.Mode"; -const char peripheralDescriptionFileKeyC[] = "BareMetal.GdbServerProvider.PeripheralDescriptionFile"; -const char initCommandsKeyC[] = "BareMetal.GdbServerProvider.InitCommands"; -const char resetCommandsKeyC[] = "BareMetal.GdbServerProvider.ResetCommands"; -const char useExtendedRemoteKeyC[] = "BareMetal.GdbServerProvider.UseExtendedRemote"; +const char startupModeKeyC[] = "Mode"; +const char peripheralDescriptionFileKeyC[] = "PeripheralDescriptionFile"; +const char initCommandsKeyC[] = "InitCommands"; +const char resetCommandsKeyC[] = "ResetCommands"; +const char useExtendedRemoteKeyC[] = "UseExtendedRemote"; // GdbServerProvider diff --git a/src/plugins/baremetal/debugservers/gdb/gdbservers.pri b/src/plugins/baremetal/debugservers/gdb/gdbservers.pri index 3d6d4c31807..cd7e4c88717 100644 --- a/src/plugins/baremetal/debugservers/gdb/gdbservers.pri +++ b/src/plugins/baremetal/debugservers/gdb/gdbservers.pri @@ -1,13 +1,15 @@ HEADERS += \ $$PWD/eblinkgdbserverprovider.h \ $$PWD/gdbserverprovider.h \ + $$PWD/genericgdbserverprovider.h \ + $$PWD/jlinkgdbserverprovider.h \ $$PWD/openocdgdbserverprovider.h \ $$PWD/stlinkutilgdbserverprovider.h \ - $$PWD/jlinkgdbserverprovider.h \ SOURCES += \ $$PWD/eblinkgdbserverprovider.cpp \ $$PWD/gdbserverprovider.cpp \ + $$PWD/genericgdbserverprovider.cpp \ + $$PWD/jlinkgdbserverprovider.cpp \ $$PWD/openocdgdbserverprovider.cpp \ $$PWD/stlinkutilgdbserverprovider.cpp \ - $$PWD/jlinkgdbserverprovider.cpp \ diff --git a/src/plugins/baremetal/debugservers/gdb/genericgdbserverprovider.cpp b/src/plugins/baremetal/debugservers/gdb/genericgdbserverprovider.cpp new file mode 100644 index 00000000000..3440f4e77c7 --- /dev/null +++ b/src/plugins/baremetal/debugservers/gdb/genericgdbserverprovider.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2020 Denis Shienkov +** 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 "genericgdbserverprovider.h" + +#include +#include + +#include +#include + +#include +#include +#include + +namespace BareMetal { +namespace Internal { + +// GenericGdbServerProvider + +GenericGdbServerProvider::GenericGdbServerProvider() + : GdbServerProvider(Constants::GDBSERVER_GENERIC_PROVIDER_ID) +{ + setChannel("localhost", 3333); + setTypeDisplayName(GdbServerProvider::tr("Generic")); + setConfigurationWidgetCreator([this] { return new GenericGdbServerProviderConfigWidget(this); }); +} + +QSet GenericGdbServerProvider::supportedStartupModes() const +{ + return {StartupOnNetwork}; +} + +// GenericGdbServerProviderFactory + +GenericGdbServerProviderFactory::GenericGdbServerProviderFactory() +{ + setId(Constants::GDBSERVER_GENERIC_PROVIDER_ID); + setDisplayName(GdbServerProvider::tr("Generic")); + setCreator([] { return new GenericGdbServerProvider; }); +} + +// GdbServerProviderConfigWidget + +GenericGdbServerProviderConfigWidget::GenericGdbServerProviderConfigWidget( + GenericGdbServerProvider *provider) + : GdbServerProviderConfigWidget(provider) +{ + Q_ASSERT(provider); + + m_hostWidget = new HostWidget(this); + m_mainLayout->addRow(tr("Host:"), m_hostWidget); + + m_useExtendedRemoteCheckBox = new QCheckBox(this); + m_useExtendedRemoteCheckBox->setToolTip("Use GDB target extended-remote"); + m_mainLayout->addRow(tr("Extended mode:"), m_useExtendedRemoteCheckBox); + m_initCommandsTextEdit = new QPlainTextEdit(this); + m_initCommandsTextEdit->setToolTip(defaultInitCommandsTooltip()); + m_mainLayout->addRow(tr("Init commands:"), m_initCommandsTextEdit); + m_resetCommandsTextEdit = new QPlainTextEdit(this); + m_resetCommandsTextEdit->setToolTip(defaultResetCommandsTooltip()); + m_mainLayout->addRow(tr("Reset commands:"), m_resetCommandsTextEdit); + + addErrorLabel(); + setFromProvider(); + + const auto chooser = new Utils::VariableChooser(this); + chooser->addSupportedWidget(m_initCommandsTextEdit); + chooser->addSupportedWidget(m_resetCommandsTextEdit); + + connect(m_hostWidget, &HostWidget::dataChanged, + this, &GdbServerProviderConfigWidget::dirty); + connect(m_useExtendedRemoteCheckBox, &QCheckBox::stateChanged, + this, &GdbServerProviderConfigWidget::dirty); + connect(m_initCommandsTextEdit, &QPlainTextEdit::textChanged, + this, &GdbServerProviderConfigWidget::dirty); + connect(m_resetCommandsTextEdit, &QPlainTextEdit::textChanged, + this, &GdbServerProviderConfigWidget::dirty); +} + +void GenericGdbServerProviderConfigWidget::apply() +{ + const auto p = static_cast(m_provider); + Q_ASSERT(p); + + p->setChannel(m_hostWidget->channel()); + p->setUseExtendedRemote(m_useExtendedRemoteCheckBox->isChecked()); + p->setInitCommands(m_initCommandsTextEdit->toPlainText()); + p->setResetCommands(m_resetCommandsTextEdit->toPlainText()); + IDebugServerProviderConfigWidget::apply(); +} + +void GenericGdbServerProviderConfigWidget::discard() +{ + setFromProvider(); + IDebugServerProviderConfigWidget::discard(); +} + +void GenericGdbServerProviderConfigWidget::setFromProvider() +{ + const auto p = static_cast(m_provider); + Q_ASSERT(p); + + const QSignalBlocker blocker(this); + m_hostWidget->setChannel(p->channel()); + m_useExtendedRemoteCheckBox->setChecked(p->useExtendedRemote()); + m_initCommandsTextEdit->setPlainText(p->initCommands()); + m_resetCommandsTextEdit->setPlainText(p->resetCommands()); +} + +} // namespace Internal +} // namespace ProjectExplorer diff --git a/src/plugins/baremetal/debugservers/gdb/genericgdbserverprovider.h b/src/plugins/baremetal/debugservers/gdb/genericgdbserverprovider.h new file mode 100644 index 00000000000..90d75496dc0 --- /dev/null +++ b/src/plugins/baremetal/debugservers/gdb/genericgdbserverprovider.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2020 Denis Shienkov +** 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 "gdbserverprovider.h" + +QT_BEGIN_NAMESPACE +class QCheckBox; +class QPlainTextEdit; +QT_END_NAMESPACE + +namespace BareMetal { +namespace Internal { + +// GenericGdbServerProvider + +class GenericGdbServerProvider final : public GdbServerProvider +{ +private: + GenericGdbServerProvider(); + QSet supportedStartupModes() const final; + + friend class GenericGdbServerProviderConfigWidget; + friend class GenericGdbServerProviderFactory; + friend class BareMetalDevice; +}; + +// GenericGdbServerProviderFactory + +class GenericGdbServerProviderFactory final : public IDebugServerProviderFactory +{ +public: + GenericGdbServerProviderFactory(); +}; + +// GenericGdbServerProviderConfigWidget + +class GenericGdbServerProviderConfigWidget final + : public GdbServerProviderConfigWidget +{ + Q_OBJECT + +public: + explicit GenericGdbServerProviderConfigWidget( + GenericGdbServerProvider *provider); + +private: + void apply() final; + void discard() final; + + void setFromProvider(); + + HostWidget *m_hostWidget = nullptr; + QCheckBox *m_useExtendedRemoteCheckBox = nullptr; + QPlainTextEdit *m_initCommandsTextEdit = nullptr; + QPlainTextEdit *m_resetCommandsTextEdit = nullptr; +}; + +} // namespace Internal +} // namespace BareMetal diff --git a/src/plugins/baremetal/debugservers/gdb/jlinkgdbserverprovider.cpp b/src/plugins/baremetal/debugservers/gdb/jlinkgdbserverprovider.cpp index 052ada87347..73475186bcf 100644 --- a/src/plugins/baremetal/debugservers/gdb/jlinkgdbserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/gdb/jlinkgdbserverprovider.cpp @@ -46,13 +46,13 @@ using namespace Utils; namespace BareMetal { namespace Internal { -const char executableFileKeyC[] = "BareMetal.JLinkGdbServerProvider.ExecutableFile"; -const char jlinkDeviceKeyC[] = "BareMetal.JLinkGdbServerProvider.JLinkDevice"; -const char jlinkHostInterfaceKeyC[] = "BareMetal.JLinkGdbServerProvider.JLinkHostInterface"; -const char jlinkHostInterfaceIPAddressKeyC[] = "BareMetal.JLinkGdbServerProvider.JLinkHostInterfaceIPAddress"; -const char jlinkTargetInterfaceKeyC[] = "BareMetal.JLinkGdbServerProvider.JLinkTargetInterface"; -const char jlinkTargetInterfaceSpeedKeyC[] = "BareMetal.JLinkGdbServerProvider.JLinkTargetInterfaceSpeed"; -const char additionalArgumentsKeyC[] = "BareMetal.JLinkGdbServerProvider.AdditionalArguments"; +const char executableFileKeyC[] = "ExecutableFile"; +const char jlinkDeviceKeyC[] = "JLinkDevice"; +const char jlinkHostInterfaceKeyC[] = "JLinkHostInterface"; +const char jlinkHostInterfaceIPAddressKeyC[] = "JLinkHostInterfaceIPAddress"; +const char jlinkTargetInterfaceKeyC[] = "JLinkTargetInterface"; +const char jlinkTargetInterfaceSpeedKeyC[] = "JLinkTargetInterfaceSpeed"; +const char additionalArgumentsKeyC[] = "AdditionalArguments"; // JLinkGdbServerProvider @@ -62,7 +62,6 @@ JLinkGdbServerProvider::JLinkGdbServerProvider() setInitCommands(defaultInitCommands()); setResetCommands(defaultResetCommands()); setChannel("localhost", 2331); - setSettingsKeyBase("BareMetal.JLinkGdbServerProvider"); setTypeDisplayName(GdbServerProvider::tr("JLink")); setConfigurationWidgetCreator([this] { return new JLinkGdbServerProviderConfigWidget(this); }); } diff --git a/src/plugins/baremetal/debugservers/gdb/openocdgdbserverprovider.cpp b/src/plugins/baremetal/debugservers/gdb/openocdgdbserverprovider.cpp index 74361dc2d4d..0e32338af72 100644 --- a/src/plugins/baremetal/debugservers/gdb/openocdgdbserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/gdb/openocdgdbserverprovider.cpp @@ -44,10 +44,10 @@ using namespace Utils; namespace BareMetal { namespace Internal { -const char executableFileKeyC[] = "BareMetal.OpenOcdGdbServerProvider.ExecutableFile"; -const char rootScriptsDirKeyC[] = "BareMetal.OpenOcdGdbServerProvider.RootScriptsDir"; -const char configurationFileKeyC[] = "BareMetal.OpenOcdGdbServerProvider.ConfigurationPath"; -const char additionalArgumentsKeyC[] = "BareMetal.OpenOcdGdbServerProvider.AdditionalArguments"; +const char executableFileKeyC[] = "ExecutableFile"; +const char rootScriptsDirKeyC[] = "RootScriptsDir"; +const char configurationFileKeyC[] = "ConfigurationPath"; +const char additionalArgumentsKeyC[] = "AdditionalArguments"; // OpenOcdGdbServerProvider @@ -57,7 +57,6 @@ OpenOcdGdbServerProvider::OpenOcdGdbServerProvider() setInitCommands(defaultInitCommands()); setResetCommands(defaultResetCommands()); setChannel("localhost", 3333); - setSettingsKeyBase("BareMetal.OpenOcdGdbServerProvider"); setTypeDisplayName(GdbServerProvider::tr("OpenOCD")); setConfigurationWidgetCreator([this] { return new OpenOcdGdbServerProviderConfigWidget(this); }); } diff --git a/src/plugins/baremetal/debugservers/gdb/stlinkutilgdbserverprovider.cpp b/src/plugins/baremetal/debugservers/gdb/stlinkutilgdbserverprovider.cpp index 0c280f2f429..c853df8b265 100644 --- a/src/plugins/baremetal/debugservers/gdb/stlinkutilgdbserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/gdb/stlinkutilgdbserverprovider.cpp @@ -44,11 +44,11 @@ using namespace Utils; namespace BareMetal { namespace Internal { -const char executableFileKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.ExecutableFile"; -const char verboseLevelKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.VerboseLevel"; -const char extendedModeKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.ExtendedMode"; -const char resetBoardKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.ResetBoard"; -const char transportLayerKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.TransportLayer"; +const char executableFileKeyC[] = "ExecutableFile"; +const char verboseLevelKeyC[] = "VerboseLevel"; +const char extendedModeKeyC[] = "ExtendedMode"; +const char resetBoardKeyC[] = "ResetBoard"; +const char transportLayerKeyC[] = "TransportLayer"; // StLinkUtilGdbServerProvider @@ -58,7 +58,6 @@ StLinkUtilGdbServerProvider::StLinkUtilGdbServerProvider() setInitCommands(defaultInitCommands()); setResetCommands(defaultResetCommands()); setChannel("localhost", 4242); - setSettingsKeyBase("BareMetal.StLinkUtilGdbServerProvider"); setTypeDisplayName(GdbServerProvider::tr("ST-LINK Utility")); setConfigurationWidgetCreator([this] { return new StLinkUtilGdbServerProviderConfigWidget(this); }); } diff --git a/src/plugins/baremetal/debugservers/uvsc/jlinkuvscserverprovider.cpp b/src/plugins/baremetal/debugservers/uvsc/jlinkuvscserverprovider.cpp index 1a269dcc7f6..60ba7eff8aa 100644 --- a/src/plugins/baremetal/debugservers/uvsc/jlinkuvscserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/jlinkuvscserverprovider.cpp @@ -52,9 +52,9 @@ namespace Internal { using namespace Uv; -constexpr char adapterOptionsKeyC[] = "BareMetal.JLinkUvscServerProvider.AdapterOptions"; -constexpr char adapterPortKeyC[] = "BareMetal.JLinkUvscServerProvider.AdapterPort"; -constexpr char adapterSpeedKeyC[] = "BareMetal.JLinkUvscServerProvider.AdapterSpeed"; +constexpr char adapterOptionsKeyC[] = "AdapterOptions"; +constexpr char adapterPortKeyC[] = "AdapterPort"; +constexpr char adapterSpeedKeyC[] = "AdapterSpeed"; static int decodeSpeedCode(JLinkUvscAdapterOptions::Speed speed) { diff --git a/src/plugins/baremetal/debugservers/uvsc/simulatoruvscserverprovider.cpp b/src/plugins/baremetal/debugservers/uvsc/simulatoruvscserverprovider.cpp index b37ff75ec9a..f5056844c45 100644 --- a/src/plugins/baremetal/debugservers/uvsc/simulatoruvscserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/simulatoruvscserverprovider.cpp @@ -50,7 +50,7 @@ namespace Internal { using namespace Uv; -const char limitSpeedKeyC[] = "BareMetal.SimulatorUvscServerProvider.LimitSpeed"; +const char limitSpeedKeyC[] = "LimitSpeed"; static DriverSelection defaultSimulatorDriverSelection() { diff --git a/src/plugins/baremetal/debugservers/uvsc/stlinkuvscserverprovider.cpp b/src/plugins/baremetal/debugservers/uvsc/stlinkuvscserverprovider.cpp index 98adbb212af..717c7b9ce98 100644 --- a/src/plugins/baremetal/debugservers/uvsc/stlinkuvscserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/stlinkuvscserverprovider.cpp @@ -52,9 +52,9 @@ namespace Internal { using namespace Uv; -constexpr char adapterOptionsKeyC[] = "BareMetal.StLinkUvscServerProvider.AdapterOptions"; -constexpr char adapterPortKeyC[] = "BareMetal.StLinkUvscServerProvider.AdapterPort"; -constexpr char adapterSpeedKeyC[] = "BareMetal.StLinkUvscServerProvider.AdapterSpeed"; +constexpr char adapterOptionsKeyC[] = "AdapterOptions"; +constexpr char adapterPortKeyC[] = "AdapterPort"; +constexpr char adapterSpeedKeyC[] = "AdapterSpeed"; static QString buildAdapterOptions(const StLinkUvscAdapterOptions &opts) { diff --git a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp index 59b0b6d3734..05aaa59c429 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp @@ -58,9 +58,9 @@ namespace Internal { using namespace Uv; // Whole software package selection keys. -constexpr char toolsIniKeyC[] = "BareMetal.UvscServerProvider.ToolsIni"; -constexpr char deviceSelectionKeyC[] = "BareMetal.UvscServerProvider.DeviceSelection"; -constexpr char driverSelectionKeyC[] = "BareMetal.UvscServerProvider.DriverSelection"; +constexpr char toolsIniKeyC[] = "ToolsIni"; +constexpr char deviceSelectionKeyC[] = "DeviceSelection"; +constexpr char driverSelectionKeyC[] = "DriverSelection"; constexpr int defaultPortNumber = 5101; diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.cpp index 7bb3eca8968..4c287199cdd 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.cpp @@ -38,39 +38,39 @@ namespace Internal { namespace Uv { // Software package data keys. -constexpr char packageDescrKeyC[] = "BareMetal.UvscServerProvider.PackageDescription"; -constexpr char packageFileKeyC[] = "BareMetal.UvscServerProvider.PackageFile"; -constexpr char packageNameKeyC[] = "BareMetal.UvscServerProvider.PackageName"; -constexpr char packageUrlKeyC[] = "BareMetal.UvscServerProvider.PackageUrl"; -constexpr char packageVendorNameKeyC[] = "BareMetal.UvscServerProvider.PackageVendorName"; -constexpr char packageVendorIdKeyC[] = "BareMetal.UvscServerProvider.PackageVendorId"; -constexpr char packageVersionKeyC[] = "BareMetal.UvscServerProvider.PackageVersion"; +constexpr char packageDescrKeyC[] = "PackageDescription"; +constexpr char packageFileKeyC[] = "PackageFile"; +constexpr char packageNameKeyC[] = "PackageName"; +constexpr char packageUrlKeyC[] = "PackageUrl"; +constexpr char packageVendorNameKeyC[] = "PackageVendorName"; +constexpr char packageVendorIdKeyC[] = "PackageVendorId"; +constexpr char packageVersionKeyC[] = "PackageVersion"; // Device data keys. -constexpr char deviceNameKeyC[] = "BareMetal.UvscServerProvider.DeviceName"; -constexpr char deviceDescrKeyC[] = "BareMetal.UvscServerProvider.DeviceDescription"; -constexpr char deviceFamilyKeyC[] = "BareMetal.UvscServerProvider.DeviceFamily"; -constexpr char deviceSubFamilyKeyC[] = "BareMetal.UvscServerProvider.DeviceSubFamily"; -constexpr char deviceVendorNameKeyC[] = "BareMetal.UvscServerProvider.DeviceVendorName"; -constexpr char deviceVendorIdKeyC[] = "BareMetal.UvscServerProvider.DeviceVendorId"; -constexpr char deviceSvdKeyC[] = "BareMetal.UvscServerProvider.DeviceSVD"; +constexpr char deviceNameKeyC[] = "DeviceName"; +constexpr char deviceDescrKeyC[] = "DeviceDescription"; +constexpr char deviceFamilyKeyC[] = "DeviceFamily"; +constexpr char deviceSubFamilyKeyC[] = "DeviceSubFamily"; +constexpr char deviceVendorNameKeyC[] = "DeviceVendorName"; +constexpr char deviceVendorIdKeyC[] = "DeviceVendorId"; +constexpr char deviceSvdKeyC[] = "DeviceSVD"; // Device CPU data keys. -constexpr char deviceClockKeyC[] = "BareMetal.UvscServerProvider.DeviceClock"; -constexpr char deviceCoreKeyC[] = "BareMetal.UvscServerProvider.DeviceCore"; -constexpr char deviceFpuKeyC[] = "BareMetal.UvscServerProvider.DeviceFPU"; -constexpr char deviceMpuKeyC[] = "BareMetal.UvscServerProvider.DeviceMPU"; +constexpr char deviceClockKeyC[] = "DeviceClock"; +constexpr char deviceCoreKeyC[] = "DeviceCore"; +constexpr char deviceFpuKeyC[] = "DeviceFPU"; +constexpr char deviceMpuKeyC[] = "DeviceMPU"; // Device MEMORY data keys. -constexpr char deviceMemoryKeyC[] = "BareMetal.UvscServerProvider.DeviceMemory"; -constexpr char deviceMemoryIdKeyC[] = "BareMetal.UvscServerProvider.DeviceMemoryId"; -constexpr char deviceMemoryStartKeyC[] = "BareMetal.UvscServerProvider.DeviceMemoryStart"; -constexpr char deviceMemorySizeKeyC[] = "BareMetal.UvscServerProvider.DeviceMemorySize"; +constexpr char deviceMemoryKeyC[] = "DeviceMemory"; +constexpr char deviceMemoryIdKeyC[] = "DeviceMemoryId"; +constexpr char deviceMemoryStartKeyC[] = "DeviceMemoryStart"; +constexpr char deviceMemorySizeKeyC[] = "DeviceMemorySize"; // Device ALGORITHM data keys. -constexpr char deviceAlgorithmKeyC[] = "BareMetal.UvscServerProvider.DeviceAlgorithm"; -constexpr char deviceAlgorithmPathKeyC[] = "BareMetal.UvscServerProvider.DeviceAlgorithmPath"; -constexpr char deviceAlgorithmFlashStartKeyC[] = "BareMetal.UvscServerProvider.DeviceAlgorithmStart"; -constexpr char deviceAlgorithmFlashSizeKeyC[] = "BareMetal.UvscServerProvider.DeviceAlgorithmSize"; -constexpr char deviceAlgorithmRamStartKeyC[] = "BareMetal.UvscServerProvider.DeviceAlgorithmRamStart"; -constexpr char deviceAlgorithmRamSizeKeyC[] = "BareMetal.UvscServerProvider.DeviceAlgorithmRamSize"; -constexpr char deviceAlgorithmIndexKeyC[] = "BareMetal.UvscServerProvider.DeviceAlgorithmIndex"; +constexpr char deviceAlgorithmKeyC[] = "DeviceAlgorithm"; +constexpr char deviceAlgorithmPathKeyC[] = "DeviceAlgorithmPath"; +constexpr char deviceAlgorithmFlashStartKeyC[] = "DeviceAlgorithmStart"; +constexpr char deviceAlgorithmFlashSizeKeyC[] = "DeviceAlgorithmSize"; +constexpr char deviceAlgorithmRamStartKeyC[] = "DeviceAlgorithmRamStart"; +constexpr char deviceAlgorithmRamSizeKeyC[] = "DeviceAlgorithmRamSize"; +constexpr char deviceAlgorithmIndexKeyC[] = "DeviceAlgorithmIndex"; // DeviceSelection diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverselection.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverselection.cpp index 41350613ca8..c8ab64a1335 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverselection.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverselection.cpp @@ -36,11 +36,11 @@ namespace Internal { namespace Uv { // Driver data keys. -constexpr char driverIndexKeyC[] = "BareMetal.UvscServerProvider.DriverIndex"; -constexpr char driverCpuDllIndexKeyC[] = "BareMetal.UvscServerProvider.DriverCpuDllIndex"; -constexpr char driverDllKeyC[] = "BareMetal.UvscServerProvider.DriverDll"; -constexpr char driverCpuDllsKeyC[] = "BareMetal.UvscServerProvider.DriverCpuDlls"; -constexpr char driverNameKeyC[] = "BareMetal.UvscServerProvider.DriverName"; +constexpr char driverIndexKeyC[] = "DriverIndex"; +constexpr char driverCpuDllIndexKeyC[] = "DriverCpuDllIndex"; +constexpr char driverDllKeyC[] = "DriverDll"; +constexpr char driverCpuDllsKeyC[] = "DriverCpuDlls"; +constexpr char driverNameKeyC[] = "DriverName"; // DriverSelection diff --git a/src/plugins/baremetal/iarewtoolchain.cpp b/src/plugins/baremetal/iarewtoolchain.cpp index 84b57d4db69..0296a3e8094 100644 --- a/src/plugins/baremetal/iarewtoolchain.cpp +++ b/src/plugins/baremetal/iarewtoolchain.cpp @@ -58,9 +58,9 @@ namespace Internal { // Helpers: -static const char compilerCommandKeyC[] = "BareMetal.IarToolChain.CompilerPath"; -static const char compilerPlatformCodeGenFlagsKeyC[] = "BareMetal.IarToolChain.PlatformCodeGenFlags"; -static const char targetAbiKeyC[] = "BareMetal.IarToolChain.TargetAbi"; +static const char compilerCommandKeyC[] = "CompilerPath"; +static const char compilerPlatformCodeGenFlagsKeyC[] = "PlatformCodeGenFlags"; +static const char targetAbiKeyC[] = "TargetAbi"; static bool compilerExists(const FilePath &compilerPath) { diff --git a/src/plugins/baremetal/idebugserverprovider.cpp b/src/plugins/baremetal/idebugserverprovider.cpp index 02deed298a4..553a0f76568 100644 --- a/src/plugins/baremetal/idebugserverprovider.cpp +++ b/src/plugins/baremetal/idebugserverprovider.cpp @@ -43,12 +43,12 @@ using namespace ProjectExplorer; namespace BareMetal { namespace Internal { -const char idKeyC[] = "BareMetal.IDebugServerProvider.Id"; -const char displayNameKeyC[] = "BareMetal.IDebugServerProvider.DisplayName"; -const char engineTypeKeyC[] = "BareMetal.IDebugServerProvider.EngineType"; +const char idKeyC[] = "Id"; +const char displayNameKeyC[] = "DisplayName"; +const char engineTypeKeyC[] = "EngineType"; -const char hostKeySuffixC[] = ".Host"; -const char portKeySuffixC[] = ".Port"; +const char hostKeyC[] = "Host"; +const char portKeyC[] = "Port"; static QString createId(const QString &id) { @@ -139,11 +139,6 @@ void IDebugServerProvider::setEngineType(DebuggerEngineType engineType) providerUpdated(); } -void IDebugServerProvider::setSettingsKeyBase(const QString &settingsBase) -{ - m_settingsBase = settingsBase; -} - bool IDebugServerProvider::operator==(const IDebugServerProvider &other) const { if (this == &other) @@ -170,8 +165,8 @@ QVariantMap IDebugServerProvider::toMap() const {idKeyC, m_id}, {displayNameKeyC, m_displayName}, {engineTypeKeyC, m_engineType}, - {m_settingsBase + hostKeySuffixC, m_channel.host()}, - {m_settingsBase + portKeySuffixC, m_channel.port()}, + {hostKeyC, m_channel.host()}, + {portKeyC, m_channel.port()}, }; } @@ -201,8 +196,8 @@ bool IDebugServerProvider::fromMap(const QVariantMap &data) m_displayName = data.value(displayNameKeyC).toString(); m_engineType = static_cast( data.value(engineTypeKeyC, NoEngineType).toInt()); - m_channel.setHost(data.value(m_settingsBase + hostKeySuffixC).toString()); - m_channel.setPort(data.value(m_settingsBase + portKeySuffixC).toInt()); + m_channel.setHost(data.value(hostKeyC).toString()); + m_channel.setPort(data.value(portKeyC).toInt()); return true; } @@ -238,9 +233,7 @@ IDebugServerProvider *IDebugServerProviderFactory::create() const IDebugServerProvider *IDebugServerProviderFactory::restore(const QVariantMap &data) const { IDebugServerProvider *p = m_creator(); - const auto updated = data; - - if (p->fromMap(updated)) + if (p->fromMap(data)) return p; delete p; return nullptr; diff --git a/src/plugins/baremetal/idebugserverprovider.h b/src/plugins/baremetal/idebugserverprovider.h index cf82d8c7b9b..19792dcaf0b 100644 --- a/src/plugins/baremetal/idebugserverprovider.h +++ b/src/plugins/baremetal/idebugserverprovider.h @@ -104,7 +104,6 @@ public: protected: void setTypeDisplayName(const QString &typeDisplayName); void setEngineType(Debugger::DebuggerEngineType engineType); - void setSettingsKeyBase(const QString &settingsBase); void providerUpdated(); void resetId(); @@ -112,7 +111,6 @@ protected: QString m_id; mutable QString m_displayName; QString m_typeDisplayName; - QString m_settingsBase; QUrl m_channel; Debugger::DebuggerEngineType m_engineType = Debugger::NoEngineType; QSet m_devices; diff --git a/src/plugins/baremetal/keiltoolchain.cpp b/src/plugins/baremetal/keiltoolchain.cpp index ac548bf3c14..3728017baa9 100644 --- a/src/plugins/baremetal/keiltoolchain.cpp +++ b/src/plugins/baremetal/keiltoolchain.cpp @@ -60,9 +60,9 @@ namespace Internal { // Helpers: -static const char compilerCommandKeyC[] = "BareMetal.KeilToolchain.CompilerPath"; -static const char compilerPlatformCodeGenFlagsKeyC[] = "BareMetal.KeilToolchain.PlatformCodeGenFlags"; -static const char targetAbiKeyC[] = "BareMetal.KeilToolchain.TargetAbi"; +static const char compilerCommandKeyC[] = "CompilerPath"; +static const char compilerPlatformCodeGenFlagsKeyC[] = "PlatformCodeGenFlags"; +static const char targetAbiKeyC[] = "TargetAbi"; static bool compilerExists(const FilePath &compilerPath) { diff --git a/src/plugins/baremetal/sdcctoolchain.cpp b/src/plugins/baremetal/sdcctoolchain.cpp index aa701d08f09..fe9754cce80 100644 --- a/src/plugins/baremetal/sdcctoolchain.cpp +++ b/src/plugins/baremetal/sdcctoolchain.cpp @@ -58,8 +58,8 @@ namespace Internal { // Helpers: -static const char compilerCommandKeyC[] = "BareMetal.SdccToolChain.CompilerPath"; -static const char targetAbiKeyC[] = "BareMetal.SdccToolChain.TargetAbi"; +static const char compilerCommandKeyC[] = "CompilerPath"; +static const char targetAbiKeyC[] = "TargetAbi"; static bool compilerExists(const FilePath &compilerPath) { diff --git a/src/plugins/clangtools/clangtoolruncontrol.cpp b/src/plugins/clangtools/clangtoolruncontrol.cpp index 738e98fa6ca..fda0b596ee2 100644 --- a/src/plugins/clangtools/clangtoolruncontrol.cpp +++ b/src/plugins/clangtools/clangtoolruncontrol.cpp @@ -121,7 +121,7 @@ AnalyzeUnit::AnalyzeUnit(const FileInfo &fileInfo, { CompilerOptionsBuilder optionsBuilder(*fileInfo.projectPart, UseSystemHeader::No, - UseTweakedHeaderPaths::Yes, + UseTweakedHeaderPaths::Tools, UseLanguageDefines::No, UseBuildSystemWarnings::No, clangVersion, diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp index ef5c6d974d8..aa4fbede31d 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp +++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp @@ -629,8 +629,10 @@ bool DiagnosticFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &s const Diagnostic &diag = diagnosticItem->diagnostic(); // Filtered out? - if (m_filterOptions && !m_filterOptions->checks.contains(diag.name)) + if (m_filterOptions && !m_filterOptions->checks.contains(diag.name)) { + diagnosticItem->textMark()->setVisible(false); return false; + } // Explicitly suppressed? foreach (const SuppressedDiagnostic &d, m_suppressedDiagnostics) { @@ -640,10 +642,12 @@ bool DiagnosticFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &s QFileInfo fi(filePath); if (fi.isRelative()) filePath = m_lastProjectDirectory.toString() + QLatin1Char('/') + filePath; - if (filePath == diag.location.filePath) + if (filePath == diag.location.filePath) { + diagnosticItem->textMark()->setVisible(false); return false; + } } - + diagnosticItem->textMark()->setVisible(true); return true; } diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.h b/src/plugins/clangtools/clangtoolsdiagnosticmodel.h index 695cd088e51..0e21006cab3 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.h +++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.h @@ -74,6 +74,7 @@ public: ~DiagnosticItem() override; const Diagnostic &diagnostic() const { return m_diagnostic; } + TextEditor::TextMark *textMark() { return m_mark; } FixitStatus fixItStatus() const { return m_fixitStatus; } void setFixItStatus(const FixitStatus &status); diff --git a/src/plugins/clangtools/clangtoolsdiagnosticview.cpp b/src/plugins/clangtools/clangtoolsdiagnosticview.cpp index ca421e5c825..689886d3f26 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticview.cpp +++ b/src/plugins/clangtools/clangtoolsdiagnosticview.cpp @@ -232,12 +232,14 @@ void DiagnosticView::goNext() { const QModelIndex currentIndex = selectionModel()->currentIndex(); selectIndex(getIndex(currentIndex, Next)); + openEditorForCurrentIndex(); } void DiagnosticView::goBack() { const QModelIndex currentIndex = selectionModel()->currentIndex(); selectIndex(getIndex(currentIndex, Previous)); + openEditorForCurrentIndex(); } QModelIndex DiagnosticView::getIndex(const QModelIndex &index, Direction direction) const diff --git a/src/plugins/clangtools/clazychecks.ui b/src/plugins/clangtools/clazychecks.ui index 0818b8d31e8..5704a6c2429 100644 --- a/src/plugins/clangtools/clazychecks.ui +++ b/src/plugins/clangtools/clazychecks.ui @@ -69,7 +69,7 @@ - Reset to All + Reset Filter diff --git a/src/plugins/clangtools/diagnosticconfigswidget.cpp b/src/plugins/clangtools/diagnosticconfigswidget.cpp index 9d076f8e29e..9375e84c21f 100644 --- a/src/plugins/clangtools/diagnosticconfigswidget.cpp +++ b/src/plugins/clangtools/diagnosticconfigswidget.cpp @@ -199,13 +199,6 @@ static bool needsLink(ProjectExplorer::Tree *node) { return !node->isDir && !node->fullPath.toString().startsWith("clang-analyzer-"); } -static void selectAll(QAbstractItemView *view) -{ - view->setSelectionMode(QAbstractItemView::MultiSelection); - view->selectAll(); - view->setSelectionMode(QAbstractItemView::SingleSelection); -} - class BaseChecksTreeModel : public ProjectExplorer::SelectableFilesModel { Q_OBJECT @@ -628,7 +621,7 @@ public: const auto *node = ClazyChecksTree::fromIndex(index); if (node->kind == ClazyChecksTree::CheckNode) { const QStringList topics = node->check.topics; - return Utils::anyOf(m_topics, [topics](const QString &topic) { + return m_topics.isEmpty() || Utils::anyOf(m_topics, [topics](const QString &topic) { return topics.contains(topic); }); } @@ -717,8 +710,9 @@ DiagnosticConfigsWidget::DiagnosticConfigsWidget(const ClangDiagnosticConfigs &c topicsModel->sort(0); m_clazyChecks->topicsView->setModel(topicsModel); connect(m_clazyChecks->topicsResetButton, &QPushButton::clicked, [this](){ - selectAll(m_clazyChecks->topicsView); + m_clazyChecks->topicsView->clearSelection(); }); + m_clazyChecks->topicsView->setSelectionMode(QAbstractItemView::MultiSelection); connect(m_clazyChecks->topicsView->selectionModel(), &QItemSelectionModel::selectionChanged, [this, topicsModel](const QItemSelection &, const QItemSelection &) { @@ -731,7 +725,6 @@ DiagnosticConfigsWidget::DiagnosticConfigsWidget(const ClangDiagnosticConfigs &c this->syncClazyChecksGroupBox(); }); - selectAll(m_clazyChecks->topicsView); connect(m_clazyChecks->checksView, &QTreeView::clicked, [model = m_clazySortFilterProxyModel](const QModelIndex &index) { @@ -866,7 +859,7 @@ void DiagnosticConfigsWidget::syncClazyWidgets(const ClangDiagnosticConfig &conf const bool enabled = !config.isReadOnly(); m_clazyChecks->topicsResetButton->setEnabled(enabled); m_clazyChecks->enableLowerLevelsCheckBox->setEnabled(enabled); - selectAll(m_clazyChecks->topicsView); + m_clazyChecks->topicsView->clearSelection(); m_clazyChecks->topicsView->setEnabled(enabled); m_clazyTreeModel->setEnabled(enabled); diff --git a/src/plugins/clangtools/documentclangtoolrunner.cpp b/src/plugins/clangtools/documentclangtoolrunner.cpp index fadac9b8628..9e2b388e5da 100644 --- a/src/plugins/clangtools/documentclangtoolrunner.cpp +++ b/src/plugins/clangtools/documentclangtoolrunner.cpp @@ -194,6 +194,9 @@ void DocumentClangToolRunner::run() const RunSettings &runSettings = projectSettings->useGlobalSettings() ? ClangToolsSettings::instance()->runSettings() : projectSettings->runSettings(); + + m_suppressed = projectSettings->suppressedDiagnostics(); + m_lastProjectDirectory = project->projectDirectory(); m_projectSettingsUpdate = connect(projectSettings.data(), &ClangToolsProjectSettings::changed, this, @@ -293,6 +296,9 @@ void DocumentClangToolRunner::onSuccess() TextEditor::RefactorMarkers markers; for (const Diagnostic &diagnostic : diagnostics) { + if (isSuppressed(diagnostic)) + continue; + auto mark = new DiagnosticMark(diagnostic); mark->source = m_currentRunner->name(); @@ -351,6 +357,20 @@ void DocumentClangToolRunner::cancel() } } +bool DocumentClangToolRunner::isSuppressed(const Diagnostic &diagnostic) const +{ + auto equalsSuppressed = [this, &diagnostic](const SuppressedDiagnostic &suppressed) { + if (suppressed.description != diagnostic.description) + return false; + QString filePath = suppressed.filePath.toString(); + QFileInfo fi(filePath); + if (fi.isRelative()) + filePath = m_lastProjectDirectory.toString() + QLatin1Char('/') + filePath; + return filePath == diagnostic.location.filePath; + }; + return Utils::anyOf(m_suppressed, equalsSuppressed); +} + const CppTools::ClangDiagnosticConfig DocumentClangToolRunner::getDiagnosticConfig(ProjectExplorer::Project *project) { const auto projectSettings = ClangToolsProjectSettings::getSettings(project); diff --git a/src/plugins/clangtools/documentclangtoolrunner.h b/src/plugins/clangtools/documentclangtoolrunner.h index e15ec336551..4cf8f25308e 100644 --- a/src/plugins/clangtools/documentclangtoolrunner.h +++ b/src/plugins/clangtools/documentclangtoolrunner.h @@ -27,6 +27,7 @@ #include "clangfileinfo.h" #include "clangtoolsdiagnostic.h" +#include "clangtoolsprojectsettings.h" #include #include @@ -67,6 +68,7 @@ private: void cancel(); + bool isSuppressed(const Diagnostic &diagnostic) const; const CppTools::ClangDiagnosticConfig getDiagnosticConfig(ProjectExplorer::Project *project); template @@ -82,6 +84,8 @@ private: FileInfo m_fileInfo; QMetaObject::Connection m_projectSettingsUpdate; QSet m_editorsWithMarkers; + SuppressedDiagnosticsList m_suppressed; + Utils::FilePath m_lastProjectDirectory; }; } // namespace Internal diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 12ae70bf033..36c1ae3634d 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -1650,62 +1650,91 @@ bool EditorManagerPrivate::closeEditors(const QList &editors, CloseFla if (acceptedEditors.isEmpty()) return false; - QList closedViews; - EditorView *focusView = nullptr; - - // remove the editors - foreach (IEditor *editor, acceptedEditors) { - emit m_instance->editorAboutToClose(editor); - if (!editor->document()->filePath().isEmpty() - && !editor->document()->isTemporary()) { + // save editor states + for (IEditor *editor : qAsConst(acceptedEditors)) { + if (!editor->document()->filePath().isEmpty() && !editor->document()->isTemporary()) { QByteArray state = editor->saveState(); if (!state.isEmpty()) d->m_editorStates.insert(editor->document()->filePath().toString(), QVariant(state)); } + } + EditorView *focusView = nullptr; + + // Remove accepted editors from document model/manager and context list, + // and sort them per view, so we can remove them from views in an orderly + // manner. + QMultiHash editorsPerView; + for (IEditor *editor : qAsConst(acceptedEditors)) { + emit m_instance->editorAboutToClose(editor); removeEditor(editor, flag != CloseFlag::Suspend); if (EditorView *view = viewForEditor(editor)) { - if (QApplication::focusWidget() && QApplication::focusWidget() == editor->widget()->focusWidget()) + editorsPerView.insert(view, editor); + if (QApplication::focusWidget() + && QApplication::focusWidget() == editor->widget()->focusWidget()) { focusView = view; - if (editor == view->currentEditor()) - closedViews += view; - if (d->m_currentEditor == editor) { - // avoid having a current editor without view - setCurrentView(view); - setCurrentEditor(nullptr); } - view->removeEditor(editor); } } + QTC_CHECK(!focusView || focusView == currentView); - // TODO doesn't work as expected with multiple areas in main window and some other cases - // instead each view should have its own file history and handle solely themselves - // which editor is shown if their current editor closes - EditorView *forceViewToShowEditor = nullptr; - if (!closedViews.isEmpty() && EditorManager::visibleEditors().isEmpty()) { - if (closedViews.contains(currentView)) - forceViewToShowEditor = currentView; - else - forceViewToShowEditor = closedViews.first(); - } - foreach (EditorView *view, closedViews) { - IEditor *newCurrent = view->currentEditor(); - if (!newCurrent && forceViewToShowEditor == view) - newCurrent = pickUnusedEditor(); - if (newCurrent) { - activateEditor(view, newCurrent, EditorManager::DoNotChangeCurrentEditor); - } else if (forceViewToShowEditor == view) { - DocumentModel::Entry *entry = DocumentModelPrivate::firstSuspendedEntry(); - if (entry) { - activateEditorForEntry(view, entry, EditorManager::DoNotChangeCurrentEditor); - } else { // no "suspended" ones, so any entry left should have a document - const QList documents = DocumentModel::entries(); - if (!documents.isEmpty()) { - if (IDocument *document = documents.last()->document) { - activateEditorForDocument(view, document, EditorManager::DoNotChangeCurrentEditor); + // Go through views, remove the editors from them. + // Sort such that views for which the current editor is closed come last, + // and if the global current view is one of them, that comes very last. + // When handling the last view in the list we handle the case where all + // visible editors are closed, and we need to e.g. revive an invisible or + // a suspended editor + QList views = editorsPerView.keys(); + Utils::sort(views, [editorsPerView, currentView](EditorView *a, EditorView *b) { + if (a == b) + return false; + const bool aHasCurrent = editorsPerView.values(a).contains(a->currentEditor()); + const bool bHasCurrent = editorsPerView.values(b).contains(b->currentEditor()); + const bool aHasGlobalCurrent = (a == currentView && aHasCurrent); + const bool bHasGlobalCurrent = (b == currentView && bHasCurrent); + if (bHasGlobalCurrent && !aHasGlobalCurrent) + return true; + if (bHasCurrent && !aHasCurrent) + return true; + return false; + }); + for (EditorView *view : qAsConst(views)) { + QList editors = editorsPerView.values(view); + // handle current editor in view last + IEditor *viewCurrentEditor = view->currentEditor(); + if (editors.contains(viewCurrentEditor) && editors.last() != viewCurrentEditor) { + editors.removeAll(viewCurrentEditor); + editors.append(viewCurrentEditor); + } + for (IEditor *editor : qAsConst(editors)) { + if (editor == viewCurrentEditor && view == views.last()) { + // Avoid removing the globally current editor from its view, + // set a new current editor before. + const EditorManager::OpenEditorFlags flags = view != currentView + ? EditorManager::DoNotChangeCurrentEditor + : EditorManager::NoFlags; + const QList viewEditors = view->editors(); + IEditor *newCurrent = viewEditors.size() > 1 ? viewEditors.at(viewEditors.size() - 2) + : nullptr; + if (!newCurrent) + newCurrent = pickUnusedEditor(); + if (newCurrent) { + activateEditor(view, newCurrent, flags); + } else { + DocumentModel::Entry *entry = DocumentModelPrivate::firstSuspendedEntry(); + if (entry) { + activateEditorForEntry(view, entry, flags); + } else { // no "suspended" ones, so any entry left should have a document + const QList documents = DocumentModel::entries(); + if (!documents.isEmpty()) { + if (IDocument *document = documents.last()->document) { + activateEditorForDocument(view, document, flags); + } + } } } } + view->removeEditor(editor); } } diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h index a68c2edf72a..7cf5f27fbf3 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppeditorplugin.h @@ -190,6 +190,7 @@ private slots: void test_quickfix_MoveFuncDefOutside_respectWsInOperatorNames2(); void test_quickfix_MoveFuncDefOutside_macroUses(); void test_quickfix_MoveFuncDefOutside_template(); + void test_quickfix_MoveFuncDefOutside_unnamedTemplate(); void test_quickfix_MoveAllFuncDefOutside_MemberFuncToCpp(); void test_quickfix_MoveAllFuncDefOutside_MemberFuncOutside(); diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index da2e62e6760..43befecb7db 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -383,6 +383,32 @@ void CppEditorPlugin::test_quickfix_data() "}\n" ); + // Same as above for enum class. + QTest::newRow("CompleteSwitchCaseStatement_basic1_enum class") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( + "enum class EnumType { V1, V2 };\n" + "\n" + "void f()\n" + "{\n" + " EnumType t;\n" + " @switch (t) {\n" + " }\n" + "}\n" + ) << _( + "enum class EnumType { V1, V2 };\n" + "\n" + "void f()\n" + "{\n" + " EnumType t;\n" + " switch (t) {\n" + " case EnumType::V1:\n" + " break;\n" + " case EnumType::V2:\n" + " break;\n" + " }\n" + "}\n" + ); + // Checks: All enum values are added as case statements for a blank switch when // the variable is declared alongside the enum definition. QTest::newRow("CompleteSwitchCaseStatement_basic1_enum_with_declaration") @@ -408,6 +434,30 @@ void CppEditorPlugin::test_quickfix_data() "}\n" ); + // Same as above for enum class. + QTest::newRow("CompleteSwitchCaseStatement_basic1_enum_with_declaration_enumClass") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( + "enum class EnumType { V1, V2 } t;\n" + "\n" + "void f()\n" + "{\n" + " @switch (t) {\n" + " }\n" + "}\n" + ) << _( + "enum class EnumType { V1, V2 } t;\n" + "\n" + "void f()\n" + "{\n" + " switch (t) {\n" + " case EnumType::V1:\n" + " break;\n" + " case EnumType::V2:\n" + " break;\n" + " }\n" + "}\n" + ); + // Checks: All enum values are added as case statements for a blank switch // for anonymous enums. QTest::newRow("CompleteSwitchCaseStatement_basic1_anonymous_enum") @@ -463,6 +513,36 @@ void CppEditorPlugin::test_quickfix_data() "}\n" ); + // Same as above for enum class. + QTest::newRow("CompleteSwitchCaseStatement_basic2_enumClass") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( + "enum class EnumType { V1, V2 };\n" + "\n" + "void f()\n" + "{\n" + " EnumType t;\n" + " @switch (t) {\n" + " default:\n" + " break;\n" + " }\n" + "}\n" + ) << _( + "enum class EnumType { V1, V2 };\n" + "\n" + "void f()\n" + "{\n" + " EnumType t;\n" + " switch (t) {\n" + " case EnumType::V1:\n" + " break;\n" + " case EnumType::V2:\n" + " break;\n" + " default:\n" + " break;\n" + " }\n" + "}\n" + ); + // Checks: Enum type in class is found. QTest::newRow("CompleteSwitchCaseStatement_enumTypeInClass") << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( @@ -485,6 +565,28 @@ void CppEditorPlugin::test_quickfix_data() "}\n" ); + // Same as above for enum class. + QTest::newRow("CompleteSwitchCaseStatement_enumClassInClass") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( + "struct C { enum class EnumType { V1, V2 }; };\n" + "\n" + "void f(C::EnumType t) {\n" + " @switch (t) {\n" + " }\n" + "}\n" + ) << _( + "struct C { enum class EnumType { V1, V2 }; };\n" + "\n" + "void f(C::EnumType t) {\n" + " switch (t) {\n" + " case C::EnumType::V1:\n" + " break;\n" + " case C::EnumType::V2:\n" + " break;\n" + " }\n" + "}\n" + ); + // Checks: Enum type in namespace is found. QTest::newRow("CompleteSwitchCaseStatement_enumTypeInNamespace") << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( @@ -507,6 +609,28 @@ void CppEditorPlugin::test_quickfix_data() "}\n" ); + // Same as above for enum class. + QTest::newRow("CompleteSwitchCaseStatement_enumClassInNamespace") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( + "namespace N { enum class EnumType { V1, V2 }; };\n" + "\n" + "void f(N::EnumType t) {\n" + " @switch (t) {\n" + " }\n" + "}\n" + ) << _( + "namespace N { enum class EnumType { V1, V2 }; };\n" + "\n" + "void f(N::EnumType t) {\n" + " switch (t) {\n" + " case N::EnumType::V1:\n" + " break;\n" + " case N::EnumType::V2:\n" + " break;\n" + " }\n" + "}\n" + ); + // Checks: The missing enum value is added. QTest::newRow("CompleteSwitchCaseStatement_oneValueMissing") << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( @@ -539,6 +663,38 @@ void CppEditorPlugin::test_quickfix_data() "}\n" ); + // Checks: Same as above for enum class. + QTest::newRow("CompleteSwitchCaseStatement_oneValueMissing_enumClass") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( + "enum class EnumType { V1, V2 };\n" + "\n" + "void f()\n" + "{\n" + " EnumType t;\n" + " @switch (t) {\n" + " case EnumType::V2:\n" + " break;\n" + " default:\n" + " break;\n" + " }\n" + "}\n" + ) << _( + "enum class EnumType { V1, V2 };\n" + "\n" + "void f()\n" + "{\n" + " EnumType t;\n" + " switch (t) {\n" + " case EnumType::V1:\n" + " break;\n" + " case EnumType::V2:\n" + " break;\n" + " default:\n" + " break;\n" + " }\n" + "}\n" + ); + // Checks: Find the correct enum type despite there being a declaration with the same name. QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_1") << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( @@ -563,6 +719,30 @@ void CppEditorPlugin::test_quickfix_data() "}\n" ); + // Same as above for enum class. + QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_1_enumClass") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( + "enum class test { TEST_1, TEST_2 };\n" + "\n" + "void f() {\n" + " enum test test;\n" + " @switch (test) {\n" + " }\n" + "}\n" + ) << _( + "enum class test { TEST_1, TEST_2 };\n" + "\n" + "void f() {\n" + " enum test test;\n" + " switch (test) {\n" + " case test::TEST_1:\n" + " break;\n" + " case test::TEST_2:\n" + " break;\n" + " }\n" + "}\n" + ); + // Checks: Find the correct enum type despite there being a declaration with the same name. QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_2") << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( @@ -591,6 +771,34 @@ void CppEditorPlugin::test_quickfix_data() "}\n" ); + // Same as above for enum class. + QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_2_enumClass") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( + "enum class test1 { Wrong11, Wrong12 };\n" + "enum class test { Right1, Right2 };\n" + "enum class test2 { Wrong21, Wrong22 };\n" + "\n" + "int main() {\n" + " enum test test;\n" + " @switch (test) {\n" + " }\n" + "}\n" + ) << _( + "enum class test1 { Wrong11, Wrong12 };\n" + "enum class test { Right1, Right2 };\n" + "enum class test2 { Wrong21, Wrong22 };\n" + "\n" + "int main() {\n" + " enum test test;\n" + " switch (test) {\n" + " case test::Right1:\n" + " break;\n" + " case test::Right2:\n" + " break;\n" + " }\n" + "}\n" + ); + // Checks: Do not crash on incomplete case statetement. QTest::newRow("CompleteSwitchCaseStatement_doNotCrashOnIncompleteCase") << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( @@ -606,6 +814,21 @@ void CppEditorPlugin::test_quickfix_data() "" ); + // Same as above for enum class. + QTest::newRow("CompleteSwitchCaseStatement_doNotCrashOnIncompleteCase_enumClass") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( + "enum class E {};\n" + "void f(E o)\n" + "{\n" + " @switch (o)\n" + " {\n" + " case\n" + " }\n" + "}\n" + ) << _( + "" + ); + // Checks: complete switch statement where enum is goes via a template type parameter QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG-24752") << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( @@ -632,6 +855,32 @@ void CppEditorPlugin::test_quickfix_data() "}\n" ); + // Same as above for enum class. + QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG-24752_enumClass") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( + "enum class E {A, B};\n" + "template struct S {\n" + " static T theType() { return T(); }\n" + "};\n" + "int main() {\n" + " @switch (S::theType()) {\n" + " }\n" + "}\n" + ) << _( + "enum class E {A, B};\n" + "template struct S {\n" + " static T theType() { return T(); }\n" + "};\n" + "int main() {\n" + " switch (S::theType()) {\n" + " case E::A:\n" + " break;\n" + " case E::B:\n" + " break;\n" + " }\n" + "}\n" + ); + // Checks: No special treatment for reference to non const. // Check: Quick fix is not triggered on a member function. @@ -5954,7 +6203,24 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_template() "class Foo { void fu@nc(); };\n" "\n" "template\n" - "void Foo::func() {}\n"; // Should be Foo::func + "void Foo::func() {}\n"; + ; + + MoveFuncDefOutside factory; + QuickFixOperationTest(singleDocument(original, expected), &factory); +} + +void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_unnamedTemplate() +{ + QByteArray original = + "template\n" + "class Foo { void fu@nc() {} };\n"; + QByteArray expected = + "template\n" + "class Foo { void fu@nc(); };\n" + "\n" + "template\n" + "void Foo::func() {}\n"; ; MoveFuncDefOutside factory; diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 1e0fbd9f074..66a780bf617 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -2770,7 +2770,12 @@ static Enum *findEnum(const QList &results, const LookupContext &ctx return e; if (const NamedType *namedType = type->asNamedType()) { if (ClassOrNamespace *con = ctxt.lookupType(namedType->name(), result.scope())) { - const QList enums = con->unscopedEnums(); + QList enums = con->unscopedEnums(); + const QList symbols = con->symbols(); + for (Symbol * const s : symbols) { + if (const auto e = s->asEnum()) + enums << e; + } const Name *referenceName = namedType->name(); if (const QualifiedNameId *qualifiedName = referenceName->asQualifiedNameId()) referenceName = qualifiedName->name(); @@ -6457,6 +6462,7 @@ QString definitionSignature(const CppQuickFixInterface *assist, oo.showReturnTypes = true; oo.showArgumentNames = true; oo.showEnclosingTemplate = true; + oo.showTemplateParameters = true; const Name *name = func->name(); if (name && nameIncludesOperatorName(name)) { CoreDeclaratorAST *coreDeclarator = functionDefinitionAST->declarator->core_declarator; diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp index ff51c43504f..246298d98c1 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.cpp +++ b/src/plugins/cpptools/compileroptionsbuilder.cpp @@ -298,7 +298,8 @@ void CompilerOptionsBuilder::enableExceptions() void CompilerOptionsBuilder::insertWrappedQtHeaders() { - insertWrappedHeaders(wrappedQtHeadersIncludePath()); + if (m_useTweakedHeaderPaths == UseTweakedHeaderPaths::Yes) + insertWrappedHeaders(wrappedQtHeadersIncludePath()); } void CompilerOptionsBuilder::insertWrappedMingwHeaders() diff --git a/src/plugins/cpptools/compileroptionsbuilder.h b/src/plugins/cpptools/compileroptionsbuilder.h index a83aba74666..af4663930f4 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.h +++ b/src/plugins/cpptools/compileroptionsbuilder.h @@ -33,7 +33,7 @@ namespace CppTools { enum class UsePrecompiledHeaders : char { Yes, No }; enum class UseSystemHeader : char { Yes, No }; -enum class UseTweakedHeaderPaths : char { Yes, No }; +enum class UseTweakedHeaderPaths : char { Yes, Tools, No }; enum class UseToolchainMacros : char { Yes, No }; enum class UseLanguageDefines : char { Yes, No }; enum class UseBuildSystemWarnings : char { Yes, No }; diff --git a/src/plugins/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs index 161ea3fd1d5..8740eddb360 100644 --- a/src/plugins/cpptools/cpptools.qbs +++ b/src/plugins/cpptools/cpptools.qbs @@ -8,6 +8,7 @@ Project { QtcPlugin { Depends { name: "Qt.widgets" } + Depends { name: "Qt.testlib"; condition: project.withAutotests } Depends { name: "CPlusPlus" } Depends { name: "Utils" } @@ -216,6 +217,15 @@ Project { "usages.h", ] + Group { + name: "TestCase" + condition: qtc.testsEnabled || project.withAutotests + files: [ + "cpptoolstestcase.cpp", + "cpptoolstestcase.h", + ] + } + Group { name: "Tests" condition: qtc.testsEnabled @@ -230,8 +240,6 @@ Project { "cppsourceprocessertesthelper.cpp", "cppsourceprocessertesthelper.h", "cppsourceprocessor_test.cpp", - "cpptoolstestcase.cpp", - "cpptoolstestcase.h", "modelmanagertesthelper.cpp", "modelmanagertesthelper.h", "symbolsearcher_test.cpp", diff --git a/src/plugins/git/branchview.cpp b/src/plugins/git/branchview.cpp index 0328d5aefc7..b0c97935050 100644 --- a/src/plugins/git/branchview.cpp +++ b/src/plugins/git/branchview.cpp @@ -164,6 +164,11 @@ void BranchView::refresh(const QString &repository, bool force) m_addButton->setToolTip(tr("Add Branch...")); m_branchView->setEnabled(true); } + + // Do not refresh the model when the view is hidden + if (!isVisible()) + return; + QString errorMessage; if (!m_model->refresh(m_repository, &errorMessage)) VcsBase::VcsOutputWindow::appendError(errorMessage); @@ -174,6 +179,11 @@ void BranchView::refreshCurrentBranch() m_model->refreshCurrentBranch(); } +void BranchView::showEvent(QShowEvent *) +{ + refreshCurrentRepository(); +} + QToolButton *BranchView::addButton() const { return m_addButton; diff --git a/src/plugins/git/branchview.h b/src/plugins/git/branchview.h index faceea2ef57..a02bfa2567f 100644 --- a/src/plugins/git/branchview.h +++ b/src/plugins/git/branchview.h @@ -65,6 +65,9 @@ public: QAction *m_includeOldEntriesAction = nullptr; QAction *m_includeTagsAction = nullptr; +protected: + void showEvent(QShowEvent *) override; + private: void refreshCurrentRepository(); void resizeColumns(); diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 9f237ea8072..77462e1833f 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -1169,7 +1169,7 @@ void Client::handleDiagnostics(const PublishDiagnosticsParams ¶ms) const DocumentUri &uri = params.uri(); const QList &diagnostics = params.diagnostics(); - m_diagnosticManager.setDiagnostics(uri, params.diagnostics()); + m_diagnosticManager.setDiagnostics(uri, diagnostics); if (LanguageClientManager::clientForUri(uri) == this) { m_diagnosticManager.showDiagnostics(uri); requestCodeActions(uri, diagnostics); diff --git a/src/plugins/marketplace/productlistmodel.cpp b/src/plugins/marketplace/productlistmodel.cpp index 0e240cc243e..476b7f1a92a 100644 --- a/src/plugins/marketplace/productlistmodel.cpp +++ b/src/plugins/marketplace/productlistmodel.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -380,8 +381,10 @@ void SectionedProducts::onImageDownloadFinished(QNetworkReply *reply) if (reply->error() == QNetworkReply::NoError) { const QByteArray data = reply->readAll(); QPixmap pixmap; - if (pixmap.loadFromData(data)) { - const QString url = reply->request().url().toString(); + const QUrl imageUrl = reply->request().url(); + const QString imageFormat = QFileInfo(imageUrl.fileName()).suffix(); + if (pixmap.loadFromData(data, imageFormat.toLatin1())) { + const QString url = imageUrl.toString(); QPixmapCache::insert(url, pixmap.scaled(ProductListModel::defaultImageSize, Qt::KeepAspectRatio, Qt::SmoothTransformation)); for (ProductListModel *model : m_productModels.values()) diff --git a/src/plugins/projectexplorer/CMakeLists.txt b/src/plugins/projectexplorer/CMakeLists.txt index 13ede53da94..87e3a45bfd8 100644 --- a/src/plugins/projectexplorer/CMakeLists.txt +++ b/src/plugins/projectexplorer/CMakeLists.txt @@ -183,6 +183,11 @@ add_qtc_plugin(ProjectExplorer xcodebuildparser.cpp xcodebuildparser.h ) +extend_qtc_plugin(ProjectExplorer + CONDITION PROJECT_USER_FILE_EXTENSION + DEFINES "PROJECT_USER_FILE_EXTENSION=${PROJECT_USER_FILE_EXTENSION}" +) + if (TARGET libclang) set(CLANG_BINDIR "$") endif() diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp index ce7a2db229a..f9da875f9ea 100644 --- a/src/plugins/projectexplorer/projectwindow.cpp +++ b/src/plugins/projectexplorer/projectwindow.cpp @@ -661,8 +661,38 @@ void ProjectWindow::activateProjectPanel(Utils::Id panelId) d->activateProjectPanel(panelId); } +void ProjectWindow::hideEvent(QHideEvent *event) +{ + savePersistentSettings(); + FancyMainWindow::hideEvent(event); +} + +void ProjectWindow::showEvent(QShowEvent *event) +{ + loadPersistentSettings(); + FancyMainWindow::showEvent(event); +} + ProjectWindow::~ProjectWindow() = default; +const char PROJECT_WINDOW_KEY[] = "ProjectExplorer.ProjectWindow"; + +void ProjectWindow::savePersistentSettings() const +{ + QSettings * const settings = ICore::settings(); + settings->beginGroup(PROJECT_WINDOW_KEY); + saveSettings(settings); + settings->endGroup(); +} + +void ProjectWindow::loadPersistentSettings() +{ + QSettings * const settings = ICore::settings(); + settings->beginGroup(PROJECT_WINDOW_KEY); + restoreSettings(settings); + settings->endGroup(); +} + QSize SelectorDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QSize s = QStyledItemDelegate::sizeHint(option, index); diff --git a/src/plugins/projectexplorer/projectwindow.h b/src/plugins/projectexplorer/projectwindow.h index 09c242034c8..c048a4ac460 100644 --- a/src/plugins/projectexplorer/projectwindow.h +++ b/src/plugins/projectexplorer/projectwindow.h @@ -64,6 +64,12 @@ public: void activateProjectPanel(Utils::Id panelId); private: + void hideEvent(QHideEvent *event) override; + void showEvent(QShowEvent *event) override; + + void savePersistentSettings() const; + void loadPersistentSettings(); + const std::unique_ptr d; }; diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 620b3645f70..1f1d1bae4b6 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -614,7 +614,8 @@ void QMakeStep::userArgumentsChanged() { if (m_ignoreChange) return; - qmakeAdditonalArgumentsLineEdit->setText(m_userArgs); + if (qmakeAdditonalArgumentsLineEdit) + qmakeAdditonalArgumentsLineEdit->setText(m_userArgs); updateAbiWidgets(); updateEffectiveQMakeCall(); } @@ -723,6 +724,9 @@ bool QMakeStep::isAndroidKit() const void QMakeStep::updateAbiWidgets() { + if (!abisLabel) + return; + BaseQtVersion *qtVersion = QtKitAspect::qtVersion(target()->kit()); if (!qtVersion) return; @@ -762,7 +766,8 @@ void QMakeStep::updateAbiWidgets() void QMakeStep::updateEffectiveQMakeCall() { - qmakeArgumentsEdit->setPlainText(effectiveQMakeCall()); + if (qmakeArgumentsEdit) + qmakeArgumentsEdit->setPlainText(effectiveQMakeCall()); } void QMakeStep::recompileMessageBoxFinished(int button) diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 21b1c9cf647..48c1f2cc874 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -42,7 +42,7 @@ add_qtc_plugin(QmlDesigner add_qtc_plugin(assetexporterplugin CONDITION TARGET QmlDesigner - DEPENDS Core ProjectExplorer QmlDesigner Utils Qt5::Qml + DEPENDS Core ProjectExplorer QmlDesigner Utils Qt5::Qml Qt5::QuickPrivate PUBLIC_INCLUDES assetexporterplugin SOURCES assetexporterplugin/assetexportdialog.h assetexporterplugin/assetexportdialog.cpp assetexporterplugin/assetexportdialog.ui diff --git a/src/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.pri b/src/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.pri index 713ab1184fb..41b144f6853 100644 --- a/src/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.pri +++ b/src/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.pri @@ -1,4 +1,5 @@ QT *= qml quick core widgets +QT += quick-private VPATH += $$PWD diff --git a/src/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.qbs b/src/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.qbs index e847525324d..39b1b2909cd 100644 --- a/src/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.qbs +++ b/src/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.qbs @@ -10,6 +10,12 @@ QtcProduct { Depends { name: "ProjectExplorer" } Depends { name: "QmlDesigner" } Depends { name: "Utils" } + Depends { + name: "Qt" + submodules: [ + "quick-private" + ] + } cpp.includePaths: base.concat([ "./", diff --git a/src/plugins/qmldesigner/assetexporterplugin/parsers/textnodeparser.cpp b/src/plugins/qmldesigner/assetexporterplugin/parsers/textnodeparser.cpp index dfbc78a75d9..1a0c938a6ad 100644 --- a/src/plugins/qmldesigner/assetexporterplugin/parsers/textnodeparser.cpp +++ b/src/plugins/qmldesigner/assetexporterplugin/parsers/textnodeparser.cpp @@ -28,7 +28,11 @@ #include #include +#include #include +#include + +#include namespace { const QHash AlignMapping{ @@ -86,6 +90,14 @@ QJsonObject TextNodeParser::json(Component &component) const textDetails.insert(IsMultilineTag, propertyValue("wrapMode").toString().compare("NoWrap") != 0); + // Calculate line height in pixels + QFontMetricsF fm(font); + auto lineHeightMode = propertyValue("lineHeightMode").value(); + double lineHeight = propertyValue("lineHeight").toDouble(); + qreal lineHeightPx = (lineHeightMode == QQuickText::FixedHeight) ? + lineHeight : qCeil(fm.height()) * lineHeight; + textDetails.insert(LineHeightTag, lineHeightPx); + QJsonObject metadata = jsonObject.value(MetadataTag).toObject(); metadata.insert(TextDetailsTag, textDetails); jsonObject.insert(MetadataTag, metadata); diff --git a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h index 6186575e43c..7de6c4fe64a 100644 --- a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h +++ b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h @@ -34,7 +34,7 @@ namespace ComponentCoreConstants { const char rootCategory[] = ""; const char selectionCategory[] = "Selection"; -const char stackCategory[] = "Stack (z)"; +const char arrangeCategory[] = "Arrange"; const char qmlPreviewCategory[] = "QmlPreview"; const char editCategory[] = "Edit"; const char anchorsCategory[] = "Anchors"; @@ -52,6 +52,7 @@ const char toBackCommandId[] = "ToBack"; const char raiseCommandId[] = "Raise"; const char lowerCommandId[] = "Lower"; const char resetZCommandId[] = "ResetZ"; +const char reverseCommandId[] = "Reverse"; const char resetSizeCommandId[] = "ResetSize"; const char resetPositionCommandId[] = "ResetPosition"; const char visiblityCommandId[] = "ToggleVisiblity"; @@ -90,7 +91,7 @@ const char fitSelectionToScreenCommandId[] = "FitSelectionToScreen"; const char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Selection"); const char flowConnectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect"); const char selectEffectDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select Effect"); -const char stackCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Stack (z)"); +const char arrangeCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Arrange"); const char editCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit"); const char anchorsCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Anchors"); const char positionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Position"); @@ -105,11 +106,11 @@ const char copySelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMen const char pasteSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Paste"); const char deleteSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Delete Selection"); -const char toFrontDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "To Front"); -const char toBackDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "To Back"); +const char toFrontDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Bring to Front"); +const char toBackDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Send to Back"); -const char raiseDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Raise"); -const char lowerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Lower"); +const char raiseDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Bring Forward"); +const char lowerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Send Backward"); const char undoDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Undo"); const char redoDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Redo"); @@ -129,6 +130,8 @@ const char setIdDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set const char resetZDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset z Property"); +const char reverseDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reverse"); + const char anchorsFillDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Fill"); const char anchorsResetDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset"); diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index ea34b091cd4..f7953e2fbe6 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -594,6 +594,11 @@ bool selectionHasSameParentAndInBaseState(const SelectionContext &context) return selectionHasSameParent(context) && inBaseState(context); } +bool multiSelectionAndHasSameParent(const SelectionContext &context) +{ + return multiSelection(context) && selectionHasSameParent(context); +} + bool isNotInLayout(const SelectionContext &context) { if (selectionNotEmpty(context)) { @@ -914,8 +919,8 @@ void DesignerActionManager::createDefaultDesignerActions() prioritySelectionCategory)); addDesignerAction(new ActionGroup( - stackCategoryDisplayName, - stackCategory, + arrangeCategoryDisplayName, + arrangeCategory, priorityStackCategory, &selectionNotEmpty)); @@ -923,28 +928,19 @@ void DesignerActionManager::createDefaultDesignerActions() toFrontCommandId, toFrontDisplayName, {}, - stackCategory, + arrangeCategory, QKeySequence(), 200, &toFront, &singleSelection)); addDesignerAction(new ModelNodeContextMenuAction( - toBackCommandId, - toBackDisplayName, - {}, - stackCategory, + raiseCommandId, + raiseDisplayName, + Utils::Icon({{":/qmldesigner/icon/designeractions/images/raise.png", Utils::Theme::IconsBaseColor}}).icon(), + arrangeCategory, QKeySequence(), 180, - &toBack, - &singleSelection)); - - addDesignerAction(new ModelNodeContextMenuAction( - raiseCommandId, raiseDisplayName, - Utils::Icon({{":/qmldesigner/icon/designeractions/images/raise.png", Utils::Theme::IconsBaseColor}}).icon(), - stackCategory, - QKeySequence(), - 160, &raise, &raiseAvailable)); @@ -952,23 +948,31 @@ void DesignerActionManager::createDefaultDesignerActions() lowerCommandId, lowerDisplayName, Utils::Icon({{":/qmldesigner/icon/designeractions/images/lower.png", Utils::Theme::IconsBaseColor}}).icon(), - stackCategory, + arrangeCategory, QKeySequence(), - 140, + 160, &lower, &lowerAvailable)); - addDesignerAction(new SeperatorDesignerAction(stackCategory, 120)); + addDesignerAction(new ModelNodeContextMenuAction( + toBackCommandId, + toBackDisplayName, + {}, + arrangeCategory, + QKeySequence(), + 140, + &toBack, + &singleSelection)); addDesignerAction(new ModelNodeContextMenuAction( - resetZCommandId, - resetZDisplayName, + reverseCommandId, + reverseDisplayName, {}, - stackCategory, + arrangeCategory, QKeySequence(), 100, - &resetZ, - &selectionNotEmptyAndHasZProperty)); + &reverse, + &multiSelectionAndHasSameParent)); addDesignerAction(new ActionGroup(editCategoryDisplayName, editCategory, priorityEditCategory, &selectionNotEmpty)); @@ -979,7 +983,9 @@ void DesignerActionManager::createDefaultDesignerActions() resetPositionDisplayName, Utils::Icon({{":/utils/images/pan.png", Utils::Theme::IconsBaseColor}, {":/utils/images/iconoverlay_reset.png", Utils::Theme::IconsStopToolBarColor}}).icon(), - resetPositionTooltip, editCategory, QKeySequence("Ctrl+d"), + resetPositionTooltip, + editCategory, + QKeySequence("Ctrl+d"), 200, &resetPosition, &selectionNotEmptyAndHasXorYProperty)); diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index f76542d3789..7bda65bf1aa 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -206,9 +206,9 @@ void toBack(const SelectionContext &selectionState) } } -enum OderAction {RaiseItem, LowerItem}; +enum OrderAction {RaiseItem, LowerItem}; -void changeOrder(const SelectionContext &selectionState, OderAction orderAction) +void changeOrder(const SelectionContext &selectionState, OrderAction orderAction) { if (!selectionState.view()) return; @@ -221,13 +221,12 @@ void changeOrder(const SelectionContext &selectionState, OderAction orderAction) if (!modelNode.parentProperty().isNodeListProperty()) return; - selectionState.view()->executeInTransaction("DesignerActionManager|raise",[orderAction, selectionState, modelNode](){ + selectionState.view()->executeInTransaction("DesignerActionManager|changeOrder", [orderAction, selectionState, modelNode]() { ModelNode modelNode = selectionState.currentSingleSelectedNode(); NodeListProperty parentProperty = modelNode.parentProperty().toNodeListProperty(); const int index = parentProperty.indexOf(modelNode); if (orderAction == RaiseItem) { - if (index < parentProperty.count() - 1) parentProperty.slide(index, index + 1); } else if (orderAction == LowerItem) { @@ -244,7 +243,6 @@ void raise(const SelectionContext &selectionState) void lower(const SelectionContext &selectionState) { - changeOrder(selectionState, LowerItem); } @@ -344,8 +342,8 @@ void resetZ(const SelectionContext &selectionState) if (!selectionState.view()) return; - selectionState.view()->executeInTransaction("DesignerActionManager|resetZ",[selectionState](){ - foreach (ModelNode node, selectionState.selectedModelNodes()) { + selectionState.view()->executeInTransaction("DesignerActionManager|resetZ", [selectionState](){ + for (ModelNode node : selectionState.selectedModelNodes()) { QmlItemNode itemNode(node); if (itemNode.isValid()) itemNode.removeProperty("z"); @@ -353,6 +351,16 @@ void resetZ(const SelectionContext &selectionState) }); } +void reverse(const SelectionContext &selectionState) +{ + if (!selectionState.view()) + return; + + selectionState.view()->executeInTransaction("DesignerActionManager|reverse", [selectionState](){ + NodeListProperty::reverseModelNodes(selectionState.selectedModelNodes()); + }); +} + static inline void backupPropertyAndRemove(const ModelNode &node, const PropertyName &propertyName) { if (node.hasVariantProperty(propertyName)) { @@ -366,7 +374,6 @@ static inline void backupPropertyAndRemove(const ModelNode &node, const Property } } - static inline void restoreProperty(const ModelNode &node, const PropertyName &propertyName) { if (node.hasAuxiliaryData(auxDataString + propertyName)) diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h index d22e673c801..aa43933224d 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h @@ -52,6 +52,7 @@ void resetPosition(const SelectionContext &selectionState); void goIntoComponentOperation(const SelectionContext &selectionState); void setId(const SelectionContext &selectionState); void resetZ(const SelectionContext &selectionState); +void reverse(const SelectionContext &selectionState); void anchorsFill(const SelectionContext &selectionState); void anchorsReset(const SelectionContext &selectionState); void layoutRowPositioner(const SelectionContext &selectionState); diff --git a/src/plugins/qmldesigner/components/curveeditor/animationcurve.cpp b/src/plugins/qmldesigner/components/curveeditor/animationcurve.cpp index 237d89dcb20..9a88b332407 100644 --- a/src/plugins/qmldesigner/components/curveeditor/animationcurve.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/animationcurve.cpp @@ -33,7 +33,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { AnimationCurve::AnimationCurve() : m_fromData(false) @@ -395,4 +395,4 @@ void AnimationCurve::analyze() } } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/animationcurve.h b/src/plugins/qmldesigner/components/curveeditor/animationcurve.h index d8ea0d628f4..d364fd247c9 100644 --- a/src/plugins/qmldesigner/components/curveeditor/animationcurve.h +++ b/src/plugins/qmldesigner/components/curveeditor/animationcurve.h @@ -33,7 +33,7 @@ QT_FORWARD_DECLARE_CLASS(QEasingCurve); QT_FORWARD_DECLARE_CLASS(QPainterPath); -namespace DesignTools { +namespace QmlDesigner { class CurveSegment; @@ -100,4 +100,4 @@ private: std::vector m_frames; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp index 2db3509b184..1d238a265cc 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp @@ -35,7 +35,7 @@ #include #include -namespace DesignTools { +namespace QmlDesigner { CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent) : QWidget(parent) @@ -52,10 +52,9 @@ CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent) box->addWidget(splitter); setLayout(box); - connect(m_tree, &TreeView::treeItemLocked, model, &CurveEditorModel::curveChanged); - connect(m_tree, &TreeView::treeItemPinned, model, &CurveEditorModel::curveChanged); + connect(m_tree, &TreeView::treeItemLocked, model, &CurveEditorModel::setLocked); + connect(m_tree, &TreeView::treeItemPinned, model, &CurveEditorModel::setPinned); - connect(m_tree, &TreeView::treeItemLocked, m_view, &GraphicsView::setLocked); connect(m_tree->selectionModel(), &SelectionModel::curvesSelected, m_view, @@ -180,4 +179,4 @@ QToolBar *CurveEditor::createToolBar(CurveEditorModel *model) return bar; } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditor.h b/src/plugins/qmldesigner/components/curveeditor/curveeditor.h index 86f6c592578..f248a0ed080 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditor.h +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditor.h @@ -28,7 +28,7 @@ #include #include -namespace DesignTools { +namespace QmlDesigner { class CurveEditorModel; class GraphicsView; @@ -57,4 +57,4 @@ private: GraphicsView *m_view; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp index 56b91d0af65..7827cf03c0f 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp @@ -25,6 +25,7 @@ #include "curveeditormodel.h" #include "curveeditorstyle.h" +#include "detail/treeview.h" #include "treeitem.h" #include "detail/graphicsview.h" @@ -34,10 +35,11 @@ #include "qmltimeline.h" #include +#include #include #include -namespace DesignTools { +namespace QmlDesigner { CurveEditorModel::CurveEditorModel(QObject *parent) : TreeModel(parent) @@ -57,10 +59,10 @@ double CurveEditorModel::maximumTime() const return m_maxTime; } -DesignTools::CurveEditorStyle CurveEditorModel::style() const +CurveEditorStyle CurveEditorModel::style() const { // Pseudo auto generated. See: CurveEditorStyleDialog - DesignTools::CurveEditorStyle out; + CurveEditorStyle out; out.backgroundBrush = QBrush(QColor(21, 21, 21)); out.backgroundAlternateBrush = QBrush(QColor(32, 32, 32)); out.fontColor = QColor(255, 255, 255); @@ -98,9 +100,9 @@ void CurveEditorModel::setTimeline(const QmlDesigner::QmlTimeline &timeline) { m_minTime = timeline.startKeyframe(); m_maxTime = timeline.endKeyframe(); - std::vector items; + std::vector items; for (auto &&target : timeline.allTargets()) { - if (DesignTools::TreeItem *item = createTopLevelItem(timeline, target)) + if (TreeItem *item = createTopLevelItem(timeline, target)) items.push_back(item); } @@ -135,6 +137,32 @@ void CurveEditorModel::setCurve(unsigned int id, const AnimationCurve &curve) } } +void CurveEditorModel::setLocked(TreeItem *item, bool val) +{ + item->setLocked(val); + + if (auto *gview = graphicsView()) + gview->setLocked(item); + + if (auto *tview = treeView()) + tview->viewport()->update(); + + emit curveChanged(item); +} + +void CurveEditorModel::setPinned(TreeItem *item, bool val) +{ + item->setPinned(val); + + if (auto *gview = graphicsView()) + gview->setPinned(item); + + if (auto *tview = treeView()) + tview->viewport()->update(); + + emit curveChanged(item); +} + bool contains(const std::vector &selection, const TreeItem::Path &path) { for (auto &&sel : selection) @@ -176,38 +204,57 @@ void CurveEditorModel::reset(const std::vector &items) sm->selectPaths(sel); } -DesignTools::ValueType typeFrom(const QmlDesigner::QmlTimelineKeyframeGroup &group) +PropertyTreeItem::ValueType typeFrom(const QmlDesigner::QmlTimelineKeyframeGroup &group) { if (group.valueType() == QmlDesigner::TypeName("double") || group.valueType() == QmlDesigner::TypeName("real") || group.valueType() == QmlDesigner::TypeName("float")) - return DesignTools::ValueType::Double; + return PropertyTreeItem::ValueType::Double; if (group.valueType() == QmlDesigner::TypeName("boolean") || group.valueType() == QmlDesigner::TypeName("bool")) - return DesignTools::ValueType::Bool; + return PropertyTreeItem::ValueType::Bool; if (group.valueType() == QmlDesigner::TypeName("integer") || group.valueType() == QmlDesigner::TypeName("int")) - return DesignTools::ValueType::Integer; + return PropertyTreeItem::ValueType::Integer; // Ignoring: QColor / HAlignment / VAlignment - return DesignTools::ValueType::Undefined; + return PropertyTreeItem::ValueType::Undefined; } -DesignTools::TreeItem *CurveEditorModel::createTopLevelItem(const QmlDesigner::QmlTimeline &timeline, - const QmlDesigner::ModelNode &node) +std::vector parentIds(const QmlDesigner::ModelNode &node) +{ + std::vector out; + + QmlDesigner::ModelNode parent = node.parentProperty().parentModelNode(); + while (parent.isValid()) { + out.push_back(parent.id()); + + if (parent.hasParentProperty()) + parent = parent.parentProperty().parentModelNode(); + else + break; + } + return out; +} + +TreeItem *CurveEditorModel::createTopLevelItem(const QmlDesigner::QmlTimeline &timeline, + const QmlDesigner::ModelNode &node) { if (!node.isValid()) return nullptr; - auto *nodeItem = new DesignTools::NodeTreeItem(node.id(), QIcon(":/ICON_INSTANCE")); + auto *nodeItem = new NodeTreeItem(node.id(), node.typeIcon(), parentIds(node)); + if (node.hasAuxiliaryData("locked")) + nodeItem->setLocked(true); + for (auto &&grp : timeline.keyframeGroupsForTarget(node)) { if (grp.isValid()) { - DesignTools::AnimationCurve curve = createAnimationCurve(grp); + AnimationCurve curve = createAnimationCurve(grp); if (curve.isValid()) { QString name = QString::fromUtf8(grp.propertyName()); - auto propertyItem = new DesignTools::PropertyTreeItem(name, curve, typeFrom(grp)); + auto propertyItem = new PropertyTreeItem(name, curve, typeFrom(grp)); QmlDesigner::ModelNode target = grp.modelNode(); if (target.hasAuxiliaryData("locked")) @@ -229,25 +276,24 @@ DesignTools::TreeItem *CurveEditorModel::createTopLevelItem(const QmlDesigner::Q return nodeItem; } -DesignTools::AnimationCurve CurveEditorModel::createAnimationCurve( - const QmlDesigner::QmlTimelineKeyframeGroup &group) +AnimationCurve CurveEditorModel::createAnimationCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group) { switch (typeFrom(group)) { - case DesignTools::ValueType::Bool: + case PropertyTreeItem::ValueType::Bool: return createDoubleCurve(group); - case DesignTools::ValueType::Integer: + case PropertyTreeItem::ValueType::Integer: return createDoubleCurve(group); - case DesignTools::ValueType::Double: + case PropertyTreeItem::ValueType::Double: return createDoubleCurve(group); default: - return DesignTools::AnimationCurve(); + return AnimationCurve(); } } -std::vector createKeyframes(QList nodes) +std::vector createKeyframes(QList nodes) { auto byTime = [](const auto &a, const auto &b) { return a.variantProperty("frame").value().toDouble() @@ -255,7 +301,7 @@ std::vector createKeyframes(QList }; std::sort(nodes.begin(), nodes.end(), byTime); - std::vector frames; + std::vector frames; for (auto &&node : nodes) { QVariant timeVariant = node.variantProperty("frame").value(); QVariant valueVariant = node.variantProperty("value").value(); @@ -264,7 +310,7 @@ std::vector createKeyframes(QList QPointF position(timeVariant.toDouble(), valueVariant.toDouble()); - auto keyframe = DesignTools::Keyframe(position); + auto keyframe = Keyframe(position); if (node.hasBindingProperty("easing.bezierCurve")) { QmlDesigner::EasingCurve ecurve; @@ -276,15 +322,15 @@ std::vector createKeyframes(QList return frames; } -std::vector resolveSmallCurves(const std::vector &frames) +std::vector resolveSmallCurves(const std::vector &frames) { - std::vector out; + std::vector out; for (auto &&frame : frames) { if (frame.hasData() && !out.empty()) { QEasingCurve curve = frame.data().toEasingCurve(); // One-segment-curve: Since (0,0) is implicit => 3 if (curve.toCubicSpline().count() == 3) { - DesignTools::Keyframe &previous = out.back(); + Keyframe &previous = out.back(); #if 0 // Do not resolve when two adjacent keyframes have the same value. if (qFuzzyCompare(previous.position().y(), frame.position().y())) { @@ -292,7 +338,7 @@ std::vector resolveSmallCurves(const std::vector resolveSmallCurves(const std::vector keyframes = createKeyframes(group.keyframePositions()); + std::vector keyframes = createKeyframes(group.keyframePositions()); keyframes = resolveSmallCurves(keyframes); QString str; @@ -321,7 +366,7 @@ DesignTools::AnimationCurve CurveEditorModel::createDoubleCurve( } } - return DesignTools::AnimationCurve(keyframes); + return AnimationCurve(keyframes); } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h index cf7575ca5c1..71fca7de039 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h @@ -35,7 +35,7 @@ QT_BEGIN_NAMESPACE class QPointF; QT_END_NAMESPACE -namespace DesignTools { +namespace QmlDesigner { struct CurveEditorStyle; @@ -54,7 +54,7 @@ signals: void commitEndFrame(int frame); - void curveChanged(PropertyTreeItem *item); + void curveChanged(TreeItem *item); public: CurveEditorModel(QObject *parent = nullptr); @@ -65,7 +65,7 @@ public: double maximumTime() const; - DesignTools::CurveEditorStyle style() const; + CurveEditorStyle style() const; public: void setTimeline(const QmlDesigner::QmlTimeline &timeline); @@ -78,19 +78,23 @@ public: void setCurve(unsigned int id, const AnimationCurve &curve); + void setLocked(TreeItem *item, bool val); + + void setPinned(TreeItem *item, bool val); + void reset(const std::vector &items); private: - DesignTools::TreeItem *createTopLevelItem(const QmlDesigner::QmlTimeline &timeline, - const QmlDesigner::ModelNode &node); + TreeItem *createTopLevelItem(const QmlDesigner::QmlTimeline &timeline, + const QmlDesigner::ModelNode &node); - DesignTools::AnimationCurve createAnimationCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group); + AnimationCurve createAnimationCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group); - DesignTools::AnimationCurve createDoubleCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group); + AnimationCurve createDoubleCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group); double m_minTime = 0.; double m_maxTime = 0.; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorstyle.h b/src/plugins/qmldesigner/components/curveeditor/curveeditorstyle.h index f6c6c378c59..eb5ef7ee71f 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditorstyle.h +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorstyle.h @@ -27,7 +27,9 @@ #include "detail/shortcut.h" +#include #include +#include #include #include @@ -38,15 +40,30 @@ #include -namespace DesignTools { +namespace QmlDesigner { struct TreeItemStyleOption { double margins; - QIcon pinnedIcon = QIcon(":/curveeditor/images/treeview_pin.png"); - QIcon unpinnedIcon = QIcon(":/curveeditor/images/treeview_unpin.png"); - QIcon lockedIcon = QIcon(":/curveeditor/images/treeview_lock.png"); - QIcon unlockedIcon = QIcon(":/curveeditor/images/treeview_unlock.png"); + + QIcon pinnedIcon = iconFromFont(QmlDesigner::Theme::Icon::pin); + QIcon unpinnedIcon = iconFromFont(QmlDesigner::Theme::Icon::unpin); + QIcon implicitlyPinnedIcon = iconFromFont(QmlDesigner::Theme::Icon::pin, Qt::gray); + QIcon lockedIcon = iconFromFont(QmlDesigner::Theme::Icon::lockOn); + QIcon unlockedIcon = iconFromFont(QmlDesigner::Theme::Icon::lockOff); + QIcon implicitlyLockedIcon = iconFromFont(QmlDesigner::Theme::Icon::lockOn, Qt::gray); + + static QIcon iconFromFont(QmlDesigner::Theme::Icon type, const QColor &color = Qt::white) + { + const QString fontName = "qtds_propertyIconFont.ttf"; + static const int fontSize = 28; + static const int iconSize = 28; + return Utils::StyleHelper::getIconFromIconFont(fontName, + QmlDesigner::Theme::getIconUnicode(type), + fontSize, + iconSize, + color); + } }; struct HandleItemStyleOption @@ -122,15 +139,15 @@ struct CurveEditorStyle QColor iconColor = QColor(128, 128, 128); QColor iconHoverColor = QColor(170, 170, 170); QColor gridColor = QColor(128, 128, 128); - double canvasMargin = 5.0; + int canvasMargin = 5; int zoomInWidth = 100; int zoomInHeight = 100; - double timeAxisHeight = 40.0; + int timeAxisHeight = 40; double timeOffsetLeft = 10.0; double timeOffsetRight = 10.0; QColor rangeBarColor = QColor(128, 128, 128); QColor rangeBarCapsColor = QColor(50, 50, 255); - double valueAxisWidth = 60.0; + int valueAxisWidth = 60; double valueOffsetTop = 10.0; double valueOffsetBottom = 10.0; double labelDensityY = 2.0; @@ -151,4 +168,4 @@ inline QPixmap pixmapFromIcon(const QIcon &icon, const QSize &size, const QColor return mask; } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp index b84d386f8e3..51fc7c31a32 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp @@ -27,6 +27,7 @@ #include "curveeditor.h" #include "curveeditormodel.h" #include "curvesegment.h" +#include "treeitem.h" #include #include @@ -42,29 +43,14 @@ namespace QmlDesigner { CurveEditorView::CurveEditorView(QObject *parent) : AbstractView(parent) , m_block(false) - , m_model(new DesignTools::CurveEditorModel()) - , m_editor(new DesignTools::CurveEditor(m_model)) + , m_model(new CurveEditorModel()) + , m_editor(new CurveEditor(m_model)) { Q_UNUSED(parent); - connect(m_model, - &DesignTools::CurveEditorModel::commitCurrentFrame, - this, - &CurveEditorView::commitCurrentFrame); - - connect(m_model, - &DesignTools::CurveEditorModel::commitStartFrame, - this, - &CurveEditorView::commitStartFrame); - - connect(m_model, - &DesignTools::CurveEditorModel::commitEndFrame, - this, - &CurveEditorView::commitEndFrame); - - connect(m_model, - &DesignTools::CurveEditorModel::curveChanged, - this, - &CurveEditorView::commitKeyframes); + connect(m_model, &CurveEditorModel::commitCurrentFrame, this, &CurveEditorView::commitCurrentFrame); + connect(m_model, &CurveEditorModel::commitStartFrame, this, &CurveEditorView::commitStartFrame); + connect(m_model, &CurveEditorModel::commitEndFrame, this, &CurveEditorView::commitEndFrame); + connect(m_model, &CurveEditorModel::curveChanged, this, &CurveEditorView::commitKeyframes); } CurveEditorView::~CurveEditorView() {} @@ -134,6 +120,18 @@ void CurveEditorView::nodeReparented(const ModelNode &node, updateKeyframes(); } +void CurveEditorView::auxiliaryDataChanged(const ModelNode &node, + const PropertyName &name, + const QVariant &data) +{ + if (name == "locked") { + if (auto *item = m_model->find(node.id())) { + QSignalBlocker blocker(m_model); + m_model->setLocked(item, data.toBool()); + } + } +} + void CurveEditorView::instancePropertyChanged(const QList> &propertyList) { Q_UNUSED(propertyList); @@ -261,9 +259,9 @@ void CurveEditorView::updateEndFrame(const ModelNode &node) m_model->setMaximumTime(static_cast(std::round(timeline.endKeyframe()))); } -ModelNode getTargetNode1(DesignTools::PropertyTreeItem *item, const QmlTimeline &timeline) +ModelNode getTargetNode(PropertyTreeItem *item, const QmlTimeline &timeline) { - if (const DesignTools::NodeTreeItem *nodeItem = item->parentNodeTreeItem()) { + if (const NodeTreeItem *nodeItem = item->parentNodeTreeItem()) { QString targetId = nodeItem->name(); if (timeline.isValid()) { for (auto &&target : timeline.allTargets()) { @@ -275,17 +273,16 @@ ModelNode getTargetNode1(DesignTools::PropertyTreeItem *item, const QmlTimeline return ModelNode(); } -QmlTimelineKeyframeGroup timelineKeyframeGroup1(QmlTimeline &timeline, - DesignTools::PropertyTreeItem *item) +QmlTimelineKeyframeGroup timelineKeyframeGroup(QmlTimeline &timeline, PropertyTreeItem *item) { - ModelNode node = getTargetNode1(item, timeline); + ModelNode node = getTargetNode(item, timeline); if (node.isValid()) return timeline.keyframeGroup(node, item->name().toLatin1()); return QmlTimelineKeyframeGroup(); } -void attachEasingCurve1(double frame, const QEasingCurve &curve, const QmlTimelineKeyframeGroup &group) +void attachEasingCurve(const QmlTimelineKeyframeGroup &group, double frame, const QEasingCurve &curve) { ModelNode frameNode = group.keyframe(frame); if (frameNode.isValid()) { @@ -294,61 +291,73 @@ void attachEasingCurve1(double frame, const QEasingCurve &curve, const QmlTimeli } } -void CurveEditorView::commitKeyframes(DesignTools::PropertyTreeItem *item) +void commitAuxiliaryData(ModelNode &node, TreeItem *item) { - QmlTimeline currentTimeline = activeTimeline(); - QmlTimelineKeyframeGroup group = timelineKeyframeGroup1(currentTimeline, item); + if (node.isValid()) { + if (item->locked()) + node.setAuxiliaryData("locked", true); + else + node.removeAuxiliaryData("locked"); - if (group.isValid()) { - ModelNode groupNode = group.modelNode(); + if (item->pinned()) + node.setAuxiliaryData("pinned", true); + else + node.removeAuxiliaryData("pinned"); - if (groupNode.isValid()) { - if (item->locked()) - groupNode.setAuxiliaryData("locked", true); + if (auto *pitem = item->asPropertyItem()) { + if (pitem->hasUnified()) + node.setAuxiliaryData("unified", pitem->unifyString()); else - groupNode.removeAuxiliaryData("locked"); - - if (item->pinned()) - groupNode.setAuxiliaryData("pinned", true); - else - groupNode.removeAuxiliaryData("pinned"); - - if (item->hasUnified()) - groupNode.setAuxiliaryData("unified", item->unifyString()); - else - groupNode.removeAuxiliaryData("unified"); + node.removeAuxiliaryData("unified"); } + } +} - auto replaceKeyframes = [&group, item, this]() { - m_block = true; - for (auto frame : group.keyframes()) - frame.destroy(); +void CurveEditorView::commitKeyframes(TreeItem *item) +{ + if (auto *nitem = item->asNodeItem()) { + ModelNode node = modelNodeForId(nitem->name()); + commitAuxiliaryData(node, item); - DesignTools::Keyframe previous; - for (auto &&frame : item->curve().keyframes()) { - QPointF pos = frame.position(); - group.setValue(QVariant(pos.y()), pos.x()); + } else if (auto *pitem = item->asPropertyItem()) { + QmlTimeline currentTimeline = activeTimeline(); + QmlTimelineKeyframeGroup group = timelineKeyframeGroup(currentTimeline, pitem); - if (previous.isValid()) { - if (frame.interpolation() == DesignTools::Keyframe::Interpolation::Bezier) { - DesignTools::CurveSegment segment(previous, frame); - if (segment.isValid()) - attachEasingCurve1(pos.x(), segment.easingCurve(), group); - } else if (frame.interpolation() == DesignTools::Keyframe::Interpolation::Easing) { - QVariant data = frame.data(); - if (data.type() == static_cast(QMetaType::QEasingCurve)) - attachEasingCurve1(pos.x(), data.value(), group); - } else if (frame.interpolation() == DesignTools::Keyframe::Interpolation::Step) { - // Warning: Keyframe::Interpolation::Step not yet implemented + if (group.isValid()) { + ModelNode groupNode = group.modelNode(); + commitAuxiliaryData(groupNode, item); + + auto replaceKeyframes = [&group, pitem, this]() { + m_block = true; + for (auto frame : group.keyframes()) + frame.destroy(); + + Keyframe previous; + for (auto &&frame : pitem->curve().keyframes()) { + QPointF pos = frame.position(); + group.setValue(QVariant(pos.y()), pos.x()); + + if (previous.isValid()) { + if (frame.interpolation() == Keyframe::Interpolation::Bezier) { + CurveSegment segment(previous, frame); + if (segment.isValid()) + attachEasingCurve(group, pos.x(), segment.easingCurve()); + } else if (frame.interpolation() == Keyframe::Interpolation::Easing) { + QVariant data = frame.data(); + if (data.type() == static_cast(QMetaType::QEasingCurve)) + attachEasingCurve(group, pos.x(), data.value()); + } else if (frame.interpolation() == Keyframe::Interpolation::Step) { + // Warning: Keyframe::Interpolation::Step not yet implemented + } } + + previous = frame; } + m_block = false; + }; - previous = frame; - } - m_block = false; - }; - - executeInTransaction("CurveEditor::commitKeyframes", replaceKeyframes); + executeInTransaction("CurveEditor::commitKeyframes", replaceKeyframes); + } } } diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.h b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.h index 5da7c4514b9..e774d2bc434 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.h +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.h @@ -59,6 +59,10 @@ public: const NodeAbstractProperty &oldPropertyParent, PropertyChangeFlags propertyChange) override; + void auxiliaryDataChanged(const ModelNode &node, + const PropertyName &name, + const QVariant &data) override; + void instancePropertyChanged(const QList> &propertyList) override; void variantPropertiesChanged(const QList &propertyList, @@ -77,15 +81,15 @@ private: void updateStartFrame(const ModelNode &node); void updateEndFrame(const ModelNode &node); - void commitKeyframes(DesignTools::PropertyTreeItem *item); + void commitKeyframes(TreeItem *item); void commitCurrentFrame(int frame); void commitStartFrame(int frame); void commitEndFrame(int frame); private: bool m_block; - DesignTools::CurveEditorModel *m_model; - DesignTools::CurveEditor *m_editor; + CurveEditorModel *m_model; + CurveEditor *m_editor; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/curveeditor/curvesegment.cpp b/src/plugins/qmldesigner/components/curveeditor/curvesegment.cpp index 578edf8fea1..75d956c666c 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curvesegment.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curvesegment.cpp @@ -33,7 +33,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { class CubicPolynomial { @@ -566,4 +566,4 @@ void CurveSegment::setInterpolation(const Keyframe::Interpolation &interpol) } } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/curvesegment.h b/src/plugins/qmldesigner/components/curveeditor/curvesegment.h index 9d496b613ec..11257b93639 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curvesegment.h +++ b/src/plugins/qmldesigner/components/curveeditor/curvesegment.h @@ -36,7 +36,7 @@ class QEasingCurve; class QPainterPath; QT_END_NAMESPACE -namespace DesignTools { +namespace QmlDesigner { class CurveSegment { @@ -97,4 +97,4 @@ private: Keyframe m_right; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/axis.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/axis.cpp index 6e18e49a269..7087a5d7efd 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/axis.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/axis.cpp @@ -29,7 +29,7 @@ #include #include -namespace DesignTools { +namespace QmlDesigner { // The following is based on: "An Extension of Wilkinson's Algorithm for Positioning Tick Labels on Axes" // by Justin Talbot, Sharon Lin and Pat Hanrahan. @@ -210,4 +210,4 @@ Axis Axis::compute(double dmin, double dmax, double height, double pt) return result; } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/axis.h b/src/plugins/qmldesigner/components/curveeditor/detail/axis.h index ee8c197748d..fcb90beb5ef 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/axis.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/axis.h @@ -28,7 +28,7 @@ #include #include -namespace DesignTools { +namespace QmlDesigner { struct Axis { @@ -39,4 +39,4 @@ struct Axis double lstep; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/colorcontrol.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/colorcontrol.cpp index a833a4c6ff3..f8587df06fe 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/colorcontrol.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/colorcontrol.cpp @@ -30,7 +30,9 @@ #include #include -namespace DesignTools { +namespace QmlDesigner { + +namespace StyleEditor { ColorControl::ColorControl() : QWidget(nullptr) @@ -98,4 +100,6 @@ void ColorControl::mousePressEvent(QMouseEvent *event) event->accept(); } -} // End namespace DesignTools. +} // End namespace StyleEditor. + +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/colorcontrol.h b/src/plugins/qmldesigner/components/curveeditor/detail/colorcontrol.h index 54dfe194f88..cb687370f56 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/colorcontrol.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/colorcontrol.h @@ -27,7 +27,9 @@ #include -namespace DesignTools { +namespace QmlDesigner { + +namespace StyleEditor { class ColorControl : public QWidget { @@ -60,4 +62,6 @@ private: QColor m_color; }; -} // End namespace DesignTools. +} // End namespace StyleEditor. + +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/curveeditorstyledialog.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/curveeditorstyledialog.cpp index 32df0a8230f..90ca8f91fba 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/curveeditorstyledialog.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/curveeditorstyledialog.cpp @@ -33,7 +33,7 @@ #include #include -namespace DesignTools { +namespace QmlDesigner { QHBoxLayout *createRow(const QString &title, QWidget *widget) { @@ -50,35 +50,35 @@ QHBoxLayout *createRow(const QString &title, QWidget *widget) CurveEditorStyleDialog::CurveEditorStyleDialog(CurveEditorStyle &style, QWidget *parent) : QDialog(parent) , m_printButton(new QPushButton("Print")) - , m_background(new ColorControl(style.backgroundBrush.color())) - , m_backgroundAlternate(new ColorControl(style.backgroundAlternateBrush.color())) - , m_fontColor(new ColorControl(style.fontColor)) - , m_gridColor(new ColorControl(style.gridColor)) + , m_background(new StyleEditor::ColorControl(style.backgroundBrush.color())) + , m_backgroundAlternate(new StyleEditor::ColorControl(style.backgroundAlternateBrush.color())) + , m_fontColor(new StyleEditor::ColorControl(style.fontColor)) + , m_gridColor(new StyleEditor::ColorControl(style.gridColor)) , m_canvasMargin(new QDoubleSpinBox()) , m_zoomInWidth(new QSpinBox()) , m_zoomInHeight(new QSpinBox()) , m_timeAxisHeight(new QDoubleSpinBox()) , m_timeOffsetLeft(new QDoubleSpinBox()) , m_timeOffsetRight(new QDoubleSpinBox()) - , m_rangeBarColor(new ColorControl(style.rangeBarCapsColor)) - , m_rangeBarCapsColor(new ColorControl(style.rangeBarCapsColor)) + , m_rangeBarColor(new StyleEditor::ColorControl(style.rangeBarCapsColor)) + , m_rangeBarCapsColor(new StyleEditor::ColorControl(style.rangeBarCapsColor)) , m_valueAxisWidth(new QDoubleSpinBox()) , m_valueOffsetTop(new QDoubleSpinBox()) , m_valueOffsetBottom(new QDoubleSpinBox()) , m_handleSize(new QDoubleSpinBox()) , m_handleLineWidth(new QDoubleSpinBox()) - , m_handleColor(new ColorControl(style.handleStyle.color)) - , m_handleSelectionColor(new ColorControl(style.handleStyle.selectionColor)) + , m_handleColor(new StyleEditor::ColorControl(style.handleStyle.color)) + , m_handleSelectionColor(new StyleEditor::ColorControl(style.handleStyle.selectionColor)) , m_keyframeSize(new QDoubleSpinBox()) - , m_keyframeColor(new ColorControl(style.keyframeStyle.color)) - , m_keyframeSelectionColor(new ColorControl(style.keyframeStyle.selectionColor)) + , m_keyframeColor(new StyleEditor::ColorControl(style.keyframeStyle.color)) + , m_keyframeSelectionColor(new StyleEditor::ColorControl(style.keyframeStyle.selectionColor)) , m_curveWidth(new QDoubleSpinBox()) - , m_curveColor(new ColorControl(style.curveStyle.color)) - , m_curveSelectionColor(new ColorControl(style.curveStyle.selectionColor)) + , m_curveColor(new StyleEditor::ColorControl(style.curveStyle.color)) + , m_curveSelectionColor(new StyleEditor::ColorControl(style.curveStyle.selectionColor)) , m_treeMargins(new QDoubleSpinBox()) , m_playheadWidth(new QDoubleSpinBox()) , m_playheadRadius(new QDoubleSpinBox()) - , m_playheadColor(new ColorControl(style.playhead.color)) + , m_playheadColor(new StyleEditor::ColorControl(style.playhead.color)) { setWindowFlag(Qt::Tool, true); @@ -111,35 +111,35 @@ CurveEditorStyleDialog::CurveEditorStyleDialog(CurveEditorStyle &style, QWidget auto intSignal = static_cast(&QSpinBox::valueChanged); auto doubleSignal = static_cast(&QDoubleSpinBox::valueChanged); - connect(m_background, &ColorControl::valueChanged, colorChanged); - connect(m_backgroundAlternate, &ColorControl::valueChanged, colorChanged); - connect(m_fontColor, &ColorControl::valueChanged, colorChanged); - connect(m_gridColor, &ColorControl::valueChanged, colorChanged); + connect(m_background, &StyleEditor::ColorControl::valueChanged, colorChanged); + connect(m_backgroundAlternate, &StyleEditor::ColorControl::valueChanged, colorChanged); + connect(m_fontColor, &StyleEditor::ColorControl::valueChanged, colorChanged); + connect(m_gridColor, &StyleEditor::ColorControl::valueChanged, colorChanged); connect(m_canvasMargin, doubleSignal, doubleChanged); connect(m_zoomInWidth, intSignal, intChanged); connect(m_zoomInHeight, intSignal, intChanged); connect(m_timeAxisHeight, doubleSignal, doubleChanged); connect(m_timeOffsetLeft, doubleSignal, doubleChanged); connect(m_timeOffsetRight, doubleSignal, doubleChanged); - connect(m_rangeBarColor, &ColorControl::valueChanged, colorChanged); - connect(m_rangeBarCapsColor, &ColorControl::valueChanged, colorChanged); + connect(m_rangeBarColor, &StyleEditor::ColorControl::valueChanged, colorChanged); + connect(m_rangeBarCapsColor, &StyleEditor::ColorControl::valueChanged, colorChanged); connect(m_valueAxisWidth, doubleSignal, doubleChanged); connect(m_valueOffsetTop, doubleSignal, doubleChanged); connect(m_valueOffsetBottom, doubleSignal, doubleChanged); connect(m_handleSize, doubleSignal, doubleChanged); connect(m_handleLineWidth, doubleSignal, doubleChanged); - connect(m_handleColor, &ColorControl::valueChanged, colorChanged); - connect(m_handleSelectionColor, &ColorControl::valueChanged, colorChanged); + connect(m_handleColor, &StyleEditor::ColorControl::valueChanged, colorChanged); + connect(m_handleSelectionColor, &StyleEditor::ColorControl::valueChanged, colorChanged); connect(m_keyframeSize, doubleSignal, doubleChanged); - connect(m_keyframeColor, &ColorControl::valueChanged, colorChanged); - connect(m_keyframeSelectionColor, &ColorControl::valueChanged, colorChanged); + connect(m_keyframeColor, &StyleEditor::ColorControl::valueChanged, colorChanged); + connect(m_keyframeSelectionColor, &StyleEditor::ColorControl::valueChanged, colorChanged); connect(m_curveWidth, doubleSignal, doubleChanged); - connect(m_curveColor, &ColorControl::valueChanged, colorChanged); - connect(m_curveSelectionColor, &ColorControl::valueChanged, colorChanged); + connect(m_curveColor, &StyleEditor::ColorControl::valueChanged, colorChanged); + connect(m_curveSelectionColor, &StyleEditor::ColorControl::valueChanged, colorChanged); connect(m_treeMargins, doubleSignal, doubleChanged); connect(m_playheadWidth, doubleSignal, doubleChanged); connect(m_playheadRadius, doubleSignal, doubleChanged); - connect(m_playheadColor, &ColorControl::valueChanged, colorChanged); + connect(m_playheadColor, &StyleEditor::ColorControl::valueChanged, colorChanged); auto *box = new QVBoxLayout; box->addLayout(createRow("Background Color", m_background)); @@ -266,4 +266,4 @@ void CurveEditorStyleDialog::printStyle() qDebug() << ""; } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/curveeditorstyledialog.h b/src/plugins/qmldesigner/components/curveeditor/detail/curveeditorstyledialog.h index f1dc3bc3728..8b876aca961 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/curveeditorstyledialog.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/curveeditorstyledialog.h @@ -34,9 +34,11 @@ class QSpinBox; class QDoubleSpinBox; QT_END_NAMESPACE -namespace DesignTools { +namespace QmlDesigner { +namespace StyleEditor { class ColorControl; +} struct CurveEditorStyle; @@ -60,13 +62,13 @@ private: private: QPushButton *m_printButton; - ColorControl *m_background; + StyleEditor::ColorControl *m_background; - ColorControl *m_backgroundAlternate; + StyleEditor::ColorControl *m_backgroundAlternate; - ColorControl *m_fontColor; + StyleEditor::ColorControl *m_fontColor; - ColorControl *m_gridColor; + StyleEditor::ColorControl *m_gridColor; QDoubleSpinBox *m_canvasMargin; @@ -80,9 +82,9 @@ private: QDoubleSpinBox *m_timeOffsetRight; - ColorControl *m_rangeBarColor; + StyleEditor::ColorControl *m_rangeBarColor; - ColorControl *m_rangeBarCapsColor; + StyleEditor::ColorControl *m_rangeBarCapsColor; QDoubleSpinBox *m_valueAxisWidth; @@ -95,23 +97,23 @@ private: QDoubleSpinBox *m_handleLineWidth; - ColorControl *m_handleColor; + StyleEditor::ColorControl *m_handleColor; - ColorControl *m_handleSelectionColor; + StyleEditor::ColorControl *m_handleSelectionColor; // KeyframeItem QDoubleSpinBox *m_keyframeSize; - ColorControl *m_keyframeColor; + StyleEditor::ColorControl *m_keyframeColor; - ColorControl *m_keyframeSelectionColor; + StyleEditor::ColorControl *m_keyframeSelectionColor; // CurveItem QDoubleSpinBox *m_curveWidth; - ColorControl *m_curveColor; + StyleEditor::ColorControl *m_curveColor; - ColorControl *m_curveSelectionColor; + StyleEditor::ColorControl *m_curveSelectionColor; // TreeItem QDoubleSpinBox *m_treeMargins; @@ -121,7 +123,7 @@ private: QDoubleSpinBox *m_playheadRadius; - ColorControl *m_playheadColor; + StyleEditor::ColorControl *m_playheadColor; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp index 90818be74bd..0e9d11a9741 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp @@ -35,13 +35,13 @@ #include #include -namespace DesignTools { +namespace QmlDesigner { CurveItem::CurveItem(QGraphicsItem *parent) : CurveEditorItem(parent) , m_id(0) , m_style() - , m_type(ValueType::Undefined) + , m_type(PropertyTreeItem::ValueType::Undefined) , m_component(PropertyTreeItem::Component::Generic) , m_transform() , m_keyframes() @@ -52,7 +52,7 @@ CurveItem::CurveItem(unsigned int id, const AnimationCurve &curve, QGraphicsItem : CurveEditorItem(parent) , m_id(id) , m_style() - , m_type(ValueType::Undefined) + , m_type(PropertyTreeItem::ValueType::Undefined) , m_component(PropertyTreeItem::Component::Generic) , m_transform() , m_keyframes() @@ -225,7 +225,7 @@ unsigned int CurveItem::id() const return m_id; } -ValueType CurveItem::valueType() const +PropertyTreeItem::ValueType CurveItem::valueType() const { return m_type; } @@ -385,7 +385,7 @@ void CurveItem::setHandleVisibility(bool visible) frame->setHandleVisibility(visible); } -void CurveItem::setValueType(ValueType type) +void CurveItem::setValueType(PropertyTreeItem::ValueType type) { m_type = type; } @@ -508,4 +508,4 @@ void CurveItem::emitCurveChanged() update(); } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h index 20708d66c80..00a3a9c3604 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h @@ -35,7 +35,7 @@ #include #include -namespace DesignTools { +namespace QmlDesigner { class AnimationCurve; class KeyframeItem; @@ -89,7 +89,7 @@ public: unsigned int id() const; - ValueType valueType() const; + PropertyTreeItem::ValueType valueType() const; PropertyTreeItem::Component component() const; @@ -113,7 +113,7 @@ public: void setHandleVisibility(bool visible); - void setValueType(ValueType type); + void setValueType(PropertyTreeItem::ValueType type); void setComponent(PropertyTreeItem::Component comp); @@ -140,7 +140,7 @@ private: CurveItemStyleOption m_style; - ValueType m_type; + PropertyTreeItem::ValueType m_type; PropertyTreeItem::Component m_component; @@ -151,4 +151,4 @@ private: bool m_itemDirty; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp index e9f9050f625..d6db50fee73 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp @@ -33,7 +33,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { GraphicsScene::GraphicsScene(QObject *parent) : QGraphicsScene(parent) @@ -236,9 +236,34 @@ void GraphicsScene::doNotMoveItems(bool val) m_doNotMoveItems = val; } +void GraphicsScene::removeCurveItem(unsigned int id) +{ + CurveItem *tmp = nullptr; + for (auto *curve : m_curves) { + if (curve->id() == id) { + removeItem(curve); + tmp = curve; + break; + } + } + + if (tmp) { + Q_UNUSED(m_curves.removeOne(tmp)); + delete tmp; + } + + m_dirty = true; +} + void GraphicsScene::addCurveItem(CurveItem *item) { - m_dirty = true; + for (auto *curve : m_curves) { + if (curve->id() == item->id()) { + delete item; + return; + } + } + item->setDirty(false); item->connect(this); addItem(item); @@ -249,6 +274,8 @@ void GraphicsScene::addCurveItem(CurveItem *item) m_curves.push_back(item); resetZValues(); + + m_dirty = true; } void GraphicsScene::moveToBottom(CurveItem *item) @@ -449,4 +476,4 @@ void GraphicsScene::resetZValues() } } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h index c19f72b1309..2e5da41bc66 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h @@ -29,7 +29,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { class AnimationCurve; class CurveItem; @@ -95,6 +95,8 @@ public: void doNotMoveItems(bool tmp); + void removeCurveItem(unsigned int id); + void addCurveItem(CurveItem *item); void moveToBottom(CurveItem *item); @@ -140,4 +142,4 @@ private: bool m_doNotMoveItems; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp index c162b5fd906..b27015aa97f 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp @@ -40,7 +40,7 @@ #include #include -namespace DesignTools { +namespace QmlDesigner { GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent) : QGraphicsView(parent) @@ -75,18 +75,15 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent) connect(m_scene, &GraphicsScene::curveChanged, itemSlot); - auto pinSlot = [this](PropertyTreeItem *pti) { m_scene->setPinned(pti->id(), pti->pinned()); }; - connect(m_model, &CurveEditorModel::curveChanged, pinSlot); - - applyZoom(m_zoomX, m_zoomY); - update(); - QmlDesigner::Navigation2dFilter *filter = new QmlDesigner::Navigation2dFilter(this); auto zoomChanged = &QmlDesigner::Navigation2dFilter::zoomChanged; connect(filter, zoomChanged, [this](double scale, const QPointF &pos) { applyZoom(m_zoomX + scale, m_zoomY, mapToGlobal(pos.toPoint())); }); installEventFilter(filter); + + applyZoom(m_zoomX, m_zoomY); + update(); } GraphicsView::~GraphicsView() @@ -189,19 +186,62 @@ void GraphicsView::setStyle(const CurveEditorStyle &style) viewport()->update(); } -void GraphicsView::setLocked(PropertyTreeItem *item) +void GraphicsView::setLocked(TreeItem *item) { - if (CurveItem *curve = m_scene->findCurve(item->id())) { - if (item->locked()) { - curve->setLocked(true); - m_scene->moveToBottom(curve); - } else { - curve->setLocked(false); - m_scene->moveToTop(curve); + if (item->asNodeItem()) { + for (auto *ci : item->children()) + setLocked(ci); + } else if (item->asPropertyItem()) { + if (CurveItem *curve = m_scene->findCurve(item->id())) { + if (item->locked() || item->implicitlyLocked()) { + curve->setLocked(true); + m_scene->moveToBottom(curve); + } else { + curve->setLocked(false); + m_scene->moveToTop(curve); + } } } } +void GraphicsView::setPinned(TreeItem *item) +{ + auto pin = [this](PropertyTreeItem *pitem, bool pinned) { + if (pinned) { + if (CurveItem *curve = m_scene->findCurve(pitem->id())) + curve->setPinned(pinned); + else if (CurveItem *citem = TreeModel::curveItem(pitem)) + m_scene->addCurveItem(citem); + } else if (!pinned) { + if (!m_model->isSelected(pitem) && !pitem->pinned()) + m_scene->removeCurveItem(pitem->id()); + else if (CurveItem *curve = m_scene->findCurve(pitem->id())) + curve->setPinned(pinned); + } + }; + + if (auto *pitem = item->asPropertyItem()) { + pin(pitem, pitem->pinned() || pitem->implicitlyPinned()); + } else if (auto *nitem = item->asNodeItem()) { + bool pinned = nitem->pinned(); + if (!pinned && m_model->isSelected(nitem)) { + for (auto *i : nitem->children()) { + if (CurveItem *curve = m_scene->findCurve(i->id())) + curve->setPinned(pinned); + } + return; + } + + for (auto *i : nitem->children()) { + if (auto *pitem = i->asPropertyItem()) + pin(pitem, pinned); + } + } + + applyZoom(m_zoomX, m_zoomY); + viewport()->update(); +} + void GraphicsView::setZoomX(double zoom, const QPoint &pivot) { applyZoom(zoom, m_zoomY, pivot); @@ -228,8 +268,8 @@ void GraphicsView::scrollContent(double x, double y) { QScrollBar *hs = horizontalScrollBar(); QScrollBar *vs = verticalScrollBar(); - hs->setValue(hs->value() + x); - vs->setValue(vs->value() + y); + hs->setValue(hs->value() + static_cast(x)); + vs->setValue(vs->value() + static_cast(y)); } void GraphicsView::reset(const std::vector &items) @@ -242,15 +282,19 @@ void GraphicsView::reset(const std::vector &items) viewport()->update(); } -void GraphicsView::updateSelection(const std::vector &items) +void GraphicsView::updateSelection() { std::vector preservedItems = m_scene->takePinnedItems(); - for (auto *curve : items) { + std::vector deleteItems; + for (auto *curve : m_model->selectedCurves()) { auto finder = [curve](CurveItem *item) { return curve->id() == item->id(); }; auto iter = std::find_if(preservedItems.begin(), preservedItems.end(), finder); if (iter == preservedItems.end()) preservedItems.push_back(curve); + else + deleteItems.push_back(curve); } + freeClear(deleteItems); reset(preservedItems); } @@ -304,7 +348,8 @@ void GraphicsView::mousePressEvent(QMouseEvent *event) QPointF pos = mapToScene(event->pos()); if (timeScaleRect().contains(pos)) { m_dragging = true; - setCurrentFrame(std::round(mapXtoTime(pos.x()))); + double t = mapXtoTime(static_cast(pos.x())); + setCurrentFrame(roundToInt(t)); m_playhead.setMoving(true); event->accept(); return; @@ -398,19 +443,18 @@ void GraphicsView::drawForeground(QPainter *painter, const QRectF &rect) void GraphicsView::drawBackground(QPainter *painter, const QRectF &rect) { painter->fillRect(rect, m_style.backgroundBrush); - painter->fillRect(scene()->sceneRect(), m_style.backgroundAlternateBrush); - drawGrid(painter, rect); + drawGrid(painter); } int GraphicsView::mapTimeToX(double time) const { - return std::round(time * scaleX(m_transform)); + return roundToInt(time * scaleX(m_transform)); } int GraphicsView::mapValueToY(double y) const { - return std::round(y * scaleY(m_transform)); + return roundToInt(y * scaleY(m_transform)); } double GraphicsView::mapXtoTime(int x) const @@ -430,7 +474,7 @@ QPointF GraphicsView::globalToScene(const QPoint &point) const QPointF GraphicsView::globalToRaster(const QPoint &point) const { - QPointF scene = globalToScene(point); + QPoint scene = globalToScene(point).toPoint(); return QPointF(mapXtoTime(scene.x()), mapYtoValue(scene.y())); } @@ -480,7 +524,7 @@ void GraphicsView::applyZoom(double x, double y, const QPoint &pivot) m_scene->doNotMoveItems(false); } -void GraphicsView::drawGrid(QPainter *painter, const QRectF &rect) +void GraphicsView::drawGrid(QPainter *painter) { QRectF gridRect = scene()->sceneRect(); @@ -488,12 +532,16 @@ void GraphicsView::drawGrid(QPainter *painter, const QRectF &rect) return; auto drawVerticalLine = [painter, gridRect](double position) { - painter->drawLine(position, gridRect.top(), position, gridRect.bottom()); + QPointF p1(position, gridRect.top()); + QPointF p2(position, gridRect.bottom()); + painter->drawLine(p1, p2); }; painter->save(); painter->setPen(m_style.gridColor); + painter->fillRect(gridRect, m_style.backgroundAlternateBrush); + double timeIncrement = timeLabelInterval(painter, m_model->maximumTime()); for (double i = minimumTime(); i <= maximumTime(); i += timeIncrement) drawVerticalLine(mapTimeToX(i)); @@ -635,7 +683,7 @@ double GraphicsView::timeLabelInterval(QPainter *painter, double maxTime) double tickDistance = mapTimeToX(deltaTime); while (true) { - if (tickDistance == 0 && deltaTime >= maxTime) + if (qFuzzyCompare(tickDistance, 0.) && deltaTime >= maxTime) return maxTime; if (tickDistance > minTextSpacing) @@ -658,12 +706,12 @@ QRectF GraphicsView::rangeMinHandle(const QRectF &rect) QRectF labelRect = fontMetrics().boundingRect(QString("0")); labelRect.moveCenter(rect.center()); - qreal top = rect.bottom() - 2; - qreal bottom = labelRect.bottom() + 2; - QSize size(10, top - bottom); + qreal top = rect.bottom() - 2.; + qreal bottom = labelRect.bottom() + 2.; + QSize size(10, roundToInt(top - bottom)); - int leftHandleLeft = mapTimeToX(m_model->minimumTime()) - size.width(); - return QRectF(QPointF(leftHandleLeft, bottom), size); + int handle = mapTimeToX(m_model->minimumTime()) - size.width(); + return QRectF(QPointF(handle, bottom), size); } QRectF GraphicsView::rangeMaxHandle(const QRectF &rect) @@ -671,10 +719,13 @@ QRectF GraphicsView::rangeMaxHandle(const QRectF &rect) QRectF labelRect = fontMetrics().boundingRect(QString("0")); labelRect.moveCenter(rect.center()); - qreal bottom = rect.bottom() - 2; - qreal top = labelRect.bottom() + 2; + qreal bottom = rect.bottom() - 2.; + qreal top = labelRect.bottom() + 2.; - return QRectF(QPointF(mapTimeToX(m_model->maximumTime()), bottom), QSize(10, top - bottom)); + QSize size(10, roundToInt(top - bottom)); + int handle = mapTimeToX(m_model->maximumTime()); + + return QRectF(QPointF(handle, bottom), size); } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h index 374109feb94..c2d2b0c714a 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h @@ -33,12 +33,12 @@ #include -namespace DesignTools { +namespace QmlDesigner { class CurveItem; class CurveEditorModel; class Playhead; -class PropertyTreeItem; +class TreeItem; class GraphicsView : public QGraphicsView { @@ -92,7 +92,9 @@ public: QRectF defaultRasterRect() const; - void setLocked(PropertyTreeItem *item); + void setLocked(TreeItem *item); + + void setPinned(TreeItem *item); void setStyle(const CurveEditorStyle &style); @@ -106,7 +108,7 @@ public: void reset(const std::vector &items); - void updateSelection(const std::vector &items); + void updateSelection(); void setInterpolation(Keyframe::Interpolation interpol); @@ -134,7 +136,7 @@ protected: private: void applyZoom(double x, double y, const QPoint &pivot = QPoint()); - void drawGrid(QPainter *painter, const QRectF &rect); + void drawGrid(QPainter *painter); #if 0 void drawExtremaX(QPainter *painter, const QRectF &rect); @@ -176,4 +178,4 @@ private: CurveEditorStyleDialog m_dialog; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.cpp index 0fdb00ff1b0..6d9dbe85d5d 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.cpp @@ -31,7 +31,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { struct HandleGeometry { @@ -196,4 +196,4 @@ QVariant HandleItem::itemChange(QGraphicsItem::GraphicsItemChange change, const return QGraphicsItem::itemChange(change, value); } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.h b/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.h index 62d48d8ffc2..efa55f8abf2 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.h @@ -28,7 +28,7 @@ #include "curveeditorstyle.h" #include "selectableitem.h" -namespace DesignTools { +namespace QmlDesigner { class KeyframeItem; class CurveSegment; @@ -77,4 +77,4 @@ private: QPointF m_validPos; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp index aba8648f7df..025f5eb6eda 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp @@ -31,7 +31,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { KeyframeItem::KeyframeItem(QGraphicsItem *parent) : SelectableItem(parent) @@ -408,9 +408,9 @@ QVariant KeyframeItem::itemChange(QGraphicsItem::GraphicsItemChange change, cons if (ok) { position.setX(std::round(position.x())); - if (curveItem->valueType() == ValueType::Integer) + if (curveItem->valueType() == PropertyTreeItem::ValueType::Integer) position.setY(std::round(position.y())); - else if (curveItem->valueType() == ValueType::Bool) + else if (curveItem->valueType() == PropertyTreeItem::ValueType::Bool) position.setY(position.y() > 0.5 ? 1.0 : 0.0); if (!legalLeft() || !legalRight()) { @@ -463,4 +463,4 @@ void KeyframeItem::selectionCallback() m_right->setSelected(selected()); } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h index 73e008aa2a8..c0d33640278 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h @@ -32,7 +32,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { class HandleItem; @@ -134,4 +134,4 @@ private: bool m_visibleOverride = true; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/playhead.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/playhead.cpp index e59c9f012e8..481370eb61e 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/playhead.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/playhead.cpp @@ -34,7 +34,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { constexpr double g_playheadMargin = 5.0; @@ -149,6 +149,7 @@ void Playhead::mouseMoveOutOfBounds(GraphicsView *view) void Playhead::mouseRelease(GraphicsView *view) { + Q_UNUSED(view); m_moving = false; } @@ -188,4 +189,4 @@ void Playhead::paint(QPainter *painter, GraphicsView *view) const painter->restore(); } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/playhead.h b/src/plugins/qmldesigner/components/curveeditor/detail/playhead.h index 9f6295c34a7..b45ecfea706 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/playhead.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/playhead.h @@ -32,7 +32,7 @@ QT_BEGIN_NAMESPACE class QPainter; QT_END_NAMESPACE -namespace DesignTools { +namespace QmlDesigner { class GraphicsView; @@ -69,4 +69,4 @@ private: QTimer m_timer; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.cpp index 5db5d0c14b0..d6b9c4c4a16 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.cpp @@ -26,7 +26,7 @@ #include "selectableitem.h" #include "keyframeitem.h" -namespace DesignTools { +namespace QmlDesigner { CurveEditorItem::CurveEditorItem(QGraphicsItem *parent) : QGraphicsObject(parent) @@ -193,4 +193,4 @@ void SelectableItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) activationCallback(); } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.h b/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.h index 920c13a9388..f985094608b 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/selectableitem.h @@ -27,7 +27,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { class CurveEditorItem : public QGraphicsObject { @@ -58,13 +58,14 @@ enum ItemType { ItemTypeCurve = QGraphicsItem::UserType + 3 }; -enum class SelectionMode : unsigned int { Undefined, Clear, New, Add, Remove, Toggle }; class SelectableItem : public CurveEditorItem { Q_OBJECT public: + enum class SelectionMode : unsigned int { Undefined, Clear, New, Add, Remove, Toggle }; + SelectableItem(QGraphicsItem *parent = nullptr); ~SelectableItem() override; @@ -102,4 +103,4 @@ private: SelectionMode m_preSelected; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/selectionmodel.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/selectionmodel.cpp index d35b0c31422..8b2e650b9d8 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/selectionmodel.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/selectionmodel.cpp @@ -27,7 +27,7 @@ #include "curveitem.h" #include "treemodel.h" -namespace DesignTools { +namespace QmlDesigner { SelectionModel::SelectionModel(QAbstractItemModel *model) : QItemSelectionModel(model) @@ -46,10 +46,19 @@ void SelectionModel::select(const QItemSelection &selection, } } +bool SelectionModel::isSelected(TreeItem *item) const +{ + for (auto *i : selectedTreeItems()) + if (i->id() == item->id()) + return true; + + return false; +} + std::vector SelectionModel::selectedPaths() const { std::vector out; - for (auto &&item : selectedTreeItems()) + for (auto *item : selectedTreeItems()) out.push_back(item->path()); return out; } @@ -112,20 +121,11 @@ void SelectionModel::selectPaths(const std::vector &selection) } } -void SelectionModel::changeSelection(const QItemSelection &selected, - const QItemSelection &deselected) +void SelectionModel::changeSelection(const QItemSelection &selected, const QItemSelection &deselected) { Q_UNUSED(selected) Q_UNUSED(deselected) - - std::vector curves; - const auto ids = selectedIndexes(); - for (auto &&index : ids) { - if (auto *curveItem = TreeModel::curveItem(index)) - curves.push_back(curveItem); - } - - emit curvesSelected(curves); + emit curvesSelected(); } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/selectionmodel.h b/src/plugins/qmldesigner/components/curveeditor/detail/selectionmodel.h index ff4a0bbf2fa..d0cfe4e0de2 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/selectionmodel.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/selectionmodel.h @@ -30,7 +30,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { class TreeItem; class NodeTreeItem; @@ -41,13 +41,14 @@ class SelectionModel : public QItemSelectionModel Q_OBJECT signals: - void curvesSelected(const std::vector &curves); + void curvesSelected(); public: SelectionModel(QAbstractItemModel *model = nullptr); - void select(const QItemSelection &selection, - QItemSelectionModel::SelectionFlags command) override; + void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override; + + bool isSelected(TreeItem *item) const; std::vector selectedPaths() const; @@ -65,4 +66,4 @@ private: void changeSelection(const QItemSelection &selected, const QItemSelection &deselected); }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/selector.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/selector.cpp index dd948a6ac28..a1bc1d268cf 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/selector.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/selector.cpp @@ -36,7 +36,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { Selector::Selector() {} @@ -139,7 +139,7 @@ void Selector::mouseRelease(QMouseEvent *event, GraphicsScene *scene) bool Selector::select(const SelectionTool &tool, const QPointF &pos, GraphicsScene *scene) { auto selectWidthTool = [this, - tool](SelectionMode mode, const QPointF &pos, GraphicsScene *scene) { + tool](SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene) { switch (tool) { case SelectionTool::Lasso: return lassoSelection(mode, pos, scene); @@ -152,19 +152,19 @@ bool Selector::select(const SelectionTool &tool, const QPointF &pos, GraphicsSce if (m_shortcut == m_shortcuts.newSelection) { clearSelection(scene); - return selectWidthTool(SelectionMode::New, pos, scene); + return selectWidthTool(SelectableItem::SelectionMode::New, pos, scene); } else if (m_shortcut == m_shortcuts.addToSelection) { - return selectWidthTool(SelectionMode::Add, pos, scene); + return selectWidthTool(SelectableItem::SelectionMode::Add, pos, scene); } else if (m_shortcut == m_shortcuts.removeFromSelection) { - return selectWidthTool(SelectionMode::Remove, pos, scene); + return selectWidthTool(SelectableItem::SelectionMode::Remove, pos, scene); } else if (m_shortcut == m_shortcuts.toggleSelection) { - return selectWidthTool(SelectionMode::Toggle, pos, scene); + return selectWidthTool(SelectableItem::SelectionMode::Toggle, pos, scene); } return false; } -bool Selector::pressSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene) +bool Selector::pressSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene) { bool out = false; const auto itemList = scene->items(); @@ -190,7 +190,7 @@ bool Selector::pressSelection(SelectionMode mode, const QPointF &pos, GraphicsSc return out; } -bool Selector::rectangleSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene) +bool Selector::rectangleSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene) { bool out = false; m_rect.setBottomRight(pos); @@ -201,14 +201,14 @@ bool Selector::rectangleSelection(SelectionMode mode, const QPointF &pos, Graphi keyframeItem->setPreselected(mode); out = true; } else { - keyframeItem->setPreselected(SelectionMode::Undefined); + keyframeItem->setPreselected(SelectableItem::SelectionMode::Undefined); } } } return out; } -bool Selector::lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene) +bool Selector::lassoSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene) { bool out = false; m_lasso.lineTo(pos); @@ -219,7 +219,7 @@ bool Selector::lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsSc keyframeItem->setPreselected(mode); out = true; } else { - keyframeItem->setPreselected(SelectionMode::Undefined); + keyframeItem->setPreselected(SelectableItem::SelectionMode::Undefined); } } } @@ -231,7 +231,7 @@ void Selector::clearSelection(GraphicsScene *scene) const auto itemList = scene->items(); for (auto *item : itemList) { if (auto *frameItem = qgraphicsitem_cast(item)) { - frameItem->setPreselected(SelectionMode::Clear); + frameItem->setPreselected(SelectableItem::SelectionMode::Clear); frameItem->applyPreselection(); frameItem->setActivated(false, HandleItem::Slot::Left); frameItem->setActivated(false, HandleItem::Slot::Right); @@ -248,4 +248,4 @@ void Selector::applyPreSelection(GraphicsScene *scene) } } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/selector.h b/src/plugins/qmldesigner/components/curveeditor/detail/selector.h index 68674c838de..bd3562f28c2 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/selector.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/selector.h @@ -28,14 +28,12 @@ #include "curveeditorstyle.h" #include "selectableitem.h" -namespace DesignTools { +namespace QmlDesigner { class GraphicsView; class GraphicsScene; class Playhead; -enum class SelectionTool { Undefined, Lasso, Rectangle }; - class Selector { public: @@ -50,13 +48,15 @@ public: void mouseRelease(QMouseEvent *event, GraphicsScene *scene); private: + enum class SelectionTool { Undefined, Lasso, Rectangle }; + bool select(const SelectionTool &tool, const QPointF &pos, GraphicsScene *scene); - bool pressSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene); + bool pressSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene); - bool rectangleSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene); + bool rectangleSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene); - bool lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene); + bool lassoSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene); void clearSelection(GraphicsScene *scene); @@ -77,4 +77,4 @@ private: QRectF m_rect; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/shortcut.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/shortcut.cpp index d6d04dbbae8..93007f494c6 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/shortcut.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/shortcut.cpp @@ -24,7 +24,7 @@ ****************************************************************************/ #include "shortcut.h" -namespace DesignTools { +namespace QmlDesigner { Shortcut::Shortcut() : m_key() @@ -78,4 +78,4 @@ bool Shortcut::operator==(const Shortcut &other) const return m_key == other.m_key && m_buttons == other.m_buttons && m_modifiers == other.m_modifiers; } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/shortcut.h b/src/plugins/qmldesigner/components/curveeditor/detail/shortcut.h index a9e075bd8b7..904c153de3c 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/shortcut.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/shortcut.h @@ -27,7 +27,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { class Shortcut { @@ -58,4 +58,4 @@ private: Qt::KeyboardModifiers m_modifiers; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/treeitemdelegate.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/treeitemdelegate.cpp index 2f6a941a204..bd57eeaaf89 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/treeitemdelegate.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/treeitemdelegate.cpp @@ -24,13 +24,14 @@ ****************************************************************************/ #include "treeitemdelegate.h" #include "treeitem.h" +#include "treemodel.h" #include #include #include #include -namespace DesignTools { +namespace QmlDesigner { TreeItemDelegate::TreeItemDelegate(const CurveEditorStyle &style, QObject *parent) : QStyledItemDelegate(parent) @@ -50,56 +51,66 @@ QRect makeSquare(const QRect &rect) return r; } -QPixmap pixmapFromStyle(int column, const CurveEditorStyle &style, const QRect &rect, TreeItem *item, bool underMouse) -{ - QColor color = underMouse ? style.iconHoverColor : style.iconColor; - if (column == 1) { - bool locked = item->locked(); - if (underMouse) - locked = !locked; - - if (locked) - return pixmapFromIcon(style.treeItemStyle.lockedIcon, rect.size(), color); - else - return pixmapFromIcon(style.treeItemStyle.unlockedIcon, rect.size(), color); - } - - bool pinned = item->pinned(); - if (underMouse) - pinned = !pinned; - - if (pinned) - return pixmapFromIcon(style.treeItemStyle.pinnedIcon, rect.size(), color); - else - return pixmapFromIcon(style.treeItemStyle.unpinnedIcon, rect.size(), color); -} - void TreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { - if (index.column() == 1 || index.column() == 2) { - QStyleOptionViewItem opt = option; - initStyleOption(&opt, index); + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); - auto *treeItem = static_cast(index.internalPointer()); + QColor high = Theme::getColor(Theme::Color::QmlDesigner_HighlightColor); + opt.palette.setColor(QPalette::Active, QPalette::Highlight, high); + opt.palette.setColor(QPalette::Inactive, QPalette::Highlight, high); - QPoint mousePos = QCursor::pos(); - mousePos = option.widget->mapFromGlobal(mousePos); + QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); + style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); - QRect iconRect = makeSquare(option.rect); - bool underMouse = option.rect.contains(m_mousePos) - && option.state & QStyle::State_MouseOver; + auto *treeItem = static_cast(index.internalPointer()); - QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); - style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); + bool textColumn = TreeModel::isTextColumn(index); + bool lockedColumn = TreeModel::isLockedColumn(index); + bool pinnedColumn = TreeModel::isPinnedColumn(index); - QPixmap pixmap = pixmapFromStyle(index.column(), m_style, iconRect, treeItem, underMouse); - painter->drawPixmap(iconRect, pixmap); + QPixmap pixmap; + QRect iconRect = makeSquare(option.rect); + + if (lockedColumn) { + if (treeItem->locked()) { + pixmap = m_style.treeItemStyle.lockedIcon.pixmap(iconRect.size()); + } else if (treeItem->asNodeItem() != nullptr && treeItem->implicitlyLocked()) { + pixmap = m_style.treeItemStyle.implicitlyLockedIcon.pixmap(iconRect.size()); + } else if (option.state.testFlag(QStyle::State_MouseOver)) { + if (treeItem->implicitlyLocked()) { + pixmap = m_style.treeItemStyle.implicitlyLockedIcon.pixmap(iconRect.size()); + } else { + pixmap = m_style.treeItemStyle.unlockedIcon.pixmap(iconRect.size()); + } + } + + } else if (pinnedColumn) { + if (treeItem->pinned()) { + pixmap = m_style.treeItemStyle.pinnedIcon.pixmap(iconRect.size()); + } else if (treeItem->asNodeItem() != nullptr && treeItem->implicitlyPinned()) { + pixmap = m_style.treeItemStyle.implicitlyPinnedIcon.pixmap(iconRect.size()); + } else if (option.state.testFlag(QStyle::State_MouseOver)) { + if (treeItem->implicitlyPinned()) { + pixmap = m_style.treeItemStyle.implicitlyPinnedIcon.pixmap(iconRect.size()); + } else { + pixmap = m_style.treeItemStyle.unpinnedIcon.pixmap(iconRect.size()); + } + } } else { - QStyledItemDelegate::paint(painter, option, index); + if (textColumn && (treeItem->locked() || treeItem->implicitlyLocked())) { + QColor col = opt.palette.color(QPalette::Disabled, QPalette::Text).darker(); + opt.palette.setColor(QPalette::Active, QPalette::Text, col); + opt.palette.setColor(QPalette::Inactive, QPalette::Text, col); + } + QStyledItemDelegate::paint(painter, opt, index); } + + if (!pixmap.isNull()) + painter->drawPixmap(iconRect, pixmap); } void TreeItemDelegate::setStyle(const CurveEditorStyle &style) @@ -118,4 +129,4 @@ bool TreeItemDelegate::editorEvent(QEvent *event, return QStyledItemDelegate::editorEvent(event, model, option, index); } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/treeitemdelegate.h b/src/plugins/qmldesigner/components/curveeditor/detail/treeitemdelegate.h index 6479f48942b..f265061c2d0 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/treeitemdelegate.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/treeitemdelegate.h @@ -29,7 +29,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { class TreeItemDelegate : public QStyledItemDelegate { @@ -60,4 +60,4 @@ private: QPoint m_mousePos; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/treemodel.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/treemodel.cpp index 075934a3ef9..c4b6845f51f 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/treemodel.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/treemodel.cpp @@ -31,7 +31,22 @@ #include -namespace DesignTools { +namespace QmlDesigner { + +bool TreeModel::isTextColumn(const QModelIndex &index) +{ + return index.column() == 0; +} + +bool TreeModel::isLockedColumn(const QModelIndex &index) +{ + return index.column() == 1; +} + +bool TreeModel::isPinnedColumn(const QModelIndex &index) +{ + return index.column() == 2; +} TreeItem *TreeModel::treeItem(const QModelIndex &index) { @@ -71,8 +86,8 @@ CurveItem *TreeModel::curveItem(TreeItem *item) auto *citem = new CurveItem(pti->id(), pti->curve()); citem->setValueType(pti->valueType()); citem->setComponent(pti->component()); - citem->setLocked(pti->locked()); - citem->setPinned(pti->pinned()); + citem->setLocked(pti->locked() || item->implicitlyLocked()); + citem->setPinned(pti->pinned() || item->implicitlyPinned()); return citem; } @@ -183,6 +198,11 @@ void TreeModel::setGraphicsView(GraphicsView *view) m_view = view; } +TreeView *TreeModel::treeView() const +{ + return m_tree; +} + GraphicsView *TreeModel::graphicsView() const { return m_view; @@ -208,6 +228,36 @@ QModelIndex TreeModel::findIdx(const QString &name, const QModelIndex &parent) c return QModelIndex(); } +bool TreeModel::isSelected(TreeItem *item) const +{ + if (auto *sm = selectionModel()) + return sm->isSelected(item); + + return false; +} + +void addCurvesFromItem(TreeItem *item, std::vector &curves) +{ + if (auto *pitem = item->asPropertyItem()) { + if (auto *curveItem = TreeModel::curveItem(pitem)) + curves.push_back(curveItem); + } else if (auto *nitem = item->asNodeItem()) { + for (auto *child : nitem->children()) + addCurvesFromItem(child, curves); + } +} + +std::vector TreeModel::selectedCurves() const +{ + std::vector curves; + const auto ids = selectionModel()->selectedIndexes(); + for (auto &&index : ids) { + if (auto *treeItem = TreeModel::treeItem(index)) + addCurvesFromItem(treeItem, curves); + } + return curves; +} + QModelIndex TreeModel::indexOf(const TreeItem::Path &path) const { QModelIndex parent; @@ -238,4 +288,9 @@ TreeItem *TreeModel::find(unsigned int id) return m_root->find(id); } -} // End namespace DesignTools. +TreeItem *TreeModel::find(const QString &id) +{ + return m_root->find(id); +} + +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/treemodel.h b/src/plugins/qmldesigner/components/curveeditor/detail/treemodel.h index e8cf12f74fb..0f86a0f5de8 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/treemodel.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/treemodel.h @@ -31,13 +31,11 @@ #include -namespace DesignTools { +namespace QmlDesigner { class GraphicsView; class TreeView; -class TreeItem; class CurveItem; -class PropertyTreeItem; class SelectionModel; class TreeModel : public QAbstractItemModel @@ -45,6 +43,12 @@ class TreeModel : public QAbstractItemModel Q_OBJECT public: + static bool isTextColumn(const QModelIndex &index); + + static bool isLockedColumn(const QModelIndex &index); + + static bool isPinnedColumn(const QModelIndex &index); + static TreeItem *treeItem(const QModelIndex &index); static NodeTreeItem *nodeItem(const QModelIndex &index); @@ -73,13 +77,23 @@ public: int columnCount(const QModelIndex &parent = QModelIndex()) const override; + bool isSelected(TreeItem *item) const; + + std::vector selectedCurves() const; + QModelIndex indexOf(const TreeItem::Path &path) const; + TreeItem *find(unsigned int id); + + TreeItem *find(const QString &id); + void setTreeView(TreeView *view); void setGraphicsView(GraphicsView *view); protected: + TreeView *treeView() const; + GraphicsView *graphicsView() const; SelectionModel *selectionModel() const; @@ -88,8 +102,6 @@ protected: TreeItem *root(); - TreeItem *find(unsigned int id); - QModelIndex findIdx(const QString &name, const QModelIndex &parent) const; private: @@ -100,4 +112,4 @@ private: TreeItem *m_root; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/treeview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/treeview.cpp index 6db2afab754..5b8df0e5701 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/treeview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/treeview.cpp @@ -28,11 +28,12 @@ #include "selectionmodel.h" #include "treeitem.h" #include "treeitemdelegate.h" +#include "treemodel.h" #include #include -namespace DesignTools { +namespace QmlDesigner { TreeView::TreeView(CurveEditorModel *model, QWidget *parent) : QTreeView(parent) @@ -105,17 +106,12 @@ void TreeView::mousePressEvent(QMouseEvent *event) QModelIndex index = indexAt(event->pos()); if (index.isValid()) { auto *treeItem = static_cast(index.internalPointer()); - if (index.column() == 1) { - treeItem->setLocked(!treeItem->locked()); - if (auto *propertyItem = treeItem->asPropertyItem()) - emit treeItemLocked(propertyItem); - } else if (index.column() == 2) { - treeItem->setPinned(!treeItem->pinned()); - if (auto *propertyItem = treeItem->asPropertyItem()) - emit treeItemPinned(propertyItem); - } + if (TreeModel::isLockedColumn(index)) + emit treeItemLocked(treeItem, !treeItem->locked()); + else if (TreeModel::isPinnedColumn(index)) + emit treeItemPinned(treeItem, !treeItem->pinned()); } QTreeView::mousePressEvent(event); } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/treeview.h b/src/plugins/qmldesigner/components/curveeditor/detail/treeview.h index 338ab6f052b..31886d5b74c 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/treeview.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/treeview.h @@ -30,7 +30,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { class AnimationCurve; class CurveEditorModel; @@ -44,9 +44,9 @@ class TreeView : public QTreeView signals: void curvesSelected(const std::vector &curves); - void treeItemLocked(PropertyTreeItem *item); + void treeItemLocked(TreeItem *item, bool val); - void treeItemPinned(PropertyTreeItem *item); + void treeItemPinned(TreeItem *item, bool val); public: TreeView(CurveEditorModel *model, QWidget *parent = nullptr); @@ -63,4 +63,4 @@ protected: void mousePressEvent(QMouseEvent *event) override; }; -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/utils.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/utils.cpp index f255cfd29e8..6cc6fce31d8 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/utils.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/utils.cpp @@ -29,7 +29,7 @@ #include #include -namespace DesignTools { +namespace QmlDesigner { double scaleX(const QTransform &transform) { @@ -92,4 +92,4 @@ QPalette singleColorPalette(const QColor &color) return palette; } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/utils.h b/src/plugins/qmldesigner/components/curveeditor/detail/utils.h index 4a236c76b96..2200cda8587 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/utils.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/utils.h @@ -26,6 +26,7 @@ #pragma once #include +#include QT_BEGIN_NAMESPACE class QColor; @@ -37,7 +38,7 @@ QT_END_NAMESPACE #include -namespace DesignTools { +namespace QmlDesigner { double scaleX(const QTransform &transform); @@ -58,7 +59,7 @@ inline void freeClear(T &vec) } template -inline double clamp(const TV &val, const TC &lo, const TC &hi) +inline TV clamp(const TV &val, const TC &lo, const TC &hi) { return val < lo ? lo : (val > hi ? hi : val); } @@ -75,4 +76,10 @@ inline T reverseLerp(double blend, const T &a, const T &b) return (blend - b) / (a - b); } -} // End namespace DesignTools. +template +inline int roundToInt(const T &val) +{ + return static_cast(std::round(val)); +} + +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp b/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp index d0a411e849c..02b2adc6366 100644 --- a/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp @@ -27,7 +27,7 @@ #include -namespace DesignTools { +namespace QmlDesigner { Keyframe::Keyframe() : m_interpolation(Interpolation::Undefined) @@ -193,4 +193,4 @@ std::string toString(Keyframe::Interpolation interpol) } } -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/keyframe.h b/src/plugins/qmldesigner/components/curveeditor/keyframe.h index 3aef8ed085a..d16e7d7a011 100644 --- a/src/plugins/qmldesigner/components/curveeditor/keyframe.h +++ b/src/plugins/qmldesigner/components/curveeditor/keyframe.h @@ -28,7 +28,7 @@ #include #include -namespace DesignTools { +namespace QmlDesigner { class Keyframe { @@ -93,4 +93,4 @@ private: std::string toString(Keyframe::Interpolation interpol); -} // End namespace DesignTools. +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/treeitem.cpp b/src/plugins/qmldesigner/components/curveeditor/treeitem.cpp index cd8b113c4b3..0b90d7d83b0 100644 --- a/src/plugins/qmldesigner/components/curveeditor/treeitem.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/treeitem.cpp @@ -28,7 +28,7 @@ #include #include -namespace DesignTools { +namespace QmlDesigner { TreeItem::TreeItem(const QString &name) : m_name(name) @@ -123,9 +123,9 @@ bool TreeItem::compare(const std::vector &path) const int TreeItem::row() const { if (m_parent) { - for (int i = 0, total = int(m_parent->m_children.size()); i < total; ++i) { + for (size_t i = 0, total = m_parent->m_children.size(); i < total; ++i) { if (m_parent->m_children[i] == this) - return i; + return static_cast(i); } } @@ -147,6 +147,17 @@ int TreeItem::columnCount() const return 3; } +TreeItem *TreeItem::root() const +{ + TreeItem *p = parent(); + while (p) { + if (!p->parent()) + return p; + p = p->parent(); + } + return p; +} + TreeItem *TreeItem::parent() const { return m_parent; @@ -154,10 +165,10 @@ TreeItem *TreeItem::parent() const TreeItem *TreeItem::child(int row) const { - if (row < 0 || row >= static_cast(m_children.size())) + if (row < 0 || row >= rowCount()) return nullptr; - return m_children.at(row); + return m_children.at(static_cast(row)); } TreeItem *TreeItem::find(unsigned int id) const @@ -173,6 +184,24 @@ TreeItem *TreeItem::find(unsigned int id) const return nullptr; } +TreeItem *TreeItem::find(const QString &id) const +{ + for (auto *child : m_children) { + if (child->name() == id) + return child; + + if (auto *childsChild = child->find(id)) + return childsChild; + } + + return nullptr; +} + +std::vector TreeItem::children() const +{ + return m_children; +} + QVariant TreeItem::data(int column) const { switch (column) { @@ -205,6 +234,11 @@ QVariant TreeItem::headerData(int column) const } } +bool TreeItem::operator==(unsigned int id) const +{ + return m_id == id; +} + void TreeItem::setId(unsigned int &id) { m_id = id; @@ -229,9 +263,10 @@ void TreeItem::setPinned(bool pinned) m_pinned = pinned; } -NodeTreeItem::NodeTreeItem(const QString &name, const QIcon &icon) +NodeTreeItem::NodeTreeItem(const QString &name, const QIcon &icon, const std::vector &parentIds) : TreeItem(name) , m_icon(icon) + , m_parentIds(parentIds) { Q_UNUSED(icon) } @@ -241,6 +276,35 @@ NodeTreeItem *NodeTreeItem::asNodeItem() return this; } +bool NodeTreeItem::implicitlyLocked() const +{ + TreeItem *r = root(); + if (!r) + return false; + + for (auto &&id : m_parentIds) { + if (TreeItem *item = r->find(id)) + if (item->locked()) + return true; + } + + return false; +} + +bool NodeTreeItem::implicitlyPinned() const +{ + TreeItem *r = root(); + if (!r) + return false; + + for (auto &&id : m_parentIds) { + if (TreeItem *item = r->find(id)) + if (item->pinned()) + return true; + } + return false; +} + QIcon NodeTreeItem::icon() const { return m_icon; @@ -257,20 +321,6 @@ std::vector NodeTreeItem::properties() const return out; } -std::string toString(ValueType type) -{ - switch (type) { - case ValueType::Bool: - return "Bool"; - case ValueType::Integer: - return "Integer"; - case ValueType::Double: - return "Double"; - default: - return "Undefined"; - } -} - PropertyTreeItem::PropertyTreeItem(const QString &name, const AnimationCurve &curve, const ValueType &type) @@ -280,6 +330,22 @@ PropertyTreeItem::PropertyTreeItem(const QString &name, , m_curve(curve) {} +bool PropertyTreeItem::implicitlyLocked() const +{ + if (auto *parentNode = parentNodeTreeItem()) + return parentNode->locked() || parentNode->implicitlyLocked(); + + return false; +} + +bool PropertyTreeItem::implicitlyPinned() const +{ + if (auto *parentNode = parentNodeTreeItem()) + return parentNode->pinned() || parentNode->implicitlyPinned(); + + return false; +} + PropertyTreeItem *PropertyTreeItem::asPropertyItem() { return this; @@ -296,7 +362,7 @@ const NodeTreeItem *PropertyTreeItem::parentNodeTreeItem() const return nullptr; } -ValueType PropertyTreeItem::valueType() const +PropertyTreeItem::ValueType PropertyTreeItem::valueType() const { return m_type; } @@ -331,4 +397,18 @@ void PropertyTreeItem::setComponent(const Component &comp) m_component = comp; } -} // End namespace DesignTools. +std::string toString(PropertyTreeItem::ValueType type) +{ + switch (type) { + case PropertyTreeItem::ValueType::Bool: + return "Bool"; + case PropertyTreeItem::ValueType::Integer: + return "Integer"; + case PropertyTreeItem::ValueType::Double: + return "Double"; + default: + return "Undefined"; + } +} + +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/treeitem.h b/src/plugins/qmldesigner/components/curveeditor/treeitem.h index 64448af9e5a..60538778092 100644 --- a/src/plugins/qmldesigner/components/curveeditor/treeitem.h +++ b/src/plugins/qmldesigner/components/curveeditor/treeitem.h @@ -38,7 +38,7 @@ class QIcon; class QVariant; QT_END_NAMESPACE -namespace DesignTools { +namespace QmlDesigner { class NodeTreeItem; class PropertyTreeItem; @@ -48,6 +48,10 @@ class TreeItem public: using Path = std::vector; + virtual bool implicitlyLocked() const { return false; } + + virtual bool implicitlyPinned() const { return false; } + public: TreeItem(const QString &name); @@ -81,16 +85,24 @@ public: int columnCount() const; + TreeItem *root() const; + TreeItem *parent() const; TreeItem *child(int row) const; - TreeItem *find(unsigned int row) const; + TreeItem *find(unsigned int id) const; + + TreeItem *find(const QString &id) const; + + std::vector children() const; QVariant data(int column) const; QVariant headerData(int column) const; + bool operator==(unsigned int id) const; + void setId(unsigned int &id); void addChild(TreeItem *child); @@ -116,37 +128,45 @@ protected: class NodeTreeItem : public TreeItem { public: - NodeTreeItem(const QString &name, const QIcon &icon); + NodeTreeItem(const QString &name, const QIcon &icon, const std::vector &parentIds); NodeTreeItem *asNodeItem() override; + bool implicitlyLocked() const override; + + bool implicitlyPinned() const override; + QIcon icon() const override; std::vector properties() const; private: QIcon m_icon; -}; -enum class ValueType { - Undefined, - Bool, - Integer, - Double, + std::vector m_parentIds; }; -std::string toString(ValueType type); - class PropertyTreeItem : public TreeItem { public: enum class Component { Generic, R, G, B, A, X, Y, Z, W }; + enum class ValueType { + Undefined, + Bool, + Integer, + Double, + }; + public: PropertyTreeItem(const QString &name, const AnimationCurve &curve, const ValueType &type); PropertyTreeItem *asPropertyItem() override; + bool implicitlyLocked() const override; + + bool implicitlyPinned() const override; + const NodeTreeItem *parentNodeTreeItem() const; ValueType valueType() const; @@ -173,4 +193,6 @@ private: AnimationCurve m_curve; }; -} // End namespace DesignTools. +std::string toString(PropertyTreeItem::ValueType type); + +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp index ca00b66f462..cfb946a95df 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp @@ -184,20 +184,18 @@ void ItemLibraryAssetImporter::processFinished(int exitCode, QProcess::ExitStatu Q_UNUSED(exitCode) Q_UNUSED(exitStatus) - auto process = qobject_cast(sender()); - if (process) { - m_qmlPuppetProcesses.erase( - std::remove_if(m_qmlPuppetProcesses.begin(), - m_qmlPuppetProcesses.end(), - [&](const auto &entry) { return entry.get() == process; })); - const QString progressTitle = tr("Generating icons."); - if (m_qmlPuppetProcesses.empty()) { - notifyProgress(100, progressTitle); - finalizeQuick3DImport(); - } else { - notifyProgress(int(100. * (1. - double(m_qmlPuppetCount) / double(m_qmlPuppetProcesses.size()))), - progressTitle); - } + m_qmlPuppetProcesses.erase( + std::remove_if(m_qmlPuppetProcesses.begin(), m_qmlPuppetProcesses.end(), [&](const auto &entry) { + return !entry || entry->state() == QProcess::NotRunning; + })); + + const QString progressTitle = tr("Generating icons."); + if (m_qmlPuppetProcesses.empty()) { + notifyProgress(100, progressTitle); + finalizeQuick3DImport(); + } else { + notifyProgress(int(100. * (1. - double(m_qmlPuppetCount) / double(m_qmlPuppetProcesses.size()))), + progressTitle); } } diff --git a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.cpp b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.cpp index 0cf73976a84..107a0940ebc 100644 --- a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.cpp +++ b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.cpp @@ -131,6 +131,9 @@ void ListModelEditorDialog::removeColumns() void ListModelEditorDialog::changeHeader(int column) { + if (column < 0) + return; + const QString propertyName = QString::fromUtf8(m_model->propertyNames()[column]); bool ok; diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index f02e41fc863..16cb7e50ea7 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -247,19 +247,19 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const } else if (index.column() == ColumnType::Alias) { // export if (role == Qt::CheckStateRole) return currentQmlObjectNode.isAliasExported() ? Qt::Checked : Qt::Unchecked; - else if (role == Qt::ToolTipRole) + else if (role == Qt::ToolTipRole && !modelNodeForIndex(index).isRootNode()) return tr("Toggles whether this item is exported as an " "alias property of the root item."); } else if (index.column() == ColumnType::Visibility) { // visible if (role == Qt::CheckStateRole) return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked; - else if (role == Qt::ToolTipRole) + else if (role == Qt::ToolTipRole && !modelNodeForIndex(index).isRootNode()) return tr("Toggles the visibility of this item in the form editor.\n" "This is independent of the visibility property in QML."); } else if (index.column() == ColumnType::Lock) { // lock if (role == Qt::CheckStateRole) return modelNode.locked() ? Qt::Checked : Qt::Unchecked; - else if (role == Qt::ToolTipRole) + else if (role == Qt::ToolTipRole && !modelNodeForIndex(index).isRootNode()) return tr("Toggles whether this item is locked.\n" "Locked items can't be modified or selected."); } @@ -269,6 +269,14 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const Qt::ItemFlags NavigatorTreeModel::flags(const QModelIndex &index) const { + if (modelNodeForIndex(index).isRootNode()) { + Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled; + if (index.column() == ColumnType::Name) + return flags | Qt::ItemIsEditable; + else + return flags; + } + if (index.column() == ColumnType::Alias || index.column() == ColumnType::Visibility || index.column() == ColumnType::Lock) diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.h b/src/plugins/qmldesigner/components/navigator/navigatorview.h index 451de3be71c..b78c9e612a2 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.h +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.h @@ -43,7 +43,7 @@ QT_END_NAMESPACE namespace QmlDesigner { -static int delegateMargin = 2; +const int delegateMargin = 2; class NavigatorWidget; class NavigatorTreeModel; diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp index 6c7c15451de..9e125bceb4d 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp @@ -347,41 +347,6 @@ void TimelineWidget::scroll(const TimelineUtils::Side &side) m_scrollbar->setValue(m_scrollbar->value() + m_scrollbar->singleStep()); } -ModelNode getTargetNode(DesignTools::PropertyTreeItem *item, const QmlTimeline &timeline) -{ - if (const DesignTools::NodeTreeItem *nodeItem = item->parentNodeTreeItem()) { - QString targetId = nodeItem->name(); - if (timeline.isValid()) { - for (auto &&target : timeline.allTargets()) { - if (target.displayName() == targetId) - return target; - } - } - } - return ModelNode(); -} - -QmlTimelineKeyframeGroup timelineKeyframeGroup(QmlTimeline &timeline, - DesignTools::PropertyTreeItem *item) -{ - ModelNode node = getTargetNode(item, timeline); - if (node.isValid()) - return timeline.keyframeGroup(node, item->name().toLatin1()); - - return QmlTimelineKeyframeGroup(); -} - -void attachEasingCurve(double frame, - const QEasingCurve &curve, - const QmlTimelineKeyframeGroup &group) -{ - ModelNode frameNode = group.keyframe(frame); - if (frameNode.isValid()) { - auto expression = EasingCurve(curve).toString(); - frameNode.bindingProperty("easing.bezierCurve").setExpression(expression); - } -} - void TimelineWidget::selectionChanged() { if (graphicsScene()->hasSelection()) diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.cpp b/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.cpp index a6783fbf489..5b8f737515a 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.cpp +++ b/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.cpp @@ -32,14 +32,23 @@ namespace QmlDesigner { +ImageCacheGenerator::ImageCacheGenerator(ImageCacheCollectorInterface &collector, + ImageCacheStorageInterface &storage) + : m_collector{collector} + , m_storage(storage) +{ + m_backgroundThread.reset(QThread::create([this]() { startGeneration(); })); + m_backgroundThread->start(); +} + ImageCacheGenerator::~ImageCacheGenerator() { - std::lock_guard threadLock{*m_threadMutex.get()}; + clean(); + stopThread(); + m_condition.notify_all(); if (m_backgroundThread) m_backgroundThread->wait(); - - clean(); } void ImageCacheGenerator::generateImage(Utils::SmallStringView name, @@ -48,50 +57,32 @@ void ImageCacheGenerator::generateImage(Utils::SmallStringView name, AbortCallback &&abortCallback) { { - std::lock_guard lock{m_dataMutex}; + std::lock_guard lock{m_mutex}; m_tasks.emplace_back(name, timeStamp, std::move(captureCallback), std::move(abortCallback)); } - startGenerationAsynchronously(); + m_condition.notify_all(); } void ImageCacheGenerator::clean() { - std::lock_guard dataLock{m_dataMutex}; + std::lock_guard lock{m_mutex}; + for (Task &task : m_tasks) + task.abortCallback(); m_tasks.clear(); } -class ReleaseProcessing +void ImageCacheGenerator::startGeneration() { -public: - ReleaseProcessing(std::atomic_flag &processing) - : m_processing(processing) - { - m_processing.test_and_set(std::memory_order_acquire); - } + while (isRunning()) { + waitForEntries(); - ~ReleaseProcessing() { m_processing.clear(std::memory_order_release); } - -private: - std::atomic_flag &m_processing; -}; - -void ImageCacheGenerator::startGeneration(std::shared_ptr threadMutex) -{ - ReleaseProcessing guard(m_processing); - - while (true) { Task task; { - std::unique_lock threadLock{*threadMutex.get(), std::defer_lock_t{}}; + std::lock_guard lock{m_mutex}; - if (!threadLock.try_lock()) - return; - - std::lock_guard dataLock{m_dataMutex}; - - if (m_tasks.empty()) { + if (m_finishing) { m_storage.walCheckpointFull(); return; } @@ -103,15 +94,7 @@ void ImageCacheGenerator::startGeneration(std::shared_ptr threadMute m_collector.start( task.filePath, - [this, threadMutex, task](QImage &&image) { - std::unique_lock lock{*threadMutex.get(), std::defer_lock_t{}}; - - if (!lock.try_lock()) - return; - - if (threadMutex.use_count() == 1) - return; - + [this, task](QImage &&image) { if (image.isNull()) task.abortCallback(); else @@ -119,41 +102,34 @@ void ImageCacheGenerator::startGeneration(std::shared_ptr threadMute m_storage.storeImage(std::move(task.filePath), task.timeStamp, image); }, - [this, threadMutex, task] { - std::unique_lock lock{*threadMutex.get(), std::defer_lock_t{}}; - - if (!lock.try_lock()) - return; - - if (threadMutex.use_count() == 1) - return; - + [this, task] { task.abortCallback(); m_storage.storeImage(std::move(task.filePath), task.timeStamp, {}); }); + + std::lock_guard lock{m_mutex}; + if (m_tasks.empty()) + m_storage.walCheckpointFull(); } } -void ImageCacheGenerator::startGenerationAsynchronously() +void ImageCacheGenerator::waitForEntries() { - if (m_processing.test_and_set(std::memory_order_acquire)) - return; + std::unique_lock lock{m_mutex}; + if (m_tasks.empty()) + m_condition.wait(lock, [&] { return m_tasks.size() || m_finishing; }); +} - std::unique_lock lock{*m_threadMutex.get(), std::defer_lock_t{}}; +void ImageCacheGenerator::stopThread() +{ + std::unique_lock lock{m_mutex}; + m_finishing = true; +} - if (!lock.try_lock()) - return; - - if (m_backgroundThread) - m_backgroundThread->wait(); - - m_backgroundThread.reset(QThread::create( - [this](std::shared_ptr threadMutex) { startGeneration(threadMutex); }, - m_threadMutex)); - m_backgroundThread->start(); - // m_backgroundThread = std::thread( - // [this](std::shared_ptr threadMutex) { startGeneration(threadMutex); }, - // m_threadMutex); +bool ImageCacheGenerator::isRunning() +{ + std::unique_lock lock{m_mutex}; + return !m_finishing; } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.h b/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.h index 207622714b6..945d53eabe5 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.h +++ b/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.h @@ -46,10 +46,7 @@ class ImageCacheStorageInterface; class ImageCacheGenerator final : public ImageCacheGeneratorInterface { public: - ImageCacheGenerator(ImageCacheCollectorInterface &collector, ImageCacheStorageInterface &storage) - : m_collector{collector} - , m_storage(storage) - {} + ImageCacheGenerator(ImageCacheCollectorInterface &collector, ImageCacheStorageInterface &storage); ~ImageCacheGenerator(); @@ -79,17 +76,21 @@ private: Sqlite::TimeStamp timeStamp; }; - void startGeneration(std::shared_ptr threadMutex); - void startGenerationAsynchronously(); + void startGeneration(); + + void waitForEntries(); + void stopThread(); + bool isRunning(); +private: private: std::unique_ptr m_backgroundThread; - std::mutex m_dataMutex; - std::shared_ptr m_threadMutex{std::make_shared()}; + mutable std::mutex m_mutex; + std::condition_variable m_condition; std::vector m_tasks; ImageCacheCollectorInterface &m_collector; ImageCacheStorageInterface &m_storage; - std::atomic_flag m_processing = ATOMIC_FLAG_INIT; + bool m_finishing{false}; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/nodelistproperty.h b/src/plugins/qmldesigner/designercore/include/nodelistproperty.h index dc1967efec0..b10a5a45fd9 100644 --- a/src/plugins/qmldesigner/designercore/include/nodelistproperty.h +++ b/src/plugins/qmldesigner/designercore/include/nodelistproperty.h @@ -51,9 +51,12 @@ public: const QList toModelNodeList() const; const QList toQmlObjectNodeList() const; void slide(int, int) const; + void swap(int, int) const; void reparentHere(const ModelNode &modelNode); ModelNode at(int index) const; + static void reverseModelNodes(const QList &nodes); + protected: NodeListProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view); NodeListProperty(const Internal::InternalNodeListPropertyPointer &internalNodeListProperty, Model* model, AbstractView *view); diff --git a/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp b/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp index 84864e5e518..8271bad362b 100644 --- a/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp @@ -32,7 +32,7 @@ #include "model_p.h" #include - +#include namespace QmlDesigner { @@ -95,12 +95,30 @@ void NodeListProperty::slide(int from, int to) const Internal::WriteLocker locker(model()); if (!isValid()) throw InvalidPropertyException(__LINE__, __FUNCTION__, __FILE__, ""); - if (to > count() - 1) + if (to < 0 || to > count() - 1 || from < 0 || from > count() - 1) throw InvalidPropertyException(__LINE__, __FUNCTION__, __FILE__, ""); privateModel()->changeNodeOrder(internalNode(), name(), from, to); } +void NodeListProperty::swap(int from, int to) const +{ + if (from == to) + return; + + // Prerequisite a < b + int a = from; + int b = to; + + if (a > b) { + a = to; + b = from; + } + + slide(b, a); + slide(a + 1, b); +} + void NodeListProperty::reparentHere(const ModelNode &modelNode) { NodeAbstractProperty::reparentHere(modelNode, true); @@ -119,4 +137,24 @@ ModelNode NodeListProperty::at(int index) const return ModelNode(); } +void NodeListProperty::reverseModelNodes(const QList &nodes) +{ + ModelNode firstNode = nodes.first(); + if (!firstNode.isValid()) + return; + + NodeListProperty parentProperty = firstNode.parentProperty().toNodeListProperty(); + std::vector selectedNodeIndices; + + for (ModelNode modelNode : nodes) + selectedNodeIndices.push_back(parentProperty.indexOf(modelNode)); + + std::sort(selectedNodeIndices.begin(), selectedNodeIndices.end()); + + int mid = std::ceil(selectedNodeIndices.size() / 2); + + for (int i = 0; i != mid; ++i) + parentProperty.swap(selectedNodeIndices[i], selectedNodeIndices[selectedNodeIndices.size() - 1 - i]); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index 2bb61467a91..e45d4ef2bd7 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -273,11 +273,11 @@ void DesignModeWidget::setup() // Setup Actions and Menus Core::ActionContainer *mview = Core::ActionManager::actionContainer(Core::Constants::M_VIEW); - // Window > Views + // View > Views Core::ActionContainer *mviews = Core::ActionManager::createMenu(Core::Constants::M_VIEW_VIEWS); mviews->menu()->addSeparator(); - // Window > Workspaces - Core::ActionContainer *mworkspaces = Core::ActionManager::createMenu(QmlDesigner::Constants::M_WINDOW_WORKSPACES); + // View > Workspaces + Core::ActionContainer *mworkspaces = Core::ActionManager::createMenu(QmlDesigner::Constants::M_VIEW_WORKSPACES); mview->addMenu(mworkspaces, Core::Constants::G_VIEW_VIEWS); mworkspaces->menu()->setTitle(tr("&Workspaces")); mworkspaces->setOnAllDisabledBehavior(Core::ActionContainer::Show); @@ -488,7 +488,7 @@ void DesignModeWidget::setup() void DesignModeWidget::aboutToShowWorkspaces() { - Core::ActionContainer *aci = Core::ActionManager::actionContainer(QmlDesigner::Constants::M_WINDOW_WORKSPACES); + Core::ActionContainer *aci = Core::ActionManager::actionContainer(QmlDesigner::Constants::M_VIEW_WORKSPACES); QMenu *menu = aci->menu(); menu->clear(); diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 950cfa43122..c32f5b62ecf 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -73,7 +73,7 @@ const char DEFAULT_ASSET_IMPORT_FOLDER[] = "/asset_imports"; const char QT_QUICK_3D_MODULE_NAME[] = "QtQuick3D"; // Menus -const char M_WINDOW_WORKSPACES[] = "QmlDesigner.Menu.Window.Workspaces"; +const char M_VIEW_WORKSPACES[] = "QmlDesigner.Menu.View.Workspaces"; const int MODELNODE_PREVIEW_IMAGE_DIMENSIONS = 150; diff --git a/src/plugins/qtsupport/exampleslistmodel.cpp b/src/plugins/qtsupport/exampleslistmodel.cpp index 9c895db6269..a983752838e 100644 --- a/src/plugins/qtsupport/exampleslistmodel.cpp +++ b/src/plugins/qtsupport/exampleslistmodel.cpp @@ -513,7 +513,7 @@ QPixmap ExamplesListModel::fetchPixmapAndUpdatePixmapCache(const QString &url) c if (!fetchedData.isEmpty()) { QBuffer imgBuffer(&fetchedData); imgBuffer.open(QIODevice::ReadOnly); - QImageReader reader(&imgBuffer); + QImageReader reader(&imgBuffer, QFileInfo(url).suffix().toLatin1()); QImage img = reader.read(); img = ScreenshotCropper::croppedImage(img, url, ListModel::defaultImageSize); pixmap = QPixmap::fromImage(img); diff --git a/src/plugins/qtsupport/qtcreator_tutorials.xml b/src/plugins/qtsupport/qtcreator_tutorials.xml index cfb994c4527..362d87fd77f 100644 --- a/src/plugins/qtsupport/qtcreator_tutorials.xml +++ b/src/plugins/qtsupport/qtcreator_tutorials.xml @@ -62,6 +62,10 @@ qt creator,qt quick,bindings,quick tip,qml,video,2020 + + + qt creator,qt quick,3D,FBX,quick tip,video,2020 + qt creator,qt quick,slider,quick tip,controls,video,2020 diff --git a/src/plugins/studiowelcome/CMakeLists.txt b/src/plugins/studiowelcome/CMakeLists.txt index c82b4fa2361..b04caf2a6d4 100644 --- a/src/plugins/studiowelcome/CMakeLists.txt +++ b/src/plugins/studiowelcome/CMakeLists.txt @@ -1,11 +1,3 @@ -set(qmlQrcFile "${CMAKE_CURRENT_BINARY_DIR}/StudioWelcome_qml.qrc") - -qtc_glob_resources( - QRC_FILE "${qmlQrcFile}" - ROOT "${CMAKE_CURRENT_SOURCE_DIR}" - GLOB "qml/*" -) - add_qtc_plugin(StudioWelcome DEPENDS Qt5::QuickWidgets PLUGIN_DEPENDS Core ProjectExplorer QtSupport @@ -14,8 +6,15 @@ add_qtc_plugin(StudioWelcome studiowelcomeplugin.cpp studiowelcomeplugin.h studiowelcome_global.h studiowelcome.qrc - ${qmlQrcFile} "${PROJECT_SOURCE_DIR}/src/share/3rdparty/studiofonts/studiofonts.qrc" EXTRA_TRANSLATIONS qml ) + +if (TARGET StudioWelcome) + file(GLOB_RECURSE qmlfiles + RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + qml/* + ) + qtc_add_resources(StudioWelcome StudioWelcome_qml FILES ${qmlfiles}) +endif() diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 6bd05f9b2c0..927cf294af3 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -4157,6 +4157,8 @@ void TextEditorWidgetPrivate::updateLineAnnotation(const PaintEventData &data, } for (const TextMark *mark : qAsConst(marks)) { + if (!mark->isVisible()) + continue; boundingRect = QRectF(x, boundingRect.top(), q->viewport()->width() - x, boundingRect.height()); if (boundingRect.isEmpty()) break; diff --git a/src/tools/clangbackend/source/tokeninfo.cpp b/src/tools/clangbackend/source/tokeninfo.cpp index 47b8188986c..6b2e56c8ac1 100644 --- a/src/tools/clangbackend/source/tokeninfo.cpp +++ b/src/tools/clangbackend/source/tokeninfo.cpp @@ -374,6 +374,7 @@ void TokenInfo::identifierKind(const Cursor &cursor, Recursion recursion) case CXCursor_ParmDecl: case CXCursor_VarDecl: case CXCursor_VariableRef: + case CXCursor_UnexposedDecl: // structured bindings; see https://reviews.llvm.org/D78213 variableKind(cursor.referenced()); break; case CXCursor_DeclRefExpr: diff --git a/tests/unit/unittest/data/highlightingmarks.cpp b/tests/unit/unittest/data/highlightingmarks.cpp index 33dfbe91dec..346071dea15 100644 --- a/tests/unit/unittest/data/highlightingmarks.cpp +++ b/tests/unit/unittest/data/highlightingmarks.cpp @@ -731,3 +731,8 @@ class Property { ) }; + +void structuredBindingTest() { + const int a[] = {1, 2}; + const auto [x, y] = a; +} diff --git a/tests/unit/unittest/imagecache-test.cpp b/tests/unit/unittest/imagecache-test.cpp index 42193357749..f3f2c825180 100644 --- a/tests/unit/unittest/imagecache-test.cpp +++ b/tests/unit/unittest/imagecache-test.cpp @@ -39,12 +39,12 @@ class ImageCache : public testing::Test protected: Notification notification; Notification waitInThread; + NiceMock> mockAbortCallback; + NiceMock> mockCaptureCallback; NiceMock mockStorage; NiceMock mockGenerator; NiceMock mockTimeStampProvider; QmlDesigner::ImageCache cache{mockStorage, mockGenerator, mockTimeStampProvider}; - NiceMock> mockAbortCallback; - NiceMock> mockCaptureCallback; QImage image1{10, 10, QImage::Format_ARGB32}; }; @@ -260,14 +260,10 @@ TEST_F(ImageCache, RequestIconCallsAbortCallbackFromGenerator) TEST_F(ImageCache, CleanRemovesEntries) { - EXPECT_CALL(mockGenerator, generateImage(Eq("/path/to/Component1.qml"), _, _, _)) - .WillRepeatedly([&](auto &&, auto, auto &&mockCaptureCallback, auto &&) { - mockCaptureCallback(QImage{}); - waitInThread.wait(); - }); EXPECT_CALL(mockGenerator, generateImage(_, _, _, _)) .WillRepeatedly([&](auto &&, auto, auto &&mockCaptureCallback, auto &&) { mockCaptureCallback(QImage{}); + waitInThread.wait(); }); cache.requestIcon("/path/to/Component1.qml", mockCaptureCallback.AsStdFunction(), @@ -284,7 +280,7 @@ TEST_F(ImageCache, CleanRemovesEntries) TEST_F(ImageCache, CleanCallsAbort) { - ON_CALL(mockGenerator, generateImage(Eq("/path/to/Component1.qml"), _, _, _)) + ON_CALL(mockGenerator, generateImage(_, _, _, _)) .WillByDefault( [&](auto &&, auto, auto &&mockCaptureCallback, auto &&) { waitInThread.wait(); }); cache.requestIcon("/path/to/Component1.qml", diff --git a/tests/unit/unittest/imagecachegenerator-test.cpp b/tests/unit/unittest/imagecachegenerator-test.cpp index f152bd83ad3..3b183d00672 100644 --- a/tests/unit/unittest/imagecachegenerator-test.cpp +++ b/tests/unit/unittest/imagecachegenerator-test.cpp @@ -106,10 +106,22 @@ TEST_F(ImageCacheGenerator, DontCrashAtDestructingGenerator) captureCallback(QImage{image1}); }); - generator.generateImage("name", {}, imageCallbackMock.AsStdFunction(), {}); - generator.generateImage("name2", {}, imageCallbackMock.AsStdFunction(), {}); - generator.generateImage("name3", {}, imageCallbackMock.AsStdFunction(), {}); - generator.generateImage("name4", {}, imageCallbackMock.AsStdFunction(), {}); + generator.generateImage("name", + {}, + imageCallbackMock.AsStdFunction(), + abortCallbackMock.AsStdFunction()); + generator.generateImage("name2", + {}, + imageCallbackMock.AsStdFunction(), + abortCallbackMock.AsStdFunction()); + generator.generateImage("name3", + {}, + imageCallbackMock.AsStdFunction(), + abortCallbackMock.AsStdFunction()); + generator.generateImage("name4", + {}, + imageCallbackMock.AsStdFunction(), + abortCallbackMock.AsStdFunction()); } TEST_F(ImageCacheGenerator, StoreImage) @@ -168,11 +180,10 @@ TEST_F(ImageCacheGenerator, StoreNullImageForAbortCallback) { ON_CALL(collectorMock, start(_, _, _)).WillByDefault([&](auto, auto, auto abortCallback) { abortCallback(); - notification.notify(); }); - EXPECT_CALL(abortCallbackMock, Call()).WillOnce([&]() { notification.notify(); }); - EXPECT_CALL(storageMock, storeImage(Eq("name"), Eq(Sqlite::TimeStamp{11}), Eq(QImage{}))); + EXPECT_CALL(storageMock, storeImage(Eq("name"), Eq(Sqlite::TimeStamp{11}), Eq(QImage{}))) + .WillOnce([&](auto, auto, auto) { notification.notify(); }); generator.generateImage("name", {11}, @@ -183,7 +194,6 @@ TEST_F(ImageCacheGenerator, StoreNullImageForAbortCallback) TEST_F(ImageCacheGenerator, AbortForEmptyImage) { - NiceMock> abortCallbackMock; ON_CALL(collectorMock, start(Eq("name"), _, _)).WillByDefault([&](auto, auto captureCallback, auto) { captureCallback(QImage{}); }); @@ -216,7 +226,7 @@ TEST_F(ImageCacheGenerator, CallWalCheckpointFullIfQueueIsEmpty) notification.wait(); } -TEST_F(ImageCacheGenerator, Clean) +TEST_F(ImageCacheGenerator, CleanIsCallingAbortCallback) { ON_CALL(collectorMock, start(_, _, _)).WillByDefault([&](auto, auto captureCallback, auto) { captureCallback({}); @@ -231,7 +241,7 @@ TEST_F(ImageCacheGenerator, Clean) imageCallbackMock.AsStdFunction(), abortCallbackMock.AsStdFunction()); - EXPECT_CALL(imageCallbackMock, Call(_)).Times(0); + EXPECT_CALL(abortCallbackMock, Call()).Times(AtLeast(1)); generator.clean(); waitInThread.notify(); diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp index c7268a51d8a..04561a230b1 100644 --- a/tests/unit/unittest/pchcreator-test.cpp +++ b/tests/unit/unittest/pchcreator-test.cpp @@ -362,7 +362,7 @@ TEST_F(PchCreatorVerySlowTest, ClangToolCleared) ASSERT_TRUE(creator.clangTool().isClean()); } -TEST_F(PchCreatorVerySlowTest, FaultyProjectPartPchForCreatesFaultyPchForPchTask) +TEST_F(PchCreatorVerySlowTest, DISABLED_FaultyProjectPartPchForCreatesFaultyPchForPchTask) { PchTask faultyPchTask{ 0, diff --git a/tests/unit/unittest/symbolscollector-test.cpp b/tests/unit/unittest/symbolscollector-test.cpp index 5954f8a9f5a..84fc26ca89b 100644 --- a/tests/unit/unittest/symbolscollector-test.cpp +++ b/tests/unit/unittest/symbolscollector-test.cpp @@ -190,7 +190,7 @@ TEST_F(SymbolsCollector, CollectSymbolName) Contains(HasSymbolName("function"))); } -TEST_F(SymbolsCollector, SymbolMatchesLocation) +TEST_F(SymbolsCollector, DISABLED_SymbolMatchesLocation) { collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/simple.cpp"), {"cc"}); @@ -202,7 +202,7 @@ TEST_F(SymbolsCollector, SymbolMatchesLocation) HasLineColumn(1, 6)))); } -TEST_F(SymbolsCollector, OtherSymboldMatchesLocation) +TEST_F(SymbolsCollector, DISABLED_OtherSymboldMatchesLocation) { collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/simple.cpp"), {"cc"}); @@ -250,7 +250,7 @@ TEST_F(SymbolsCollector, CollectReference) Field(&SourceLocationEntry::kind, SourceLocationKind::DeclarationReference)))); } -TEST_F(SymbolsCollector, ReferencedSymboldMatchesLocation) +TEST_F(SymbolsCollector, DISABLED_ReferencedSymboldMatchesLocation) { collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/simple.cpp"), {"cc"}); diff --git a/tests/unit/unittest/tokenprocessor-test.cpp b/tests/unit/unittest/tokenprocessor-test.cpp index f74fb0dbedd..62a84af59d0 100644 --- a/tests/unit/unittest/tokenprocessor-test.cpp +++ b/tests/unit/unittest/tokenprocessor-test.cpp @@ -1759,6 +1759,14 @@ TEST_F(TokenProcessor, TemplateAlias) ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::TypeAlias)); } +TEST_F(TokenProcessor, StructuredBinding) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(737, 23)); + + ASSERT_THAT(infos[3], IsHighlightingMark(737u, 17u, 1u, HighlightingType::LocalVariable)); + ASSERT_THAT(infos[5], IsHighlightingMark(737u, 20u, 1u, HighlightingType::LocalVariable)); +} + Data *TokenProcessor::d; void TokenProcessor::SetUpTestCase()