diff --git a/doc/qtcreator/images/qtcreator-build-configuration-set-clicolor-force.webp b/doc/qtcreator/images/qtcreator-build-configuration-set-clicolor-force.webp new file mode 100644 index 00000000000..fcb66513a39 Binary files /dev/null and b/doc/qtcreator/images/qtcreator-build-configuration-set-clicolor-force.webp differ diff --git a/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc b/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc index 6cc19684276..90ffd7cd809 100644 --- a/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc +++ b/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc @@ -1,4 +1,4 @@ -// Copyright (C) 2023 The Qt Company Ltd. +// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! @@ -190,6 +190,16 @@ To hide the output, select the \inlineimage icons/rightsidebaricon.png (\uicontrol {Hide/Show Right Sidebar}) button or press \key {Alt+Shift+0}. + \section1 CLICOLOR_FORCE Environment Variable + + \QC sets the environment variable \c CLICOLOR_FORCE to \e 1 to show + ANSI-colored output for CMake. This might affect the process output. + + If the output looks incorrect or different from earlier \QC versions, try + setting \c CLICOLOR_FORCE to \e 0 in \uicontrol {Use Build Environment}. + + \image qtcreator-build-configuration-set-clicolor-force.webp {Build Environment with CLICOLOR_FORCE set} + \section1 CMake Build Steps \QC builds CMake projects by running \c {cmake . --build}, which then runs diff --git a/src/libs/utils/treemodel.cpp b/src/libs/utils/treemodel.cpp index 72e80c636e7..6ebf1703ad3 100644 --- a/src/libs/utils/treemodel.cpp +++ b/src/libs/utils/treemodel.cpp @@ -604,7 +604,7 @@ TreeItem::~TreeItem() { QTC_CHECK(m_parent == nullptr); QTC_CHECK(m_model == nullptr); - removeChildren(false); + removeChildrenSilently(); } TreeItem *TreeItem::childAt(int pos) const @@ -716,6 +716,13 @@ void TreeItem::removeChildren(bool emitSignals) } } +void TreeItem::removeChildrenSilently() +{ + if (childCount() == 0) + return; + clear(); +} + void TreeItem::sortChildren(const std::function &cmp) { if (m_model) { @@ -1081,7 +1088,7 @@ void BaseTreeModel::setRootItemInternal(TreeItem *item) QTC_CHECK(m_root->m_model == this); // needs to be done explicitly before setting the model to 0, otherwise it might lead to a // crash inside a view or proxy model, especially if there are selected items - m_root->removeChildren(false); + m_root->removeChildrenSilently(); m_root->m_model = nullptr; delete m_root; } diff --git a/src/libs/utils/treemodel.h b/src/libs/utils/treemodel.h index 13d340cdf6f..d1e22f907fc 100644 --- a/src/libs/utils/treemodel.h +++ b/src/libs/utils/treemodel.h @@ -39,6 +39,7 @@ public: void removeChildAt(int pos); void removeChildren(bool emitSignals = true); + void removeChildrenSilently(); void sortChildren(const std::function &cmp); void update(); void updateAll(); diff --git a/src/plugins/texteditor/markdowneditor.cpp b/src/plugins/texteditor/markdowneditor.cpp index 3532b6a4fa0..b4f82200666 100644 --- a/src/plugins/texteditor/markdowneditor.cpp +++ b/src/plugins/texteditor/markdowneditor.cpp @@ -20,7 +20,9 @@ #include #include +#include #include +#include #include #include #include @@ -70,9 +72,22 @@ public: // preview m_previewWidget = new QTextBrowser(); - m_previewWidget->setOpenExternalLinks(true); + m_previewWidget->setOpenLinks(false); // we want to open files in QtC, not the browser m_previewWidget->setFrameShape(QFrame::NoFrame); new Utils::MarkdownHighlighter(m_previewWidget->document()); + connect(m_previewWidget, &QTextBrowser::anchorClicked, this, [this](const QUrl &link) { + if (link.hasFragment() && link.path().isEmpty() && link.scheme().isEmpty()) { + // local anchor + m_previewWidget->scrollToAnchor(link.fragment(QUrl::FullyEncoded)); + } else if (link.isLocalFile() || link.scheme().isEmpty()) { + // absolute path or relative (to the document) + // open in Qt Creator + EditorManager::openEditor( + document()->filePath().parentDir().resolvePath(link.path())); + } else { + QDesktopServices::openUrl(link); + } + }); // editor m_textEditorWidget = new TextEditorWidget; @@ -173,6 +188,26 @@ public: m_previewRestoreScrollPosition.reset(); m_previewWidget->setMarkdown(m_document->plainText()); + // Add anchors to headings. This should actually be done by Qt QTBUG-120518 + for (QTextBlock block = m_previewWidget->document()->begin(); block.isValid(); + block = block.next()) { + QTextBlockFormat fmt = block.blockFormat(); + if (fmt.hasProperty(QTextFormat::HeadingLevel)) { + QTextCharFormat cFormat = block.charFormat(); + QString anchor; + const QString text = block.text(); + for (const QChar &c : text) { + if (c == ' ') + anchor.append('-'); + else if (c == '_' || c == '-' || c.isDigit() || c.isLetter()) + anchor.append(c.toLower()); + } + cFormat.setAnchor(true); + cFormat.setAnchorNames({anchor}); + QTextCursor cursor(block); + cursor.setBlockCharFormat(cFormat); + } + } m_previewWidget->horizontalScrollBar()->setValue(positions.x()); m_previewWidget->verticalScrollBar()->setValue(positions.y()); diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index ab546fc2f83..49de5496d41 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -8782,7 +8782,7 @@ QAction * TextEditorWidget::insertExtraToolBarWidget(TextEditorWidget::Side side findLeftMostAction); return d->m_toolBar->insertWidget(before, widget); } else { - return d->m_toolBar->insertWidget(d->m_fileEncodingLabelAction, widget); + return d->m_toolBar->insertWidget(d->m_fileLineEndingAction, widget); } } diff --git a/src/share/3rdparty/package-manager/auto-setup.cmake b/src/share/3rdparty/package-manager/auto-setup.cmake index 59a43692dfb..2b14e4ae2b9 100644 --- a/src/share/3rdparty/package-manager/auto-setup.cmake +++ b/src/share/3rdparty/package-manager/auto-setup.cmake @@ -31,6 +31,13 @@ macro(qtc_auto_setup_compiler_standard toolchainFile) endif() endforeach() endforeach() + + foreach(osx_var CMAKE_SYSROOT CMAKE_OSX_SYSROOT CMAKE_OSX_ARCHITECTURES) + if (${osx_var}) + file(APPEND "${toolchainFile}" + "set(${osx_var} ${${osx_var}})\n") + endif() + endforeach() endmacro() # @@ -101,47 +108,61 @@ macro(qtc_auto_setup_conan) "include(\"${CMAKE_TOOLCHAIN_FILE}\")\n") endif() - file(WRITE "${CMAKE_BINARY_DIR}/conan-dependencies/CMakeLists.txt" " - cmake_minimum_required(VERSION 3.15) + file(WRITE "${CMAKE_BINARY_DIR}/conan-dependencies/CMakeLists.txt" " + cmake_minimum_required(VERSION 3.15) - unset(CMAKE_PROJECT_INCLUDE_BEFORE CACHE) - project(conan-setup) + unset(CMAKE_PROJECT_INCLUDE_BEFORE CACHE) + project(conan-setup) - if (${conan_version} VERSION_GREATER_EQUAL 2.0) - set(CONAN_COMMAND \"${conan_program}\") - include(\"${CMAKE_CURRENT_LIST_DIR}/conan_provider.cmake\") - conan_profile_detect_default() - detect_host_profile(\"${CMAKE_BINARY_DIR}/conan-dependencies/conan_host_profile\") + if (${conan_version} VERSION_GREATER_EQUAL 2.0) + set(CONAN_COMMAND \"${conan_program}\") + include(\"${CMAKE_CURRENT_LIST_DIR}/conan_provider.cmake\") + conan_profile_detect_default() + detect_host_profile(\"${CMAKE_BINARY_DIR}/conan-dependencies/conan_host_profile\") + set(build_types \${CMAKE_BUILD_TYPE}) + if (CMAKE_CONFIGURATION_TYPES) + set(build_types \${CMAKE_CONFIGURATION_TYPES}) + endif() + + foreach(type \${build_types}) conan_install( -pr \"${CMAKE_BINARY_DIR}/conan-dependencies/conan_host_profile\" --build=${QT_CREATOR_CONAN_BUILD_POLICY} - -s build_type=${CMAKE_BUILD_TYPE} + -s build_type=\${type} -g CMakeDeps) + endforeach() - get_property(CONAN_INSTALL_SUCCESS GLOBAL PROPERTY CONAN_INSTALL_SUCCESS) - if (CONAN_INSTALL_SUCCESS) - get_property(CONAN_GENERATORS_FOLDER GLOBAL PROPERTY CONAN_GENERATORS_FOLDER) - file(WRITE \"${CMAKE_BINARY_DIR}/conan-dependencies/conan_paths.cmake\" \" - list(PREPEND CMAKE_PREFIX_PATH \\\"\${CONAN_GENERATORS_FOLDER}\\\") - list(PREPEND CMAKE_MODULE_PATH \\\"\${CONAN_GENERATORS_FOLDER}\\\") - list(REMOVE_DUPLICATES CMAKE_PREFIX_PATH) - list(REMOVE_DUPLICATES CMAKE_MODULE_PATH) - set(CMAKE_PREFIX_PATH \\\"\\\${CMAKE_PREFIX_PATH}\\\" CACHE STRING \\\"\\\" FORCE) - set(CMAKE_MODULE_PATH \\\"\\\${CMAKE_MODULE_PATH}\\\" CACHE STRING \\\"\\\" FORCE) - \") - endif() - else() - include(\"${CMAKE_CURRENT_LIST_DIR}/conan.cmake\") - conan_cmake_run( - CONANFILE \"${conanfile_txt}\" - INSTALL_FOLDER \"${CMAKE_BINARY_DIR}/conan-dependencies\" - GENERATORS cmake_paths cmake_find_package json - BUILD ${QT_CREATOR_CONAN_BUILD_POLICY} - ENV CONAN_CMAKE_TOOLCHAIN_FILE=\"${CMAKE_BINARY_DIR}/conan-dependencies/toolchain.cmake\" - ) + get_property(CONAN_INSTALL_SUCCESS GLOBAL PROPERTY CONAN_INSTALL_SUCCESS) + if (CONAN_INSTALL_SUCCESS) + get_property(CONAN_GENERATORS_FOLDER GLOBAL PROPERTY CONAN_GENERATORS_FOLDER) + file(WRITE \"${CMAKE_BINARY_DIR}/conan-dependencies/conan_paths.cmake\" \" + list(PREPEND CMAKE_PREFIX_PATH \\\"\${CONAN_GENERATORS_FOLDER}\\\") + list(PREPEND CMAKE_MODULE_PATH \\\"\${CONAN_GENERATORS_FOLDER}\\\") + list(PREPEND CMAKE_FIND_ROOT_PATH \\\"\${CONAN_GENERATORS_FOLDER}\\\") + list(REMOVE_DUPLICATES CMAKE_PREFIX_PATH) + list(REMOVE_DUPLICATES CMAKE_MODULE_PATH) + list(REMOVE_DUPLICATES CMAKE_FIND_ROOT_PATH) + set(CMAKE_PREFIX_PATH \\\"\\\${CMAKE_PREFIX_PATH}\\\" CACHE STRING \\\"\\\" FORCE) + set(CMAKE_MODULE_PATH \\\"\\\${CMAKE_MODULE_PATH}\\\" CACHE STRING \\\"\\\" FORCE) + set(CMAKE_FIND_ROOT_PATH \\\"\\\${CMAKE_FIND_ROOT_PATH}\\\" CACHE STRING \\\"\\\" FORCE) + \") endif() - ") + else() + include(\"${CMAKE_CURRENT_LIST_DIR}/conan.cmake\") + conan_cmake_run( + CONANFILE \"${conanfile_txt}\" + INSTALL_FOLDER \"${CMAKE_BINARY_DIR}/conan-dependencies\" + GENERATORS cmake_paths cmake_find_package json + BUILD ${QT_CREATOR_CONAN_BUILD_POLICY} + ENV CONAN_CMAKE_TOOLCHAIN_FILE=\"${CMAKE_BINARY_DIR}/conan-dependencies/toolchain.cmake\" + ) + endif() + ") + + if (NOT DEFINED CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES) + set(CMAKE_CONFIGURATION_TYPES "Debug;Release") + endif() execute_process(COMMAND ${CMAKE_COMMAND} -S "${CMAKE_BINARY_DIR}/conan-dependencies/" @@ -150,6 +171,7 @@ macro(qtc_auto_setup_conan) -D "CMAKE_TOOLCHAIN_FILE=${CMAKE_BINARY_DIR}/conan-dependencies/toolchain.cmake" -G ${CMAKE_GENERATOR} -D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -D "CMAKE_CONFIGURATION_TYPES=${CMAKE_CONFIGURATION_TYPES}" RESULT_VARIABLE result ) if (result EQUAL 0)