Merge remote-tracking branch 'origin/4.10'

Conflicts:
	CMakeLists.txt
	tests/unit/unittest/unittest.pro

Change-Id: I64296ad31502d9b35012da129a28e9277e9fcf8e
This commit is contained in:
Eike Ziller
2019-06-28 12:50:03 +02:00
149 changed files with 2394 additions and 1020 deletions

View File

@@ -1,33 +1,18 @@
cmake_minimum_required(VERSION 3.9) cmake_minimum_required(VERSION 3.9)
include(FeatureSummary)
#BINARY_ARTIFACTS_BRANCH = master
#PROJECT_USER_FILE_EXTENSION = .user
set(IDE_VERSION "4.10.82" CACHE STRING "The IDE version.")
set(IDE_VERSION_COMPAT "4.10.82" CACHE STRING "The IDE Compatibility version.")
set(IDE_VERSION_DISPLAY "4.11.0-beta1" CACHE STRING "The IDE display version.")
set(IDE_COPYRIGHT_YEAR "2019" CACHE STRING "The IDE copyright year.")
set(IDE_REVISION FALSE CACHE BOOL "Marks the presence of IDE revision string.")
set(IDE_REVISION_STR "" CACHE STRING "The IDE revision string.")
set(IDE_SETTINGSVARIANT "QtProject" CACHE STRING "The IDE settings variation.")
set(IDE_COPY_SETTINGSVARIANT "Nokia" CACHE STRING "The IDE settings to initially import.")
set(IDE_DISPLAY_NAME "Qt Creator" CACHE STRING "The IDE display name.")
set(IDE_ID "qtcreator" CACHE STRING "The IDE id (no spaces, lowercase!)")
set(IDE_CASED_ID "QtCreator" CACHE STRING "The cased IDE id (no spaces!)")
set(IDE_BUNDLE_IDENTIFIER "org.qt-project.${IDE_ID}" CACHE STRING "The macOS application bundle identifier.")
mark_as_advanced(IDE_VERSION_COMPAT IDE_VERSION_DISPLAY IDE_COPYRIGHT_YEAR
IDE_REVISION IDE_REVISION_STR IDE_SETTINGSVARIANT IDE_COPY_SETTINGSVARIANT
IDE_DISPLAY_NAME IDE_ID IDE_CASED_ID IDE_BUNDLE_IDENTIFIER)
project(QtCreator VERSION ${IDE_VERSION})
## Add paths to check for cmake modules: ## Add paths to check for cmake modules:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(FeatureSummary)
include(QtCreatorIDEBranding)
set(IDE_REVISION FALSE CACHE BOOL "Marks the presence of IDE revision string.")
set(IDE_REVISION_STR "" CACHE STRING "The IDE revision string.")
mark_as_advanced(IDE_REVISION IDE_REVISION_STR)
project(QtCreator VERSION ${IDE_VERSION})
# Force C++ standard, do not fall back, do not use compiler extensions # Force C++ standard, do not fall back, do not use compiler extensions
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -127,7 +112,7 @@ endif()
set(_IDE_APP_PATH "bin") set(_IDE_APP_PATH "bin")
if (APPLE) if (APPLE)
set(_IDE_APP_TARGET "Qt Creator") set(_IDE_APP_TARGET "${IDE_DISPLAY_NAME}")
set(_IDE_OUTPUT_PATH "${_IDE_APP_PATH}/${_IDE_APP_TARGET}.app/Contents") set(_IDE_OUTPUT_PATH "${_IDE_APP_PATH}/${_IDE_APP_TARGET}.app/Contents")
@@ -139,7 +124,7 @@ if (APPLE)
set(_IDE_DOC_PATH "${_IDE_OUTPUT_PATH}/Resources/doc") set(_IDE_DOC_PATH "${_IDE_OUTPUT_PATH}/Resources/doc")
set(_IDE_BIN_PATH "${_IDE_OUTPUT_PATH}/MacOS") set(_IDE_BIN_PATH "${_IDE_OUTPUT_PATH}/MacOS")
else () else ()
set(_IDE_APP_TARGET "qtcreator") set(_IDE_APP_TARGET "${IDE_ID}")
set(_IDE_LIBRARY_BASE_PATH "lib") set(_IDE_LIBRARY_BASE_PATH "lib")
set(_IDE_LIBRARY_PATH "lib/qtcreator") set(_IDE_LIBRARY_PATH "lib/qtcreator")
@@ -154,15 +139,15 @@ else ()
set(_IDE_BIN_PATH "bin") set(_IDE_BIN_PATH "bin")
endif () endif ()
set(IDE_APP_PATH "${_IDE_APP_PATH}" CACHE PATH "The target path of the IDE application (relative to CMAKE_INSTALL_PREFIX).") set(IDE_APP_PATH "${_IDE_APP_PATH}") # The target path of the IDE application (relative to CMAKE_INSTALL_PREFIX).
set(IDE_APP_TARGET "${_IDE_APP_TARGET}" CACHE PATH "The IDE application name.") set(IDE_APP_TARGET "${_IDE_APP_TARGET}") # The IDE application name.
set(IDE_PLUGIN_PATH "${_IDE_PLUGIN_PATH}" CACHE PATH "The IDE plugin path (relative to CMAKE_INSTALL_PREFIX).") set(IDE_PLUGIN_PATH "${_IDE_PLUGIN_PATH}") # The IDE plugin path (relative to CMAKE_INSTALL_PREFIX).
set(IDE_LIBRARY_BASE_PATH "${_IDE_LIBRARY_BASE_PATH}" CACHE PATH "The IDE library base path (relative to CMAKE_INSTALL_PREFIX).") set(IDE_LIBRARY_BASE_PATH "${_IDE_LIBRARY_BASE_PATH}") # The IDE library base path (relative to CMAKE_INSTALL_PREFIX).
set(IDE_LIBRARY_PATH "${_IDE_LIBRARY_PATH}" CACHE PATH "The IDE library path (relative to CMAKE_INSTALL_PREFIX).") set(IDE_LIBRARY_PATH "${_IDE_LIBRARY_PATH}") # The IDE library path (relative to CMAKE_INSTALL_PREFIX).
set(IDE_LIBEXEC_PATH "${_IDE_LIBEXEC_PATH}" CACHE PATH "The IDE libexec path (relative to CMAKE_INSTALL_PREFIX).") set(IDE_LIBEXEC_PATH "${_IDE_LIBEXEC_PATH}") # The IDE libexec path (relative to CMAKE_INSTALL_PREFIX).
set(IDE_DATA_PATH "${_IDE_DATA_PATH}" CACHE PATH "The IDE data path (relative to CMAKE_INSTALL_PREFIX).") set(IDE_DATA_PATH "${_IDE_DATA_PATH}") # The IDE data path (relative to CMAKE_INSTALL_PREFIX).
set(IDE_DOC_PATH "${_IDE_DOC_PATH}" CACHE PATH "The IDE documentation path (relative to CMAKE_INSTALL_PREFIX).") set(IDE_DOC_PATH "${_IDE_DOC_PATH}") # The IDE documentation path (relative to CMAKE_INSTALL_PREFIX).
set(IDE_BIN_PATH "${_IDE_BIN_PATH}" CACHE PATH "The IDE bin path (relative to CMAKE_INSTALL_PREFIX).") set(IDE_BIN_PATH "${_IDE_BIN_PATH}") # The IDE bin path (relative to CMAKE_INSTALL_PREFIX).
file(RELATIVE_PATH RELATIVE_PLUGIN_PATH "/${IDE_BIN_PATH}" "/${IDE_PLUGIN_PATH}") file(RELATIVE_PATH RELATIVE_PLUGIN_PATH "/${IDE_BIN_PATH}" "/${IDE_PLUGIN_PATH}")
file(RELATIVE_PATH RELATIVE_LIBEXEC_PATH "/${IDE_BIN_PATH}" "/${IDE_LIBEXEC_PATH}") file(RELATIVE_PATH RELATIVE_LIBEXEC_PATH "/${IDE_BIN_PATH}" "/${IDE_LIBEXEC_PATH}")

View File

@@ -0,0 +1,14 @@
#BINARY_ARTIFACTS_BRANCH = master
#PROJECT_USER_FILE_EXTENSION = .user
set(IDE_VERSION "4.9.83") # The IDE version.
set(IDE_VERSION_COMPAT "4.9.83") # The IDE Compatibility version.
set(IDE_VERSION_DISPLAY "4.10.0-beta2") # The IDE display version.
set(IDE_COPYRIGHT_YEAR "2019") # The IDE copyright year.
set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation.
set(IDE_COPY_SETTINGSVARIANT "Nokia") # The IDE settings to initially import.
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.

View File

@@ -13,6 +13,12 @@ you can check out from the public Git repository. For example:
* Removed support for KDE code paster after removal of official API * Removed support for KDE code paster after removal of official API
* Added option for pinning files so they stay open when closing all files (QTCREATORBUG-21899) * Added option for pinning files so they stay open when closing all files (QTCREATORBUG-21899)
* Fixed low contrast of hovered folding markers (QTCREATORBUG-21702)
### Generic Highlighter
* Fixed that highlighting definition with MIME type `text/plain`
overrode better matching definitions (QTCREATORBUG-22540)
### Language Client ### Language Client
@@ -96,6 +102,9 @@ you can check out from the public Git repository. For example:
* Improved auto-insertion of closing curly brace (QTCREATORBUG-18872) * Improved auto-insertion of closing curly brace (QTCREATORBUG-18872)
* Fixed that snippet completion could get in the way (QTCREATORBUG-21767) * Fixed that snippet completion could get in the way (QTCREATORBUG-21767)
* Fixed crash because of small stack size (QTCREATORBUG-22496)
* Fixed recognition of C++ version (QTCREATORBUG-22444)
* Fixed `unknown argument: '-fno-keep-inline-dllexport'` (QTCREATORBUG-22452)
### Clang Format ### Clang Format
@@ -105,6 +114,8 @@ you can check out from the public Git repository. For example:
## QML Support ## QML Support
* Fixed various formatting issues * Fixed various formatting issues
* Fixed incorrect syntax warning in JavaScript template literal
(QTCREATORBUG-22474)
## Debugging ## Debugging
@@ -127,6 +138,7 @@ you can check out from the public Git repository. For example:
* Added gradient picker that allows loading and saving of presets * Added gradient picker that allows loading and saving of presets
* Added support for changing properties for multiple items at once (QDS-324) * Added support for changing properties for multiple items at once (QDS-324)
* Added missing properties for `LineEdit` and `ComboBox` * Added missing properties for `LineEdit` and `ComboBox`
* Added all fonts from project directory to font selector (QDS-100)
* Updated properties of `Flickable` * Updated properties of `Flickable`
* Improved handling of errors in state editor (QDS-695) * Improved handling of errors in state editor (QDS-695)
@@ -154,13 +166,12 @@ you can check out from the public Git repository. For example:
* Added `Clone` for MSVC toolchains (QTCREATORBUG-22163) * Added `Clone` for MSVC toolchains (QTCREATORBUG-22163)
* Fixed that `mingw32-make`'s warnings were categorized as errors (QTCREATORBUG-22171) * Fixed that `mingw32-make`'s warnings were categorized as errors (QTCREATORBUG-22171)
* Fixed bitness detection for MinGW (QTCREATORBUG-22160) * Fixed bitness detection for MinGW (QTCREATORBUG-22160)
* Fixed registration as post mortem debugger on recent Windows versions
### Linux ### Linux
* Improved auto-detection of toolchains (QTCREATORBUG-19179, QTCREATORBUG-20044, QTCREATORBUG-22081) * Improved auto-detection of toolchains (QTCREATORBUG-19179, QTCREATORBUG-20044, QTCREATORBUG-22081)
### macOS
### Android ### Android
* Removed support for MIPS64 * Removed support for MIPS64
@@ -172,13 +183,12 @@ you can check out from the public Git repository. For example:
* Added support for opening remote terminal with run environment * Added support for opening remote terminal with run environment
* Added option for `rsync` flags for deployment (QTCREATORBUG-22352) * Added option for `rsync` flags for deployment (QTCREATORBUG-22352)
### Boot to Qt
### Bare Metal ### Bare Metal
* Added include path detection and output parsers for `IAR`, `KEIL` and `SDCC` toolchains * Added include path detection and output parsers for `IAR`, `KEIL` and `SDCC` toolchains
## Credits for these changes go to: ## Credits for these changes go to:
Aleksei German Aleksei German
Alessandro Ambrosano Alessandro Ambrosano
Alessandro Portale Alessandro Portale
@@ -208,10 +218,12 @@ Ivan Komissarov
Joel Smith Joel Smith
Jörg Bornemann Jörg Bornemann
Kavindra Palaraja Kavindra Palaraja
Knud Dollereder
Leena Miettinen Leena Miettinen
Luca Carlon Luca Carlon
Marco Bubke Marco Bubke
Martin Haase Martin Haase
Michael Weghorn
Mitch Curtis Mitch Curtis
Nikolai Kosjar Nikolai Kosjar
Oliver Wolff Oliver Wolff

56
dist/changes-4.9.2.md vendored Normal file
View File

@@ -0,0 +1,56 @@
# Qt Creator 4.9.2
Qt Creator version 4.9.2 contains bug fixes.
The most important changes are listed in this document. For a complete
list of changes, see the Git log for the Qt Creator sources that
you can check out from the public Git repository. For example:
git clone git://code.qt.io/qt-creator/qt-creator.git
git log --cherry-pick --pretty=oneline origin/v4.9.1..v4.9.2
## General
* Fixed display of shortcuts in `Keyboard` preferences (QTCREATORBUG-22333)
## Editing
* Fixed disabled editor close button in Design mode (QTCREATORBUG-22553)
### Syntax Highlighting
* Fixed highlighting issue while editing (QTCREATORBUG-22290)
## All Projects
* Fixed saving state of `Hide Empty Directories`
* Fixed crash that could happen after project parsing failed
## C++ Support
* Fixed expansion of `%DATE%` in license templates (QTCREATORBUG-22440)
## Qt Quick Designer
* Fixed crash on malformed QML (QDS-778)
## Platform Specific
### macOS
* Re-enabled graphics card switching that was disabled as a workaround
for OpenGL issues on macOS 10.14.4 (QTCREATORBUG-22215)
## Credits for these changes go to:
Christian Kandeler
Christian Stenger
David Schulz
Eike Ziller
Leena Miettinen
Michl Voznesensky
Robert Löhning
Thomas Hartmann
Tim Jenssen
Tobias Hunger
Ulf Hermann

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2018 The Qt Company Ltd. ** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -43,6 +43,9 @@
native build configurations and workspaces that you can use in the compiler native build configurations and workspaces that you can use in the compiler
environment of your choice. environment of your choice.
You can use CMake from \QC to build applications for the desktop and
Android devices. You can also build single files to test your changes.
\QC automatically detects the CMake executable specified in the \c PATH. \QC automatically detects the CMake executable specified in the \c PATH.
You can add paths to other CMake executables and use them in different You can add paths to other CMake executables and use them in different
build and run \l{glossary-buildandrun-kit}{kits}. build and run \l{glossary-buildandrun-kit}{kits}.
@@ -109,6 +112,8 @@
\li Code completion \li Code completion
\li Path completion
\li Auto-indentation \li Auto-indentation
\li Matching parentheses and quotes \li Matching parentheses and quotes

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2018 The Qt Company Ltd. ** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -31,27 +31,28 @@
\title Running Autotests \title Running Autotests
\QC integrates the \l{Qt Test} framework and \QC integrates the \l{Qt Test} framework,
\l{https://github.com/google/googletest}{Google C++ Testing Framework} for \l{https://github.com/google/googletest}{Google C++ Testing Framework}, and
unit testing applications and libraries. You can use \QC to build and run \l{https://www.boost.org/doc/libs/1_70_0/libs/test/doc/html/index.html}
Qt tests, Qt Quick tests (QML-based Qt tests), and Google tests for your {Boost.Test} for unit testing applications and libraries. You can use \QC to
projects. create, build, and run Qt tests, Qt Quick tests (QML-based Qt tests), Google
tests, and Boost tests for your projects.
\image qtcreator-autotests.png \image qtcreator-autotests.png
\section1 Creating Tests \section1 Creating Tests
You can use a wizard to create projects that contain Qt or Google tests. You can use a wizard to create projects that contain tests.
\section2 Creating Qt Tests \section2 Creating Qt and Qt Quick Tests
To create a Qt test: To create a Qt or Qt Quick test:
\list 1 \list 1
\li Select \uicontrol File > \uicontrol {New File or Project} > \li Select \uicontrol File > \uicontrol {New File or Project} >
\uicontrol {Other Project} > \uicontrol {Auto Test Project} > \uicontrol {Other Project} > \uicontrol {Auto Test Project} >
\uicontrol Choose to create a project with boilerplate code for a \uicontrol Choose to create a project with boilerplate code for a
Qt test. Qt test or a Qt Quick test.
\li In the \uicontrol {Project and Test Information} dialog, specify \li In the \uicontrol {Project and Test Information} dialog, specify
settings for the project and test: settings for the project and test:
@@ -59,17 +60,17 @@
\list 1 \list 1
\li In the \uicontrol {Test framework} field, select \li In the \uicontrol {Test framework} field, select
\uicontrol {Qt Test}. \uicontrol {Qt Test} or \uicontrol {Qt Quick Test}.
\li Select the \uicontrol {GUI Application} check box to create \li For a Qt test, select the \uicontrol {GUI Application} check
a Qt application. box to create a Qt application.
\li In the \uicontrol {Test case name} field, enter a name for \li In the \uicontrol {Test case name} field, enter a name for
the test case. the test case.
\li Select the \uicontrol {Requires QApplication} check box to \li For a Qt test, select the \uicontrol {Requires \QApplication}
add the include statement for QApplication to the main.cpp check box to add the include statement for QApplication to
file of the project. the main.cpp file of the project.
\li Select the \uicontrol {Generate initialization and cleanup \li Select the \uicontrol {Generate initialization and cleanup
code} checkbox to add functions to your test that are code} checkbox to add functions to your test that are
@@ -135,6 +136,46 @@
\l{https://github.com/google/googletest/blob/master/googletest/docs/primer.md} \l{https://github.com/google/googletest/blob/master/googletest/docs/primer.md}
{Google Test Primer}. {Google Test Primer}.
\section2 Creating Boost Tests
To build and run Boost tests, you must have the Boost.Test installed on the
development host. Typically, it is installed when you install Boost. You can
download Boost from \l{https://www.boost.org/}{Boost.org}.
If Boost libraries can be found by the used compiler and build system, you
do not need to specify the include directory when creating the test.
To create a Boost test:
\list 1
\li Select \uicontrol File > \uicontrol {New File or Project} >
\uicontrol {Other Project} > \uicontrol {Auto Test Project} >
\uicontrol Choose to create a project with boilerplate code for a
Boost test.
\li In the \uicontrol {Project and Test Information} dialog, specify
settings for the project and test:
\list 1
\li In the \uicontrol {Test framework} field, select
\uicontrol {Boost Test}.
\li In the \uicontrol {Test suite name} field, enter a name for
the test suite.
\li In the \uicontrol {Test case name} field, enter a name for
the test case.
\li In the \uicontrol {Boost include dir (optional)} field,
enter the path to the directory that contains files needed
by Boost.Test, such as \e version.hpp and a subfolder called
\e test that contains the test header files.
\li In the \uicontrol {Build system} field, select the build
system to use for building the project: qmake, CMake, or
Qbs.
\endlist
\endlist
\QC creates the test in the specified project directory.
For more information about creating Boost tests, see
\l{https://www.boost.org/doc/libs/1_70_0/libs/test/doc/html/index.html}
{Boost.Test}.
\section1 Setting Up the Google C++ Testing Framework \section1 Setting Up the Google C++ Testing Framework
To build and run Google tests, you must have the Google C++ Testing To build and run Google tests, you must have the Google C++ Testing
@@ -310,6 +351,30 @@
failures into C++ exceptions, select the \uicontrol {Throw on failure} check failures into C++ exceptions, select the \uicontrol {Throw on failure} check
box. box.
\section2 Specifying Settings for Running Boost Tests
\list 1
\li To specify settings for running Boost tests, select \uicontrol Tools
> \uicontrol Options > \uicontrol {Testing} >
\uicontrol {Boost Test}.
\image qtcreator-autotests-options-boost.png
\li In the \uicontrol {Log format} field, select the error report
format to specify the type of events you want recorded in the
test report.
\li In the \uicontrol {Report level} field, select the verbosity level
of the test result report. Select \uicontrol No if you do not want
a report.
\li Select the \uicontrol Randomize check box to execute the tests in
a random order, using the seed specified in the \uicontrol Seed
field for initializing the randomizer.
\li Select the \uicontrol {Catch system errors} check box to catch
system errors.
\li Select the \uicontrol {Floating point exceptions} check box to
detect floating point exceptions.
\li Select the \uicontrol {Detect memory leaks} check box to detect
memory leaks.
\endlist
\section1 Viewing Test Output \section1 Viewing Test Output
The test results are displayed in the \uicontrol {Test Results} output pane The test results are displayed in the \uicontrol {Test Results} output pane

View File

@@ -116,9 +116,9 @@
execution. In addition, the QML Profiler enables you to profile execution. In addition, the QML Profiler enables you to profile
Qt Quick applications. Qt Quick applications.
\QC is integrated to the \l{Qt Test} and Google C++ Testing \QC is integrated to the \l{Qt Test}, Google C++ Testing, and
frameworks for unit testing applications and libraries. You can Boost.Test frameworks for unit testing applications and
use \QC to build and run autotests. libraries. You can use \QC to create, build, and run autotests.
For more information, see \l{Testing}. For more information, see \l{Testing}.
\li \b {Publishing} \li \b {Publishing}

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2018 The Qt Company Ltd. ** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -60,9 +60,8 @@
\li \l{Running Autotests} \li \l{Running Autotests}
You can build and run Qt tests, Qt Quick tests, and Google tests You can create, build and run Qt tests, Qt Quick tests, Google
using \QC. In addition, you can use a wizard to create projects that tests, and Boost tests using \QC.
contain Qt or Google tests.
\endlist \endlist

View File

@@ -153,7 +153,7 @@ class PlainDumper:
if d.isExpanded(): if d.isExpanded():
with Children(d): with Children(d):
for child in children: for child in children:
d.putSubItem(child[0], d.fromNativeValue(child[1])) d.putSubItem(child[0], d.fromNativeValue(gdb.Value(child[1])))
def importPlainDumpers(args): def importPlainDumpers(args):
if args == 'off': if args == 'off':

View File

@@ -953,34 +953,18 @@ def qdumpHelper__std__vector(d, value, isLibCpp):
innerType = value.type[0] innerType = value.type[0]
isBool = innerType.name == 'bool' isBool = innerType.name == 'bool'
try:
allocator = value.type[1].name
except:
allocator = ''
isStdAllocator = allocator == 'std::allocator<%s>' % innerType.name
if isBool: if isBool:
if isLibCpp: if isLibCpp:
if isStdAllocator:
(start, size) = value.split("pp") # start is 'unsigned long *'
else:
start = value["__begin_"].pointer() start = value["__begin_"].pointer()
size = value["__size_"] size = value["__size_"]
alloc = size alloc = size
else:
if isStdAllocator:
(start, soffset, pad, finish, foffset, pad, alloc) = value.split("pI@pI@p")
else: else:
start = value["_M_start"]["_M_p"].pointer() start = value["_M_start"]["_M_p"].pointer()
soffset = value["_M_start"]["_M_offset"] soffset = value["_M_start"]["_M_offset"].integer()
finish = value["_M_finish"]["_M_p"].pointer() finish = value["_M_finish"]["_M_p"].pointer()
foffset = value["_M_finish"]["_M_offset"] foffset = value["_M_finish"]["_M_offset"].integer()
alloc = value["_M_end_of_storage"].pointer() alloc = value["_M_end_of_storage"].pointer()
size = (finish - start) * 8 + foffset - soffset # 8 is CHAR_BIT. size = (finish - start) * 8 + foffset - soffset # 8 is CHAR_BIT.
else:
if isStdAllocator:
(start, finish, alloc) = value.split("ppp")
else: else:
if isLibCpp: if isLibCpp:
start = value["__begin_"].pointer() start = value["__begin_"].pointer()
@@ -1088,14 +1072,7 @@ def qdump__std__basic_string(d, value):
def qdump__std____cxx11__basic_string(d, value): def qdump__std____cxx11__basic_string(d, value):
innerType = value.type[0] innerType = value.type[0]
try: try:
allocator = value.type[2].name data = value["_M_dataplus"]["_M_p"].pointer()
except:
allocator = ''
if allocator == 'std::allocator<%s>' % innerType.name:
(data, size) = value.split("pI")
else:
try:
data = value["_M_dataplus"]["_M_p"]
size = int(value["_M_string_length"]) size = int(value["_M_string_length"])
except: except:
d.putEmptyValue() d.putEmptyValue()

View File

@@ -39,7 +39,35 @@ StudioControls.ComboBox {
onTextColorChanged: setColor() onTextColorChanged: setColor()
editable: true editable: true
model: ["Arial", "Times New Roman", "Courier", "Verdana", "Tahoma"]
property string fontFilter: "*.ttf *.otf"
FileResourcesModel {
modelNodeBackendProperty: modelNodeBackend
filter: comboBox.fontFilter
id: fileModel
}
function fontUrlToName(url) {
var fontLoader = Qt.createQmlObject('import QtQuick 2.0; FontLoader { source: \"' + url + '\"; }',
comboBox,
"dynamicFontLoader");
return fontLoader.name
}
function setupModel() {
var files = fileModel.fileModel
var familyNames = ["Arial", "Times New Roman", "Courier", "Verdana", "Tahoma"]
files.forEach(function (item, index) {
var name = fontUrlToName(fileModel.dirPath + "/" + item)
familyNames.push(name)
});
familyNames.sort()
comboBox.model = familyNames
}
onModelChanged: { onModelChanged: {
editText = comboBox.backendValue.valueToString editText = comboBox.backendValue.valueToString
@@ -97,10 +125,12 @@ StudioControls.ComboBox {
target: modelNodeBackend target: modelNodeBackend
onSelectionChanged: { onSelectionChanged: {
comboBox.editText = backendValue.value comboBox.editText = backendValue.value
setupModel()
} }
} }
Component.onCompleted: { Component.onCompleted: {
setupModel()
//Hack to style the text input //Hack to style the text input
for (var i = 0; i < comboBox.children.length; i++) { for (var i = 0; i < comboBox.children.length; i++) {
if (comboBox.children[i].text !== undefined) { if (comboBox.children[i].text !== undefined) {

View File

@@ -9,7 +9,7 @@
"iconText": "java", "iconText": "java",
"enabled": "%{JS: value('Plugins').indexOf('Android') >= 0}", "enabled": "%{JS: value('Plugins').indexOf('Android') >= 0}",
"options": [ { "key": "ClassName", "value": "%{JS: value('FileName').charAt(0).toUpperCase() + value('FileName').substr(1).replace(/\\.java$/,'')}" } ], "options": [ { "key": "ClassName", "value": "%{JS: value('FileName').charAt(0).toUpperCase() + value('FileName').substr(1).replace(/[.]java$/,'')}" } ],
"pages" : "pages" :
[ [

View File

@@ -2,7 +2,7 @@ import qbs
Application { Application {
@if "%{UseVirtualKeyboard}" == "true" @if "%{UseVirtualKeyboard}" == "true"
Depends { name: "Qt"; submodules: "quick", "virtualkeyboard" } Depends { name: "Qt"; submodules: ["quick", "virtualkeyboard"] }
@else @else
Depends { name: "Qt.quick" } Depends { name: "Qt.quick" }
@endif @endif

View File

@@ -14,7 +14,7 @@
{ "key": "vcsId", "value": "B.Bazaar" }, { "key": "vcsId", "value": "B.Bazaar" },
{ "key": "vcsName", "value": "%{JS: Vcs.displayName('%{vcsId}')}" }, { "key": "vcsName", "value": "%{JS: Vcs.displayName('%{vcsId}')}" },
{ "key": "SR", "value": "%{JS: '%{Repo}'.substr('%{Repo}'.indexOf(':') + 1) }" }, { "key": "SR", "value": "%{JS: '%{Repo}'.substr('%{Repo}'.indexOf(':') + 1) }" },
{ "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/\\./, '-') }"}, { "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/[.]/g, '-') }"},
{ "key": "RevArg", "value": "%{JS: '%{Rev}' !== '' ? '-r' : ''}" }, { "key": "RevArg", "value": "%{JS: '%{Rev}' !== '' ? '-r' : ''}" },
{ "key": "TargetPath", "value": "%{Path}/%{Dir}" } { "key": "TargetPath", "value": "%{Path}/%{Dir}" }
], ],

View File

@@ -13,8 +13,8 @@
[ [
{ "key": "vcsId", "value": "G.Git" }, { "key": "vcsId", "value": "G.Git" },
{ "key": "vcsName", "value": "%{JS: Vcs.displayName('%{vcsId}')}" }, { "key": "vcsName", "value": "%{JS: Vcs.displayName('%{vcsId}')}" },
{ "key": "SR", "value": "%{JS: '%{Repo}'.replace(/\\.git$/, '') }"}, { "key": "SR", "value": "%{JS: '%{Repo}'.replace(/[.]git$/, '') }"},
{ "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/\\./, '-') }"}, { "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/[.]/g, '-') }"},
{ "key": "branchArg", "value": "%{JS: '%{Branch}' ? '--branch' : '' }" }, { "key": "branchArg", "value": "%{JS: '%{Branch}' ? '--branch' : '' }" },
{ "key": "TargetPath", "value": "%{Path}/%{Dir}" } { "key": "TargetPath", "value": "%{Path}/%{Dir}" }
], ],

View File

@@ -14,7 +14,7 @@
{ "key": "vcsId", "value": "H.Mercurial" }, { "key": "vcsId", "value": "H.Mercurial" },
{ "key": "vcsName", "value": "%{JS: Vcs.displayName('%{vcsId}')}" }, { "key": "vcsName", "value": "%{JS: Vcs.displayName('%{vcsId}')}" },
{ "key": "SR", "value": "%{JS: '%{Repo}'.substr('%{Repo}'.indexOf(':') + 1) }"}, { "key": "SR", "value": "%{JS: '%{Repo}'.substr('%{Repo}'.indexOf(':') + 1) }"},
{ "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/\\./, '-') }"}, { "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/[.]/g, '-') }"},
{ "key": "TargetPath", "value": "%{Path}/%{Dir}" } { "key": "TargetPath", "value": "%{Path}/%{Dir}" }
], ],

View File

@@ -13,8 +13,8 @@
[ [
{ "key": "vcsId", "value": "J.Subversion" }, { "key": "vcsId", "value": "J.Subversion" },
{ "key": "vcsName", "value": "%{JS: Vcs.displayName('%{vcsId}')}" }, { "key": "vcsName", "value": "%{JS: Vcs.displayName('%{vcsId}')}" },
{ "key": "SR", "value": "%{JS: '%{Repo}'.replace(/\\/trunk$/, '').replace(/\\/$/, '') }"}, { "key": "SR", "value": "%{JS: '%{Repo}'.replace(/[/]trunk$/, '').replace(/[/]$/, '') }"},
{ "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/\\./, '-') }"}, { "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/[.]/g, '-') }"},
{ "key": "TargetPath", "value": "%{Path}/%{Dir}" } { "key": "TargetPath", "value": "%{Path}/%{Dir}" }
], ],

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS> <!DOCTYPE TS>
<TS version="2.0" language="fr"> <TS version="2.1" language="fr">
<context> <context>
<name>Application</name> <name>Application</name>
<message> <message>
@@ -42412,7 +42412,7 @@ au gestionnaire de version (%2)</translation>
</message> </message>
<message> <message>
<source>Set Message Tracepoint at Line %1...</source> <source>Set Message Tracepoint at Line %1...</source>
<translation>Définir un message de traçace à la ligne %1...</translation> <translation>Définir un message de traçage à la ligne %1...</translation>
</message> </message>
<message> <message>
<source>Disassemble Function &quot;%1&quot;</source> <source>Disassemble Function &quot;%1&quot;</source>
@@ -70891,7 +70891,7 @@ réinitialisation du moniteur</translation>
<message> <message>
<source>Get Started Now</source> <source>Get Started Now</source>
<translatorcomment>attention à la longueur du texte, doit reste petit</translatorcomment> <translatorcomment>attention à la longueur du texte, doit reste petit</translatorcomment>
<translation type="unfinished">Démarrer</translation> <translation>Démarrer</translation>
</message> </message>
<message> <message>
<source>Online Community</source> <source>Online Community</source>

View File

@@ -1,4 +1,4 @@
/**************************************************************************** ; /****************************************************************************
** **
** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
@@ -27,71 +27,94 @@
#include "clangpathwatcherinterface.h" #include "clangpathwatcherinterface.h"
#include "clangpathwatchernotifier.h" #include "clangpathwatchernotifier.h"
#include "changedfilepathcompressor.h" #include "directorypathcompressor.h"
#include "filepathcachinginterface.h" #include "filepathcachinginterface.h"
#include "filesystem.h"
#include "stringcache.h" #include "stringcache.h"
#include <utils/algorithm.h>
#include <QTimer> #include <QTimer>
namespace ClangBackEnd { namespace ClangBackEnd {
template<class InputIt1, class InputIt2, class Callable>
void set_greedy_intersection_call(
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable callable)
{
while (first1 != last1 && first2 != last2) {
if (*first1 < *first2) {
++first1;
} else {
if (*first2 < *first1)
++first2;
else
callable(*first1++);
}
}
}
class WatcherEntry class WatcherEntry
{ {
public: public:
ProjectPartId id; ProjectPartId id;
FilePathId pathId; DirectoryPathId directoryPathId;
FilePathId filePathId;
long long lastModified = -1;
friend bool operator==(WatcherEntry first, WatcherEntry second) friend bool operator==(WatcherEntry first, WatcherEntry second)
{ {
return first.id == second.id && first.pathId == second.pathId; return first.id == second.id && first.directoryPathId == second.directoryPathId
&& first.filePathId == second.filePathId;
} }
friend bool operator<(WatcherEntry first, WatcherEntry second) friend bool operator<(WatcherEntry first, WatcherEntry second)
{ {
return std::tie(first.pathId, first.id) < std::tie(second.pathId, second.id); return std::tie(first.directoryPathId, first.filePathId, first.id)
< std::tie(second.directoryPathId, second.filePathId, second.id);
} }
friend bool operator<(WatcherEntry entry, FilePathId pathId) friend bool operator<(DirectoryPathId directoryPathId, WatcherEntry entry)
{ {
return entry.pathId < pathId; return directoryPathId < entry.directoryPathId;
} }
friend bool operator<(FilePathId pathId, WatcherEntry entry) friend bool operator<(WatcherEntry entry, DirectoryPathId directoryPathId)
{ {
return pathId < entry.pathId; return entry.directoryPathId < directoryPathId;
} }
operator FilePathId() const operator FilePathId() const { return filePathId; }
{
return pathId; operator DirectoryPathId() const { return directoryPathId; }
}
}; };
using WatcherEntries = std::vector<WatcherEntry>; using WatcherEntries = std::vector<WatcherEntry>;
template <typename FileSystemWatcher, template<typename FileSystemWatcher, typename Timer>
typename Timer>
class CLANGSUPPORT_GCCEXPORT ClangPathWatcher : public ClangPathWatcherInterface class CLANGSUPPORT_GCCEXPORT ClangPathWatcher : public ClangPathWatcherInterface
{ {
public: public:
ClangPathWatcher(FilePathCachingInterface &pathCache, ClangPathWatcher(FilePathCachingInterface &pathCache,
ClangPathWatcherNotifier *notifier=nullptr) FileSystemInterface &fileSystem,
: m_changedFilePathCompressor(pathCache), ClangPathWatcherNotifier *notifier = nullptr)
m_pathCache(pathCache), : m_pathCache(pathCache)
m_notifier(notifier) , m_fileStatusCache(fileSystem)
, m_fileSystem(fileSystem)
, m_notifier(notifier)
{ {
QObject::connect(&m_fileSystemWatcher, QObject::connect(&m_fileSystemWatcher,
&FileSystemWatcher::fileChanged, &FileSystemWatcher::directoryChanged,
[&] (const QString &filePath) { compressChangedFilePath(filePath); }); [&](const QString &path) { compressChangedDirectoryPath(path); });
m_changedFilePathCompressor.setCallback([&] (ClangBackEnd::FilePathIds &&filePathIds) { m_directoryPathCompressor.setCallback([&](ClangBackEnd::DirectoryPathIds &&directoryPathIds) {
addChangedPathForFilePath(std::move(filePathIds)); addChangedPathForFilePath(std::move(directoryPathIds));
}); });
} }
~ClangPathWatcher() ~ClangPathWatcher()
{ {
m_changedFilePathCompressor.setCallback([&] (FilePathIds &&) {}); m_directoryPathCompressor.setCallback([&](DirectoryPathIds &&) {});
} }
void updateIdPaths(const std::vector<IdPaths> &idPaths) override void updateIdPaths(const std::vector<IdPaths> &idPaths) override
@@ -109,7 +132,7 @@ public:
auto filteredPaths = filterNotWatchedPaths(removedEntries); auto filteredPaths = filterNotWatchedPaths(removedEntries);
if (!filteredPaths.empty()) if (!filteredPaths.empty())
m_fileSystemWatcher.removePaths(convertWatcherEntriesToQStringList(filteredPaths)); m_fileSystemWatcher.removePaths(convertWatcherEntriesToDirectoryPathList(filteredPaths));
} }
void setNotifier(ClangPathWatcherNotifier *notifier) override void setNotifier(ClangPathWatcherNotifier *notifier) override
@@ -164,7 +187,13 @@ public:
outputIterator = std::transform(idPath.filePathIds.begin(), outputIterator = std::transform(idPath.filePathIds.begin(),
idPath.filePathIds.end(), idPath.filePathIds.end(),
outputIterator, outputIterator,
[&] (FilePathId pathId) { return WatcherEntry{id, pathId}; }); [&](FilePathId filePathId) {
return WatcherEntry{
id,
m_pathCache.directoryPathId(filePathId),
filePathId,
m_fileStatusCache.lastModifiedTime(filePathId)};
});
} }
std::sort(entries.begin(), entries.end()); std::sort(entries.begin(), entries.end());
@@ -182,7 +211,7 @@ public:
mergeToWatchedEntries(newEntries); mergeToWatchedEntries(newEntries);
if (!filteredPaths.empty()) if (!filteredPaths.empty())
m_fileSystemWatcher.addPaths(convertWatcherEntriesToQStringList(filteredPaths)); m_fileSystemWatcher.addPaths(convertWatcherEntriesToDirectoryPathList(filteredPaths));
} }
void removeUnusedEntries(const WatcherEntries &entries, const ProjectPartIds &ids) void removeUnusedEntries(const WatcherEntries &entries, const ProjectPartIds &ids)
@@ -194,33 +223,31 @@ public:
auto filteredPaths = filterNotWatchedPaths(oldEntries); auto filteredPaths = filterNotWatchedPaths(oldEntries);
if (!filteredPaths.empty()) if (!filteredPaths.empty())
m_fileSystemWatcher.removePaths(convertWatcherEntriesToQStringList(filteredPaths)); m_fileSystemWatcher.removePaths(convertWatcherEntriesToDirectoryPathList(filteredPaths));
} }
FileSystemWatcher &fileSystemWatcher() FileSystemWatcher &fileSystemWatcher() { return m_fileSystemWatcher; }
{
return m_fileSystemWatcher;
}
QStringList convertWatcherEntriesToQStringList( QStringList convertWatcherEntriesToDirectoryPathList(const DirectoryPathIds &directoryPathIds) const
const WatcherEntries &watcherEntries)
{ {
QStringList paths; return Utils::transform<QStringList>(directoryPathIds, [&](DirectoryPathId id) {
paths.reserve(int(watcherEntries.size())); return QString(m_pathCache.directoryPath(id));
std::transform(watcherEntries.begin(),
watcherEntries.end(),
std::back_inserter(paths),
[&] (WatcherEntry entry) {
return QString(m_pathCache.filePath(entry.pathId).path());
}); });
return paths;
} }
template <typename Compare> QStringList convertWatcherEntriesToDirectoryPathList(const WatcherEntries &watcherEntries) const
WatcherEntries notWatchedEntries(const WatcherEntries &entries, {
Compare compare) const DirectoryPathIds directoryPathIds = Utils::transform<DirectoryPathIds>(
watcherEntries, [&](WatcherEntry entry) { return entry.directoryPathId; });
std::sort(directoryPathIds.begin(), directoryPathIds.end());
directoryPathIds.erase(std::unique(directoryPathIds.begin(), directoryPathIds.end()),
directoryPathIds.end());
return convertWatcherEntriesToDirectoryPathList(directoryPathIds);
}
WatcherEntries notWatchedEntries(const WatcherEntries &entries) const
{ {
WatcherEntries notWatchedEntries; WatcherEntries notWatchedEntries;
notWatchedEntries.reserve(entries.size()); notWatchedEntries.reserve(entries.size());
@@ -229,24 +256,23 @@ public:
entries.end(), entries.end(),
m_watchedEntries.cbegin(), m_watchedEntries.cbegin(),
m_watchedEntries.cend(), m_watchedEntries.cend(),
std::back_inserter(notWatchedEntries), std::back_inserter(notWatchedEntries));
compare);
return notWatchedEntries; return notWatchedEntries;
} }
WatcherEntries notWatchedEntries(const WatcherEntries &entries) const DirectoryPathIds notWatchedPaths(const DirectoryPathIds &ids) const
{ {
return notWatchedEntries(entries, std::less<WatcherEntry>()); DirectoryPathIds notWatchedDirectoryIds;
} notWatchedDirectoryIds.reserve(ids.size());
WatcherEntries notWatchedPaths(const WatcherEntries &entries) const std::set_difference(ids.begin(),
{ ids.end(),
auto compare = [] (WatcherEntry first, WatcherEntry second) { m_watchedEntries.cbegin(),
return first.pathId < second.pathId; m_watchedEntries.cend(),
}; std::back_inserter(notWatchedDirectoryIds));
return notWatchedEntries(entries, compare); return notWatchedDirectoryIds;
} }
template <typename Compare> template <typename Compare>
@@ -297,25 +323,24 @@ public:
m_watchedEntries = std::move(newWatchedEntries); m_watchedEntries = std::move(newWatchedEntries);
} }
static static DirectoryPathIds uniquePaths(const WatcherEntries &pathEntries)
WatcherEntries uniquePaths(const WatcherEntries &pathEntries)
{ {
WatcherEntries uniqueEntries; DirectoryPathIds uniqueDirectoryIds;
uniqueEntries.reserve(pathEntries.size()); uniqueDirectoryIds.reserve(pathEntries.size());
auto compare = [] (WatcherEntry first, WatcherEntry second) { auto compare = [](WatcherEntry first, WatcherEntry second) {
return first.pathId == second.pathId; return first.directoryPathId == second.directoryPathId;
}; };
std::unique_copy(pathEntries.begin(), std::unique_copy(pathEntries.begin(),
pathEntries.end(), pathEntries.end(),
std::back_inserter(uniqueEntries), std::back_inserter(uniqueDirectoryIds),
compare); compare);
return uniqueEntries; return uniqueDirectoryIds;
} }
WatcherEntries filterNotWatchedPaths(const WatcherEntries &entries) DirectoryPathIds filterNotWatchedPaths(const WatcherEntries &entries) const
{ {
return notWatchedPaths(uniquePaths(entries)); return notWatchedPaths(uniquePaths(entries));
} }
@@ -351,40 +376,48 @@ public:
oldEntries.end(), oldEntries.end(),
std::back_inserter(newWatchedEntries)); std::back_inserter(newWatchedEntries));
m_watchedEntries = std::move(newWatchedEntries);
m_watchedEntries = newWatchedEntries;
} }
void compressChangedFilePath(const QString &filePath) void compressChangedDirectoryPath(const QString &path)
{ {
m_changedFilePathCompressor.addFilePath(filePath); m_directoryPathCompressor.addDirectoryPathId(
m_pathCache.directoryPathId(Utils::PathString{path}));
} }
WatcherEntries watchedEntriesForPaths(ClangBackEnd::FilePathIds &&filePathIds) WatcherEntries watchedEntriesForPaths(ClangBackEnd::DirectoryPathIds &&directoryPathIds)
{ {
WatcherEntries foundEntries; WatcherEntries foundEntries;
foundEntries.reserve(filePathIds.size()); foundEntries.reserve(m_watchedEntries.size());
for (FilePathId pathId : filePathIds) { set_greedy_intersection_call(m_watchedEntries.begin(),
auto range = std::equal_range(m_watchedEntries.begin(), m_watchedEntries.end(), pathId); m_watchedEntries.end(),
foundEntries.insert(foundEntries.end(), range.first, range.second); directoryPathIds.begin(),
directoryPathIds.end(),
[&](WatcherEntry &entry) {
m_fileStatusCache.update(entry.filePathId);
auto currentLastModified = m_fileStatusCache.lastModifiedTime(
entry.filePathId);
if (entry.lastModified < currentLastModified) {
foundEntries.push_back(entry);
entry.lastModified = currentLastModified;
} }
});
return foundEntries; return foundEntries;
} }
FilePathIds watchedPaths(const FilePathIds &filePathIds) const FilePathIds watchedPaths(const WatcherEntries &entries) const
{ {
FilePathIds watchedFilePathIds; auto filePathIds = Utils::transform<FilePathIds>(entries, [](WatcherEntry entry) {
watchedFilePathIds.reserve(filePathIds.size()); return entry.filePathId;
});
std::set_intersection(m_watchedEntries.begin(), std::sort(filePathIds.begin(), filePathIds.end());
m_watchedEntries.end(),
filePathIds.begin(),
filePathIds.end(),
std::back_inserter(watchedFilePathIds));
return watchedFilePathIds; filePathIds.erase(std::unique(filePathIds.begin(), filePathIds.end()), filePathIds.end());
return filePathIds;
} }
ProjectPartIds idsForWatcherEntries(const WatcherEntries &foundEntries) ProjectPartIds idsForWatcherEntries(const WatcherEntries &foundEntries)
@@ -403,21 +436,20 @@ public:
ProjectPartIds uniqueIds(ProjectPartIds &&ids) ProjectPartIds uniqueIds(ProjectPartIds &&ids)
{ {
std::sort(ids.begin(), ids.end()); std::sort(ids.begin(), ids.end());
auto newEnd = std::unique(ids.begin(), ids.end()); ids.erase(std::unique(ids.begin(), ids.end()), ids.end());
ids.erase(newEnd, ids.end());
return std::move(ids); return std::move(ids);
} }
void addChangedPathForFilePath(FilePathIds &&filePathIds) void addChangedPathForFilePath(DirectoryPathIds &&directoryPathIds)
{ {
if (m_notifier) { if (m_notifier) {
WatcherEntries foundEntries = watchedEntriesForPaths(std::move(filePathIds)); WatcherEntries foundEntries = watchedEntriesForPaths(std::move(directoryPathIds));
ProjectPartIds changedIds = idsForWatcherEntries(foundEntries); ProjectPartIds changedIds = idsForWatcherEntries(foundEntries);
m_notifier->pathsWithIdsChanged(uniqueIds(std::move(changedIds))); m_notifier->pathsWithIdsChanged(uniqueIds(std::move(changedIds)));
m_notifier->pathsChanged(watchedPaths(filePathIds)); m_notifier->pathsChanged(watchedPaths(foundEntries));
} }
} }
@@ -428,10 +460,12 @@ public:
private: private:
WatcherEntries m_watchedEntries; WatcherEntries m_watchedEntries;
ChangedFilePathCompressor<Timer> m_changedFilePathCompressor;
FileSystemWatcher m_fileSystemWatcher; FileSystemWatcher m_fileSystemWatcher;
FileStatusCache m_fileStatusCache;
FileSystemInterface &m_fileSystem;
FilePathCachingInterface &m_pathCache; FilePathCachingInterface &m_pathCache;
ClangPathWatcherNotifier *m_notifier; ClangPathWatcherNotifier *m_notifier;
DirectoryPathCompressor<Timer> m_directoryPathCompressor;
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -18,6 +18,7 @@ SOURCES += \
$$PWD/clangcodemodelserverproxy.cpp \ $$PWD/clangcodemodelserverproxy.cpp \
$$PWD/alivemessage.cpp \ $$PWD/alivemessage.cpp \
$$PWD/completionsmessage.cpp \ $$PWD/completionsmessage.cpp \
$$PWD/filesystem.cpp \
$$PWD/requestcompletionsmessage.cpp \ $$PWD/requestcompletionsmessage.cpp \
$$PWD/echomessage.cpp \ $$PWD/echomessage.cpp \
$$PWD/endmessage.cpp \ $$PWD/endmessage.cpp \
@@ -87,7 +88,8 @@ SOURCES += \
$$PWD/removegeneratedfilesmessage.cpp \ $$PWD/removegeneratedfilesmessage.cpp \
$$PWD/generatedfiles.cpp \ $$PWD/generatedfiles.cpp \
$$PWD/projectpartartefact.cpp \ $$PWD/projectpartartefact.cpp \
$$PWD/projectpartcontainer.cpp $$PWD/projectpartcontainer.cpp \
$$PWD/filestatuscache.cpp
HEADERS += \ HEADERS += \
$$PWD/cancelmessage.h \ $$PWD/cancelmessage.h \
@@ -109,7 +111,11 @@ HEADERS += \
$$PWD/alivemessage.h \ $$PWD/alivemessage.h \
$$PWD/clangsupportexceptions.h \ $$PWD/clangsupportexceptions.h \
$$PWD/completionsmessage.h \ $$PWD/completionsmessage.h \
$$PWD/directoryandfilepathid.h \
$$PWD/directorypathid.h \
$$PWD/executeinloop.h \ $$PWD/executeinloop.h \
$$PWD/filesystem.h \
$$PWD/filesysteminterface.h \
$$PWD/pchpaths.h \ $$PWD/pchpaths.h \
$$PWD/projectpartid.h \ $$PWD/projectpartid.h \
$$PWD/projectpartsstorage.h \ $$PWD/projectpartsstorage.h \
@@ -151,6 +157,7 @@ HEADERS += \
$$PWD/refactoringserverinterface.h \ $$PWD/refactoringserverinterface.h \
$$PWD/refactoringserverproxy.h \ $$PWD/refactoringserverproxy.h \
$$PWD/referencesmessage.h \ $$PWD/referencesmessage.h \
$$PWD/set_algorithm.h \
$$PWD/unsavedfilesupdatedmessage.h \ $$PWD/unsavedfilesupdatedmessage.h \
$$PWD/removeprojectpartsmessage.h \ $$PWD/removeprojectpartsmessage.h \
$$PWD/requestannotationsmessage.h \ $$PWD/requestannotationsmessage.h \
@@ -217,6 +224,8 @@ HEADERS += \
$$PWD/sourceentry.h \ $$PWD/sourceentry.h \
$$PWD/modifiedtimecheckerinterface.h \ $$PWD/modifiedtimecheckerinterface.h \
$$PWD/environment.h \ $$PWD/environment.h \
$$PWD/filestatus.h \
$$PWD/filestatuscache.h \
$$PWD/modifiedtimechecker.h $$PWD/modifiedtimechecker.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols

View File

@@ -0,0 +1,90 @@
/****************************************************************************
**
** Copyright (C) 2019 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 "directorypathid.h"
#include "filepathid.h"
#include <QDataStream>
#include <vector>
namespace ClangBackEnd {
class DirectoryAndFilePathId
{
public:
constexpr DirectoryAndFilePathId() = default;
DirectoryAndFilePathId(const char *) = delete;
DirectoryAndFilePathId(int directoryPathId, int filePathId)
: directoryPathId(directoryPathId)
, filePathId(filePathId)
{}
bool isValid() const { return directoryPathId.isValid() && filePathId.isValid(); }
friend bool operator==(DirectoryAndFilePathId first, DirectoryAndFilePathId second)
{
return first.isValid() && first.directoryPathId == second.directoryPathId
&& first.filePathId == second.filePathId;
}
friend bool operator!=(DirectoryAndFilePathId first, DirectoryAndFilePathId second)
{
return !(first == second);
}
friend bool operator<(DirectoryAndFilePathId first, DirectoryAndFilePathId second)
{
return std::tie(first.directoryPathId, first.filePathId)
< std::tie(second.directoryPathId, second.filePathId);
}
friend QDataStream &operator<<(QDataStream &out,
const DirectoryAndFilePathId &directoryAndFilePathId)
{
out << directoryAndFilePathId.directoryPathId;
out << directoryAndFilePathId.filePathId;
return out;
}
friend QDataStream &operator>>(QDataStream &in, DirectoryAndFilePathId &directoryAndFilePathId)
{
in >> directoryAndFilePathId.directoryPathId;
in >> directoryAndFilePathId.filePathId;
return in;
}
public:
DirectoryPathId directoryPathId;
FilePathId filePathId;
};
using DirectoryAndFilePathIds = std::vector<DirectoryAndFilePathId>;
} // namespace ClangBackEnd

View File

@@ -27,53 +27,44 @@
#include "clangsupport_global.h" #include "clangsupport_global.h"
#include <filepathid.h> #include "filepathcachinginterface.h"
#include <filepathcache.h>
#include <QDir>
#include <QTimer> #include <QTimer>
#include <filepathcachinginterface.h> #include <utils/algorithm.h>
#include <functional> #include <functional>
namespace ClangBackEnd { namespace ClangBackEnd {
template <typename Timer> template<typename Timer>
class ChangedFilePathCompressor class DirectoryPathCompressor
{ {
public: public:
ChangedFilePathCompressor(FilePathCachingInterface &filePathCache) DirectoryPathCompressor() { m_timer.setSingleShot(true); }
: m_filePathCache(filePathCache)
virtual ~DirectoryPathCompressor() = default;
void addDirectoryPathId(DirectoryPathId directoryPathIdId)
{ {
m_timer.setSingleShot(true); auto found = std::lower_bound(m_directoryPathIds.begin(),
} m_directoryPathIds.end(),
directoryPathIdId);
virtual ~ChangedFilePathCompressor() if (found == m_directoryPathIds.end() || *found != directoryPathIdId)
{ m_directoryPathIds.insert(found, directoryPathIdId);
}
void addFilePath(const QString &filePath)
{
FilePathId filePathId = m_filePathCache.filePathId(FilePath(filePath));
auto found = std::lower_bound(m_filePaths.begin(), m_filePaths.end(), filePathId);
if (found == m_filePaths.end() || *found != filePathId)
m_filePaths.insert(found, filePathId);
restartTimer(); restartTimer();
} }
FilePathIds takeFilePathIds() DirectoryPathIds takeDirectoryPathIds() { return std::move(m_directoryPathIds); }
{
return std::move(m_filePaths);
}
virtual void setCallback(std::function<void(ClangBackEnd::FilePathIds &&)> &&callback) virtual void setCallback(std::function<void(ClangBackEnd::DirectoryPathIds &&)> &&callback)
{ {
QObject::connect(&m_timer, QObject::connect(&m_timer, &Timer::timeout, [this, callback = std::move(callback)] {
&Timer::timeout, callback(takeDirectoryPathIds());
[this, callback=std::move(callback)] { callback(takeFilePathIds()); }); });
} }
unittest_public: unittest_public:
@@ -88,9 +79,8 @@ unittest_public:
} }
private: private:
FilePathIds m_filePaths; DirectoryPathIds m_directoryPathIds;
Timer m_timer; Timer m_timer;
FilePathCachingInterface &m_filePathCache;
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -0,0 +1,81 @@
/****************************************************************************
**
** Copyright (C) 2019 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 <QDataStream>
#include <vector>
namespace ClangBackEnd {
class DirectoryPathId
{
public:
constexpr DirectoryPathId() = default;
DirectoryPathId(const char *) = delete;
DirectoryPathId(int directoryPathId)
: directoryPathId(directoryPathId)
{}
bool isValid() const { return directoryPathId >= 0; }
friend bool operator==(DirectoryPathId first, DirectoryPathId second)
{
return first.isValid() && first.directoryPathId == second.directoryPathId;
}
friend bool operator!=(DirectoryPathId first, DirectoryPathId second)
{
return !(first == second);
}
friend bool operator<(DirectoryPathId first, DirectoryPathId second)
{
return first.directoryPathId < second.directoryPathId;
}
friend QDataStream &operator<<(QDataStream &out, const DirectoryPathId &directoryPathId)
{
out << directoryPathId.directoryPathId;
return out;
}
friend QDataStream &operator>>(QDataStream &in, DirectoryPathId &directoryPathId)
{
in >> directoryPathId.directoryPathId;
return in;
}
public:
int directoryPathId = -1;
};
using DirectoryPathIds = std::vector<DirectoryPathId>;
} // namespace ClangBackEnd

View File

@@ -25,9 +25,10 @@
#pragma once #pragma once
#include "directorypathid.h"
#include "filepath.h"
#include "filepathexceptions.h" #include "filepathexceptions.h"
#include "filepathid.h" #include "filepathid.h"
#include "filepath.h"
#include "filepathview.h" #include "filepathview.h"
#include "stringcache.h" #include "stringcache.h"
@@ -121,8 +122,8 @@ public:
{ {
Utils::SmallStringView directoryPath = filePath.directory(); Utils::SmallStringView directoryPath = filePath.directory();
int directoryId = m_directoryPathCache.stringId(directoryPath, int directoryId = m_directoryPathCache.stringId(
[&] (const Utils::SmallStringView) { directoryPath, [&](const Utils::SmallStringView directoryPath) {
return m_filePathStorage.fetchDirectoryId(directoryPath); return m_filePathStorage.fetchDirectoryId(directoryPath);
}); });
@@ -136,6 +137,17 @@ public:
return fileNameId; return fileNameId;
} }
DirectoryPathId directoryPathId(Utils::SmallStringView directoryPath) const
{
Utils::SmallStringView path = directoryPath.back() == '/'
? directoryPath.mid(0, directoryPath.size() - 1)
: directoryPath;
return m_directoryPathCache.stringId(path, [&](const Utils::SmallStringView directoryPath) {
return m_filePathStorage.fetchDirectoryId(directoryPath);
});
}
FilePath filePath(FilePathId filePathId) const FilePath filePath(FilePathId filePathId) const
{ {
if (Q_UNLIKELY(!filePathId.isValid())) if (Q_UNLIKELY(!filePathId.isValid()))
@@ -157,6 +169,32 @@ public:
return FilePath{directoryPath, entry.fileName}; return FilePath{directoryPath, entry.fileName};
} }
Utils::PathString directoryPath(DirectoryPathId directoryPathId) const
{
if (Q_UNLIKELY(!directoryPathId.isValid()))
throw NoDirectoryPathForInvalidDirectoryPathId();
auto fetchDirectoryPath = [&](int id) { return m_filePathStorage.fetchDirectoryPath(id); };
return m_directoryPathCache.string(directoryPathId.directoryPathId, fetchDirectoryPath);
}
DirectoryPathId directoryPathId(FilePathId filePathId) const
{
if (Q_UNLIKELY(!filePathId.isValid()))
throw NoFilePathForInvalidFilePathId();
auto fetchSoureNameAndDirectoryId = [&](int id) {
auto entry = m_filePathStorage.fetchSourceNameAndDirectoryId(id);
return FileNameEntry{entry.sourceName, entry.directoryId};
};
FileNameEntry entry = m_fileNameCache.string(filePathId.filePathId,
fetchSoureNameAndDirectoryId);
return m_fileNameCache.string(filePathId.filePathId, fetchSoureNameAndDirectoryId).directoryId;
}
private: private:
mutable DirectoryPathCache m_directoryPathCache; mutable DirectoryPathCache m_directoryPathCache;
mutable FileNameCache m_fileNameCache; mutable FileNameCache m_fileNameCache;

View File

@@ -37,4 +37,19 @@ FilePath FilePathCaching::filePath(FilePathId filePathId) const
return m_cache.filePath(filePathId); return m_cache.filePath(filePathId);
} }
DirectoryPathId FilePathCaching::directoryPathId(Utils::SmallStringView directoryPath) const
{
return m_cache.directoryPathId(directoryPath);
}
Utils::PathString FilePathCaching::directoryPath(DirectoryPathId directoryPathId) const
{
return m_cache.directoryPath(directoryPathId);
}
DirectoryPathId FilePathCaching::directoryPathId(FilePathId filePathId) const
{
return m_cache.directoryPathId(filePathId);
}
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -50,6 +50,9 @@ public:
FilePathId filePathId(FilePathView filePath) const override; FilePathId filePathId(FilePathView filePath) const override;
FilePath filePath(FilePathId filePathId) const override; FilePath filePath(FilePathId filePathId) const override;
DirectoryPathId directoryPathId(Utils::SmallStringView directoryPath) const override;
Utils::PathString directoryPath(DirectoryPathId directoryPathId) const override;
DirectoryPathId directoryPathId(FilePathId filePathId) const override;
private: private:
Factory m_factory; Factory m_factory;

View File

@@ -25,6 +25,7 @@
#pragma once #pragma once
#include "directorypathid.h"
#include "filepath.h" #include "filepath.h"
#include "filepathid.h" #include "filepathid.h"
#include "filepathview.h" #include "filepathview.h"
@@ -40,8 +41,11 @@ public:
virtual FilePathId filePathId(FilePathView filePath) const = 0; virtual FilePathId filePathId(FilePathView filePath) const = 0;
virtual FilePath filePath(FilePathId filePathId) const = 0; virtual FilePath filePath(FilePathId filePathId) const = 0;
virtual DirectoryPathId directoryPathId(Utils::SmallStringView directoryPath) const = 0;
virtual DirectoryPathId directoryPathId(FilePathId filePathId) const = 0;
virtual Utils::PathString directoryPath(DirectoryPathId directoryPathId) const = 0;
template <typename Container> template<typename Container>
FilePathIds filePathIds(Container &&filePaths) const FilePathIds filePathIds(Container &&filePaths) const
{ {
FilePathIds filePathIds; FilePathIds filePathIds;

View File

@@ -38,6 +38,15 @@ public:
} }
}; };
class NoDirectoryPathForInvalidDirectoryPathId : std::exception
{
public:
const char *what() const noexcept override
{
return "You cannot get a directory path for an invalid directory path id!";
}
};
class SourceNameIdDoesNotExists : std::exception class SourceNameIdDoesNotExists : std::exception
{ {
public: public:

View File

@@ -179,12 +179,32 @@ public:
transaction.commit(); transaction.commit();
return optionalSourceName.value(); return *optionalSourceName;
} catch (const Sqlite::StatementIsBusy &) { } catch (const Sqlite::StatementIsBusy &) {
return fetchSourceNameAndDirectoryId(sourceId); return fetchSourceNameAndDirectoryId(sourceId);
} }
} }
int fetchDirectoryId(int sourceId)
{
try {
Sqlite::DeferredTransaction transaction{m_statementFactory.database};
ReadStatement &statement = m_statementFactory.selectDirectoryIdFromSourcesBySourceId;
auto optionalDirectoryId = statement.template value<int>(sourceId);
if (!optionalDirectoryId)
throw SourceNameIdDoesNotExists();
transaction.commit();
return *optionalDirectoryId;
} catch (const Sqlite::StatementIsBusy &) {
return fetchDirectoryId(sourceId);
}
}
std::vector<Sources::Source> fetchAllSources() std::vector<Sources::Source> fetchAllSources()
{ {
try { try {

View File

@@ -69,6 +69,8 @@ public:
"SELECT sourceName, directoryId FROM sources WHERE sourceId = ?", "SELECT sourceName, directoryId FROM sources WHERE sourceId = ?",
database database
}; };
ReadStatement selectDirectoryIdFromSourcesBySourceId{
"SELECT directoryId FROM sources WHERE sourceId = ?", database};
WriteStatement insertIntoSources{ WriteStatement insertIntoSources{
"INSERT INTO sources(directoryId, sourceName) VALUES (?,?)", "INSERT INTO sources(directoryId, sourceName) VALUES (?,?)",
database database

View File

@@ -0,0 +1,137 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "filestatuscache.h"
#include "filesystem.h"
#include <set_algorithm.h>
#include <utils/algorithm.h>
#include <QDateTime>
#include <QFileInfo>
namespace ClangBackEnd {
long long FileStatusCache::lastModifiedTime(FilePathId filePathId) const
{
return findEntry(filePathId).lastModified;
}
void FileStatusCache::update(FilePathId filePathId)
{
auto found = std::lower_bound(m_cacheEntries.begin(),
m_cacheEntries.end(),
Internal::FileStatusCacheEntry{filePathId},
[] (const auto &first, const auto &second) {
return first.filePathId < second.filePathId;
});
if (found != m_cacheEntries.end() && found->filePathId == filePathId)
found->lastModified = m_fileSystem.lastModified(filePathId);
}
void FileStatusCache::update(FilePathIds filePathIds)
{
std::set_intersection(m_cacheEntries.begin(),
m_cacheEntries.end(),
filePathIds.begin(),
filePathIds.end(),
make_iterator([&](auto &entry) {
entry.lastModified = m_fileSystem.lastModified(entry.filePathId);
}));
}
FilePathIds FileStatusCache::modified(FilePathIds filePathIds) const
{
FilePathIds modifiedFilePathIds;
modifiedFilePathIds.reserve(filePathIds.size());
std::set_intersection(m_cacheEntries.begin(),
m_cacheEntries.end(),
filePathIds.begin(),
filePathIds.end(),
make_iterator([&](auto &entry) {
auto newLastModified = m_fileSystem.lastModified(entry.filePathId);
if (newLastModified > entry.lastModified) {
modifiedFilePathIds.push_back(entry.filePathId);
entry.lastModified = newLastModified;
}
}));
Internal::FileStatusCacheEntries newEntries;
newEntries.reserve(filePathIds.size());
std::set_difference(filePathIds.begin(),
filePathIds.end(),
m_cacheEntries.begin(),
m_cacheEntries.end(),
make_iterator([&](FilePathId newFilePathId) {
newEntries.emplace_back(newFilePathId,
m_fileSystem.lastModified(newFilePathId));
modifiedFilePathIds.push_back(newFilePathId);
}));
if (newEntries.size()) {
Internal::FileStatusCacheEntries mergedEntries;
mergedEntries.reserve(m_cacheEntries.size() + newEntries.size());
std::set_union(newEntries.begin(),
newEntries.end(),
m_cacheEntries.begin(),
m_cacheEntries.end(),
std::back_inserter(mergedEntries));
m_cacheEntries = std::move(mergedEntries);
}
std::sort(modifiedFilePathIds.begin(), modifiedFilePathIds.end());
return modifiedFilePathIds;
}
FileStatusCache::size_type FileStatusCache::size() const
{
return m_cacheEntries.size();
}
Internal::FileStatusCacheEntry FileStatusCache::findEntry(FilePathId filePathId) const
{
auto found = std::lower_bound(m_cacheEntries.begin(),
m_cacheEntries.end(),
Internal::FileStatusCacheEntry{filePathId},
[] (const auto &first, const auto &second) {
return first.filePathId < second.filePathId;
});
if (found != m_cacheEntries.end() && found->filePathId == filePathId)
return *found;
auto inserted = m_cacheEntries.emplace(found, filePathId, m_fileSystem.lastModified(filePathId));
return *inserted;
}
} // namespace ClangBackEnd

View File

@@ -31,6 +31,8 @@ QT_FORWARD_DECLARE_CLASS(QFileInfo)
namespace ClangBackEnd { namespace ClangBackEnd {
class FileSystemInterface;
namespace Internal { namespace Internal {
class FileStatusCacheEntry class FileStatusCacheEntry
{ {
@@ -41,8 +43,23 @@ public:
lastModified(lastModified) lastModified(lastModified)
{} {}
friend bool operator<(FileStatusCacheEntry first, FileStatusCacheEntry second)
{
return first.filePathId < second.filePathId;
}
friend bool operator<(FileStatusCacheEntry first, FilePathId second)
{
return first.filePathId < second;
}
friend bool operator<(FilePathId first, FileStatusCacheEntry second)
{
return first < second.filePathId;
}
public: public:
ClangBackEnd::FilePathId filePathId; FilePathId filePathId;
long long lastModified; long long lastModified;
}; };
@@ -50,27 +67,30 @@ using FileStatusCacheEntries = std::vector<FileStatusCacheEntry>;
} }
class FileStatusCache class CLANGSUPPORT_EXPORT FileStatusCache
{ {
public: public:
using size_type = Internal::FileStatusCacheEntries::size_type; using size_type = Internal::FileStatusCacheEntries::size_type;
FileStatusCache(FilePathCachingInterface &filePathCache); FileStatusCache(FileSystemInterface &fileSystem)
: m_fileSystem(fileSystem)
{}
FileStatusCache &operator=(const FileStatusCache &) = delete; FileStatusCache &operator=(const FileStatusCache &) = delete;
FileStatusCache(const FileStatusCache &) = delete; FileStatusCache(const FileStatusCache &) = delete;
long long lastModifiedTime(ClangBackEnd::FilePathId filePathId) const; long long lastModifiedTime(FilePathId filePathId) const;
void update(ClangBackEnd::FilePathId filePathId); void update(FilePathId filePathId);
void update(FilePathIds filePathIds);
FilePathIds modified(FilePathIds filePathIds) const;
size_type size() const; size_type size() const;
private: private:
Internal::FileStatusCacheEntry findEntry(ClangBackEnd::FilePathId filePathId) const; Internal::FileStatusCacheEntry findEntry(FilePathId filePathId) const;
QFileInfo qFileInfo(ClangBackEnd::FilePathId filePathId) const;
private: private:
mutable Internal::FileStatusCacheEntries m_cacheEntries; mutable Internal::FileStatusCacheEntries m_cacheEntries;
FilePathCachingInterface &m_filePathCache; FileSystemInterface &m_fileSystem;
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -0,0 +1,61 @@
/****************************************************************************
**
** Copyright (C) 2019 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 "filesystem.h"
#include "filepathcachinginterface.h"
#include <utils/algorithm.h>
#include <QDateTime>
#include <QDir>
#include <QFileInfo>
namespace ClangBackEnd {
FilePathIds FileSystem::directoryEntries(const QString &directoryPath) const
{
QDir directory{directoryPath};
QFileInfoList fileInfos = directory.entryInfoList();
FilePathIds filePathIds = Utils::transform<FilePathIds>(fileInfos, [&](const QFileInfo &fileInfo) {
return m_filePathCache.filePathId(FilePath{fileInfo.path()});
});
std::sort(filePathIds.begin(), filePathIds.end());
return filePathIds;
}
long long FileSystem::lastModified(FilePathId filePathId) const
{
QFileInfo fileInfo(QString(m_filePathCache.filePath(filePathId)));
fileInfo.refresh();
return fileInfo.lastModified().toMSecsSinceEpoch() / 1000;
}
} // namespace ClangBackEnd

View File

@@ -0,0 +1,48 @@
/****************************************************************************
**
** Copyright (C) 2019 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 "filestatuscache.h"
#include "filesysteminterface.h"
namespace ClangBackEnd {
class FilePathCachingInterface;
class CLANGSUPPORT_EXPORT FileSystem final : public FileSystemInterface
{
public:
FileSystem(FilePathCachingInterface &filePathCache)
: m_filePathCache(filePathCache)
{}
FilePathIds directoryEntries(const QString &directoryPath) const override;
long long lastModified(FilePathId filePathId) const override;
private:
FilePathCachingInterface &m_filePathCache;
};
} // namespace ClangBackEnd

View File

@@ -0,0 +1,43 @@
/****************************************************************************
**
** Copyright (C) 2019 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 "filepathid.h"
#include <utils/smallstringview.h>
namespace ClangBackEnd {
class FileSystemInterface
{
public:
virtual FilePathIds directoryEntries(const QString &directoryPath) const = 0;
virtual long long lastModified(FilePathId filePathId) const = 0;
protected:
~FileSystemInterface() = default;
};
} // namespace ClangBackEnd

View File

@@ -25,23 +25,23 @@
#pragma once #pragma once
#include "filepathcachinginterface.h" #include "filesysteminterface.h"
#include "modifiedtimecheckerinterface.h" #include "modifiedtimecheckerinterface.h"
#include "set_algorithm.h"
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
namespace ClangBackEnd { namespace ClangBackEnd {
template<typename SourceEntries = ::ClangBackEnd::SourceEntries> template<typename SourceEntries = ::ClangBackEnd::SourceEntries>
class ModifiedTimeChecker final : public ModifiedTimeCheckerInterface<SourceEntries> class ModifiedTimeChecker final : public ModifiedTimeCheckerInterface<SourceEntries>
{ {
using SourceEntry = typename SourceEntries::value_type; using SourceEntry = typename SourceEntries::value_type;
public: public:
using GetModifiedTime = std::function<ClangBackEnd::TimeStamp(ClangBackEnd::FilePathView filePath)>; ModifiedTimeChecker(FileSystemInterface &fileSystem)
ModifiedTimeChecker(GetModifiedTime &getModifiedTime, FilePathCachingInterface &filePathCache) : m_fileSystem(fileSystem)
: m_getModifiedTime(getModifiedTime)
, m_filePathCache(filePathCache)
{} {}
bool isUpToDate(const SourceEntries &sourceEntries) const bool isUpToDate(const SourceEntries &sourceEntries) const
@@ -51,165 +51,101 @@ public:
updateCurrentSourceTimeStamps(sourceEntries); updateCurrentSourceTimeStamps(sourceEntries);
return compareEntries(sourceEntries); return compareEntries(sourceEntries) && notReseted(sourceEntries);
} }
void pathsChanged(const FilePathIds &filePathIds) void pathsChanged(const FilePathIds &filePathIds) override
{ {
using SourceTimeStampReferences = std::vector<std::reference_wrapper<SourceTimeStamp>>;
SourceTimeStampReferences timeStampsToUpdate;
timeStampsToUpdate.reserve(filePathIds.size());
std::set_intersection(m_currentSourceTimeStamps.begin(), std::set_intersection(m_currentSourceTimeStamps.begin(),
m_currentSourceTimeStamps.end(), m_currentSourceTimeStamps.end(),
filePathIds.begin(), filePathIds.begin(),
filePathIds.end(), filePathIds.end(),
std::back_inserter(timeStampsToUpdate)); make_iterator([&](SourceTimeStamp &sourceTimeStamp) {
sourceTimeStamp.timeStamp = m_fileSystem.lastModified(
for (SourceTimeStamp &sourceTimeStamp : timeStampsToUpdate) { sourceTimeStamp.sourceId);
sourceTimeStamp.timeStamp = m_getModifiedTime( }));
m_filePathCache.filePath(sourceTimeStamp.sourceId));
} }
void reset(const FilePathIds &filePathIds)
{
FilePathIds newResetFilePathIds;
newResetFilePathIds.reserve(newResetFilePathIds.size() + m_resetFilePathIds.size());
std::set_union(m_resetFilePathIds.begin(),
m_resetFilePathIds.end(),
filePathIds.begin(),
filePathIds.end(),
std::back_inserter(newResetFilePathIds));
m_resetFilePathIds = std::move(newResetFilePathIds);
} }
private: private:
bool compareEntries(const SourceEntries &sourceEntries) const bool compareEntries(const SourceEntries &sourceEntries) const
{ {
class CompareSourceId return set_intersection_compare(
{ m_currentSourceTimeStamps.begin(),
public:
bool operator()(SourceTimeStamp first, SourceTimeStamp second)
{
return first.sourceId < second.sourceId;
}
bool operator()(::ClangBackEnd::SourceEntry first, ::ClangBackEnd::SourceEntry second)
{
return first.sourceId < second.sourceId;
}
bool operator()(SourceTimeStamp first, ::ClangBackEnd::SourceEntry second)
{
return first.sourceId < second.sourceId;
}
bool operator()(::ClangBackEnd::SourceEntry first, SourceTimeStamp second)
{
return first.sourceId < second.sourceId;
}
};
SourceTimeStamps currentSourceTimeStamp;
currentSourceTimeStamp.reserve(sourceEntries.size());
std::set_intersection(m_currentSourceTimeStamps.begin(),
m_currentSourceTimeStamps.end(), m_currentSourceTimeStamps.end(),
sourceEntries.begin(), sourceEntries.begin(),
sourceEntries.end(), sourceEntries.end(),
std::back_inserter(currentSourceTimeStamp), [](auto first, auto second) { return second.timeStamp > first.timeStamp; },
CompareSourceId{}); [](auto first, auto second) { return first.sourceId < second.sourceId; });
class CompareTime
{
public:
bool operator()(SourceTimeStamp first, SourceTimeStamp second)
{
return first.timeStamp <= second.timeStamp;
}
bool operator()(::ClangBackEnd::SourceEntry first, ::ClangBackEnd::SourceEntry second)
{
return first.timeStamp <= second.timeStamp;
}
bool operator()(SourceTimeStamp first, ::ClangBackEnd::SourceEntry second)
{
return first.timeStamp <= second.timeStamp;
}
bool operator()(::ClangBackEnd::SourceEntry first, SourceTimeStamp second)
{
return first.timeStamp <= second.timeStamp;
}
};
return std::lexicographical_compare(currentSourceTimeStamp.begin(),
currentSourceTimeStamp.end(),
sourceEntries.begin(),
sourceEntries.end(),
CompareTime{});
} }
void updateCurrentSourceTimeStamps(const SourceEntries &sourceEntries) const void updateCurrentSourceTimeStamps(const SourceEntries &sourceEntries) const
{ {
SourceTimeStamps sourceTimeStamps = newSourceTimeStamps(sourceEntries); SourceTimeStamps sourceTimeStamps = newSourceTimeStamps(sourceEntries);
for (SourceTimeStamp &newSourceTimeStamp : sourceTimeStamps) {
newSourceTimeStamp.timeStamp = m_getModifiedTime(
m_filePathCache.filePath(newSourceTimeStamp.sourceId));
}
auto split = sourceTimeStamps.insert(sourceTimeStamps.end(), auto split = sourceTimeStamps.insert(sourceTimeStamps.end(),
m_currentSourceTimeStamps.begin(), m_currentSourceTimeStamps.begin(),
m_currentSourceTimeStamps.end()); m_currentSourceTimeStamps.end());
std::inplace_merge(sourceTimeStamps.begin(), split, sourceTimeStamps.end()); std::inplace_merge(sourceTimeStamps.begin(), split, sourceTimeStamps.end());
m_currentSourceTimeStamps = sourceTimeStamps; m_currentSourceTimeStamps = std::move(sourceTimeStamps);
} }
SourceTimeStamps newSourceTimeStamps(const SourceEntries &sourceEntries) const SourceTimeStamps newSourceTimeStamps(const SourceEntries &sourceEntries) const
{ {
SourceEntries newSourceEntries; SourceTimeStamps newTimeStamps;
newSourceEntries.reserve(sourceEntries.size()); newTimeStamps.reserve(sourceEntries.size());
class CompareSourceId
{
public:
bool operator()(SourceTimeStamp first, SourceTimeStamp second)
{
return first.sourceId < second.sourceId;
}
bool operator()(::ClangBackEnd::SourceEntry first, ::ClangBackEnd::SourceEntry second)
{
return first.sourceId < second.sourceId;
}
bool operator()(SourceTimeStamp first, ::ClangBackEnd::SourceEntry second)
{
return first.sourceId < second.sourceId;
}
bool operator()(::ClangBackEnd::SourceEntry first, SourceTimeStamp second)
{
return first.sourceId < second.sourceId;
}
};
std::set_difference(sourceEntries.begin(), std::set_difference(sourceEntries.begin(),
sourceEntries.end(), sourceEntries.end(),
m_currentSourceTimeStamps.begin(), m_currentSourceTimeStamps.begin(),
m_currentSourceTimeStamps.end(), m_currentSourceTimeStamps.end(),
std::back_inserter(newSourceEntries), make_iterator([&](const SourceEntry &sourceEntry) {
CompareSourceId{}); newTimeStamps.emplace_back(sourceEntry.sourceId,
m_fileSystem.lastModified(
SourceTimeStamps newTimeStamps; sourceEntry.sourceId));
newTimeStamps.reserve(newSourceEntries.size()); }),
[](auto first, auto second) {
std::transform(newSourceEntries.begin(), return first.sourceId < second.sourceId && first.timeStamp > 0;
newSourceEntries.end(),
std::back_inserter(newTimeStamps),
[](SourceEntry entry) {
return SourceTimeStamp{entry.sourceId, {}};
}); });
return newTimeStamps; return newTimeStamps;
} }
bool notReseted(const SourceEntries &sourceEntries) const
{
auto oldSize = m_resetFilePathIds.size();
FilePathIds newResetFilePathIds;
newResetFilePathIds.reserve(newResetFilePathIds.size());
std::set_difference(m_resetFilePathIds.begin(),
m_resetFilePathIds.end(),
sourceEntries.begin(),
sourceEntries.end(),
std::back_inserter(newResetFilePathIds));
m_resetFilePathIds = std::move(newResetFilePathIds);
return oldSize == m_resetFilePathIds.size();
}
private: private:
mutable SourceTimeStamps m_currentSourceTimeStamps; mutable SourceTimeStamps m_currentSourceTimeStamps;
GetModifiedTime &m_getModifiedTime; mutable FilePathIds m_resetFilePathIds;
FilePathCachingInterface &m_filePathCache; FileSystemInterface &m_fileSystem;
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -38,6 +38,7 @@ public:
ModifiedTimeCheckerInterface &operator=(const ModifiedTimeCheckerInterface &) = delete; ModifiedTimeCheckerInterface &operator=(const ModifiedTimeCheckerInterface &) = delete;
virtual bool isUpToDate(const SourceEntries &sourceEntries) const = 0; virtual bool isUpToDate(const SourceEntries &sourceEntries) const = 0;
virtual void pathsChanged(const FilePathIds &filePathIds) = 0;
protected: protected:
~ModifiedTimeCheckerInterface() = default; ~ModifiedTimeCheckerInterface() = default;

View File

@@ -144,11 +144,11 @@ public:
table.setName("projectPartsFiles"); table.setName("projectPartsFiles");
const Sqlite::Column &projectPartIdColumn = table.addColumn("projectPartId", Sqlite::ColumnType::Integer); const Sqlite::Column &projectPartIdColumn = table.addColumn("projectPartId", Sqlite::ColumnType::Integer);
const Sqlite::Column &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer); const Sqlite::Column &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
table.addColumn("sourceType", Sqlite::ColumnType::Integer); const Sqlite::Column &sourceType = table.addColumn("sourceType", Sqlite::ColumnType::Integer);
table.addColumn("pchCreationTimeStamp", Sqlite::ColumnType::Integer); table.addColumn("pchCreationTimeStamp", Sqlite::ColumnType::Integer);
table.addColumn("hasMissingIncludes", Sqlite::ColumnType::Integer); table.addColumn("hasMissingIncludes", Sqlite::ColumnType::Integer);
table.addUniqueIndex({sourceIdColumn, projectPartIdColumn}); table.addUniqueIndex({sourceIdColumn, projectPartIdColumn});
table.addIndex({projectPartIdColumn}); table.addIndex({projectPartIdColumn, sourceType});
table.initialize(database); table.initialize(database);
} }

View File

@@ -0,0 +1,101 @@
/****************************************************************************
**
** Copyright (C) 2019 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 <algorithm>
namespace ClangBackEnd {
template<class Callable>
class function_output_iterator
{
public:
typedef std::output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit function_output_iterator() {}
explicit function_output_iterator(const Callable &callable)
: m_callable(&callable)
{}
function_output_iterator &operator=(const function_output_iterator &iterator)
{
m_callable = iterator.m_callable;
return *this;
}
struct helper
{
helper(const Callable *callable)
: m_callable(callable)
{}
template<class T>
helper &operator=(T &&value)
{
(*m_callable)(std::forward<T>(value));
return *this;
}
const Callable *m_callable;
};
helper operator*() { return helper(m_callable); }
function_output_iterator &operator++() { return *this; }
function_output_iterator &operator++(int) { return *this; }
private:
const Callable *m_callable;
};
template<typename Callable>
function_output_iterator<Callable> make_iterator(const Callable &callable)
{
return function_output_iterator<Callable>(callable);
}
template<class InputIt1, class InputIt2, class Callable, class Compare>
bool set_intersection_compare(
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable call, Compare comp)
{
while (first1 != last1 && first2 != last2) {
if (comp(*first1, *first2)) {
++first1;
} else {
if (!comp(*first2, *first1)) {
if (call(*first2, *first1++))
return false;
}
++first2;
}
}
return true;
}
} // namespace ClangBackEnd

View File

@@ -131,6 +131,10 @@ public:
return first.sourceId < second.sourceId; return first.sourceId < second.sourceId;
} }
friend bool operator<(SourceEntry first, FilePathId second) { return first.sourceId < second; }
friend bool operator<(FilePathId first, SourceEntry second) { return first < second.sourceId; }
friend bool operator==(SourceEntry first, SourceEntry second) friend bool operator==(SourceEntry first, SourceEntry second)
{ {
return first.sourceId == second.sourceId && first.sourceType == second.sourceType return first.sourceId == second.sourceId && first.sourceType == second.sourceType

View File

@@ -92,7 +92,7 @@ using ResponseHandler = std::function<void(const QByteArray &, QTextCodec *)>;
using ResponseHandlers = std::function<void(MessageId, const QByteArray &, QTextCodec *)>; using ResponseHandlers = std::function<void(MessageId, const QByteArray &, QTextCodec *)>;
using MethodHandler = std::function<void(const QString, MessageId, const IContent *)>; using MethodHandler = std::function<void(const QString, MessageId, const IContent *)>;
inline LANGUAGESERVERPROTOCOL_EXPORT uint qHash(const LanguageServerProtocol::MessageId &id) inline uint qHash(const LanguageServerProtocol::MessageId &id)
{ {
if (Utils::holds_alternative<int>(id)) if (Utils::holds_alternative<int>(id))
return QT_PREPEND_NAMESPACE(qHash(Utils::get<int>(id))); return QT_PREPEND_NAMESPACE(qHash(Utils::get<int>(id)));
@@ -102,8 +102,7 @@ inline LANGUAGESERVERPROTOCOL_EXPORT uint qHash(const LanguageServerProtocol::Me
} }
template <typename Error> template <typename Error>
inline LANGUAGESERVERPROTOCOL_EXPORT QDebug operator<<(QDebug stream, inline QDebug operator<<(QDebug stream, const LanguageServerProtocol::MessageId &id)
const LanguageServerProtocol::MessageId &id)
{ {
if (Utils::holds_alternative<int>(id)) if (Utils::holds_alternative<int>(id))
stream << Utils::get<int>(id); stream << Utils::get<int>(id);

View File

@@ -1676,7 +1676,7 @@ bool Check::visit(CallExpression *ast)
if (!whiteListedFunction && !isMathFunction && !isDateFunction && !isDirectInConnectionsScope) if (!whiteListedFunction && !isMathFunction && !isDateFunction && !isDirectInConnectionsScope)
addMessage(ErrFunctionsNotSupportedInQmlUi, location); addMessage(ErrFunctionsNotSupportedInQmlUi, location);
static const QStringList globalFunctions = {"String", "Boolean", "Date", "Number", "Object", "QT_TR_NOOP", "QT_TRANSLATE_NOOP", "QT_TRID_NOOP"}; static const QStringList globalFunctions = {"String", "Boolean", "Date", "Number", "Object", "Array", "QT_TR_NOOP", "QT_TRANSLATE_NOOP", "QT_TRID_NOOP"};
if (!name.isEmpty() && name.at(0).isUpper() && !globalFunctions.contains(name)) { if (!name.isEmpty() && name.at(0).isUpper() && !globalFunctions.contains(name)) {
addMessage(WarnExpectedNewWithUppercaseFunction, location); addMessage(WarnExpectedNewWithUppercaseFunction, location);

View File

@@ -179,6 +179,10 @@ public:
return m_pointer[0] == characterToSearch; return m_pointer[0] == characterToSearch;
} }
char back() const { return m_pointer[m_size - 1]; }
char operator[](std::size_t index) { return m_pointer[index]; }
private: private:
const char *m_pointer = ""; const char *m_pointer = "";
size_type m_size = 0; size_type m_size = 0;

View File

@@ -77,8 +77,9 @@ void AutoTestUnitTests::initTestCase()
if (!qgetenv("BOOST_INCLUDE_DIR").isEmpty()) { if (!qgetenv("BOOST_INCLUDE_DIR").isEmpty()) {
m_checkBoost = true; m_checkBoost = true;
} else { } else {
if (QFileInfo::exists("/usr/include/boost/version.hpp") if (Utils::HostOsInfo::isLinuxHost()
|| QFileInfo::exists("/usr/local/include/boost/version.hpp")) { && (QFileInfo::exists("/usr/include/boost/version.hpp")
|| QFileInfo::exists("/usr/local/include/boost/version.hpp"))) {
qDebug() << "Found boost at system level - will run boost parser test."; qDebug() << "Found boost at system level - will run boost parser test.";
m_checkBoost = true; m_checkBoost = true;
} }

View File

@@ -37,6 +37,7 @@ enum class ReportLevel;
class BoostTestOutputReader : public TestOutputReader class BoostTestOutputReader : public TestOutputReader
{ {
Q_OBJECT
public: public:
BoostTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, BoostTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
QProcess *testApplication, const QString &buildDirectory, QProcess *testApplication, const QString &buildDirectory,

View File

@@ -411,9 +411,9 @@ QList<ToolChain *> IarToolChainFactory::autoDetect(const QList<ToolChain *> &alr
QString registryKey; QString registryKey;
QString subExePath; QString subExePath;
} knowToolchains[] = { } knowToolchains[] = {
{"EWARM", "\\arm\\bin\\iccarm.exe"}, {{"EWARM"}, {"\\arm\\bin\\iccarm.exe"}},
{"EWAVR", "\\avr\\bin\\iccavr.exe"}, {{"EWAVR"}, {"\\avr\\bin\\iccavr.exe"}},
{"EW8051", "\\8051\\bin\\icc8051.exe"}, {{"EW8051"}, {"\\8051\\bin\\icc8051.exe"}},
}; };
QSettings registry(kRegistryNode, QSettings::NativeFormat); QSettings registry(kRegistryNode, QSettings::NativeFormat);

View File

@@ -144,7 +144,7 @@ void ClangCodeModelPlugin::createCompilationDBButton()
message = tr("Clang compilation database generated at \"%1\".") message = tr("Clang compilation database generated at \"%1\".")
.arg(QDir::toNativeSeparators(result.filePath)); .arg(QDir::toNativeSeparators(result.filePath));
} else { } else {
message = tr("Generating clang compilation database failed: %1").arg(result.error); message = tr("Generating Clang compilation database failed: %1").arg(result.error);
} }
Core::MessageManager::write(message, Core::MessageManager::Flash); Core::MessageManager::write(message, Core::MessageManager::Flash);
m_generateCompilationDBAction->setEnabled( m_generateCompilationDBAction->setEnabled(

View File

@@ -295,6 +295,7 @@ SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo,
CppTools::ClangDiagnosticConfigsSelectionWidget *diagnosticConfigsSelectionWidget CppTools::ClangDiagnosticConfigsSelectionWidget *diagnosticConfigsSelectionWidget
= m_ui->clangToolsBasicSettings->ui()->clangDiagnosticConfigsSelectionWidget; = m_ui->clangToolsBasicSettings->ui()->clangDiagnosticConfigsSelectionWidget;
QCheckBox *buildBeforeAnalysis = m_ui->clangToolsBasicSettings->ui()->buildBeforeAnalysis; QCheckBox *buildBeforeAnalysis = m_ui->clangToolsBasicSettings->ui()->buildBeforeAnalysis;
buildBeforeAnalysis->setToolTip(hintAboutBuildBeforeAnalysis());
ClangToolsProjectSettings *settings = ClangToolsProjectSettingsManager::getSettings(m_project); ClangToolsProjectSettings *settings = ClangToolsProjectSettingsManager::getSettings(m_project);
m_customDiagnosticConfig = diagnosticConfiguration(settings); m_customDiagnosticConfig = diagnosticConfiguration(settings);
@@ -337,6 +338,8 @@ SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo,
m_customDiagnosticConfig = currentConfigId; m_customDiagnosticConfig = currentConfigId;
}); });
connect(buildBeforeAnalysis, &QCheckBox::toggled, [this](bool checked) { connect(buildBeforeAnalysis, &QCheckBox::toggled, [this](bool checked) {
if (!checked)
showHintAboutBuildBeforeAnalysis();
if (m_ui->globalOrCustom->currentIndex() == CustomSettings) if (m_ui->globalOrCustom->currentIndex() == CustomSettings)
m_buildBeforeAnalysis = checked; m_buildBeforeAnalysis = checked;
}); });

View File

@@ -477,6 +477,16 @@ void ClangToolRunControl::finalize()
if (m_filesNotAnalyzed != 0) { if (m_filesNotAnalyzed != 0) {
QString msg = tr("%1: Not all files could be analyzed.").arg(toolName); QString msg = tr("%1: Not all files could be analyzed.").arg(toolName);
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID); TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
if (m_target && !m_target->activeBuildConfiguration()->buildDirectory().exists()
&& !ClangToolsProjectSettingsManager::getSettings(m_target->project())
->buildBeforeAnalysis()) {
msg = tr("%1: You might need to build the project to generate or update source "
"files. To build automatically, enable \"Build the project before starting "
"analysis\".")
.arg(toolName);
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
}
TaskHub::requestPopup(); TaskHub::requestPopup();
} }

View File

@@ -56,9 +56,12 @@ ClangToolsConfigWidget::ClangToolsConfigWidget(
[settings](int count) { settings->setSimultaneousProcesses(count); }); [settings](int count) { settings->setSimultaneousProcesses(count); });
QCheckBox *buildBeforeAnalysis = m_ui->clangToolsBasicSettings->ui()->buildBeforeAnalysis; QCheckBox *buildBeforeAnalysis = m_ui->clangToolsBasicSettings->ui()->buildBeforeAnalysis;
buildBeforeAnalysis->setToolTip(hintAboutBuildBeforeAnalysis());
buildBeforeAnalysis->setCheckState(settings->savedBuildBeforeAnalysis() buildBeforeAnalysis->setCheckState(settings->savedBuildBeforeAnalysis()
? Qt::Checked : Qt::Unchecked); ? Qt::Checked : Qt::Unchecked);
connect(buildBeforeAnalysis, &QCheckBox::toggled, [settings](bool checked) { connect(buildBeforeAnalysis, &QCheckBox::toggled, [settings](bool checked) {
if (!checked)
showHintAboutBuildBeforeAnalysis();
settings->setBuildBeforeAnalysis(checked); settings->setBuildBeforeAnalysis(checked);
}); });

View File

@@ -87,7 +87,9 @@ void ClangToolsProjectSettings::load()
m_useGlobalSettings = useGlobalVariant.isValid() ? useGlobalVariant.toBool() : true; m_useGlobalSettings = useGlobalVariant.isValid() ? useGlobalVariant.toBool() : true;
m_diagnosticConfig = Core::Id::fromSetting( m_diagnosticConfig = Core::Id::fromSetting(
m_project->namedSettings(SETTINGS_KEY_DIAGNOSTIC_CONFIG)); m_project->namedSettings(SETTINGS_KEY_DIAGNOSTIC_CONFIG));
m_buildBeforeAnalysis = m_project->namedSettings(SETTINGS_KEY_BUILD_BEFORE_ANALYSIS).toBool();
const QVariant value = m_project->namedSettings(SETTINGS_KEY_BUILD_BEFORE_ANALYSIS);
m_buildBeforeAnalysis = value.isValid() ? value.toBool() : true;
auto toFileName = [](const QString &s) { return Utils::FilePath::fromString(s); }; auto toFileName = [](const QString &s) { return Utils::FilePath::fromString(s); };

View File

@@ -25,6 +25,7 @@
#include "clangtoolsutils.h" #include "clangtoolsutils.h"
#include "clangtool.h"
#include "clangtoolsdiagnostic.h" #include "clangtoolsdiagnostic.h"
#include "clangtoolssettings.h" #include "clangtoolssettings.h"
@@ -32,8 +33,9 @@
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <utils/hostosinfo.h> #include <utils/checkablemessagebox.h>
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/hostosinfo.h>
#include <utils/synchronousprocess.h> #include <utils/synchronousprocess.h>
#include <QCoreApplication> #include <QCoreApplication>
@@ -49,5 +51,24 @@ QString createFullLocationString(const Debugger::DiagnosticLocation &location)
+ QLatin1Char(':') + QString::number(location.column); + QLatin1Char(':') + QString::number(location.column);
} }
QString hintAboutBuildBeforeAnalysis()
{
return ClangTool::tr(
"In general, the project should be built before starting the analysis to ensure that the "
"code to analyze is valid.<br/><br/>"
"Building the project might also run code generators that update the source files as "
"necessary.");
}
void showHintAboutBuildBeforeAnalysis()
{
Utils::CheckableMessageBox::doNotShowAgainInformation(
Core::ICore::dialogParent(),
ClangTool::tr("Info About Build the Project Before Analysis"),
hintAboutBuildBeforeAnalysis(),
Core::ICore::settings(),
"ClangToolsDisablingBuildBeforeAnalysisHint");
}
} // namespace Internal } // namespace Internal
} // namespace ClangTools } // namespace ClangTools

View File

@@ -41,5 +41,8 @@ namespace Internal {
QString createFullLocationString(const Debugger::DiagnosticLocation &location); QString createFullLocationString(const Debugger::DiagnosticLocation &location);
QString hintAboutBuildBeforeAnalysis();
void showHintAboutBuildBeforeAnalysis();
} // namespace Internal } // namespace Internal
} // namespace ClangTools } // namespace ClangTools

View File

@@ -2429,12 +2429,12 @@ void EditorManager::closeOtherDocuments(IDocument *document)
closeDocuments(documentsToClose, true); closeDocuments(documentsToClose, true);
} }
void EditorManager::closeAllDocuments() bool EditorManager::closeAllDocuments()
{ {
// Only close the files that aren't pinned. // Only close the files that aren't pinned.
const QList<DocumentModel::Entry *> entriesToClose const QList<DocumentModel::Entry *> entriesToClose
= Utils::filtered(DocumentModel::entries(), Utils::equal(&DocumentModel::Entry::pinned, false)); = Utils::filtered(DocumentModel::entries(), Utils::equal(&DocumentModel::Entry::pinned, false));
EditorManager::closeDocuments(entriesToClose); return EditorManager::closeDocuments(entriesToClose);
} }
// SLOT connected to action // SLOT connected to action
@@ -2631,7 +2631,7 @@ void EditorManager::closeDocument(DocumentModel::Entry *entry)
closeDocuments({entry->document}); closeDocuments({entry->document});
} }
void EditorManager::closeDocuments(const QList<DocumentModel::Entry *> &entries) bool EditorManager::closeDocuments(const QList<DocumentModel::Entry *> &entries)
{ {
QList<IDocument *> documentsToClose; QList<IDocument *> documentsToClose;
for (DocumentModel::Entry *entry : entries) { for (DocumentModel::Entry *entry : entries) {
@@ -2642,7 +2642,7 @@ void EditorManager::closeDocuments(const QList<DocumentModel::Entry *> &entries)
else else
documentsToClose << entry->document; documentsToClose << entry->document;
} }
closeDocuments(documentsToClose); return closeDocuments(documentsToClose);
} }
bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool askAboutModifiedEditors) bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool askAboutModifiedEditors)

View File

@@ -128,9 +128,9 @@ public:
static bool closeDocument(IDocument *document, bool askAboutModifiedEditors = true); static bool closeDocument(IDocument *document, bool askAboutModifiedEditors = true);
static bool closeDocuments(const QList<IDocument *> &documents, bool askAboutModifiedEditors = true); static bool closeDocuments(const QList<IDocument *> &documents, bool askAboutModifiedEditors = true);
static void closeDocument(DocumentModel::Entry *entry); static void closeDocument(DocumentModel::Entry *entry);
static void closeDocuments(const QList<DocumentModel::Entry *> &entries); static bool closeDocuments(const QList<DocumentModel::Entry *> &entries);
static void closeOtherDocuments(IDocument *document); static void closeOtherDocuments(IDocument *document);
static void closeAllDocuments(); static bool closeAllDocuments();
static void addCurrentPositionToNavigationHistory(const QByteArray &saveState = QByteArray()); static void addCurrentPositionToNavigationHistory(const QByteArray &saveState = QByteArray());
static void cutForwardNavigationHistory(); static void cutForwardNavigationHistory();

View File

@@ -79,7 +79,6 @@ public:
bool hasWriteWarning = false; bool hasWriteWarning = false;
bool restored = false; bool restored = false;
bool isSuspendAllowed = false; bool isSuspendAllowed = false;
bool pinned = false;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -41,6 +41,8 @@ class QWidget;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Core { namespace Core {
class CommandButton;
class IContext;
class CORE_EXPORT IOutputPane : public QObject class CORE_EXPORT IOutputPane : public QObject
{ {
@@ -93,6 +95,7 @@ signals:
void setBadgeNumber(int number); void setBadgeNumber(int number);
void zoomIn(int range); void zoomIn(int range);
void zoomOut(int range); void zoomOut(int range);
void resetZoom();
void wheelZoomEnabledChanged(bool enabled); void wheelZoomEnabledChanged(bool enabled);
void fontChanged(const QFont &font); void fontChanged(const QFont &font);
@@ -103,7 +106,7 @@ protected:
Qt::CaseSensitivity filterCaseSensitivity() const { return m_filterCaseSensitivity; } Qt::CaseSensitivity filterCaseSensitivity() const { return m_filterCaseSensitivity; }
void setFilteringEnabled(bool enable); void setFilteringEnabled(bool enable);
QWidget *filterWidget() const { return m_filterOutputLineEdit; } QWidget *filterWidget() const { return m_filterOutputLineEdit; }
void setupContext(const char *context, QWidget *widget);
void setZoomButtonsEnabled(bool enabled); void setZoomButtonsEnabled(bool enabled);
private: private:
@@ -115,11 +118,12 @@ private:
Id filterRegexpActionId() const; Id filterRegexpActionId() const;
Id filterCaseSensitivityActionId() const; Id filterCaseSensitivityActionId() const;
QToolButton * const m_zoomInButton = nullptr; Core::CommandButton * const m_zoomInButton;
QToolButton * const m_zoomOutButton = nullptr; Core::CommandButton * const m_zoomOutButton;
QAction *m_filterActionRegexp = nullptr; QAction *m_filterActionRegexp = nullptr;
QAction *m_filterActionCaseSensitive = nullptr; QAction *m_filterActionCaseSensitive = nullptr;
Utils::FancyLineEdit *m_filterOutputLineEdit = nullptr; Utils::FancyLineEdit *m_filterOutputLineEdit = nullptr;
IContext *m_context = nullptr;
bool m_filterRegexp = false; bool m_filterRegexp = false;
Qt::CaseSensitivity m_filterCaseSensitivity = Qt::CaseInsensitive; Qt::CaseSensitivity m_filterCaseSensitivity = Qt::CaseInsensitive;
}; };

View File

@@ -56,6 +56,7 @@ MessageOutputWindow::MessageOutputWindow()
connect(this, &IOutputPane::zoomIn, m_widget, &Core::OutputWindow::zoomIn); connect(this, &IOutputPane::zoomIn, m_widget, &Core::OutputWindow::zoomIn);
connect(this, &IOutputPane::zoomOut, m_widget, &Core::OutputWindow::zoomOut); connect(this, &IOutputPane::zoomOut, m_widget, &Core::OutputWindow::zoomOut);
connect(this, &IOutputPane::resetZoom, m_widget, &Core::OutputWindow::resetZoom);
connect(this, &IOutputPane::fontChanged, m_widget, &OutputWindow::setBaseFont); connect(this, &IOutputPane::fontChanged, m_widget, &OutputWindow::setBaseFont);
connect(this, &IOutputPane::wheelZoomEnabledChanged, m_widget, &OutputWindow::setWheelZoomEnabled); connect(this, &IOutputPane::wheelZoomEnabledChanged, m_widget, &OutputWindow::setWheelZoomEnabled);
@@ -65,6 +66,7 @@ MessageOutputWindow::MessageOutputWindow()
setupFilterUi("MessageOutputPane.Filter"); setupFilterUi("MessageOutputPane.Filter");
setFilteringEnabled(true); setFilteringEnabled(true);
setupContext(Constants::C_GENERAL_OUTPUT_PANE, m_widget);
} }
MessageOutputWindow::~MessageOutputWindow() MessageOutputWindow::~MessageOutputWindow()

View File

@@ -35,6 +35,7 @@
#include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/actioncontainer.h> #include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/command.h> #include <coreplugin/actionmanager/command.h>
#include <coreplugin/actionmanager/commandbutton.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h> #include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/find/optionspopup.h> #include <coreplugin/find/optionspopup.h>
@@ -90,24 +91,27 @@ static bool g_managerConstructed = false; // For debugging reasons.
IOutputPane::IOutputPane(QObject *parent) IOutputPane::IOutputPane(QObject *parent)
: QObject(parent), : QObject(parent),
m_zoomInButton(new QToolButton), m_zoomInButton(new Core::CommandButton),
m_zoomOutButton(new QToolButton) m_zoomOutButton(new Core::CommandButton)
{ {
// We need all pages first. Ignore latecomers and shout. // We need all pages first. Ignore latecomers and shout.
QTC_ASSERT(!g_managerConstructed, return); QTC_ASSERT(!g_managerConstructed, return);
g_outputPanes.append(OutputPaneData(this)); g_outputPanes.append(OutputPaneData(this));
m_zoomInButton->setToolTip(tr("Increase Font Size"));
m_zoomInButton->setIcon(Utils::Icons::PLUS_TOOLBAR.icon()); m_zoomInButton->setIcon(Utils::Icons::PLUS_TOOLBAR.icon());
m_zoomInButton->setCommandId(Constants::ZOOM_IN);
connect(m_zoomInButton, &QToolButton::clicked, this, [this] { emit zoomIn(1); }); connect(m_zoomInButton, &QToolButton::clicked, this, [this] { emit zoomIn(1); });
m_zoomOutButton->setToolTip(tr("Decrease Font Size"));
m_zoomOutButton->setIcon(Utils::Icons::MINUS.icon()); m_zoomOutButton->setIcon(Utils::Icons::MINUS.icon());
m_zoomOutButton->setCommandId(Constants::ZOOM_OUT);
connect(m_zoomOutButton, &QToolButton::clicked, this, [this] { emit zoomOut(1); }); connect(m_zoomOutButton, &QToolButton::clicked, this, [this] { emit zoomOut(1); });
} }
IOutputPane::~IOutputPane() IOutputPane::~IOutputPane()
{ {
if (m_context)
ICore::removeContextObject(m_context);
const int i = Utils::indexOf(g_outputPanes, Utils::equal(&OutputPaneData::pane, this)); const int i = Utils::indexOf(g_outputPanes, Utils::equal(&OutputPaneData::pane, this));
QTC_ASSERT(i >= 0, return); QTC_ASSERT(i >= 0, return);
delete g_outputPanes.at(i).button; delete g_outputPanes.at(i).button;
@@ -174,6 +178,26 @@ void IOutputPane::setFilteringEnabled(bool enable)
m_filterOutputLineEdit->setEnabled(enable); m_filterOutputLineEdit->setEnabled(enable);
} }
void IOutputPane::setupContext(const char *context, QWidget *widget)
{
QTC_ASSERT(!m_context, return);
m_context = new IContext(this);
m_context->setContext(Context(context));
m_context->setWidget(widget);
ICore::addContextObject(m_context);
const auto zoomInAction = new QAction(this);
Core::ActionManager::registerAction(zoomInAction, Constants::ZOOM_IN, m_context->context());
connect(zoomInAction, &QAction::triggered, this, [this] { emit zoomIn(1); });
const auto zoomOutAction = new QAction(this);
Core::ActionManager::registerAction(zoomOutAction, Constants::ZOOM_OUT, m_context->context());
connect(zoomOutAction, &QAction::triggered, this, [this] { emit zoomOut(1); });
const auto resetZoomAction = new QAction(this);
Core::ActionManager::registerAction(resetZoomAction, Constants::ZOOM_RESET,
m_context->context());
connect(resetZoomAction, &QAction::triggered, this, &IOutputPane::resetZoom);
}
void IOutputPane::setZoomButtonsEnabled(bool enabled) void IOutputPane::setZoomButtonsEnabled(bool enabled)
{ {
m_zoomInButton->setEnabled(enabled); m_zoomInButton->setEnabled(enabled);

View File

@@ -75,6 +75,7 @@ public:
void setBaseFont(const QFont &newFont); void setBaseFont(const QFont &newFont);
float fontZoom() const; float fontZoom() const;
void setFontZoom(float zoom); void setFontZoom(float zoom);
void resetZoom() { setFontZoom(0); }
void setWheelZoomEnabled(bool enabled); void setWheelZoomEnabled(bool enabled);
void updateFilterProperties(const QString &filterText, Qt::CaseSensitivity caseSensitivity, bool regexp); void updateFilterProperties(const QString &filterText, Qt::CaseSensitivity caseSensitivity, bool regexp);

View File

@@ -111,14 +111,16 @@ QString ParseContextModel::currentId() const
return m_projectParts[m_currentIndex]->id(); return m_projectParts[m_currentIndex]->id();
} }
int ParseContextModel::rowCount(const QModelIndex &) const int ParseContextModel::rowCount(const QModelIndex &parent) const
{ {
if (parent.isValid())
return 0;
return m_projectParts.size(); return m_projectParts.size();
} }
QVariant ParseContextModel::data(const QModelIndex &index, int role) const QVariant ParseContextModel::data(const QModelIndex &index, int role) const
{ {
if (m_projectParts.isEmpty()) if (!index.isValid() || index.row() < 0 || index.row() >= m_projectParts.size())
return QVariant(); return QVariant();
const int row = index.row(); const int row = index.row();

View File

@@ -709,6 +709,7 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
qgetenv("QTC_CLANG_CMD_OPTIONS_BLACKLIST")) qgetenv("QTC_CLANG_CMD_OPTIONS_BLACKLIST"))
.split(';', QString::SkipEmptyParts); .split(';', QString::SkipEmptyParts);
const Core::Id &toolChain = m_projectPart.toolchainType;
bool containsDriverMode = false; bool containsDriverMode = false;
bool skipNext = false; bool skipNext = false;
for (const QString &option : m_projectPart.compilerFlags) { for (const QString &option : m_projectPart.compilerFlags) {
@@ -720,6 +721,13 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
if (userBlackList.contains(option)) if (userBlackList.contains(option))
continue; continue;
// TODO: Make it possible that the clang binary/driver ignores unknown options,
// as it is done for libclang/clangd (not checking for OPT_UNKNOWN).
if (toolChain == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID) {
if (option == "-fkeep-inline-dllexport" || option == "-fno-keep-inline-dllexport")
continue;
}
// Ignore warning flags as these interfere with our user-configured diagnostics. // Ignore warning flags as these interfere with our user-configured diagnostics.
// Note that once "-w" is provided, no warnings will be emitted, even if "-Wall" follows. // Note that once "-w" is provided, no warnings will be emitted, even if "-Wall" follows.
if (m_useBuildSystemWarnings == UseBuildSystemWarnings::No if (m_useBuildSystemWarnings == UseBuildSystemWarnings::No
@@ -755,7 +763,7 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
// Check whether a language version is already used. // Check whether a language version is already used.
QString theOption = option; QString theOption = option;
if (theOption.startsWith("-std=")) { if (theOption.startsWith("-std=") || theOption.startsWith("--std=")) {
m_compilerFlags.isLanguageVersionSpecified = true; m_compilerFlags.isLanguageVersionSpecified = true;
theOption.replace("=c18", "=c17"); theOption.replace("=c18", "=c17");
theOption.replace("=gnu18", "=gnu17"); theOption.replace("=gnu18", "=gnu17");
@@ -772,7 +780,6 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
m_compilerFlags.flags.append(theOption); m_compilerFlags.flags.append(theOption);
} }
const Core::Id &toolChain = m_projectPart.toolchainType;
if (!containsDriverMode if (!containsDriverMode
&& (toolChain == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID && (toolChain == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
|| toolChain == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID)) { || toolChain == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID)) {

View File

@@ -1759,9 +1759,9 @@ void DebuggerPlugin::attachExternalApplication(RunControl *rc)
ProcessHandle pid = rc->applicationProcessHandle(); ProcessHandle pid = rc->applicationProcessHandle();
auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE); auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
runControl->setTarget(rc->target()); runControl->setTarget(rc->target());
runControl->setDisplayName(tr("Process %1").arg(pid.pid()));
auto debugger = new DebuggerRunTool(runControl); auto debugger = new DebuggerRunTool(runControl);
debugger->setAttachPid(pid); debugger->setAttachPid(pid);
debugger->setRunControlName(tr("Process %1").arg(pid.pid()));
debugger->setStartMode(AttachExternal); debugger->setStartMode(AttachExternal);
debugger->setCloseMode(DetachAtClose); debugger->setCloseMode(DetachAtClose);
debugger->startRunControl(); debugger->startRunControl();

View File

@@ -605,7 +605,7 @@ BaseSettingsWidget::BaseSettingsWidget(const BaseSettings *settings, QWidget *pa
mainLayout->addLayout(mimeLayout, row, 1); mainLayout->addLayout(mimeLayout, row, 1);
m_filePattern->setPlaceholderText(tr("File pattern")); m_filePattern->setPlaceholderText(tr("File pattern"));
mainLayout->addWidget(m_filePattern, ++row, 1); mainLayout->addWidget(m_filePattern, ++row, 1);
mainLayout->addWidget(new QLabel(tr("Startup Behavior:")), ++row, 0); mainLayout->addWidget(new QLabel(tr("Startup behavior:")), ++row, 0);
for (int behavior = 0; behavior < BaseSettings::LastSentinel ; ++behavior) for (int behavior = 0; behavior < BaseSettings::LastSentinel ; ++behavior)
m_startupBehavior->addItem(startupBehaviorString(BaseSettings::StartBehavior(behavior))); m_startupBehavior->addItem(startupBehaviorString(BaseSettings::StartBehavior(behavior)));
m_startupBehavior->setCurrentIndex(settings->m_startBehavior); m_startupBehavior->setCurrentIndex(settings->m_startBehavior);
@@ -650,8 +650,8 @@ QString BaseSettingsWidget::name() const
LanguageFilter BaseSettingsWidget::filter() const LanguageFilter BaseSettingsWidget::filter() const
{ {
return {m_mimeTypes->text().split(filterSeparator), return {m_mimeTypes->text().split(filterSeparator, QString::SkipEmptyParts),
m_filePattern->text().split(filterSeparator)}; m_filePattern->text().split(filterSeparator, QString::SkipEmptyParts)};
} }
BaseSettings::StartBehavior BaseSettingsWidget::startupBehavior() const BaseSettings::StartBehavior BaseSettingsWidget::startupBehavior() const
@@ -784,10 +784,10 @@ QString StdIOSettingsWidget::arguments() const
bool LanguageFilter::isSupported(const Utils::FilePath &filePath, const QString &mimeType) const bool LanguageFilter::isSupported(const Utils::FilePath &filePath, const QString &mimeType) const
{ {
if (mimeTypes.isEmpty() && filePattern.isEmpty())
return true;
if (mimeTypes.contains(mimeType)) if (mimeTypes.contains(mimeType))
return true; return true;
if (filePattern.isEmpty() && filePath.isEmpty())
return mimeTypes.isEmpty();
auto regexps = Utils::transform(filePattern, [](const QString &pattern){ auto regexps = Utils::transform(filePattern, [](const QString &pattern){
return QRegExp(pattern, Utils::HostOsInfo::fileNameCaseSensitivity(), QRegExp::Wildcard); return QRegExp(pattern, Utils::HostOsInfo::fileNameCaseSensitivity(), QRegExp::Wildcard);
}); });

View File

@@ -157,6 +157,9 @@ PerfProfilerTool::PerfProfilerTool()
tracePointsAction->setEnabled(m_startAction->isEnabled()); tracePointsAction->setEnabled(m_startAction->isEnabled());
}); });
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
this, &PerfProfilerTool::updateRunActions);
m_recordButton = new QToolButton; m_recordButton = new QToolButton;
m_clearButton = new QToolButton; m_clearButton = new QToolButton;
m_filterButton = new QToolButton; m_filterButton = new QToolButton;
@@ -341,9 +344,6 @@ void PerfProfilerTool::createViews()
menu1->exec(m_flameGraphView->mapToGlobal(pos)); menu1->exec(m_flameGraphView->mapToGlobal(pos));
}); });
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
this, &PerfProfilerTool::updateRunActions);
m_perspective.addToolBarAction(m_startAction); m_perspective.addToolBarAction(m_startAction);
m_perspective.addToolBarAction(m_stopAction); m_perspective.addToolBarAction(m_stopAction);
m_perspective.addToolBarWidget(m_recordButton); m_perspective.addToolBarWidget(m_recordButton);

View File

@@ -213,6 +213,7 @@ AppOutputPane::AppOutputPane() :
connect(this, &Core::IOutputPane::zoomIn, this, &AppOutputPane::zoomIn); connect(this, &Core::IOutputPane::zoomIn, this, &AppOutputPane::zoomIn);
connect(this, &Core::IOutputPane::zoomOut, this, &AppOutputPane::zoomOut); connect(this, &Core::IOutputPane::zoomOut, this, &AppOutputPane::zoomOut);
connect(this, &IOutputPane::resetZoom, this, &AppOutputPane::resetZoom);
m_settingsButton->setToolTip(tr("Open Settings Page")); m_settingsButton->setToolTip(tr("Open Settings Page"));
m_settingsButton->setIcon(Utils::Icons::SETTINGS_TOOLBAR.icon()); m_settingsButton->setIcon(Utils::Icons::SETTINGS_TOOLBAR.icon());
@@ -247,6 +248,7 @@ AppOutputPane::AppOutputPane() :
setupFilterUi("AppOutputPane.Filter"); setupFilterUi("AppOutputPane.Filter");
setFilteringEnabled(false); setFilteringEnabled(false);
setZoomButtonsEnabled(false); setZoomButtonsEnabled(false);
setupContext("Core.AppOutputPane", m_mainWidget);
} }
AppOutputPane::~AppOutputPane() AppOutputPane::~AppOutputPane()
@@ -662,6 +664,12 @@ void AppOutputPane::zoomOut(int range)
tab.window->zoomOut(range); tab.window->zoomOut(range);
} }
void AppOutputPane::resetZoom()
{
for (const RunControlTab &tab : qAsConst(m_runControlTabs))
tab.window->resetZoom();
}
void AppOutputPane::enableButtons(const RunControl *rc) void AppOutputPane::enableButtons(const RunControl *rc)
{ {
if (rc) { if (rc) {

View File

@@ -120,6 +120,7 @@ private:
void zoomIn(int range); void zoomIn(int range);
void zoomOut(int range); void zoomOut(int range);
void resetZoom();
void enableButtons(const RunControl *rc); void enableButtons(const RunControl *rc);

View File

@@ -177,6 +177,7 @@ CompileOutputWindow::CompileOutputWindow(QAction *cancelBuildAction) :
connect(this, &IOutputPane::zoomIn, m_outputWindow, &Core::OutputWindow::zoomIn); connect(this, &IOutputPane::zoomIn, m_outputWindow, &Core::OutputWindow::zoomIn);
connect(this, &IOutputPane::zoomOut, m_outputWindow, &Core::OutputWindow::zoomOut); connect(this, &IOutputPane::zoomOut, m_outputWindow, &Core::OutputWindow::zoomOut);
connect(this, &IOutputPane::resetZoom, m_outputWindow, &Core::OutputWindow::resetZoom);
connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::fontSettingsChanged, connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::fontSettingsChanged,
this, updateFontSettings); this, updateFontSettings);
connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::behaviorSettingsChanged, connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::behaviorSettingsChanged,
@@ -194,6 +195,7 @@ CompileOutputWindow::CompileOutputWindow(QAction *cancelBuildAction) :
m_handler = new ShowOutputTaskHandler(this); m_handler = new ShowOutputTaskHandler(this);
ExtensionSystem::PluginManager::addObject(m_handler); ExtensionSystem::PluginManager::addObject(m_handler);
setupContext(C_COMPILE_OUTPUT, m_outputWindow);
loadSettings(); loadSettings();
updateFromSettings(); updateFromSettings();
} }

View File

@@ -381,7 +381,7 @@ void EnvironmentWidget::amendPathList(const PathListModifier &modifier)
{ {
const QString varName = d->m_model->indexToVariable(d->m_environmentView->currentIndex()); const QString varName = d->m_model->indexToVariable(d->m_environmentView->currentIndex());
const QString dir = QDir::toNativeSeparators( const QString dir = QDir::toNativeSeparators(
QFileDialog::getExistingDirectory(this, tr("Choose a directory"))); QFileDialog::getExistingDirectory(this, tr("Choose Directory")));
if (dir.isEmpty()) if (dir.isEmpty())
return; return;
QModelIndex index = d->m_model->variableToIndex(varName); QModelIndex index = d->m_model->variableToIndex(varName);

View File

@@ -92,7 +92,7 @@ class FilterKitAspectsModel : public TreeModel<TreeItem, FilterTreeItem>
public: public:
FilterKitAspectsModel(const Kit *kit, QObject *parent) : TreeModel(parent) FilterKitAspectsModel(const Kit *kit, QObject *parent) : TreeModel(parent)
{ {
setHeader({tr("Setting"), tr("Visible")}); setHeader({FilterKitAspectsDialog::tr("Setting"), FilterKitAspectsDialog::tr("Visible")});
for (const KitAspect * const aspect : KitManager::kitAspects()) { for (const KitAspect * const aspect : KitManager::kitAspects()) {
if (kit && !aspect->isApplicableToKit(kit)) if (kit && !aspect->isApplicableToKit(kit))
continue; continue;

View File

@@ -37,6 +37,7 @@ namespace Internal {
class FilterKitAspectsDialog : public QDialog class FilterKitAspectsDialog : public QDialog
{ {
Q_OBJECT
public: public:
FilterKitAspectsDialog(const Kit *kit, QWidget *parent); FilterKitAspectsDialog(const Kit *kit, QWidget *parent);
QSet<Core::Id> irrelevantAspects() const; QSet<Core::Id> irrelevantAspects() const;

View File

@@ -63,10 +63,14 @@ ImportWidget::ImportWidget(QWidget *parent) :
connect(importButton, &QAbstractButton::clicked, this, &ImportWidget::handleImportRequest); connect(importButton, &QAbstractButton::clicked, this, &ImportWidget::handleImportRequest);
connect(m_pathChooser->lineEdit(), &QLineEdit::returnPressed, this, [this] { connect(m_pathChooser->lineEdit(), &QLineEdit::returnPressed, this, [this] {
if (m_pathChooser->isValid()) { if (m_pathChooser->isValid()) {
m_ownsReturnKey = true;
handleImportRequest(); handleImportRequest();
// The next return should trigger the "Configure" button. // The next return should trigger the "Configure" button.
QTimer::singleShot(0, this, QOverload<>::of(&QWidget::setFocus)); QTimer::singleShot(0, this, [this] {
setFocus();
m_ownsReturnKey = false;
});
} }
}); });
@@ -79,9 +83,9 @@ void ImportWidget::setCurrentDirectory(const Utils::FilePath &dir)
m_pathChooser->setFileName(dir); m_pathChooser->setFileName(dir);
} }
bool ImportWidget::lineEditHasFocus() const bool ImportWidget::ownsReturnKey() const
{ {
return m_pathChooser->lineEdit()->hasFocus(); return m_ownsReturnKey;
} }
void ImportWidget::handleImportRequest() void ImportWidget::handleImportRequest()

View File

@@ -44,7 +44,7 @@ public:
void setCurrentDirectory(const Utils::FilePath &dir); void setCurrentDirectory(const Utils::FilePath &dir);
bool lineEditHasFocus() const; bool ownsReturnKey() const;
signals: signals:
void importFrom(const Utils::FilePath &dir); void importFrom(const Utils::FilePath &dir);
@@ -53,6 +53,7 @@ private:
void handleImportRequest(); void handleImportRequest();
Utils::PathChooser *m_pathChooser; Utils::PathChooser *m_pathChooser;
bool m_ownsReturnKey = false;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -104,7 +104,7 @@ public:
: QDialog(parent), m_view(new Utils::TreeView(this)) : QDialog(parent), m_view(new Utils::TreeView(this))
{ {
setWindowTitle(QCoreApplication::translate("ProjectExplorer::JsonWizard", setWindowTitle(QCoreApplication::translate("ProjectExplorer::JsonWizard",
"Choose project file")); "Choose Project File"));
const auto model = new ProjectFilesModel(candidates, this); const auto model = new ProjectFilesModel(candidates, this);
m_view->setSelectionMode(Utils::TreeView::ExtendedSelection); m_view->setSelectionMode(Utils::TreeView::ExtendedSelection);
m_view->setSelectionBehavior(Utils::TreeView::SelectRows); m_view->setSelectionBehavior(Utils::TreeView::SelectRows);
@@ -121,7 +121,7 @@ public:
const auto layout = new QVBoxLayout(this); const auto layout = new QVBoxLayout(this);
layout->addWidget(new QLabel(QCoreApplication::translate("ProjectExplorer::JsonWizard", layout->addWidget(new QLabel(QCoreApplication::translate("ProjectExplorer::JsonWizard",
"The project contains more than one project file. " "The project contains more than one project file. "
"Please select the one you would like to use."))); "Select the one you would like to use.")));
layout->addWidget(m_view); layout->addWidget(m_view);
layout->addWidget(buttonBox); layout->addWidget(buttonBox);
} }

View File

@@ -1298,6 +1298,7 @@ MsvcToolChainConfigWidget::MsvcToolChainConfigWidget(ToolChain *tc)
m_mainLayout->removeRow(m_mainLayout->rowCount() - 1); m_mainLayout->removeRow(m_mainLayout->rowCount() - 1);
QHBoxLayout *hLayout = new QHBoxLayout(); QHBoxLayout *hLayout = new QHBoxLayout();
m_varsBatPathCombo->setObjectName("varsBatCombo");
m_varsBatPathCombo->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); m_varsBatPathCombo->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
m_varsBatPathCombo->setEditable(true); m_varsBatPathCombo->setEditable(true);
for (const MsvcToolChain *tmpTc : g_availableMsvcToolchains) { for (const MsvcToolChain *tmpTc : g_availableMsvcToolchains) {
@@ -1442,6 +1443,7 @@ ClangClToolChainConfigWidget::ClangClToolChainConfigWidget(ToolChain *tc) :
{ {
m_mainLayout->removeRow(m_mainLayout->rowCount() - 1); m_mainLayout->removeRow(m_mainLayout->rowCount() - 1);
m_varsBatDisplayCombo->setObjectName("varsBatCombo");
m_varsBatDisplayCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents); m_varsBatDisplayCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
m_mainLayout->addRow(tr("Initialization:"), m_varsBatDisplayCombo); m_mainLayout->addRow(tr("Initialization:"), m_varsBatDisplayCombo);

View File

@@ -71,14 +71,14 @@ ParseIssuesDialog::ParseIssuesDialog(QWidget *parent) : QDialog(parent), d(new P
d->clearTasksCheckBox.setText(tr("Clear existing tasks")); d->clearTasksCheckBox.setText(tr("Clear existing tasks"));
d->clearTasksCheckBox.setChecked(true); d->clearTasksCheckBox.setChecked(true);
const auto loadFileButton = new QPushButton(tr("Load from file...")); const auto loadFileButton = new QPushButton(tr("Load from File..."));
connect(loadFileButton, &QPushButton::clicked, this, [this] { connect(loadFileButton, &QPushButton::clicked, this, [this] {
const QString filePath = QFileDialog::getOpenFileName(this, tr("Choose File")); const QString filePath = QFileDialog::getOpenFileName(this, tr("Choose File"));
if (filePath.isEmpty()) if (filePath.isEmpty())
return; return;
QFile file(filePath); QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
QMessageBox::critical(this, tr("Could not open file"), QMessageBox::critical(this, tr("Could Not Open File"),
tr("Could not open file: \"%1\": %2") tr("Could not open file: \"%1\": %2")
.arg(filePath, file.errorString())); .arg(filePath, file.errorString()));
return; return;
@@ -116,7 +116,7 @@ ParseIssuesDialog::ParseIssuesDialog(QWidget *parent) : QDialog(parent), d(new P
// TODO: Only very few parsers are available from a Kit (basically just the Toolchain one). // TODO: Only very few parsers are available from a Kit (basically just the Toolchain one).
// If we introduced factories for IOutputParsers, we could offer the user // If we introduced factories for IOutputParsers, we could offer the user
// to combine arbitrary parsers here. // to combine arbitrary parsers here.
const auto parserGroupBox = new QGroupBox(tr("Parsing options")); const auto parserGroupBox = new QGroupBox(tr("Parsing Options"));
layout->addWidget(parserGroupBox); layout->addWidget(parserGroupBox);
const auto parserLayout = new QVBoxLayout(parserGroupBox); const auto parserLayout = new QVBoxLayout(parserGroupBox);
const auto kitChooserWidget = new QWidget; const auto kitChooserWidget = new QWidget;
@@ -153,7 +153,7 @@ void ParseIssuesDialog::accept()
{ {
std::unique_ptr<IOutputParser> parser(d->kitChooser.currentKit()->createOutputParser()); std::unique_ptr<IOutputParser> parser(d->kitChooser.currentKit()->createOutputParser());
if (!parser) { if (!parser) {
QMessageBox::critical(this, tr("Cannot parse"), tr("Cannot parse: The chosen kit does " QMessageBox::critical(this, tr("Cannot Parse"), tr("Cannot parse: The chosen kit does "
"not provide an output parser.")); "not provide an output parser."));
return; return;
} }

View File

@@ -667,7 +667,7 @@ void Project::changeRootProjectDirectory()
{ {
Utils::FilePath rootPath = Utils::FilePath::fromString( Utils::FilePath rootPath = Utils::FilePath::fromString(
QFileDialog::getExistingDirectory(Core::ICore::dialogParent(), QFileDialog::getExistingDirectory(Core::ICore::dialogParent(),
tr("Select The Root Directory"), tr("Select the Root Directory"),
rootProjectDirectory().toString(), rootProjectDirectory().toString(),
QFileDialog::ShowDirsOnly QFileDialog::ShowDirsOnly
| QFileDialog::DontResolveSymlinks)); | QFileDialog::DontResolveSymlinks));
@@ -679,7 +679,7 @@ void Project::changeRootProjectDirectory()
} }
/*! /*!
Returns the common root directory that contains all files which belongs to a project. Returns the common root directory that contains all files which belong to a project.
*/ */
Utils::FilePath Project::rootProjectDirectory() const Utils::FilePath Project::rootProjectDirectory() const
{ {

View File

@@ -1780,7 +1780,7 @@ void ProjectExplorerPlugin::unloadProject(Project *project)
void ProjectExplorerPluginPrivate::closeAllProjects() void ProjectExplorerPluginPrivate::closeAllProjects()
{ {
if (!EditorManager::closeAllEditors()) if (!EditorManager::closeAllDocuments())
return; // Action has been cancelled return; // Action has been cancelled
SessionManager::closeAllProjects(); SessionManager::closeAllProjects();
@@ -1935,15 +1935,15 @@ void ProjectExplorerPluginPrivate::setStartupProject(Project *project)
bool ProjectExplorerPluginPrivate::closeAllFilesInProject(const Project *project) bool ProjectExplorerPluginPrivate::closeAllFilesInProject(const Project *project)
{ {
QTC_ASSERT(project, return false); QTC_ASSERT(project, return false);
QList<IDocument *> openFiles = DocumentModel::openedDocuments(); QList<DocumentModel::Entry *> openFiles = DocumentModel::entries();
Utils::erase(openFiles, [project](const IDocument *doc) { Utils::erase(openFiles, [project](const DocumentModel::Entry *entry) {
return !project->isKnownFile(doc->filePath()); return entry->pinned || !project->isKnownFile(entry->fileName());
}); });
for (const Project * const otherProject : SessionManager::projects()) { for (const Project * const otherProject : SessionManager::projects()) {
if (otherProject == project) if (otherProject == project)
continue; continue;
Utils::erase(openFiles, [otherProject](const IDocument *doc) { Utils::erase(openFiles, [otherProject](const DocumentModel::Entry *entry) {
return otherProject->isKnownFile(doc->filePath()); return otherProject->isKnownFile(entry->fileName());
}); });
} }
return EditorManager::closeDocuments(openFiles); return EditorManager::closeDocuments(openFiles);
@@ -3470,7 +3470,7 @@ void ProjectExplorerPluginPrivate::addExistingProjects()
QTC_ASSERT(projectNode, return); QTC_ASSERT(projectNode, return);
const QString dir = directoryFor(currentNode); const QString dir = directoryFor(currentNode);
QStringList subProjectFilePaths = QFileDialog::getOpenFileNames( QStringList subProjectFilePaths = QFileDialog::getOpenFileNames(
ICore::mainWindow(), tr("Please choose a project file"), dir, ICore::mainWindow(), tr("Choose Project File"), dir,
projectNode->subProjectFileNamePatterns().join(";;")); projectNode->subProjectFileNamePatterns().join(";;"));
if (!ProjectTree::hasNode(projectNode)) if (!ProjectTree::hasNode(projectNode))
return; return;

View File

@@ -457,7 +457,7 @@ public:
: m_buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel)), : m_buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel)),
m_buttonGroup(new QButtonGroup(this)) m_buttonGroup(new QButtonGroup(this))
{ {
setWindowTitle(tr("Please choose a drop action")); setWindowTitle(tr("Choose Drop Action"));
const bool offerFileIo = !defaultTargetDir.isEmpty(); const bool offerFileIo = !defaultTargetDir.isEmpty();
auto * const layout = new QVBoxLayout(this); auto * const layout = new QVBoxLayout(this);
layout->addWidget(new QLabel(tr("You just dragged some files from one project node to " layout->addWidget(new QLabel(tr("You just dragged some files from one project node to "
@@ -469,8 +469,8 @@ public:
m_buttonGroup->addButton(moveButton, int(DropAction::Move)); m_buttonGroup->addButton(moveButton, int(DropAction::Move));
layout->addWidget(moveButton); layout->addWidget(moveButton);
if (offerFileIo) { if (offerFileIo) {
copyButton->setText(tr("Copy only the file references")); copyButton->setText(tr("Copy Only File References"));
moveButton->setText(tr("Move only the file references")); moveButton->setText(tr("Move Only File References"));
auto * const copyWithFilesButton auto * const copyWithFilesButton
= new QRadioButton(tr("Copy file references and files"), this); = new QRadioButton(tr("Copy file references and files"), this);
m_buttonGroup->addButton(copyWithFilesButton, int(DropAction::CopyWithFiles)); m_buttonGroup->addButton(copyWithFilesButton, int(DropAction::CopyWithFiles));
@@ -506,8 +506,8 @@ public:
} }
}); });
} else { } else {
copyButton->setText(tr("Copy the file references")); copyButton->setText(tr("Copy File References"));
moveButton->setText(tr("Move the file references")); moveButton->setText(tr("Move File References"));
moveButton->setChecked(true); moveButton->setChecked(true);
} }
connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);

View File

@@ -332,7 +332,7 @@ void TargetSetupPage::setProjectImporter(ProjectImporter *importer)
bool TargetSetupPage::importLineEditHasFocus() const bool TargetSetupPage::importLineEditHasFocus() const
{ {
return m_importWidget->lineEditHasFocus(); return m_importWidget->ownsReturnKey();
} }
void TargetSetupPage::setNoteText(const QString &text) void TargetSetupPage::setNoteText(const QString &text)

View File

@@ -164,7 +164,7 @@ KitAspect::ItemList QmakeKitAspect::toUserOutput(const Kit *k) const
void QmakeKitAspect::addToMacroExpander(Kit *kit, MacroExpander *expander) const void QmakeKitAspect::addToMacroExpander(Kit *kit, MacroExpander *expander) const
{ {
expander->registerVariable("Qmake:mkspec", tr("Mkspec configured for qmake by the Kit."), expander->registerVariable("Qmake:mkspec", tr("Mkspec configured for qmake by the kit."),
[kit]() -> QString { [kit]() -> QString {
return QDir::toNativeSeparators(mkspec(kit)); return QDir::toNativeSeparators(mkspec(kit));
}); });

View File

@@ -103,7 +103,7 @@ public:
m_warnAgainstUnalignedBuildDirCheckbox.setText(tr("Warn if a project's source and " m_warnAgainstUnalignedBuildDirCheckbox.setText(tr("Warn if a project's source and "
"build directories are not at the same level")); "build directories are not at the same level"));
m_warnAgainstUnalignedBuildDirCheckbox.setToolTip(tr("Qmake has subtle bugs that " m_warnAgainstUnalignedBuildDirCheckbox.setToolTip(tr("Qmake has subtle bugs that "
"can trigger if source and build directory are not at the same level.")); "can be triggered if source and build directory are not at the same level."));
m_warnAgainstUnalignedBuildDirCheckbox.setChecked( m_warnAgainstUnalignedBuildDirCheckbox.setChecked(
QmakeSettings::warnAgainstUnalignedBuildDir()); QmakeSettings::warnAgainstUnalignedBuildDir());
m_alwaysRunQmakeCheckbox.setText(tr("Run qmake on every build")); m_alwaysRunQmakeCheckbox.setText(tr("Run qmake on every build"));

View File

@@ -165,6 +165,7 @@ const int priorityGenericToolBar = 50;
const int priorityLast = 60; const int priorityLast = 60;
const char addImagesDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Image Files"); const char addImagesDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Image Files");
const char addFontsDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Font Files");
} //ComponentCoreConstants } //ComponentCoreConstants

View File

@@ -1026,6 +1026,13 @@ void DesignerActionManager::createDefaultAddResourceHandler()
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addImagesDisplayString, registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addImagesDisplayString,
"*.svg", "*.svg",
ModelNodeOperations::addImageToProject)); ModelNodeOperations::addImageToProject));
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addFontsDisplayString,
"*.ttf",
ModelNodeOperations::addFontToProject));
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addFontsDisplayString,
"*.otf",
ModelNodeOperations::addFontToProject));
} }
void DesignerActionManager::addDesignerAction(ActionInterface *newAction) void DesignerActionManager::addDesignerAction(ActionInterface *newAction)

View File

@@ -966,6 +966,38 @@ void addTabBarToStackedContainer(const SelectionContext &selectionContext)
} }
bool addFontToProject(const QStringList &fileNames, const QString &defaultDirectory)
{
QString directory = AddImagesDialog::getDirectory(fileNames, defaultDirectory);
if (directory.isEmpty())
return true;
bool allSuccessful = true;
for (const QString &fileName : fileNames) {
const QString targetFile = directory + "/" + QFileInfo(fileName).fileName();
const bool success = QFile::copy(fileName, targetFile);
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
QTC_ASSERT(document, return false);
if (success) {
ProjectExplorer::Node *node = ProjectExplorer::ProjectTree::nodeForFile(document->fileName());
if (node) {
ProjectExplorer::FolderNode *containingFolder = node->parentFolderNode();
if (containingFolder)
containingFolder->addFiles(QStringList(targetFile));
}
} else {
allSuccessful = false;
}
}
return allSuccessful;
}
bool addImageToProject(const QStringList &fileNames, const QString &defaultDirectory) bool addImageToProject(const QStringList &fileNames, const QString &defaultDirectory)
{ {
QString directory = AddImagesDialog::getDirectory(fileNames, defaultDirectory); QString directory = AddImagesDialog::getDirectory(fileNames, defaultDirectory);

View File

@@ -73,6 +73,7 @@ void increaseIndexOfStackedContainer(const SelectionContext &selectionContext);
void decreaseIndexOfStackedContainer(const SelectionContext &selectionContext); void decreaseIndexOfStackedContainer(const SelectionContext &selectionContext);
void addTabBarToStackedContainer(const SelectionContext &selectionContext); void addTabBarToStackedContainer(const SelectionContext &selectionContext);
bool addImageToProject(const QStringList &fileNames, const QString &directory); bool addImageToProject(const QStringList &fileNames, const QString &directory);
bool addFontToProject(const QStringList &fileNames, const QString &directory);
} // namespace ModelNodeOperationso } // namespace ModelNodeOperationso
} //QmlDesigner } //QmlDesigner

View File

@@ -27,6 +27,7 @@
#include <qmlitemnode.h> #include <qmlitemnode.h>
#include <QDir>
#include <QObject> #include <QObject>
#include <QStringList> #include <QStringList>
#include <QUrl> #include <QUrl>

View File

@@ -256,6 +256,11 @@ QList<DeployableFile> QnxDeployQtLibrariesDialog::gatherFiles(
if (dirPath.isEmpty()) if (dirPath.isEmpty())
return result; return result;
static const QStringList unusedDirs = {"include", "mkspecs", "cmake", "pkgconfig"};
const QString dp = dirPath.endsWith('/') ? dirPath.left(dirPath.size() - 1) : dirPath;
if (unusedDirs.contains(dp))
return result;
QDir dir(dirPath); QDir dir(dirPath);
QFileInfoList list = dir.entryInfoList(nameFilters, QFileInfoList list = dir.entryInfoList(nameFilters,
QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
@@ -265,6 +270,10 @@ QList<DeployableFile> QnxDeployQtLibrariesDialog::gatherFiles(
result.append(gatherFiles(fileInfo.absoluteFilePath(), baseDirPath.isEmpty() ? result.append(gatherFiles(fileInfo.absoluteFilePath(), baseDirPath.isEmpty() ?
dirPath : baseDirPath)); dirPath : baseDirPath));
} else { } else {
static const QStringList unusedSuffixes = {"cmake", "la", "prl", "a", "pc"};
if (unusedSuffixes.contains(fileInfo.suffix()))
continue;
QString remoteDir; QString remoteDir;
if (baseDirPath.isEmpty()) { if (baseDirPath.isEmpty()) {
remoteDir = fullRemoteDirectory() + QLatin1Char('/') + remoteDir = fullRemoteDirectory() + QLatin1Char('/') +

View File

@@ -118,13 +118,13 @@ bool MakeInstallStep::init()
} }
QDir rootDir(rootDirPath); QDir rootDir(rootDirPath);
if (cleanInstallRoot() && !rootDir.removeRecursively()) { if (cleanInstallRoot() && !rootDir.removeRecursively()) {
emit addTask(Task(Task::Error, tr("The install root '%1' could not be cleaned.") emit addTask(Task(Task::Error, tr("The install root \"%1\" could not be cleaned.")
.arg(installRoot().toUserOutput()), .arg(installRoot().toUserOutput()),
FilePath(), -1, Constants::TASK_CATEGORY_BUILDSYSTEM)); FilePath(), -1, Constants::TASK_CATEGORY_BUILDSYSTEM));
return false; return false;
} }
if (!rootDir.exists() && !QDir::root().mkpath(rootDirPath)) { if (!rootDir.exists() && !QDir::root().mkpath(rootDirPath)) {
emit addTask(Task(Task::Error, tr("The install root '%1' could not be created.") emit addTask(Task(Task::Error, tr("The install root \"%1\" could not be created.")
.arg(installRoot().toUserOutput()), .arg(installRoot().toUserOutput()),
FilePath(), -1, Constants::TASK_CATEGORY_BUILDSYSTEM)); FilePath(), -1, Constants::TASK_CATEGORY_BUILDSYSTEM));
return false; return false;

View File

@@ -33,6 +33,7 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h> #include <coreplugin/messagemanager.h>
#include <utils/mimetypes/mimedatabase.h> #include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h>
#include <DefinitionDownloader> #include <DefinitionDownloader>
#include <Format> #include <Format>
@@ -119,6 +120,8 @@ Highlighter::Definition Highlighter::definitionForDocument(const TextDocument *d
Highlighter::Definition Highlighter::definitionForMimeType(const QString &mimeType) Highlighter::Definition Highlighter::definitionForMimeType(const QString &mimeType)
{ {
if (mimeType.isEmpty())
return {};
const Definitions definitions = definitionsForMimeType(mimeType); const Definitions definitions = definitionsForMimeType(mimeType);
if (definitions.size() == 1) if (definitions.size() == 1)
return definitions.first(); return definitions.first();
@@ -140,13 +143,23 @@ Highlighter::Definition Highlighter::definitionForName(const QString &name)
Highlighter::Definitions Highlighter::definitionsForDocument(const TextDocument *document) Highlighter::Definitions Highlighter::definitionsForDocument(const TextDocument *document)
{ {
const Utils::MimeType mimeType = Utils::mimeTypeForName(document->mimeType()); QTC_ASSERT(document, return {});
Definitions definitions; const Utils::MimeType &mimeType = Utils::mimeTypeForName(document->mimeType());
if (mimeType.isValid()) if (mimeType.isValid()) {
definitions = Highlighter::definitionsForMimeType(mimeType.name()); if (mimeType.name() == "text/plain") {
if (definitions.isEmpty()) // text/plain is the base mime type for all text types so ignore it and try matching the
definitions = Highlighter::definitionsForFileName(document->filePath()); // file name against the pattern and only if no definition can be found for the
return definitions; // file name try matching the mime type
const Definitions &fileNameDefinitions = definitionsForFileName(document->filePath());
if (!fileNameDefinitions.isEmpty())
return fileNameDefinitions;
return definitionsForMimeType(mimeType.name());
}
const Definitions &mimeTypeDefinitions = definitionsForMimeType(mimeType.name());
if (!mimeTypeDefinitions.isEmpty())
return mimeTypeDefinitions;
}
return definitionsForFileName(document->filePath());
} }
static Highlighter::Definition definitionForSetting(const QString &settingsKey, static Highlighter::Definition definitionForSetting(const QString &settingsKey,
@@ -193,6 +206,7 @@ Highlighter::Definitions Highlighter::definitionsForFileName(const Utils::FilePa
void Highlighter::rememberDefintionForDocument(const Highlighter::Definition &definition, void Highlighter::rememberDefintionForDocument(const Highlighter::Definition &definition,
const TextDocument *document) const TextDocument *document)
{ {
QTC_ASSERT(document, return );
if (!definition.isValid()) if (!definition.isValid())
return; return;
const QString &mimeType = document->mimeType(); const QString &mimeType = document->mimeType();

View File

@@ -630,7 +630,7 @@ MemcheckToolPrivate::MemcheckToolPrivate()
}); });
action = new QAction(this); action = new QAction(this);
action->setText(tr("Valgrind Memory Analyzer with GDB")); action->setText(MemcheckTool::tr("Valgrind Memory Analyzer with GDB"));
action->setToolTip(MemcheckTool::tr("Valgrind Analyze Memory with GDB uses the " action->setToolTip(MemcheckTool::tr("Valgrind Analyze Memory with GDB uses the "
"Memcheck tool to find memory leaks.\nWhen a problem is detected, " "Memcheck tool to find memory leaks.\nWhen a problem is detected, "
"the application is interrupted and can be debugged.")); "the application is interrupted and can be debugged."));
@@ -650,7 +650,7 @@ MemcheckToolPrivate::MemcheckToolPrivate()
} else { } else {
action = new QAction(MemcheckTool::tr("Heob"), this); action = new QAction(MemcheckTool::tr("Heob"), this);
Core::Command *cmd = Core::ActionManager::registerAction(action, "Memcheck.Local"); Core::Command *cmd = Core::ActionManager::registerAction(action, "Memcheck.Local");
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+H"))); cmd->setDefaultKeySequence(QKeySequence(MemcheckTool::tr("Ctrl+Alt+H")));
connect(action, &QAction::triggered, this, &MemcheckToolPrivate::heobAction); connect(action, &QAction::triggered, this, &MemcheckToolPrivate::heobAction);
menu->addAction(cmd, Debugger::Constants::G_ANALYZER_TOOLS); menu->addAction(cmd, Debugger::Constants::G_ANALYZER_TOOLS);
connect(m_startAction, &QAction::changed, action, [action, this] { connect(m_startAction, &QAction::changed, action, [action, this] {
@@ -659,7 +659,7 @@ MemcheckToolPrivate::MemcheckToolPrivate()
} }
action = new QAction(this); action = new QAction(this);
action->setText(tr("Valgrind Memory Analyzer (External Application)")); action->setText(MemcheckTool::tr("Valgrind Memory Analyzer (External Application)"));
action->setToolTip(toolTip); action->setToolTip(toolTip);
menu->addAction(ActionManager::registerAction(action, "Memcheck.Remote"), menu->addAction(ActionManager::registerAction(action, "Memcheck.Remote"),
Debugger::Constants::G_ANALYZER_REMOTE_TOOLS); Debugger::Constants::G_ANALYZER_REMOTE_TOOLS);
@@ -724,7 +724,7 @@ void MemcheckToolPrivate::heobAction()
} }
} }
if (!hasLocalRc) { if (!hasLocalRc) {
const QString msg = tr("Heob: No local run configuration available."); const QString msg = MemcheckTool::tr("Heob: No local run configuration available.");
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID); TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup(); TaskHub::requestPopup();
return; return;
@@ -733,7 +733,7 @@ void MemcheckToolPrivate::heobAction()
|| abi.os() != Abi::WindowsOS || abi.os() != Abi::WindowsOS
|| abi.binaryFormat() != Abi::PEFormat || abi.binaryFormat() != Abi::PEFormat
|| (abi.wordWidth() != 32 && abi.wordWidth() != 64)) { || (abi.wordWidth() != 32 && abi.wordWidth() != 64)) {
const QString msg = tr("Heob: No toolchain available."); const QString msg = MemcheckTool::tr("Heob: No toolchain available.");
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID); TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup(); TaskHub::requestPopup();
return; return;
@@ -746,7 +746,7 @@ void MemcheckToolPrivate::heobAction()
// target executable // target executable
if (executable.isEmpty()) { if (executable.isEmpty()) {
const QString msg = tr("Heob: No executable set."); const QString msg = MemcheckTool::tr("Heob: No executable set.");
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID); TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup(); TaskHub::requestPopup();
return; return;
@@ -754,7 +754,7 @@ void MemcheckToolPrivate::heobAction()
if (!QFile::exists(executable)) if (!QFile::exists(executable))
executable = Utils::HostOsInfo::withExecutableSuffix(executable); executable = Utils::HostOsInfo::withExecutableSuffix(executable);
if (!QFile::exists(executable)) { if (!QFile::exists(executable)) {
const QString msg = tr("Heob: Cannot find %1.").arg(executable); const QString msg = MemcheckTool::tr("Heob: Cannot find %1.").arg(executable);
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID); TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup(); TaskHub::requestPopup();
return; return;
@@ -775,8 +775,10 @@ void MemcheckToolPrivate::heobAction()
const QString heob = QString("heob%1.exe").arg(abi.wordWidth()); const QString heob = QString("heob%1.exe").arg(abi.wordWidth());
const QString heobPath = dialog.path() + '/' + heob; const QString heobPath = dialog.path() + '/' + heob;
if (!QFile::exists(heobPath)) { if (!QFile::exists(heobPath)) {
QMessageBox::critical(Core::ICore::mainWindow(), tr("Heob"), QMessageBox::critical(
tr("The %1 executables must be in the appropriate location.") Core::ICore::mainWindow(),
MemcheckTool::tr("Heob"),
MemcheckTool::tr("The %1 executables must be in the appropriate location.")
.arg("<a href=\"https://github.com/ssbssa/heob/releases\">Heob</a>")); .arg("<a href=\"https://github.com/ssbssa/heob/releases\">Heob</a>"));
return; return;
} }
@@ -787,12 +789,18 @@ void MemcheckToolPrivate::heobAction()
const QString dwarfstackPath = dialog.path() + '/' + dwarfstack; const QString dwarfstackPath = dialog.path() + '/' + dwarfstack;
if (!QFile::exists(dwarfstackPath) if (!QFile::exists(dwarfstackPath)
&& CheckableMessageBox::doNotShowAgainInformation( && CheckableMessageBox::doNotShowAgainInformation(
Core::ICore::mainWindow(), tr("Heob"), Core::ICore::mainWindow(),
tr("Heob used with MinGW projects needs the %1 DLLs for proper stacktrace resolution.") MemcheckTool::tr("Heob"),
.arg("<a href=\"https://github.com/ssbssa/dwarfstack/releases\">Dwarfstack</a>"), MemcheckTool::tr("Heob used with MinGW projects needs the %1 DLLs for proper "
ICore::settings(), "HeobDwarfstackInfo", "stacktrace resolution.")
.arg(
"<a "
"href=\"https://github.com/ssbssa/dwarfstack/releases\">Dwarfstack</a>"),
ICore::settings(),
"HeobDwarfstackInfo",
QDialogButtonBox::Ok | QDialogButtonBox::Cancel, QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
QDialogButtonBox::Ok) != QDialogButtonBox::Ok) QDialogButtonBox::Ok)
!= QDialogButtonBox::Ok)
return; return;
} }
@@ -837,7 +845,9 @@ void MemcheckToolPrivate::heobAction()
CREATE_UNICODE_ENVIRONMENT | CREATE_SUSPENDED | CREATE_NEW_CONSOLE, envPtr, CREATE_UNICODE_ENVIRONMENT | CREATE_SUSPENDED | CREATE_NEW_CONSOLE, envPtr,
reinterpret_cast<LPCWSTR>(workingDirectory.utf16()), &si, &pi)) { reinterpret_cast<LPCWSTR>(workingDirectory.utf16()), &si, &pi)) {
DWORD e = GetLastError(); DWORD e = GetLastError();
const QString msg = tr("Heob: Cannot create %1 process (%2).").arg(heob).arg(qt_error_string(e)); const QString msg = MemcheckTool::tr("Heob: Cannot create %1 process (%2).")
.arg(heob)
.arg(qt_error_string(e));
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID); TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup(); TaskHub::requestPopup();
return; return;

View File

@@ -239,7 +239,7 @@ void OutputWindowPlainTextEdit::appendLinesWithStyle(const QString &s,
setFormat(style); setFormat(style);
if (style == VcsOutputWindow::Command) { if (style == VcsOutputWindow::Command) {
const QString timeStamp = QTime::currentTime().toString("\nHH:mm "); const QString timeStamp = QTime::currentTime().toString("\nHH:mm:ss ");
appendLines(timeStamp + s, repository); appendLines(timeStamp + s, repository);
} else { } else {
appendLines(s, repository); appendLines(s, repository);
@@ -291,22 +291,17 @@ VcsOutputWindow::VcsOutputWindow()
Q_ASSERT(d->passwordRegExp.isValid()); Q_ASSERT(d->passwordRegExp.isValid());
m_instance = this; m_instance = this;
auto updateFontSettings = [] {
d->widget.setBaseFont(TextEditor::TextEditorSettings::fontSettings().font());
};
auto updateBehaviorSettings = [] { auto updateBehaviorSettings = [] {
d->widget.setWheelZoomEnabled( d->widget.setWheelZoomEnabled(
TextEditor::TextEditorSettings::behaviorSettings().m_scrollWheelZooming); TextEditor::TextEditorSettings::behaviorSettings().m_scrollWheelZooming);
}; };
updateFontSettings();
updateBehaviorSettings(); updateBehaviorSettings();
setupContext(Internal::C_VCS_OUTPUT_PANE, &d->widget);
connect(this, &IOutputPane::zoomIn, &d->widget, &Core::OutputWindow::zoomIn); connect(this, &IOutputPane::zoomIn, &d->widget, &Core::OutputWindow::zoomIn);
connect(this, &IOutputPane::zoomOut, &d->widget, &Core::OutputWindow::zoomOut); connect(this, &IOutputPane::zoomOut, &d->widget, &Core::OutputWindow::zoomOut);
connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::fontSettingsChanged, connect(this, &IOutputPane::resetZoom, &d->widget, &Core::OutputWindow::resetZoom);
this, updateFontSettings);
connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::behaviorSettingsChanged, connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::behaviorSettingsChanged,
this, updateBehaviorSettings); this, updateBehaviorSettings);
} }

Some files were not shown because too many files have changed in this diff Show More