diff --git a/conanfile.txt b/conanfile.txt deleted file mode 100644 index c30ca6aad47..00000000000 --- a/conanfile.txt +++ /dev/null @@ -1,24 +0,0 @@ -# This needs a special conan repository to work! -# Please run: -# conan remote add qtcreator https://api.bintray.com/conan/qtcreator/qtcreator -# conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan -# to make this repository available! -# -# Then do the following to build Qt Creator: -# 1. Create a build directory and change into it -# 2. Run "conan install /path/to/qtcreator/sources --build missing" -# 3. Run "cmake -DCMAKE_TOOLCHAIN_FILE=conan_paths.cmake /path/to/qtcreator/sources -GNinja" - -[requires] -qt/5.15.1@bincrafters/stable -llvm/8.0.0@qtcreator/stable - -[generators] -cmake_paths - -[options] -qt:qtdeclarative=True -qt:qtscript=True -qt:qtserialport=True -qt:qtsvg=True -qt:qttools=True diff --git a/dist/changes-4.14.1.md b/dist/changes-4.14.1.md index b019dd205fb..7e0dd10a98b 100644 --- a/dist/changes-4.14.1.md +++ b/dist/changes-4.14.1.md @@ -72,6 +72,7 @@ Debugging ### LLDB * Fixed that application output could be printed delayed (QTCREATORBUG-24667) +* Fixed performance issue (QTCREATORBUG-25185, QTCREATORBUG-25217) ### CDB diff --git a/doc/qtcreator/images/qtcreator-options-environment-interface.png b/doc/qtcreator/images/qtcreator-options-environment-interface.png index 43b51eb1f93..41374d1b5dc 100644 Binary files a/doc/qtcreator/images/qtcreator-options-environment-interface.png and b/doc/qtcreator/images/qtcreator-options-environment-interface.png differ diff --git a/doc/qtcreator/src/howto/creator-external-tools.qdoc b/doc/qtcreator/src/howto/creator-external-tools.qdoc index ebae6a113af..74128bed458 100644 --- a/doc/qtcreator/src/howto/creator-external-tools.qdoc +++ b/doc/qtcreator/src/howto/creator-external-tools.qdoc @@ -163,8 +163,10 @@ To globally change the system environment from the one in which \QC is started, select \uicontrol Tools > \uicontrol Options > \uicontrol Environment > \uicontrol System, and then select - \uicontrol Change in the \uicontrol Environment field. For more - information, see \l{Specifying Environment Settings}. + \uicontrol Change in the \uicontrol Environment field. + \if defined(qtcreator) + For more information, see \l{Specifying Environment Settings}. + \endif \li Select the \uicontrol {Modifies current document} check box to make sure that if the current document is modified by the tool, it is saved diff --git a/doc/qtcreator/src/howto/creator-ui.qdoc b/doc/qtcreator/src/howto/creator-ui.qdoc index 8647c66696a..0d78e314c55 100644 --- a/doc/qtcreator/src/howto/creator-ui.qdoc +++ b/doc/qtcreator/src/howto/creator-ui.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -411,6 +411,14 @@ For more information about the \uicontrol {QML Debugger Console} view, see \l{Executing JavaScript Expressions}. + If the text in the output panes is not displayed correctly, \QC might + be using a different codec from the one used by the tools that generate + the output. To specify the codec to use, select \uicontrol Tools > + \uicontrol Options > \uicontrol Environment > \uicontrol Interface, and + then select the codec in the \uicontrol {Text codec for tools} field. + + \image qtcreator-options-environment-interface.png "Interface tab in the Environment options" + \section1 Finding and Filtering Output To search from output, press \key {Ctrl+F} when the pane is active. Enter diff --git a/doc/qtcreator/src/qtquick/qtquick-designer.qdoc b/doc/qtcreator/src/qtquick/qtquick-designer.qdoc index 1fa57efd9f8..90287f9a7ca 100644 --- a/doc/qtcreator/src/qtquick/qtquick-designer.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-designer.qdoc @@ -230,17 +230,18 @@ \li Uses a \uicontrol Grid component to lay out the selected components. \li \l{Using Layouts} + \if defined(qtdesignstudio) \row \li \inlineimage icons/edit.png \li \uicontrol {Show Event List} (\key {Alt+E}): opens a dialog for - viewing and creating an {event list} for an - application flow. + viewing and creating an event list for an application flow. \li \l{Simulating Events} \row \li \inlineimage icons/assign.png \li \uicontrol {Assign Events to Actions} (\key {Alt+A}): assigns events to actions in an application flow. \li \l{Simulating Events} + \endif \row \li Styling \li Displays the UI style used for UI controls. diff --git a/doc/qtcreator/src/qtquick/qtquick-states.qdoc b/doc/qtcreator/src/qtquick/qtquick-states.qdoc index f04a7460e83..9dc2867e28b 100644 --- a/doc/qtcreator/src/qtquick/qtquick-states.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-states.qdoc @@ -89,9 +89,10 @@ \image qmldesigner-states.png "States and Properties views" - \note If you have \l{Locking Items}{locked an item} in \uicontrol Navigator, - and you attempt to remove states where you change the values of its - properties, you are prompted to confirm the removal. + \note If you have \l{Locking Components}{locked a component} in + \uicontrol Navigator, and you attempt to remove states where you + change the values of its properties, you are prompted to confirm + the removal. For more information, watch the following video: diff --git a/scripts/build.py b/scripts/build.py index afc289fd327..2ccb1a98f44 100755 --- a/scripts/build.py +++ b/scripts/build.py @@ -107,29 +107,10 @@ def get_arguments(): args.with_debug_info = args.build_type == 'RelWithDebInfo' return args -def build_qtcreator(args, paths): - if not os.path.exists(paths.build): - os.makedirs(paths.build) - prefix_paths = [os.path.abspath(fp) for fp in args.prefix_paths] + [paths.qt] - if paths.llvm: - prefix_paths += [paths.llvm] - if paths.elfutils: - prefix_paths += [paths.elfutils] - prefix_paths = [common.to_posix_path(fp) for fp in prefix_paths] - with_docs_str = 'OFF' if args.no_docs else 'ON' - build_date_option = 'OFF' if args.no_build_date else 'ON' - test_option = 'ON' if args.with_tests else 'OFF' +def common_cmake_arguments(args): separate_debug_info_option = 'ON' if args.with_debug_info else 'OFF' - cmake_args = ['cmake', - '-DCMAKE_PREFIX_PATH=' + ';'.join(prefix_paths), - '-DCMAKE_BUILD_TYPE=' + args.build_type, + cmake_args = ['-DCMAKE_BUILD_TYPE=' + args.build_type, '-DQTC_SEPARATE_DEBUG_INFO=' + separate_debug_info_option, - '-DSHOW_BUILD_DATE=' + build_date_option, - '-DWITH_DOCS=' + with_docs_str, - '-DBUILD_DEVELOPER_DOCS=' + with_docs_str, - '-DBUILD_EXECUTABLE_SDKTOOL=OFF', - '-DCMAKE_INSTALL_PREFIX=' + common.to_posix_path(paths.install), - '-DWITH_TESTS=' + test_option, '-G', 'Ninja'] if args.python3: @@ -147,14 +128,39 @@ def build_qtcreator(args, paths): if not os.environ.get('CC') and not os.environ.get('CXX'): cmake_args += ['-DCMAKE_C_COMPILER=cl', '-DCMAKE_CXX_COMPILER=cl'] - cmake_args += ['-DBUILD_EXECUTABLE_WIN32INTERRUPT=OFF', - '-DBUILD_EXECUTABLE_WIN64INTERRUPT=OFF', - '-DBUILD_LIBRARY_QTCREATORCDBEXT=OFF'] if args.python_path: python_library = glob.glob(os.path.join(args.python_path, 'libs', 'python??.lib')) if python_library: cmake_args += ['-DPYTHON_LIBRARY=' + python_library[0], '-DPYTHON_INCLUDE_DIR=' + os.path.join(args.python_path, 'include')] + return cmake_args + +def build_qtcreator(args, paths): + if not os.path.exists(paths.build): + os.makedirs(paths.build) + prefix_paths = [os.path.abspath(fp) for fp in args.prefix_paths] + [paths.qt] + if paths.llvm: + prefix_paths += [paths.llvm] + if paths.elfutils: + prefix_paths += [paths.elfutils] + prefix_paths = [common.to_posix_path(fp) for fp in prefix_paths] + with_docs_str = 'OFF' if args.no_docs else 'ON' + build_date_option = 'OFF' if args.no_build_date else 'ON' + test_option = 'ON' if args.with_tests else 'OFF' + cmake_args = ['cmake', + '-DCMAKE_PREFIX_PATH=' + ';'.join(prefix_paths), + '-DSHOW_BUILD_DATE=' + build_date_option, + '-DWITH_DOCS=' + with_docs_str, + '-DBUILD_DEVELOPER_DOCS=' + with_docs_str, + '-DBUILD_EXECUTABLE_SDKTOOL=OFF', + '-DCMAKE_INSTALL_PREFIX=' + common.to_posix_path(paths.install), + '-DWITH_TESTS=' + test_option] + cmake_args += common_cmake_arguments(args) + + if common.is_windows_platform(): + cmake_args += ['-DBUILD_EXECUTABLE_WIN32INTERRUPT=OFF', + '-DBUILD_EXECUTABLE_WIN64INTERRUPT=OFF', + '-DBUILD_LIBRARY_QTCREATORCDBEXT=OFF'] # TODO this works around a CMake bug https://gitlab.kitware.com/cmake/cmake/issues/20119 cmake_args += ['-DBUILD_WITH_PCH=OFF'] @@ -198,28 +204,34 @@ def build_qtcreator(args, paths): def build_wininterrupt(args, paths): if not common.is_windows_platform(): return - # assumes existing Qt Creator build - cmake_args = ['-DBUILD_EXECUTABLE_WIN32INTERRUPT=ON', - '-DBUILD_EXECUTABLE_WIN64INTERRUPT=ON', - '-DBUILD_LIBRARY_QTCREATORCDBEXT=OFF'] - common.check_print_call(['cmake'] + cmake_args + [paths.src], paths.build) - common.check_print_call(['cmake', '--build', '.'], paths.build) + if not os.path.exists(paths.wininterrupt_build): + os.makedirs(paths.wininterrupt_build) + prefix_paths = [common.to_posix_path(os.path.abspath(fp)) for fp in args.prefix_paths] + cmake_args = ['-DCMAKE_PREFIX_PATH=' + ';'.join(prefix_paths), + '-DCMAKE_INSTALL_PREFIX=' + common.to_posix_path(paths.wininterrupt_install)] + cmake_args += common_cmake_arguments(args) + common.check_print_call(['cmake'] + cmake_args + [os.path.join(paths.src, 'src', 'tools', 'wininterrupt')], + paths.wininterrupt_build) + common.check_print_call(['cmake', '--build', '.'], paths.wininterrupt_build) common.check_print_call(['cmake', '--install', '.', '--prefix', paths.wininterrupt_install, '--component', 'wininterrupt'], - paths.build) + paths.wininterrupt_build) def build_qtcreatorcdbext(args, paths): if args.no_cdb: return - # assumes existing Qt Creator build - cmake_args = ['-DBUILD_EXECUTABLE_WIN32INTERRUPT=OFF', - '-DBUILD_EXECUTABLE_WIN64INTERRUPT=OFF', - '-DBUILD_LIBRARY_QTCREATORCDBEXT=ON'] - common.check_print_call(['cmake'] + cmake_args + [paths.src], paths.build) - common.check_print_call(['cmake', '--build', '.'], paths.build) + if not os.path.exists(paths.qtcreatorcdbext_build): + os.makedirs(paths.qtcreatorcdbext_build) + prefix_paths = [common.to_posix_path(os.path.abspath(fp)) for fp in args.prefix_paths] + cmake_args = ['-DCMAKE_PREFIX_PATH=' + ';'.join(prefix_paths), + '-DCMAKE_INSTALL_PREFIX=' + common.to_posix_path(paths.qtcreatorcdbext_install)] + cmake_args += common_cmake_arguments(args) + common.check_print_call(['cmake'] + cmake_args + [os.path.join(paths.src, 'src', 'libs', 'qtcreatorcdbext')], + paths.qtcreatorcdbext_build) + common.check_print_call(['cmake', '--build', '.'], paths.qtcreatorcdbext_build) common.check_print_call(['cmake', '--install', '.', '--prefix', paths.qtcreatorcdbext_install, '--component', 'qtcreatorcdbext'], - paths.build) + paths.qtcreatorcdbext_build) def package_qtcreator(args, paths): if not args.no_zip: @@ -261,7 +273,7 @@ def package_qtcreator(args, paths): def get_paths(args): Paths = collections.namedtuple('Paths', - ['qt', 'src', 'build', + ['qt', 'src', 'build', 'wininterrupt_build', 'qtcreatorcdbext_build', 'install', 'dev_install', 'debug_install', 'wininterrupt_install', 'qtcreatorcdbext_install', 'result', 'elfutils', 'llvm']) @@ -270,6 +282,8 @@ def get_paths(args): return Paths(qt=os.path.abspath(args.qt_path), src=os.path.abspath(args.src), build=os.path.join(build_path, 'build'), + wininterrupt_build=os.path.join(build_path, 'build-wininterrupt'), + qtcreatorcdbext_build=os.path.join(build_path, 'build-qtcreatorcdbext'), install=os.path.join(install_path, 'qt-creator'), dev_install=os.path.join(install_path, 'qt-creator-dev'), debug_install=os.path.join(install_path, 'qt-creator-debug'), diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml index b7bc9b0b58c..f7cf00d92c3 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml @@ -75,7 +75,7 @@ Item { anchors.fill: parent onPressed: { - rootView.startDragAndDrop(mouseRegion, itemLibraryEntry) + rootView.startDragAndDrop(itemLibraryEntry) } } } diff --git a/share/qtcreator/themes/design.creatortheme b/share/qtcreator/themes/design.creatortheme index 2451371b7f8..67457b28495 100644 --- a/share/qtcreator/themes/design.creatortheme +++ b/share/qtcreator/themes/design.creatortheme @@ -307,7 +307,7 @@ QmlDesigner_ScrollBarHandleColor=ff595b5c ;palette colors -;outline colors on the combo box, zoom slider, flowtag button, dialog outlines, on loading project the whole screen flashes this color +;outline colors on the combo box, zoom slider, dialog outlines, on loading project the whole screen flashes this color ;PaletteWindow=normalBackground PaletteWindow=ff262626 @@ -347,7 +347,7 @@ PaletteText=text -;text for flowtags, import dropdown, ticks for tick boxes. +; text for ticks for tick boxes. PaletteButtonText=text ;PaletteButtonText=ffd3299a diff --git a/src/libs/languageserverprotocol/languagefeatures.cpp b/src/libs/languageserverprotocol/languagefeatures.cpp index bffa0df284f..de175b7e7e1 100644 --- a/src/libs/languageserverprotocol/languagefeatures.cpp +++ b/src/libs/languageserverprotocol/languagefeatures.cpp @@ -242,7 +242,7 @@ bool DocumentOnTypeFormattingParams::isValid(ErrorHierarchy *error) const } DocumentOnTypeFormattingRequest::DocumentOnTypeFormattingRequest( - const DocumentFormattingParams ¶ms) + const DocumentOnTypeFormattingParams ¶ms) : Request(methodName, params) { } diff --git a/src/libs/languageserverprotocol/languagefeatures.h b/src/libs/languageserverprotocol/languagefeatures.h index 5b1b9da3c2c..c1818b34f2c 100644 --- a/src/libs/languageserverprotocol/languagefeatures.h +++ b/src/libs/languageserverprotocol/languagefeatures.h @@ -786,10 +786,10 @@ public: }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentOnTypeFormattingRequest : public Request< - QList, std::nullptr_t, DocumentFormattingParams> + LanguageClientArray, std::nullptr_t, DocumentOnTypeFormattingParams> { public: - explicit DocumentOnTypeFormattingRequest(const DocumentFormattingParams ¶ms); + explicit DocumentOnTypeFormattingRequest(const DocumentOnTypeFormattingParams ¶ms); using Request::Request; constexpr static const char methodName[] = "textDocument/onTypeFormatting"; }; diff --git a/src/libs/qtcreatorcdbext/CMakeLists.txt b/src/libs/qtcreatorcdbext/CMakeLists.txt index ddffac17e3f..c2a7c60a2ef 100644 --- a/src/libs/qtcreatorcdbext/CMakeLists.txt +++ b/src/libs/qtcreatorcdbext/CMakeLists.txt @@ -1,3 +1,19 @@ +cmake_minimum_required(VERSION 3.10) + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake") + +project(qtcreatorcdbext) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +if (NOT QT_CREATOR_API_DEFINED) + # standalone build + include(QtCreatorIDEBranding) + include(QtCreatorAPI) +endif() + if (NOT WIN32 OR NOT MSVC) return() endif() @@ -111,8 +127,10 @@ if (_library_enabled) COMPONENT qtcreatorcdbext) add_custom_target(copy_python_dll ALL VERBATIM) + + qtc_output_binary_dir(output_binary_dir) add_custom_command(TARGET copy_python_dll POST_BUILD - COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${deployPythonFiles} "${PROJECT_BINARY_DIR}/lib/qtcreatorcdbext${ArchSuffix}/" + COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${deployPythonFiles} "${output_binary_dir}/lib/qtcreatorcdbext${ArchSuffix}/" VERBATIM ) endif() diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index d08027197be..41e70cb1e95 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -300,6 +300,12 @@ extend_qtc_plugin(QmlDesigner extend_qtc_plugin(QmlDesigner SOURCES_PREFIX components/itemlibrary SOURCES + assetimportupdatedialog.cpp assetimportupdatedialog.h + assetimportupdatedialog.ui + assetimportupdatetreeitem.cpp assetimportupdatetreeitem.h + assetimportupdatetreeitemdelegate.cpp assetimportupdatetreeitemdelegate.h + assetimportupdatetreemodel.cpp assetimportupdatetreemodel.h + assetimportupdatetreeview.cpp assetimportupdatetreeview.h customfilesystemmodel.cpp customfilesystemmodel.h itemlibrary.qrc itemlibraryimageprovider.cpp itemlibraryimageprovider.h diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.cpp b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.cpp new file mode 100644 index 00000000000..bc420dc6385 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ +#include "assetimportupdatedialog.h" +#include "ui_assetimportupdatedialog.h" +#include "assetimportupdatetreeview.h" +#include "assetimportupdatetreemodel.h" + +#include +#include +#include +#include +#include + +namespace QmlDesigner { +namespace Internal { + +AssetImportUpdateDialog::AssetImportUpdateDialog( + const QString &importPath, const QSet &preSelectedFiles, + const QSet &hiddenEntries, QWidget *parent) + : QDialog(parent) + , ui(new Ui::AssetImportUpdateDialog) +{ + setModal(true); + ui->setupUi(this); + + connect(ui->buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, + this, &AssetImportUpdateDialog::accept); + connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, + this, &AssetImportUpdateDialog::reject); + connect(ui->expandButton, &QPushButton::clicked, + this, &AssetImportUpdateDialog::expandAll); + connect(ui->collapseButton, &QPushButton::clicked, + this, &AssetImportUpdateDialog::collapseAll); + ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); + + QList infos; + infos.append(QFileInfo{importPath}); + QDirIterator it(importPath, {"*"}, QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, + QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + const QString absFile = it.fileInfo().absoluteFilePath(); + if (!hiddenEntries.contains(absFile)) + infos.append(it.fileInfo()); + } + + ui->treeView->model()->createItems(infos, preSelectedFiles); + ui->treeView->expandAll(); +} + +AssetImportUpdateDialog::~AssetImportUpdateDialog() +{ + delete ui; +} + +QStringList AssetImportUpdateDialog::selectedFiles() const +{ + return ui->treeView->model()->checkedFiles(); +} + +void AssetImportUpdateDialog::collapseAll() +{ + ui->treeView->collapseAll(); +} + +void AssetImportUpdateDialog::expandAll() +{ + ui->treeView->expandAll(); +} + +} // namespace Internal +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.h b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.h new file mode 100644 index 00000000000..497fc6ca384 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ +#pragma once + +#include +#include +#include + +namespace QmlDesigner { +namespace Internal { + +namespace Ui { +class AssetImportUpdateDialog; +} + +class AssetImportUpdateDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AssetImportUpdateDialog(const QString &importPath, + const QSet &preSelectedFiles, + const QSet &hiddenEntries, + QWidget *parent = nullptr); + ~AssetImportUpdateDialog(); + + QStringList selectedFiles() const; + +private: + void collapseAll(); + void expandAll(); + + Ui::AssetImportUpdateDialog *ui = nullptr; +}; + +} // namespace Internal +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.ui b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.ui new file mode 100644 index 00000000000..576987e5de0 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.ui @@ -0,0 +1,77 @@ + + + QmlDesigner::Internal::AssetImportUpdateDialog + + + + 0 + 0 + 472 + 360 + + + + Select Files to Update + + + + + + + + QAbstractItemView::NoSelection + + + + + + + + + Expand All + + + + + + + Collapse All + + + + + + + Qt::Horizontal + + + + 77 + 20 + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + + AssetImportUpdateTreeView + QTreeView +
assetimportupdatetreeview.h
+
+
+ + +
diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.cpp b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.cpp new file mode 100644 index 00000000000..81f5a143924 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "assetimportupdatetreeitem.h" + +namespace QmlDesigner { +namespace Internal { + +AssetImportUpdateTreeItem::AssetImportUpdateTreeItem(const QFileInfo &info, + AssetImportUpdateTreeItem *parent) + : m_parent(parent) + , m_fileInfo(info) +{ + if (parent) + parent->appendChild(this); +} + +AssetImportUpdateTreeItem::~AssetImportUpdateTreeItem() +{ + if (m_parent) + m_parent->removeChild(this); + clear(); +} + +void AssetImportUpdateTreeItem::clear() +{ + qDeleteAll(m_children); + m_children.clear(); + m_fileInfo = {}; + m_parent = nullptr; +} + +int AssetImportUpdateTreeItem::childCount() const +{ + return m_children.count(); +} + +int AssetImportUpdateTreeItem::rowOfItem() const +{ + return m_parent ? m_parent->m_children.indexOf(const_cast(this)) + : 0; +} + +AssetImportUpdateTreeItem *AssetImportUpdateTreeItem::childAt(int index) const +{ + return m_children.at(index); +} + +AssetImportUpdateTreeItem *AssetImportUpdateTreeItem::parent() const +{ + return m_parent; +} + +void AssetImportUpdateTreeItem::removeChild(AssetImportUpdateTreeItem *item) +{ + m_children.removeOne(item); +} + +void AssetImportUpdateTreeItem::appendChild(AssetImportUpdateTreeItem *item) +{ + m_children.append(item); +} + +} // namespace Internal +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.h b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.h new file mode 100644 index 00000000000..ef944e2dece --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include +#include +#include + +namespace QmlDesigner { +namespace Internal { + +class AssetImportUpdateTreeItem +{ +public: + explicit AssetImportUpdateTreeItem(const QFileInfo &info, + AssetImportUpdateTreeItem *parent = nullptr); + virtual ~AssetImportUpdateTreeItem(); + + AssetImportUpdateTreeItem *parent() const; + AssetImportUpdateTreeItem *childAt(int index) const; + int childCount() const; + int rowOfItem() const; + void clear(); + + Qt::CheckState checkState() const { return m_checkState; } + void setCheckState(Qt::CheckState checkState) { m_checkState = checkState; } + const QFileInfo &fileInfo() const { return m_fileInfo; } + void setFileInfo(const QFileInfo &info) { m_fileInfo = info; } + void removeChild(AssetImportUpdateTreeItem *item); + const QList &children() const { return m_children; } + +private: + void appendChild(AssetImportUpdateTreeItem *item); + + AssetImportUpdateTreeItem *m_parent; + QList m_children; + Qt::CheckState m_checkState = Qt::Unchecked; + QFileInfo m_fileInfo; +}; + +} // namespace Internal +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitemdelegate.cpp b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitemdelegate.cpp new file mode 100644 index 00000000000..9a517f76b24 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitemdelegate.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "assetimportupdatetreeitemdelegate.h" +#include "assetimportupdatetreemodel.h" + +#include +#include + +namespace QmlDesigner { +namespace Internal { + +AssetImportUpdateTreeItemDelegate::AssetImportUpdateTreeItemDelegate(QObject *parent) + : QItemDelegate(parent) +{ +} + +AssetImportUpdateTreeItemDelegate::LayoutInfo AssetImportUpdateTreeItemDelegate::getLayoutInfo( + const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + LayoutInfo info; + info.option = setOptions(index, option); + + const bool checkable = (index.model()->flags(index) & Qt::ItemIsUserCheckable); + info.checkState = Qt::Unchecked; + if (checkable) { + QVariant checkStateData = index.data(Qt::CheckStateRole); + info.checkState = static_cast(checkStateData.toInt()); + info.checkRect = doCheck(info.option, info.option.rect, checkStateData); + } + + info.textRect = info.option.rect.adjusted(0, 0, info.checkRect.width(), 0); + + doLayout(info.option, &info.checkRect, &info.iconRect, &info.textRect, false); + + return info; +} + +void AssetImportUpdateTreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + painter->save(); + + const LayoutInfo info = getLayoutInfo(option, index); + + painter->setFont(info.option.font); + + drawBackground(painter, info.option, index); + drawText(painter, info.option, info.textRect, index); + drawCheck(painter, info.option, info.checkRect, info.checkState); + + painter->restore(); +} + +QSize AssetImportUpdateTreeItemDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + const LayoutInfo info = getLayoutInfo(option, index); + const int height = index.data(Qt::SizeHintRole).value().height(); + // get text width, see QItemDelegatePrivate::displayRect + const QString text = index.data(Qt::DisplayRole).toString(); + const QRect textMaxRect(0, 0, INT_MAX / 256, height); + const QRect textLayoutRect = textRectangle(nullptr, textMaxRect, info.option.font, text); + const QRect textRect(info.textRect.x(), info.textRect.y(), textLayoutRect.width(), height); + const QRect layoutRect = info.checkRect | textRect; + return QSize(layoutRect.x(), layoutRect.y()) + layoutRect.size(); +} + +void AssetImportUpdateTreeItemDelegate::drawText(QPainter *painter, + const QStyleOptionViewItem &option, + const QRect &rect, + const QModelIndex &index) const +{ + const QString text = index.data(Qt::DisplayRole).toString(); + drawDisplay(painter, option, rect, text); +} + +} // namespace Internal +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitemdelegate.h b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitemdelegate.h new file mode 100644 index 00000000000..a066ebcfb41 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitemdelegate.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include +#include + +namespace QmlDesigner { +namespace Internal { + +class AssetImportUpdateTreeItemDelegate : public QItemDelegate +{ +public: + AssetImportUpdateTreeItemDelegate(QObject *parent = nullptr); + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; +private: + struct LayoutInfo + { + QRect checkRect; + QRect textRect; + QRect iconRect; + Qt::CheckState checkState; + QStyleOptionViewItem option; + }; + + LayoutInfo getLayoutInfo(const QStyleOptionViewItem &option, const QModelIndex &index) const; + void drawText(QPainter *painter, const QStyleOptionViewItem &option, + const QRect &rect, const QModelIndex &index) const; +}; + +} // namespace Internal +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreemodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreemodel.cpp new file mode 100644 index 00000000000..fac0797d5ed --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreemodel.cpp @@ -0,0 +1,262 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "assetimportupdatetreemodel.h" +#include "assetimportupdatetreeitem.h" + +#include + +namespace QmlDesigner { +namespace Internal { + +AssetImportUpdateTreeModel::AssetImportUpdateTreeModel(QObject *parent) + : QAbstractItemModel(parent) +{ + m_rootItem = new AssetImportUpdateTreeItem {{}}; +} + +AssetImportUpdateTreeModel::~AssetImportUpdateTreeModel() +{ + delete m_rootItem; +} + +Qt::ItemFlags AssetImportUpdateTreeModel::flags(const QModelIndex &idx) const +{ + Qt::ItemFlags flags = QAbstractItemModel::flags(idx); + + if (idx.isValid()) + flags |= Qt::ItemIsUserCheckable; + + return flags; +} + +QModelIndex AssetImportUpdateTreeModel::index(int row, int column, + const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + const AssetImportUpdateTreeItem *parentItem; + + parentItem = parent.isValid() ? treeItemAtIndex(parent) : m_rootItem; + + const AssetImportUpdateTreeItem *childItem = parentItem->childAt(row); + if (childItem) + return createIndex(row, column, const_cast(childItem)); + else + return QModelIndex(); +} + +QModelIndex AssetImportUpdateTreeModel::index(AssetImportUpdateTreeItem *item) const +{ + return createIndex(item->rowOfItem(), 0, item); +} + +QVariant AssetImportUpdateTreeModel::data(const AssetImportUpdateTreeItem *row, int role) const +{ + if (role == Qt::DisplayRole) + return row->fileInfo().fileName(); + if (role == Qt::CheckStateRole) + return row->checkState(); + if (role == Qt::ToolTipRole) + return row->fileInfo().absoluteFilePath(); + return {}; +} + +QModelIndex AssetImportUpdateTreeModel::parent(const QModelIndex &idx) const +{ + if (!idx.isValid()) + return QModelIndex(); + + const AssetImportUpdateTreeItem *childItem = treeItemAtIndex(idx); + const AssetImportUpdateTreeItem *parentItem = childItem->parent(); + + if (parentItem == m_rootItem) + return QModelIndex(); + + return createIndex(parentItem->rowOfItem(), 0, const_cast(parentItem)); +} + +int AssetImportUpdateTreeModel::rowCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) + return 0; + + return parent.isValid() ? treeItemAtIndex(parent)->childCount() + : m_rootItem->childCount(); +} + +int AssetImportUpdateTreeModel::columnCount(const QModelIndex &) const +{ + return 1; +} + +AssetImportUpdateTreeItem *AssetImportUpdateTreeModel::treeItemAtIndex(const QModelIndex &idx) +{ + return static_cast(idx.internalPointer()); +} + +QVariant AssetImportUpdateTreeModel::data(const QModelIndex &idx, int role) const +{ + if (!idx.isValid()) + return {}; + + if (role == Qt::SizeHintRole) + return QSize(0, 20); + + return data(treeItemAtIndex(idx), role); +} + +bool AssetImportUpdateTreeModel::setData(const QModelIndex &idx, const QVariant &value, int role) +{ + if (role == Qt::CheckStateRole) { + auto checkState = static_cast(value.toInt()); + return setCheckState(idx, checkState); + } + return QAbstractItemModel::setData(idx, value, role); +} + +bool AssetImportUpdateTreeModel::setCheckState(const QModelIndex &idx, Qt::CheckState checkState, + bool firstCall) +{ + AssetImportUpdateTreeItem *item = treeItemAtIndex(idx); + if (item->checkState() == checkState) + return false; + item->setCheckState(checkState); + if (firstCall) { + emit dataChanged(idx, idx); + // check parents + AssetImportUpdateTreeItem *parent = item->parent(); + QModelIndex parentIdx = idx.parent(); + while (parent) { + bool hasChecked = false; + bool hasUnchecked = false; + for (const auto child : parent->children()) { + if (child->checkState() == Qt::Checked) { + hasChecked = true; + } else if (child->checkState() == Qt::Unchecked) { + hasUnchecked = true; + } else if (child->checkState() == Qt::PartiallyChecked) { + hasChecked = true; + hasUnchecked = true; + } + } + if (hasChecked && hasUnchecked) + parent->setCheckState(Qt::PartiallyChecked); + else if (hasChecked) + parent->setCheckState(Qt::Checked); + else + parent->setCheckState(Qt::Unchecked); + emit dataChanged(parentIdx, parentIdx); + parent = parent->parent(); + parentIdx = parentIdx.parent(); + } + } + // check children + if (int children = item->childCount()) { + for (int i = 0; i < children; ++i) + setCheckState(index(i, 0, idx), checkState, false); + emit dataChanged(index(0, 0, idx), index(children - 1, 0, idx)); + } + return true; +} + +void AssetImportUpdateTreeModel::createItems(const QList &infos, + const QSet &preselectedFiles) +{ + beginResetModel(); + if (!infos.isEmpty()) { + QHash dirItems; + for (const auto &info : infos) { + auto parent = dirItems.value(info.absolutePath()); + if (!parent) + parent = m_rootItem; + auto item = new AssetImportUpdateTreeItem(info, parent); + if (info.isDir()) { + dirItems.insert(info.absoluteFilePath(), item); + } else { + m_fileItems.append(item); + if (preselectedFiles.contains(info.absoluteFilePath())) + item->setCheckState(Qt::Checked); + } + } + // Remove dir items that have no children from the model + for (auto dirItem : qAsConst(dirItems)) { + if (dirItem->childCount() == 0) + delete dirItem; + } + std::function updateDirCheckStatesRecursive; + updateDirCheckStatesRecursive = [&](AssetImportUpdateTreeItem *item) -> Qt::CheckState { + bool hasChecked = false; + bool hasUnchecked = false; + for (const auto child : item->children()) { + Qt::CheckState childState = child->childCount() > 0 + ? updateDirCheckStatesRecursive(child) + : child->checkState(); + if (childState == Qt::Checked) { + hasChecked = true; + } else if (childState == Qt::Unchecked) { + hasUnchecked = true; + } else { + hasChecked = true; + hasUnchecked = true; + break; + } + } + Qt::CheckState retval = Qt::Unchecked; + if (hasChecked && hasUnchecked) + retval = Qt::PartiallyChecked; + else if (hasChecked) + retval = Qt::Checked; + item->setCheckState(retval); + return retval; + }; + m_rootItem->setCheckState(updateDirCheckStatesRecursive(m_rootItem)); + } + endResetModel(); +} + +QStringList AssetImportUpdateTreeModel::checkedFiles() const +{ + QStringList retList; + + for (const auto item : qAsConst(m_fileItems)) { + if (item->checkState() == Qt::Checked) + retList.append(item->fileInfo().absoluteFilePath()); + } + + return retList; +} + +void AssetImportUpdateTreeModel::clear() +{ + beginResetModel(); + m_fileItems.clear(); + m_rootItem->clear(); // Deletes all children + endResetModel(); +} + +} // namespace Internal +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreemodel.h b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreemodel.h new file mode 100644 index 00000000000..adba52f0379 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreemodel.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace QmlDesigner { +namespace Internal { + +class AssetImportUpdateTreeItem; + +class AssetImportUpdateTreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + AssetImportUpdateTreeModel(QObject *parent = nullptr); + ~AssetImportUpdateTreeModel() override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &child) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + void createItems(const QList &infos, const QSet &preselectedFiles); + QStringList checkedFiles() const; + + static AssetImportUpdateTreeItem *treeItemAtIndex(const QModelIndex &idx); + +public slots: + void clear(); + +private: + QModelIndex index(AssetImportUpdateTreeItem *item) const; + QVariant data(const AssetImportUpdateTreeItem *row, int role) const; + bool setCheckState(const QModelIndex &idx, Qt::CheckState checkState, bool firstCall = true); + + AssetImportUpdateTreeItem *m_rootItem; + QList m_fileItems; +}; + +} // namespace Internal +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeview.cpp b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeview.cpp new file mode 100644 index 00000000000..87e9fc1c803 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeview.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "assetimportupdatetreeview.h" +#include "assetimportupdatetreemodel.h" +#include "assetimportupdatetreeitemdelegate.h" + +#include + +namespace QmlDesigner { +namespace Internal { + +AssetImportUpdateTreeView::AssetImportUpdateTreeView(QWidget *parent) + : Utils::TreeView(parent) + , m_model(new AssetImportUpdateTreeModel(this)) +{ + setModel(m_model); + setItemDelegate(new AssetImportUpdateTreeItemDelegate(this)); + setUniformRowHeights(true); + setExpandsOnDoubleClick(true); + header()->hide(); +} + +void AssetImportUpdateTreeView::clear() +{ + m_model->clear(); +} + +AssetImportUpdateTreeModel *AssetImportUpdateTreeView::model() const +{ + return m_model; +} + +} // namespace Internal +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeview.h b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeview.h new file mode 100644 index 00000000000..3c5e040cfaf --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeview.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "assetimportupdatetreeitem.h" + +#include + +namespace QmlDesigner { +namespace Internal { + +class AssetImportUpdateTreeModel; + +class AssetImportUpdateTreeView : public Utils::TreeView +{ + Q_OBJECT + +public: + explicit AssetImportUpdateTreeView(QWidget *parent = nullptr); + + AssetImportUpdateTreeModel *model() const; + +public slots: + void clear(); + +protected: + AssetImportUpdateTreeModel *m_model; +}; + +} // namespace Internal +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri index 3f05f1ab0b1..8099c878536 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri @@ -15,7 +15,12 @@ HEADERS += itemlibraryview.h \ itemlibraryaddimportmodel.h \ itemlibraryassetimportdialog.h \ itemlibraryassetimporter.h \ - customfilesystemmodel.h + customfilesystemmodel.h \ + assetimportupdatedialog.h \ + assetimportupdatetreeitem.h \ + assetimportupdatetreeitemdelegate.h \ + assetimportupdatetreemodel.h \ + assetimportupdatetreeview.h SOURCES += itemlibraryview.cpp \ $$PWD/itemlibraryiconimageprovider.cpp \ @@ -31,7 +36,13 @@ SOURCES += itemlibraryview.cpp \ itemlibraryaddimportmodel.cpp \ itemlibraryassetimportdialog.cpp \ itemlibraryassetimporter.cpp \ - customfilesystemmodel.cpp + customfilesystemmodel.cpp \ + assetimportupdatedialog.cpp \ + assetimportupdatetreeitem.cpp \ + assetimportupdatetreeitemdelegate.cpp \ + assetimportupdatetreemodel.cpp \ + assetimportupdatetreeview.cpp RESOURCES += itemlibrary.qrc -FORMS += itemlibraryassetimportdialog.ui +FORMS += itemlibraryassetimportdialog.ui \ + assetimportupdatedialog.ui diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp index 847be2c5f25..69924f20080 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp @@ -23,6 +23,7 @@ ** ****************************************************************************/ #include "itemlibraryassetimporter.h" +#include "assetimportupdatedialog.h" #include "qmldesignerplugin.h" #include "qmldesignerconstants.h" @@ -41,6 +42,7 @@ #include #include #include +#include namespace { @@ -262,11 +264,43 @@ bool ItemLibraryAssetImporter::preParseQuick3DAsset(const QString &file, ParseDa pd.assetName = assetDirs[0]; pd.targetDirPath = pd.targetDir.filePath(pd.assetName); } - if (!confirmAssetOverwrite(pd.assetName)) { + OverwriteResult result = confirmAssetOverwrite(pd.assetName); + if (result == OverwriteResult::Skip) { addWarning(tr("Skipped import of existing asset: \"%1\"").arg(pd.assetName)); return false; + } else if (result == OverwriteResult::Update) { + // Add generated icons and existing source asset file, as those will always need + // to be overwritten + QSet alwaysOverwrite; + QString iconPath = pd.targetDirPath + '/' + Constants::QUICK_3D_ASSET_ICON_DIR; + // Note: Despite the name, QUICK_3D_ASSET_LIBRARY_ICON_SUFFIX is not a traditional file + // suffix. It's guaranteed to be in the generated icon filename, though. + QStringList filters {QStringLiteral("*%1*").arg(Constants::QUICK_3D_ASSET_LIBRARY_ICON_SUFFIX)}; + QDirIterator iconIt(iconPath, filters, QDir::Files); + while (iconIt.hasNext()) { + iconIt.next(); + alwaysOverwrite.insert(iconIt.fileInfo().absoluteFilePath()); + } + alwaysOverwrite.insert(sourceSceneTargetFilePath(pd)); + + Internal::AssetImportUpdateDialog dlg {pd.targetDirPath, {}, alwaysOverwrite, + qobject_cast(parent())}; + int exitVal = dlg.exec(); + + QStringList overwriteFiles; + if (exitVal == QDialog::Accepted) + overwriteFiles = dlg.selectedFiles(); + if (!overwriteFiles.isEmpty()) { + overwriteFiles.append(QStringList::fromSet(alwaysOverwrite)); + m_overwrittenImports.insert(pd.targetDirPath, overwriteFiles); + } else { + addWarning(tr("No files selected for overwrite, skipping import: \"%1\"").arg(pd.assetName)); + return false; + } + + } else { + m_overwrittenImports.insert(pd.targetDirPath, {}); } - m_overwrittenImports << pd.targetDirPath; } pd.outDir.mkpath(pd.assetName); @@ -395,8 +429,7 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(const ParseData &pd) } // Copy the original asset into a subdirectory - assetFiles.insert(pd.sourceInfo.absoluteFilePath(), - pd.targetDirPath + QStringLiteral("/source scene/") + pd.sourceInfo.fileName()); + assetFiles.insert(pd.sourceInfo.absoluteFilePath(), sourceSceneTargetFilePath(pd)); m_importFiles.insert(assetFiles); } @@ -408,11 +441,22 @@ void ItemLibraryAssetImporter::copyImportedFiles() notifyProgress(0, progressTitle); int counter = 0; - for (const QString &dirPath : qAsConst(m_overwrittenImports)) { - QDir dir(dirPath); - if (dir.exists()) - dir.removeRecursively(); + auto it = m_overwrittenImports.constBegin(); + while (it != m_overwrittenImports.constEnd()) { + QDir dir(it.key()); + if (dir.exists()) { + const auto &overwrittenFiles = it.value(); + if (overwrittenFiles.isEmpty()) { + // Overwrite entire import + dir.removeRecursively(); + } else { + // Overwrite just selected files + for (const auto &fileName : overwrittenFiles) + QFile::remove(fileName); + } + } notifyProgress((100 * ++counter) / m_overwrittenImports.size(), progressTitle); + ++it; } } @@ -430,7 +474,7 @@ void ItemLibraryAssetImporter::copyImportedFiles() // by filesystem watchers. QHash::const_iterator it = assetFiles.begin(); while (it != assetFiles.end()) { - if (QFileInfo::exists(it.key())) { + if (QFileInfo::exists(it.key()) && !QFileInfo::exists(it.value())) { QDir targetDir = QFileInfo(it.value()).dir(); if (!targetDir.exists()) targetDir.mkpath("."); @@ -461,13 +505,26 @@ void ItemLibraryAssetImporter::keepUiAlive() const QApplication::processEvents(); } -bool ItemLibraryAssetImporter::confirmAssetOverwrite(const QString &assetName) +ItemLibraryAssetImporter::OverwriteResult ItemLibraryAssetImporter::confirmAssetOverwrite(const QString &assetName) { const QString title = tr("Overwrite Existing Asset?"); - const QString question = tr("Asset already exists. Overwrite?\n\"%1\"").arg(assetName); - return QMessageBox::question(qobject_cast(parent()), - title, question, - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes; + const QString question = tr("Asset already exists. Overwrite existing or skip?\n\"%1\"").arg(assetName); + + QMessageBox msgBox {QMessageBox::Question, title, question, QMessageBox::NoButton, + qobject_cast(parent())}; + QPushButton *updateButton = msgBox.addButton(tr("Overwrite Selected Files"), QMessageBox::NoRole); + QPushButton *overwriteButton = msgBox.addButton(tr("Overwrite All Files"), QMessageBox::NoRole); + QPushButton *skipButton = msgBox.addButton(tr("Skip"), QMessageBox::NoRole); + msgBox.setDefaultButton(overwriteButton); + msgBox.setEscapeButton(skipButton); + + msgBox.exec(); + + if (msgBox.clickedButton() == updateButton) + return OverwriteResult::Update; + else if (msgBox.clickedButton() == overwriteButton) + return OverwriteResult::Overwrite; + return OverwriteResult::Skip; } bool ItemLibraryAssetImporter::startImportProcess(const ParseData &pd) @@ -623,6 +680,11 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport() } } +QString ItemLibraryAssetImporter::sourceSceneTargetFilePath(const ParseData &pd) +{ + return pd.targetDirPath + QStringLiteral("/source scene/") + pd.sourceInfo.fileName(); +} + bool ItemLibraryAssetImporter::isCancelled() const { keepUiAlive(); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h index 022859a8527..56bd8ec8f29 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h @@ -99,14 +99,22 @@ private: void notifyProgress(int value, const QString &text); void notifyProgress(int value); void keepUiAlive() const; - bool confirmAssetOverwrite(const QString &assetName); + + enum class OverwriteResult { + Skip, + Overwrite, + Update + }; + + OverwriteResult confirmAssetOverwrite(const QString &assetName); bool startImportProcess(const ParseData &pd); bool startIconProcess(int size, const QString &iconFile, const QString &iconSource); void postImport(); void finalizeQuick3DImport(); + QString sourceSceneTargetFilePath(const ParseData &pd); QSet> m_importFiles; - QSet m_overwrittenImports; + QHash m_overwrittenImports; bool m_isImporting = false; bool m_cancelled = false; QString m_importPath; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp index da508e7a6a7..f2f22b1b74f 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp @@ -64,6 +64,9 @@ QString ItemLibraryImport::sortingName() const if (m_isUserSection) // user components always come first return "_"; + if (!hasCategories()) // imports with no categories are at the bottom of the list + return "zzzzz" + importName(); + return importName(); } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index 317a5ed9834..25bef1edd4b 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -30,12 +30,13 @@ #include "itemlibraryitem.h" #include "itemlibraryinfo.h" +#include #include #include #include - -#include - +#include +#include +#include "qmldesignerplugin.h" #include #include @@ -184,9 +185,13 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model) beginResetModel(); clearSections(); + Utils::FilePath qmlFileName = QmlDesignerPlugin::instance()->currentDesignDocument()->fileName(); + ProjectExplorer::Project *project = ProjectExplorer::SessionManager::projectForFile(qmlFileName); + QString projectName = project ? project->displayName() : ""; + // create import sections for (const Import &import : model->imports()) { - if (import.isLibraryImport()) { + if (import.isLibraryImport() && import.url() != projectName) { ItemLibraryImport *itemLibImport = new ItemLibraryImport(import, this); m_importList.append(itemLibImport); itemLibImport->setImportExpanded(loadExpandedState(import.url())); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 37ce58ab493..9fdef025483 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -84,6 +84,17 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event) if (event->type() == QEvent::FocusOut) { if (obj == m_itemViewQuickWidget.data()) QMetaObject::invokeMethod(m_itemViewQuickWidget->rootObject(), "closeContextMenu"); + } else if (event->type() == QMouseEvent::MouseMove) { + if (m_itemToDrag.isValid()) { + ItemLibraryEntry entry = m_itemToDrag.value(); + auto drag = new QDrag(this); + drag->setPixmap(Utils::StyleHelper::dpiSpecificImageFile(entry.libraryEntryIconPath())); + drag->setMimeData(m_itemLibraryModel->getMimeData(entry)); + drag->exec(); + drag->deleteLater(); + + m_itemToDrag = {}; + } } return QObject::eventFilter(obj, event); @@ -218,15 +229,11 @@ void ItemLibraryWidget::setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo) if (m_itemLibraryInfo) { disconnect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged, this, &ItemLibraryWidget::delayedUpdateModel); - disconnect(m_itemLibraryInfo.data(), &ItemLibraryInfo::importTagsChanged, - this, &ItemLibraryWidget::delayedUpdateModel); } m_itemLibraryInfo = itemLibraryInfo; if (itemLibraryInfo) { connect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged, this, &ItemLibraryWidget::delayedUpdateModel); - connect(m_itemLibraryInfo.data(), &ItemLibraryInfo::importTagsChanged, - this, &ItemLibraryWidget::delayedUpdateModel); } delayedUpdateModel(); } @@ -367,25 +374,12 @@ void ItemLibraryWidget::setResourcePath(const QString &resourcePath) updateSearch(); } -void ItemLibraryWidget::startDragAndDrop(QQuickItem *mouseArea, QVariant itemLibraryId) +void ItemLibraryWidget::startDragAndDrop(const QVariant &itemLibEntry) { - m_currentitemLibraryEntry = itemLibraryId.value(); - - QMimeData *mimeData = m_itemLibraryModel->getMimeData(m_currentitemLibraryEntry); - auto drag = new QDrag(this); - - drag->setPixmap(Utils::StyleHelper::dpiSpecificImageFile( - m_currentitemLibraryEntry.libraryEntryIconPath())); - drag->setMimeData(mimeData); - - /* Workaround for bug in Qt. The release event is not delivered for Qt < 5.9 if a drag is started */ - QMouseEvent event (QEvent::MouseButtonRelease, QPoint(-1, -1), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); - QApplication::sendEvent(mouseArea, &event); - - QTimer::singleShot(0, [drag]() { - drag->exec(); - drag->deleteLater(); - }); + // Actual drag is created after mouse has moved to avoid a QDrag bug that causes drag to stay + // active (and blocks mouse release) if mouse is released at the same spot of the drag start. + // This doesn't completely eliminate the bug but makes it significantly harder to produce. + m_itemToDrag = itemLibEntry; } void ItemLibraryWidget::setFlowMode(bool b) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h index 3a274069fa2..5bde054fc9b 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -87,7 +87,7 @@ public: void setModel(Model *model); void setFlowMode(bool b); - Q_INVOKABLE void startDragAndDrop(QQuickItem *mouseArea, QVariant itemLibId); + Q_INVOKABLE void startDragAndDrop(const QVariant &itemLibEntry); Q_INVOKABLE void removeImport(const QString &importUrl); signals: @@ -123,7 +123,7 @@ private: QShortcut *m_qmlSourceUpdateShortcut; AsynchronousImageCache &m_imageCache; QPointer m_model; - ItemLibraryEntry m_currentitemLibraryEntry; + QVariant m_itemToDrag; bool m_updateRetry = false; QString m_filterText; diff --git a/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h b/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h index 9e26d8a3c22..e7d0c3e2927 100644 --- a/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h +++ b/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h @@ -108,14 +108,11 @@ public: void clearEntries(); QStringList blacklistImports() const; - QStringList showTagsForImports() const; void addBlacklistImports(const QStringList &list); - void addShowTagsForImports(const QStringList &list); signals: void entriesChanged(); - void importTagsChanged(); private: // functions ItemLibraryInfo(QObject *parent = nullptr); @@ -126,7 +123,6 @@ private: // variables QPointer m_baseInfo; QStringList m_blacklistImports; - QStringList m_showTagsForImports; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp index 31ad31aa91f..4fc5e7c0887 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp @@ -344,29 +344,11 @@ QStringList ItemLibraryInfo::blacklistImports() const return list; } -// TODO: remove this and its dependencies, as flow tags are removed -QStringList ItemLibraryInfo::showTagsForImports() const -{ - auto list = m_showTagsForImports; - if (m_baseInfo) - list.append(m_baseInfo->m_showTagsForImports); - list.removeDuplicates(); - return list; -} - void ItemLibraryInfo::addBlacklistImports(const QStringList &list) { m_blacklistImports.append(list); } -void ItemLibraryInfo::addShowTagsForImports(const QStringList &list) -{ - if (!list.isEmpty()) { - m_showTagsForImports.append(list); - emit importTagsChanged(); - } -} - void ItemLibraryInfo::setBaseInfo(ItemLibraryInfo *baseInfo) { m_baseInfo = baseInfo; diff --git a/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp b/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp index cfb35aac772..83d826ad9ac 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp @@ -231,7 +231,7 @@ void MetaInfoReader::readImportsProperty(const QString &name, const QVariant &va if (name == "blacklistImports" && !values.isEmpty()) { m_metaInfo.itemLibraryInfo()->addBlacklistImports(values); } else if (name == "showTagsForImports" && !values.isEmpty()) { - m_metaInfo.itemLibraryInfo()->addShowTagsForImports(values); + // Flow tags removed, but keeping this for now to avoid errors parsing old metadata files } else { addError(tr("Unknown property for Imports %1").arg(name), currentSourceLocation()); setParserState(Error); diff --git a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp b/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp index adc7b482d55..0c759c59ced 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp @@ -369,23 +369,6 @@ void SubComponentManager::parseQuick3DAssetDir(const QString &assetPath) for (QString &asset : assets) asset.prepend(assetImportRoot + QLatin1Char('.')); - QStringList newFlowTags; - const QStringList flowTags = model()->metaInfo().itemLibraryInfo()->showTagsForImports(); - const QString quick3Dlib = QLatin1String(Constants::QT_QUICK_3D_MODULE_NAME); - const QList possibleImports = model()->possibleImports(); - - auto isPossibleImport = [&possibleImports](const QString &asset) { - for (const Import &import : possibleImports) { - if (import.url() == asset) - return true; - } - return false; - }; - - // If there are 3D assets in import path, add a flow tag for QtQuick3D - if (!assets.isEmpty() && !flowTags.contains(quick3Dlib) && isPossibleImport(quick3Dlib)) - newFlowTags << quick3Dlib; - // Create item library entries for Quick3D assets that are imported by document const QString iconPath = QStringLiteral(":/ItemLibrary/images/item-3D_model-icon.png"); for (auto &import : qAsConst(m_imports)) { @@ -427,17 +410,6 @@ void SubComponentManager::parseQuick3DAssetDir(const QString &assetPath) } } } - - // Create flow tags for the rest, if they are possible imports - if (!assets.isEmpty()) { - for (const QString &asset : qAsConst(assets)) { - if (!flowTags.contains(asset) && isPossibleImport(asset)) - newFlowTags << asset; - } - } - - if (!newFlowTags.isEmpty()) - model()->metaInfo().itemLibraryInfo()->addShowTagsForImports(newFlowTags); } QStringList SubComponentManager::quick3DAssetPaths() const diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index f91caac9597..84985b991f7 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -70,7 +70,6 @@ const char QUICK_3D_ASSETS_FOLDER[] = "/Quick3DAssets"; const char QUICK_3D_ASSET_LIBRARY_ICON_SUFFIX[] = "_libicon"; const char QUICK_3D_ASSET_ICON_DIR[] = "_icons"; const char DEFAULT_ASSET_IMPORT_FOLDER[] = "/asset_imports"; -const char QT_QUICK_3D_MODULE_NAME[] = "QtQuick3D"; // Menus const char M_VIEW_WORKSPACES[] = "QmlDesigner.Menu.View.Workspaces"; @@ -86,7 +85,6 @@ const char EVENT_ANNOTATION_ADDED[] = "Annotation Added"; const char EVENT_RESOURCE_IMPORTED[] = "Resource Imported "; const char EVENT_ACTION_EXECUTED[] = "Action Executed "; const char EVENT_IMPORT_ADDED[] = "Import Added "; -const char EVENT_IMPORT_ADDED_FLOWTAG[] = "Import Added FlowTag "; const char EVENT_BINDINGEDITOR_OPENED[] = "Binding Editor Opened"; const char EVENT_RICHTEXT_OPENED[] = "Richtext Editor Opened"; const char EVENT_FORMEDITOR_TIME[] = "Form Editor"; diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs index 0011be7a786..bd6c94cbb62 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs @@ -603,6 +603,17 @@ Project { "integration/stackedutilitypanelcontroller.h", "integration/utilitypanelcontroller.cpp", "integration/utilitypanelcontroller.h", + "itemlibrary/assetimportupdatedialog.cpp", + "itemlibrary/assetimportupdatedialog.h", + "itemlibrary/assetimportupdatedialog.ui", + "itemlibrary/assetimportupdatetreeitem.cpp", + "itemlibrary/assetimportupdatetreeitem.h", + "itemlibrary/assetimportupdatetreeitemdelegate.cpp", + "itemlibrary/assetimportupdatetreeitemdelegate.h", + "itemlibrary/assetimportupdatetreemodel.cpp", + "itemlibrary/assetimportupdatetreemodel.h", + "itemlibrary/assetimportupdatetreeview.cpp", + "itemlibrary/assetimportupdatetreeview.h", "itemlibrary/itemlibrary.qrc", "itemlibrary/itemlibraryaddimportmodel.cpp", "itemlibrary/itemlibraryaddimportmodel.h", diff --git a/src/share/3rdparty/data.pro b/src/share/3rdparty/data.pro index 3c3ab29bcdb..b8fb477854f 100644 --- a/src/share/3rdparty/data.pro +++ b/src/share/3rdparty/data.pro @@ -7,7 +7,8 @@ STATIC_OUTPUT_BASE = $$IDE_DATA_PATH STATIC_INSTALL_BASE = $$INSTALL_DATA_PATH DATA_DIRS = \ - fonts + fonts \ + package-manager for(data_dir, DATA_DIRS) { STATIC_FILES += $$files($$PWD/$$data_dir/*, true) diff --git a/src/shared/CMakeLists.txt b/src/shared/CMakeLists.txt index cbf076479f0..6101e2a46c0 100644 --- a/src/shared/CMakeLists.txt +++ b/src/shared/CMakeLists.txt @@ -37,6 +37,7 @@ if (ENABLE_BUILD_QBS) set(INSTALL_PUBLIC_HEADERS OFF CACHE BOOL "") set(WITH_TESTS OFF) + set(WITH_PROJECT_FILE_UPDATES ON) set(QBS_INSTALL_QCH_DOCS ${WITH_DOCS} CACHE BOOL "") add_subdirectory(qbs) endif() diff --git a/src/tools/wininterrupt/CMakeLists.txt b/src/tools/wininterrupt/CMakeLists.txt index f87825ed8e8..b16e2e1e65b 100644 --- a/src/tools/wininterrupt/CMakeLists.txt +++ b/src/tools/wininterrupt/CMakeLists.txt @@ -1,3 +1,19 @@ +cmake_minimum_required(VERSION 3.10) + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake") + +project(wininterrupt) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +if (NOT QT_CREATOR_API_DEFINED) + # standalone build + include(QtCreatorIDEBranding) + include(QtCreatorAPI) +endif() + if (NOT WIN32) return() endif()