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)
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:
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
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -127,7 +112,7 @@ endif()
set(_IDE_APP_PATH "bin")
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")
@@ -139,7 +124,7 @@ if (APPLE)
set(_IDE_DOC_PATH "${_IDE_OUTPUT_PATH}/Resources/doc")
set(_IDE_BIN_PATH "${_IDE_OUTPUT_PATH}/MacOS")
else ()
set(_IDE_APP_TARGET "qtcreator")
set(_IDE_APP_TARGET "${IDE_ID}")
set(_IDE_LIBRARY_BASE_PATH "lib")
set(_IDE_LIBRARY_PATH "lib/qtcreator")
@@ -154,15 +139,15 @@ else ()
set(_IDE_BIN_PATH "bin")
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_TARGET "${_IDE_APP_TARGET}" CACHE PATH "The IDE application name.")
set(IDE_PLUGIN_PATH "${_IDE_PLUGIN_PATH}" CACHE 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_PATH "${_IDE_LIBRARY_PATH}" CACHE 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_DATA_PATH "${_IDE_DATA_PATH}" CACHE 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_BIN_PATH "${_IDE_BIN_PATH}" CACHE PATH "The IDE bin path (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}") # The IDE application name.
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}") # The IDE library base 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}") # The IDE libexec 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}") # The IDE documentation 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_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
* 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
@@ -96,6 +102,9 @@ you can check out from the public Git repository. For example:
* Improved auto-insertion of closing curly brace (QTCREATORBUG-18872)
* 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
@@ -105,6 +114,8 @@ you can check out from the public Git repository. For example:
## QML Support
* Fixed various formatting issues
* Fixed incorrect syntax warning in JavaScript template literal
(QTCREATORBUG-22474)
## 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 support for changing properties for multiple items at once (QDS-324)
* Added missing properties for `LineEdit` and `ComboBox`
* Added all fonts from project directory to font selector (QDS-100)
* Updated properties of `Flickable`
* 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)
* Fixed that `mingw32-make`'s warnings were categorized as errors (QTCREATORBUG-22171)
* Fixed bitness detection for MinGW (QTCREATORBUG-22160)
* Fixed registration as post mortem debugger on recent Windows versions
### Linux
* Improved auto-detection of toolchains (QTCREATORBUG-19179, QTCREATORBUG-20044, QTCREATORBUG-22081)
### macOS
### Android
* 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 option for `rsync` flags for deployment (QTCREATORBUG-22352)
### Boot to Qt
### Bare Metal
* Added include path detection and output parsers for `IAR`, `KEIL` and `SDCC` toolchains
## Credits for these changes go to:
Aleksei German
Alessandro Ambrosano
Alessandro Portale
@@ -208,10 +218,12 @@ Ivan Komissarov
Joel Smith
Jörg Bornemann
Kavindra Palaraja
Knud Dollereder
Leena Miettinen
Luca Carlon
Marco Bubke
Martin Haase
Michael Weghorn
Mitch Curtis
Nikolai Kosjar
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/
**
** 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
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.
You can add paths to other CMake executables and use them in different
build and run \l{glossary-buildandrun-kit}{kits}.
@@ -109,6 +112,8 @@
\li Code completion
\li Path completion
\li Auto-indentation
\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/
**
** This file is part of the Qt Creator documentation.
@@ -31,27 +31,28 @@
\title Running Autotests
\QC integrates the \l{Qt Test} framework and
\l{https://github.com/google/googletest}{Google C++ Testing Framework} for
unit testing applications and libraries. You can use \QC to build and run
Qt tests, Qt Quick tests (QML-based Qt tests), and Google tests for your
projects.
\QC integrates the \l{Qt Test} framework,
\l{https://github.com/google/googletest}{Google C++ Testing Framework}, and
\l{https://www.boost.org/doc/libs/1_70_0/libs/test/doc/html/index.html}
{Boost.Test} for unit testing applications and libraries. You can use \QC to
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
\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
\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
Qt test.
Qt test or a Qt Quick test.
\li In the \uicontrol {Project and Test Information} dialog, specify
settings for the project and test:
@@ -59,17 +60,17 @@
\list 1
\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
a Qt application.
\li For a Qt test, select the \uicontrol {GUI Application} check
box to create a Qt application.
\li In the \uicontrol {Test case name} field, enter a name for
the test case.
\li Select the \uicontrol {Requires QApplication} check box to
add the include statement for QApplication to the main.cpp
file of the project.
\li For a Qt test, select the \uicontrol {Requires \QApplication}
check box to add the include statement for QApplication to
the main.cpp file of the project.
\li Select the \uicontrol {Generate initialization and cleanup
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}
{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
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
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
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
Qt Quick applications.
\QC is integrated to the \l{Qt Test} and Google C++ Testing
frameworks for unit testing applications and libraries. You can
use \QC to build and run autotests.
\QC is integrated to the \l{Qt Test}, Google C++ Testing, and
Boost.Test frameworks for unit testing applications and
libraries. You can use \QC to create, build, and run autotests.
For more information, see \l{Testing}.
\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/
**
** This file is part of the Qt Creator documentation.
@@ -60,9 +60,8 @@
\li \l{Running Autotests}
You can build and run Qt tests, Qt Quick tests, and Google tests
using \QC. In addition, you can use a wizard to create projects that
contain Qt or Google tests.
You can create, build and run Qt tests, Qt Quick tests, Google
tests, and Boost tests using \QC.
\endlist

View File

@@ -153,7 +153,7 @@ class PlainDumper:
if d.isExpanded():
with Children(d):
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):
if args == 'off':

View File

@@ -953,43 +953,27 @@ def qdumpHelper__std__vector(d, value, isLibCpp):
innerType = value.type[0]
isBool = innerType.name == 'bool'
try:
allocator = value.type[1].name
except:
allocator = ''
isStdAllocator = allocator == 'std::allocator<%s>' % innerType.name
if isBool:
if isLibCpp:
if isStdAllocator:
(start, size) = value.split("pp") # start is 'unsigned long *'
else:
start = value["__begin_"].pointer()
size = value["__size_"]
start = value["__begin_"].pointer()
size = value["__size_"]
alloc = size
else:
if isStdAllocator:
(start, soffset, pad, finish, foffset, pad, alloc) = value.split("pI@pI@p")
else:
start = value["_M_start"]["_M_p"].pointer()
soffset = value["_M_start"]["_M_offset"]
finish = value["_M_finish"]["_M_p"].pointer()
foffset = value["_M_finish"]["_M_offset"]
alloc = value["_M_end_of_storage"].pointer()
start = value["_M_start"]["_M_p"].pointer()
soffset = value["_M_start"]["_M_offset"].integer()
finish = value["_M_finish"]["_M_p"].pointer()
foffset = value["_M_finish"]["_M_offset"].integer()
alloc = value["_M_end_of_storage"].pointer()
size = (finish - start) * 8 + foffset - soffset # 8 is CHAR_BIT.
else:
if isStdAllocator:
(start, finish, alloc) = value.split("ppp")
if isLibCpp:
start = value["__begin_"].pointer()
finish = value["__end_"].pointer()
alloc = value["__end_cap_"].pointer()
else:
if isLibCpp:
start = value["__begin_"].pointer()
finish = value["__end_"].pointer()
alloc = value["__end_cap_"].pointer()
else:
start = value["_M_start"].pointer()
finish = value["_M_finish"].pointer()
alloc = value["_M_end_of_storage"].pointer()
start = value["_M_start"].pointer()
finish = value["_M_finish"].pointer()
alloc = value["_M_end_of_storage"].pointer()
size = int((finish - start) / innerType.size())
d.check(finish <= alloc)
if size > 0:
@@ -1088,19 +1072,12 @@ def qdump__std__basic_string(d, value):
def qdump__std____cxx11__basic_string(d, value):
innerType = value.type[0]
try:
allocator = value.type[2].name
data = value["_M_dataplus"]["_M_p"].pointer()
size = int(value["_M_string_length"])
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"])
except:
d.putEmptyValue()
d.putPlainChildren(value)
return
d.putEmptyValue()
d.putPlainChildren(value)
return
d.check(0 <= size) #and size <= alloc and alloc <= 100*1000*1000)
d.putCharArrayHelper(data, size, innerType, d.currentItemFormat())

View File

@@ -39,7 +39,35 @@ StudioControls.ComboBox {
onTextColorChanged: setColor()
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: {
editText = comboBox.backendValue.valueToString
@@ -97,10 +125,12 @@ StudioControls.ComboBox {
target: modelNodeBackend
onSelectionChanged: {
comboBox.editText = backendValue.value
setupModel()
}
}
Component.onCompleted: {
setupModel()
//Hack to style the text input
for (var i = 0; i < comboBox.children.length; i++) {
if (comboBox.children[i].text !== undefined) {

View File

@@ -9,7 +9,7 @@
"iconText": "java",
"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" :
[

View File

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

View File

@@ -14,7 +14,7 @@
{ "key": "vcsId", "value": "B.Bazaar" },
{ "key": "vcsName", "value": "%{JS: Vcs.displayName('%{vcsId}')}" },
{ "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": "TargetPath", "value": "%{Path}/%{Dir}" }
],

View File

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

View File

@@ -14,7 +14,7 @@
{ "key": "vcsId", "value": "H.Mercurial" },
{ "key": "vcsName", "value": "%{JS: Vcs.displayName('%{vcsId}')}" },
{ "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}" }
],

View File

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

View File

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

View File

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

View File

@@ -18,6 +18,7 @@ SOURCES += \
$$PWD/clangcodemodelserverproxy.cpp \
$$PWD/alivemessage.cpp \
$$PWD/completionsmessage.cpp \
$$PWD/filesystem.cpp \
$$PWD/requestcompletionsmessage.cpp \
$$PWD/echomessage.cpp \
$$PWD/endmessage.cpp \
@@ -87,7 +88,8 @@ SOURCES += \
$$PWD/removegeneratedfilesmessage.cpp \
$$PWD/generatedfiles.cpp \
$$PWD/projectpartartefact.cpp \
$$PWD/projectpartcontainer.cpp
$$PWD/projectpartcontainer.cpp \
$$PWD/filestatuscache.cpp
HEADERS += \
$$PWD/cancelmessage.h \
@@ -109,7 +111,11 @@ HEADERS += \
$$PWD/alivemessage.h \
$$PWD/clangsupportexceptions.h \
$$PWD/completionsmessage.h \
$$PWD/directoryandfilepathid.h \
$$PWD/directorypathid.h \
$$PWD/executeinloop.h \
$$PWD/filesystem.h \
$$PWD/filesysteminterface.h \
$$PWD/pchpaths.h \
$$PWD/projectpartid.h \
$$PWD/projectpartsstorage.h \
@@ -151,6 +157,7 @@ HEADERS += \
$$PWD/refactoringserverinterface.h \
$$PWD/refactoringserverproxy.h \
$$PWD/referencesmessage.h \
$$PWD/set_algorithm.h \
$$PWD/unsavedfilesupdatedmessage.h \
$$PWD/removeprojectpartsmessage.h \
$$PWD/requestannotationsmessage.h \
@@ -217,6 +224,8 @@ HEADERS += \
$$PWD/sourceentry.h \
$$PWD/modifiedtimecheckerinterface.h \
$$PWD/environment.h \
$$PWD/filestatus.h \
$$PWD/filestatuscache.h \
$$PWD/modifiedtimechecker.h
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 <filepathid.h>
#include <filepathcache.h>
#include "filepathcachinginterface.h"
#include <QDir>
#include <QTimer>
#include <filepathcachinginterface.h>
#include <utils/algorithm.h>
#include <functional>
namespace ClangBackEnd {
template <typename Timer>
class ChangedFilePathCompressor
template<typename Timer>
class DirectoryPathCompressor
{
public:
ChangedFilePathCompressor(FilePathCachingInterface &filePathCache)
: m_filePathCache(filePathCache)
DirectoryPathCompressor() { m_timer.setSingleShot(true); }
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()
{
}
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);
if (found == m_directoryPathIds.end() || *found != directoryPathIdId)
m_directoryPathIds.insert(found, directoryPathIdId);
restartTimer();
}
FilePathIds takeFilePathIds()
{
return std::move(m_filePaths);
}
DirectoryPathIds takeDirectoryPathIds() { return std::move(m_directoryPathIds); }
virtual void setCallback(std::function<void(ClangBackEnd::FilePathIds &&)> &&callback)
virtual void setCallback(std::function<void(ClangBackEnd::DirectoryPathIds &&)> &&callback)
{
QObject::connect(&m_timer,
&Timer::timeout,
[this, callback=std::move(callback)] { callback(takeFilePathIds()); });
QObject::connect(&m_timer, &Timer::timeout, [this, callback = std::move(callback)] {
callback(takeDirectoryPathIds());
});
}
unittest_public:
@@ -88,9 +79,8 @@ unittest_public:
}
private:
FilePathIds m_filePaths;
DirectoryPathIds m_directoryPathIds;
Timer m_timer;
FilePathCachingInterface &m_filePathCache;
};
} // 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
#include "directorypathid.h"
#include "filepath.h"
#include "filepathexceptions.h"
#include "filepathid.h"
#include "filepath.h"
#include "filepathview.h"
#include "stringcache.h"
@@ -121,10 +122,10 @@ public:
{
Utils::SmallStringView directoryPath = filePath.directory();
int directoryId = m_directoryPathCache.stringId(directoryPath,
[&] (const Utils::SmallStringView) {
return m_filePathStorage.fetchDirectoryId(directoryPath);
});
int directoryId = m_directoryPathCache.stringId(
directoryPath, [&](const Utils::SmallStringView directoryPath) {
return m_filePathStorage.fetchDirectoryId(directoryPath);
});
Utils::SmallStringView fileName = filePath.name();
@@ -136,6 +137,17 @@ public:
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
{
if (Q_UNLIKELY(!filePathId.isValid()))
@@ -157,6 +169,32 @@ public:
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:
mutable DirectoryPathCache m_directoryPathCache;
mutable FileNameCache m_fileNameCache;

View File

@@ -37,4 +37,19 @@ FilePath FilePathCaching::filePath(FilePathId filePathId) const
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

View File

@@ -50,6 +50,9 @@ public:
FilePathId filePathId(FilePathView filePath) 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:
Factory m_factory;

View File

@@ -25,6 +25,7 @@
#pragma once
#include "directorypathid.h"
#include "filepath.h"
#include "filepathid.h"
#include "filepathview.h"
@@ -40,8 +41,11 @@ public:
virtual FilePathId filePathId(FilePathView filePath) 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;

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
{
public:

View File

@@ -179,12 +179,32 @@ public:
transaction.commit();
return optionalSourceName.value();
return *optionalSourceName;
} catch (const Sqlite::StatementIsBusy &) {
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()
{
try {

View File

@@ -69,6 +69,8 @@ public:
"SELECT sourceName, directoryId FROM sources WHERE sourceId = ?",
database
};
ReadStatement selectDirectoryIdFromSourcesBySourceId{
"SELECT directoryId FROM sources WHERE sourceId = ?", database};
WriteStatement insertIntoSources{
"INSERT INTO sources(directoryId, sourceName) VALUES (?,?)",
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 {
class FileSystemInterface;
namespace Internal {
class FileStatusCacheEntry
{
@@ -41,8 +43,23 @@ public:
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:
ClangBackEnd::FilePathId filePathId;
FilePathId filePathId;
long long lastModified;
};
@@ -50,27 +67,30 @@ using FileStatusCacheEntries = std::vector<FileStatusCacheEntry>;
}
class FileStatusCache
class CLANGSUPPORT_EXPORT FileStatusCache
{
public:
using size_type = Internal::FileStatusCacheEntries::size_type;
FileStatusCache(FilePathCachingInterface &filePathCache);
FileStatusCache(FileSystemInterface &fileSystem)
: m_fileSystem(fileSystem)
{}
FileStatusCache &operator=(const FileStatusCache &) = delete;
FileStatusCache(const FileStatusCache &) = delete;
long long lastModifiedTime(ClangBackEnd::FilePathId filePathId) const;
void update(ClangBackEnd::FilePathId filePathId);
long long lastModifiedTime(FilePathId filePathId) const;
void update(FilePathId filePathId);
void update(FilePathIds filePathIds);
FilePathIds modified(FilePathIds filePathIds) const;
size_type size() const;
private:
Internal::FileStatusCacheEntry findEntry(ClangBackEnd::FilePathId filePathId) const;
QFileInfo qFileInfo(ClangBackEnd::FilePathId filePathId) const;
Internal::FileStatusCacheEntry findEntry(FilePathId filePathId) const;
private:
mutable Internal::FileStatusCacheEntries m_cacheEntries;
FilePathCachingInterface &m_filePathCache;
FileSystemInterface &m_fileSystem;
};
} // 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
#include "filepathcachinginterface.h"
#include "filesysteminterface.h"
#include "modifiedtimecheckerinterface.h"
#include "set_algorithm.h"
#include <algorithm>
#include <iterator>
namespace ClangBackEnd {
template<typename SourceEntries = ::ClangBackEnd::SourceEntries>
class ModifiedTimeChecker final : public ModifiedTimeCheckerInterface<SourceEntries>
{
using SourceEntry = typename SourceEntries::value_type;
public:
using GetModifiedTime = std::function<ClangBackEnd::TimeStamp(ClangBackEnd::FilePathView filePath)>;
ModifiedTimeChecker(GetModifiedTime &getModifiedTime, FilePathCachingInterface &filePathCache)
: m_getModifiedTime(getModifiedTime)
, m_filePathCache(filePathCache)
ModifiedTimeChecker(FileSystemInterface &fileSystem)
: m_fileSystem(fileSystem)
{}
bool isUpToDate(const SourceEntries &sourceEntries) const
@@ -51,165 +51,101 @@ public:
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(),
m_currentSourceTimeStamps.end(),
filePathIds.begin(),
filePathIds.end(),
std::back_inserter(timeStampsToUpdate));
make_iterator([&](SourceTimeStamp &sourceTimeStamp) {
sourceTimeStamp.timeStamp = m_fileSystem.lastModified(
sourceTimeStamp.sourceId);
}));
}
for (SourceTimeStamp &sourceTimeStamp : timeStampsToUpdate) {
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:
bool compareEntries(const SourceEntries &sourceEntries) const
{
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;
}
};
SourceTimeStamps currentSourceTimeStamp;
currentSourceTimeStamp.reserve(sourceEntries.size());
std::set_intersection(m_currentSourceTimeStamps.begin(),
m_currentSourceTimeStamps.end(),
sourceEntries.begin(),
sourceEntries.end(),
std::back_inserter(currentSourceTimeStamp),
CompareSourceId{});
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{});
return set_intersection_compare(
m_currentSourceTimeStamps.begin(),
m_currentSourceTimeStamps.end(),
sourceEntries.begin(),
sourceEntries.end(),
[](auto first, auto second) { return second.timeStamp > first.timeStamp; },
[](auto first, auto second) { return first.sourceId < second.sourceId; });
}
void updateCurrentSourceTimeStamps(const SourceEntries &sourceEntries) const
{
SourceTimeStamps sourceTimeStamps = newSourceTimeStamps(sourceEntries);
for (SourceTimeStamp &newSourceTimeStamp : sourceTimeStamps) {
newSourceTimeStamp.timeStamp = m_getModifiedTime(
m_filePathCache.filePath(newSourceTimeStamp.sourceId));
}
auto split = sourceTimeStamps.insert(sourceTimeStamps.end(),
m_currentSourceTimeStamps.begin(),
m_currentSourceTimeStamps.end());
std::inplace_merge(sourceTimeStamps.begin(), split, sourceTimeStamps.end());
m_currentSourceTimeStamps = sourceTimeStamps;
m_currentSourceTimeStamps = std::move(sourceTimeStamps);
}
SourceTimeStamps newSourceTimeStamps(const SourceEntries &sourceEntries) const
{
SourceEntries newSourceEntries;
newSourceEntries.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;
}
};
SourceTimeStamps newTimeStamps;
newTimeStamps.reserve(sourceEntries.size());
std::set_difference(sourceEntries.begin(),
sourceEntries.end(),
m_currentSourceTimeStamps.begin(),
m_currentSourceTimeStamps.end(),
std::back_inserter(newSourceEntries),
CompareSourceId{});
SourceTimeStamps newTimeStamps;
newTimeStamps.reserve(newSourceEntries.size());
std::transform(newSourceEntries.begin(),
newSourceEntries.end(),
std::back_inserter(newTimeStamps),
[](SourceEntry entry) {
return SourceTimeStamp{entry.sourceId, {}};
});
make_iterator([&](const SourceEntry &sourceEntry) {
newTimeStamps.emplace_back(sourceEntry.sourceId,
m_fileSystem.lastModified(
sourceEntry.sourceId));
}),
[](auto first, auto second) {
return first.sourceId < second.sourceId && first.timeStamp > 0;
});
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:
mutable SourceTimeStamps m_currentSourceTimeStamps;
GetModifiedTime &m_getModifiedTime;
FilePathCachingInterface &m_filePathCache;
mutable FilePathIds m_resetFilePathIds;
FileSystemInterface &m_fileSystem;
};
} // namespace ClangBackEnd

View File

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

View File

@@ -144,11 +144,11 @@ public:
table.setName("projectPartsFiles");
const Sqlite::Column &projectPartIdColumn = table.addColumn("projectPartId", 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("hasMissingIncludes", Sqlite::ColumnType::Integer);
table.addUniqueIndex({sourceIdColumn, projectPartIdColumn});
table.addIndex({projectPartIdColumn});
table.addIndex({projectPartIdColumn, sourceType});
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;
}
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)
{
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 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))
return QT_PREPEND_NAMESPACE(qHash(Utils::get<int>(id)));
@@ -102,8 +102,7 @@ inline LANGUAGESERVERPROTOCOL_EXPORT uint qHash(const LanguageServerProtocol::Me
}
template <typename Error>
inline LANGUAGESERVERPROTOCOL_EXPORT QDebug operator<<(QDebug stream,
const LanguageServerProtocol::MessageId &id)
inline QDebug operator<<(QDebug stream, const LanguageServerProtocol::MessageId &id)
{
if (Utils::holds_alternative<int>(id))
stream << Utils::get<int>(id);

View File

@@ -1676,7 +1676,7 @@ bool Check::visit(CallExpression *ast)
if (!whiteListedFunction && !isMathFunction && !isDateFunction && !isDirectInConnectionsScope)
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)) {
addMessage(WarnExpectedNewWithUppercaseFunction, location);

View File

@@ -179,6 +179,10 @@ public:
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:
const char *m_pointer = "";
size_type m_size = 0;

View File

@@ -77,8 +77,9 @@ void AutoTestUnitTests::initTestCase()
if (!qgetenv("BOOST_INCLUDE_DIR").isEmpty()) {
m_checkBoost = true;
} else {
if (QFileInfo::exists("/usr/include/boost/version.hpp")
|| QFileInfo::exists("/usr/local/include/boost/version.hpp")) {
if (Utils::HostOsInfo::isLinuxHost()
&& (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.";
m_checkBoost = true;
}

View File

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

View File

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

View File

@@ -144,7 +144,7 @@ void ClangCodeModelPlugin::createCompilationDBButton()
message = tr("Clang compilation database generated at \"%1\".")
.arg(QDir::toNativeSeparators(result.filePath));
} 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);
m_generateCompilationDBAction->setEnabled(

View File

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

View File

@@ -477,6 +477,16 @@ void ClangToolRunControl::finalize()
if (m_filesNotAnalyzed != 0) {
QString msg = tr("%1: Not all files could be analyzed.").arg(toolName);
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();
}

View File

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

View File

@@ -87,7 +87,9 @@ void ClangToolsProjectSettings::load()
m_useGlobalSettings = useGlobalVariant.isValid() ? useGlobalVariant.toBool() : true;
m_diagnosticConfig = Core::Id::fromSetting(
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); };

View File

@@ -25,6 +25,7 @@
#include "clangtoolsutils.h"
#include "clangtool.h"
#include "clangtoolsdiagnostic.h"
#include "clangtoolssettings.h"
@@ -32,8 +33,9 @@
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/hostosinfo.h>
#include <utils/checkablemessagebox.h>
#include <utils/environment.h>
#include <utils/hostosinfo.h>
#include <utils/synchronousprocess.h>
#include <QCoreApplication>
@@ -49,5 +51,24 @@ QString createFullLocationString(const Debugger::DiagnosticLocation &location)
+ 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 ClangTools

View File

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

View File

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

View File

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

View File

@@ -41,6 +41,8 @@ class QWidget;
QT_END_NAMESPACE
namespace Core {
class CommandButton;
class IContext;
class CORE_EXPORT IOutputPane : public QObject
{
@@ -93,6 +95,7 @@ signals:
void setBadgeNumber(int number);
void zoomIn(int range);
void zoomOut(int range);
void resetZoom();
void wheelZoomEnabledChanged(bool enabled);
void fontChanged(const QFont &font);
@@ -103,7 +106,7 @@ protected:
Qt::CaseSensitivity filterCaseSensitivity() const { return m_filterCaseSensitivity; }
void setFilteringEnabled(bool enable);
QWidget *filterWidget() const { return m_filterOutputLineEdit; }
void setupContext(const char *context, QWidget *widget);
void setZoomButtonsEnabled(bool enabled);
private:
@@ -115,11 +118,12 @@ private:
Id filterRegexpActionId() const;
Id filterCaseSensitivityActionId() const;
QToolButton * const m_zoomInButton = nullptr;
QToolButton * const m_zoomOutButton = nullptr;
Core::CommandButton * const m_zoomInButton;
Core::CommandButton * const m_zoomOutButton;
QAction *m_filterActionRegexp = nullptr;
QAction *m_filterActionCaseSensitive = nullptr;
Utils::FancyLineEdit *m_filterOutputLineEdit = nullptr;
IContext *m_context = nullptr;
bool m_filterRegexp = false;
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::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::wheelZoomEnabledChanged, m_widget, &OutputWindow::setWheelZoomEnabled);
@@ -65,6 +66,7 @@ MessageOutputWindow::MessageOutputWindow()
setupFilterUi("MessageOutputPane.Filter");
setFilteringEnabled(true);
setupContext(Constants::C_GENERAL_OUTPUT_PANE, m_widget);
}
MessageOutputWindow::~MessageOutputWindow()

View File

@@ -35,6 +35,7 @@
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/actionmanager/commandbutton.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/find/optionspopup.h>
@@ -90,24 +91,27 @@ static bool g_managerConstructed = false; // For debugging reasons.
IOutputPane::IOutputPane(QObject *parent)
: QObject(parent),
m_zoomInButton(new QToolButton),
m_zoomOutButton(new QToolButton)
m_zoomInButton(new Core::CommandButton),
m_zoomOutButton(new Core::CommandButton)
{
// We need all pages first. Ignore latecomers and shout.
QTC_ASSERT(!g_managerConstructed, return);
g_outputPanes.append(OutputPaneData(this));
m_zoomInButton->setToolTip(tr("Increase Font Size"));
m_zoomInButton->setIcon(Utils::Icons::PLUS_TOOLBAR.icon());
m_zoomInButton->setCommandId(Constants::ZOOM_IN);
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->setCommandId(Constants::ZOOM_OUT);
connect(m_zoomOutButton, &QToolButton::clicked, this, [this] { emit zoomOut(1); });
}
IOutputPane::~IOutputPane()
{
if (m_context)
ICore::removeContextObject(m_context);
const int i = Utils::indexOf(g_outputPanes, Utils::equal(&OutputPaneData::pane, this));
QTC_ASSERT(i >= 0, return);
delete g_outputPanes.at(i).button;
@@ -174,6 +178,26 @@ void IOutputPane::setFilteringEnabled(bool 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)
{
m_zoomInButton->setEnabled(enabled);

View File

@@ -75,6 +75,7 @@ public:
void setBaseFont(const QFont &newFont);
float fontZoom() const;
void setFontZoom(float zoom);
void resetZoom() { setFontZoom(0); }
void setWheelZoomEnabled(bool enabled);
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();
}
int ParseContextModel::rowCount(const QModelIndex &) const
int ParseContextModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return m_projectParts.size();
}
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();
const int row = index.row();

View File

@@ -709,6 +709,7 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
qgetenv("QTC_CLANG_CMD_OPTIONS_BLACKLIST"))
.split(';', QString::SkipEmptyParts);
const Core::Id &toolChain = m_projectPart.toolchainType;
bool containsDriverMode = false;
bool skipNext = false;
for (const QString &option : m_projectPart.compilerFlags) {
@@ -720,6 +721,13 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
if (userBlackList.contains(option))
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.
// Note that once "-w" is provided, no warnings will be emitted, even if "-Wall" follows.
if (m_useBuildSystemWarnings == UseBuildSystemWarnings::No
@@ -755,7 +763,7 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
// Check whether a language version is already used.
QString theOption = option;
if (theOption.startsWith("-std=")) {
if (theOption.startsWith("-std=") || theOption.startsWith("--std=")) {
m_compilerFlags.isLanguageVersionSpecified = true;
theOption.replace("=c18", "=c17");
theOption.replace("=gnu18", "=gnu17");
@@ -772,7 +780,6 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
m_compilerFlags.flags.append(theOption);
}
const Core::Id &toolChain = m_projectPart.toolchainType;
if (!containsDriverMode
&& (toolChain == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
|| toolChain == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID)) {

View File

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

View File

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

View File

@@ -157,6 +157,9 @@ PerfProfilerTool::PerfProfilerTool()
tracePointsAction->setEnabled(m_startAction->isEnabled());
});
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
this, &PerfProfilerTool::updateRunActions);
m_recordButton = new QToolButton;
m_clearButton = new QToolButton;
m_filterButton = new QToolButton;
@@ -341,9 +344,6 @@ void PerfProfilerTool::createViews()
menu1->exec(m_flameGraphView->mapToGlobal(pos));
});
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
this, &PerfProfilerTool::updateRunActions);
m_perspective.addToolBarAction(m_startAction);
m_perspective.addToolBarAction(m_stopAction);
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::zoomOut, this, &AppOutputPane::zoomOut);
connect(this, &IOutputPane::resetZoom, this, &AppOutputPane::resetZoom);
m_settingsButton->setToolTip(tr("Open Settings Page"));
m_settingsButton->setIcon(Utils::Icons::SETTINGS_TOOLBAR.icon());
@@ -247,6 +248,7 @@ AppOutputPane::AppOutputPane() :
setupFilterUi("AppOutputPane.Filter");
setFilteringEnabled(false);
setZoomButtonsEnabled(false);
setupContext("Core.AppOutputPane", m_mainWidget);
}
AppOutputPane::~AppOutputPane()
@@ -662,6 +664,12 @@ void AppOutputPane::zoomOut(int range)
tab.window->zoomOut(range);
}
void AppOutputPane::resetZoom()
{
for (const RunControlTab &tab : qAsConst(m_runControlTabs))
tab.window->resetZoom();
}
void AppOutputPane::enableButtons(const RunControl *rc)
{
if (rc) {

View File

@@ -120,6 +120,7 @@ private:
void zoomIn(int range);
void zoomOut(int range);
void resetZoom();
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::zoomOut, m_outputWindow, &Core::OutputWindow::zoomOut);
connect(this, &IOutputPane::resetZoom, m_outputWindow, &Core::OutputWindow::resetZoom);
connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::fontSettingsChanged,
this, updateFontSettings);
connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::behaviorSettingsChanged,
@@ -194,6 +195,7 @@ CompileOutputWindow::CompileOutputWindow(QAction *cancelBuildAction) :
m_handler = new ShowOutputTaskHandler(this);
ExtensionSystem::PluginManager::addObject(m_handler);
setupContext(C_COMPILE_OUTPUT, m_outputWindow);
loadSettings();
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 dir = QDir::toNativeSeparators(
QFileDialog::getExistingDirectory(this, tr("Choose a directory")));
QFileDialog::getExistingDirectory(this, tr("Choose Directory")));
if (dir.isEmpty())
return;
QModelIndex index = d->m_model->variableToIndex(varName);

View File

@@ -92,7 +92,7 @@ class FilterKitAspectsModel : public TreeModel<TreeItem, FilterTreeItem>
public:
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()) {
if (kit && !aspect->isApplicableToKit(kit))
continue;

View File

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

View File

@@ -63,10 +63,14 @@ ImportWidget::ImportWidget(QWidget *parent) :
connect(importButton, &QAbstractButton::clicked, this, &ImportWidget::handleImportRequest);
connect(m_pathChooser->lineEdit(), &QLineEdit::returnPressed, this, [this] {
if (m_pathChooser->isValid()) {
m_ownsReturnKey = true;
handleImportRequest();
// 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);
}
bool ImportWidget::lineEditHasFocus() const
bool ImportWidget::ownsReturnKey() const
{
return m_pathChooser->lineEdit()->hasFocus();
return m_ownsReturnKey;
}
void ImportWidget::handleImportRequest()

View File

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

View File

@@ -104,7 +104,7 @@ public:
: QDialog(parent), m_view(new Utils::TreeView(this))
{
setWindowTitle(QCoreApplication::translate("ProjectExplorer::JsonWizard",
"Choose project file"));
"Choose Project File"));
const auto model = new ProjectFilesModel(candidates, this);
m_view->setSelectionMode(Utils::TreeView::ExtendedSelection);
m_view->setSelectionBehavior(Utils::TreeView::SelectRows);
@@ -121,7 +121,7 @@ public:
const auto layout = new QVBoxLayout(this);
layout->addWidget(new QLabel(QCoreApplication::translate("ProjectExplorer::JsonWizard",
"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(buttonBox);
}

View File

@@ -1298,6 +1298,7 @@ MsvcToolChainConfigWidget::MsvcToolChainConfigWidget(ToolChain *tc)
m_mainLayout->removeRow(m_mainLayout->rowCount() - 1);
QHBoxLayout *hLayout = new QHBoxLayout();
m_varsBatPathCombo->setObjectName("varsBatCombo");
m_varsBatPathCombo->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
m_varsBatPathCombo->setEditable(true);
for (const MsvcToolChain *tmpTc : g_availableMsvcToolchains) {
@@ -1442,6 +1443,7 @@ ClangClToolChainConfigWidget::ClangClToolChainConfigWidget(ToolChain *tc) :
{
m_mainLayout->removeRow(m_mainLayout->rowCount() - 1);
m_varsBatDisplayCombo->setObjectName("varsBatCombo");
m_varsBatDisplayCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
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.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] {
const QString filePath = QFileDialog::getOpenFileName(this, tr("Choose File"));
if (filePath.isEmpty())
return;
QFile file(filePath);
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")
.arg(filePath, file.errorString()));
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).
// If we introduced factories for IOutputParsers, we could offer the user
// to combine arbitrary parsers here.
const auto parserGroupBox = new QGroupBox(tr("Parsing options"));
const auto parserGroupBox = new QGroupBox(tr("Parsing Options"));
layout->addWidget(parserGroupBox);
const auto parserLayout = new QVBoxLayout(parserGroupBox);
const auto kitChooserWidget = new QWidget;
@@ -153,7 +153,7 @@ void ParseIssuesDialog::accept()
{
std::unique_ptr<IOutputParser> parser(d->kitChooser.currentKit()->createOutputParser());
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."));
return;
}

View File

@@ -667,7 +667,7 @@ void Project::changeRootProjectDirectory()
{
Utils::FilePath rootPath = Utils::FilePath::fromString(
QFileDialog::getExistingDirectory(Core::ICore::dialogParent(),
tr("Select The Root Directory"),
tr("Select the Root Directory"),
rootProjectDirectory().toString(),
QFileDialog::ShowDirsOnly
| 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
{

View File

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

View File

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

View File

@@ -332,7 +332,7 @@ void TargetSetupPage::setProjectImporter(ProjectImporter *importer)
bool TargetSetupPage::importLineEditHasFocus() const
{
return m_importWidget->lineEditHasFocus();
return m_importWidget->ownsReturnKey();
}
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
{
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 {
return QDir::toNativeSeparators(mkspec(kit));
});

View File

@@ -103,7 +103,7 @@ public:
m_warnAgainstUnalignedBuildDirCheckbox.setText(tr("Warn if a project's source and "
"build directories are not at the same level"));
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(
QmakeSettings::warnAgainstUnalignedBuildDir());
m_alwaysRunQmakeCheckbox.setText(tr("Run qmake on every build"));

View File

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

View File

@@ -1026,6 +1026,13 @@ void DesignerActionManager::createDefaultAddResourceHandler()
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addImagesDisplayString,
"*.svg",
ModelNodeOperations::addImageToProject));
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addFontsDisplayString,
"*.ttf",
ModelNodeOperations::addFontToProject));
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addFontsDisplayString,
"*.otf",
ModelNodeOperations::addFontToProject));
}
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)
{
QString directory = AddImagesDialog::getDirectory(fileNames, defaultDirectory);

View File

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

View File

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

View File

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

View File

@@ -118,13 +118,13 @@ bool MakeInstallStep::init()
}
QDir rootDir(rootDirPath);
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()),
FilePath(), -1, Constants::TASK_CATEGORY_BUILDSYSTEM));
return false;
}
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()),
FilePath(), -1, Constants::TASK_CATEGORY_BUILDSYSTEM));
return false;

View File

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

View File

@@ -630,7 +630,7 @@ MemcheckToolPrivate::MemcheckToolPrivate()
});
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 "
"Memcheck tool to find memory leaks.\nWhen a problem is detected, "
"the application is interrupted and can be debugged."));
@@ -650,7 +650,7 @@ MemcheckToolPrivate::MemcheckToolPrivate()
} else {
action = new QAction(MemcheckTool::tr("Heob"), this);
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);
menu->addAction(cmd, Debugger::Constants::G_ANALYZER_TOOLS);
connect(m_startAction, &QAction::changed, action, [action, this] {
@@ -659,7 +659,7 @@ MemcheckToolPrivate::MemcheckToolPrivate()
}
action = new QAction(this);
action->setText(tr("Valgrind Memory Analyzer (External Application)"));
action->setText(MemcheckTool::tr("Valgrind Memory Analyzer (External Application)"));
action->setToolTip(toolTip);
menu->addAction(ActionManager::registerAction(action, "Memcheck.Remote"),
Debugger::Constants::G_ANALYZER_REMOTE_TOOLS);
@@ -724,7 +724,7 @@ void MemcheckToolPrivate::heobAction()
}
}
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::requestPopup();
return;
@@ -733,7 +733,7 @@ void MemcheckToolPrivate::heobAction()
|| abi.os() != Abi::WindowsOS
|| abi.binaryFormat() != Abi::PEFormat
|| (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::requestPopup();
return;
@@ -746,7 +746,7 @@ void MemcheckToolPrivate::heobAction()
// target executable
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::requestPopup();
return;
@@ -754,7 +754,7 @@ void MemcheckToolPrivate::heobAction()
if (!QFile::exists(executable))
executable = Utils::HostOsInfo::withExecutableSuffix(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::requestPopup();
return;
@@ -775,9 +775,11 @@ void MemcheckToolPrivate::heobAction()
const QString heob = QString("heob%1.exe").arg(abi.wordWidth());
const QString heobPath = dialog.path() + '/' + heob;
if (!QFile::exists(heobPath)) {
QMessageBox::critical(Core::ICore::mainWindow(), tr("Heob"),
tr("The %1 executables must be in the appropriate location.")
.arg("<a href=\"https://github.com/ssbssa/heob/releases\">Heob</a>"));
QMessageBox::critical(
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>"));
return;
}
@@ -786,13 +788,19 @@ void MemcheckToolPrivate::heobAction()
const QString dwarfstack = QString("dwarfstack%1.dll").arg(abi.wordWidth());
const QString dwarfstackPath = dialog.path() + '/' + dwarfstack;
if (!QFile::exists(dwarfstackPath)
&& CheckableMessageBox::doNotShowAgainInformation(
Core::ICore::mainWindow(), tr("Heob"),
tr("Heob used with MinGW projects needs the %1 DLLs for proper stacktrace resolution.")
.arg("<a href=\"https://github.com/ssbssa/dwarfstack/releases\">Dwarfstack</a>"),
ICore::settings(), "HeobDwarfstackInfo",
QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
QDialogButtonBox::Ok) != QDialogButtonBox::Ok)
&& CheckableMessageBox::doNotShowAgainInformation(
Core::ICore::mainWindow(),
MemcheckTool::tr("Heob"),
MemcheckTool::tr("Heob used with MinGW projects needs the %1 DLLs for proper "
"stacktrace resolution.")
.arg(
"<a "
"href=\"https://github.com/ssbssa/dwarfstack/releases\">Dwarfstack</a>"),
ICore::settings(),
"HeobDwarfstackInfo",
QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
QDialogButtonBox::Ok)
!= QDialogButtonBox::Ok)
return;
}
@@ -837,7 +845,9 @@ void MemcheckToolPrivate::heobAction()
CREATE_UNICODE_ENVIRONMENT | CREATE_SUSPENDED | CREATE_NEW_CONSOLE, envPtr,
reinterpret_cast<LPCWSTR>(workingDirectory.utf16()), &si, &pi)) {
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::requestPopup();
return;

View File

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

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