Merge "Merge remote-tracking branch 'origin/4.6'"
23
README.md
@@ -277,6 +277,29 @@ http://llvm.org/docs/GettingStarted.html#git-mirror:
|
|||||||
Qt Creator includes the following third-party components,
|
Qt Creator includes the following third-party components,
|
||||||
we thank the authors who made this possible:
|
we thank the authors who made this possible:
|
||||||
|
|
||||||
|
### Clazy
|
||||||
|
|
||||||
|
https://github.com/KDE/clazy
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018 Clazy Team
|
||||||
|
|
||||||
|
Distributed under GNU LIBRARY GENERAL PUBLIC LICENSE Version 2 (LGPL2).
|
||||||
|
|
||||||
|
Integrated with patches from QtCreator/dist/clang/patches, see README.md there.
|
||||||
|
|
||||||
|
### LLVM/Clang
|
||||||
|
|
||||||
|
http://llvm.org/svn/llvm-project/llvm
|
||||||
|
http://llvm.org/svn/llvm-project/cfe/trunk
|
||||||
|
http://llvm.org/svn/llvm-project/clang-tools-extra/trunk
|
||||||
|
|
||||||
|
Copyright (C) 2003-2018 LLVM Team
|
||||||
|
|
||||||
|
Distributed under the University of Illinois/NCSA Open Source License (NCSA),
|
||||||
|
see https://github.com/llvm-mirror/llvm/blob/master/LICENSE.TXT
|
||||||
|
|
||||||
|
With additional patches from QtCreator/dist/clang/patches, see README.md there.
|
||||||
|
|
||||||
### Reference implementation for std::experimental::optional
|
### Reference implementation for std::experimental::optional
|
||||||
|
|
||||||
https://github.com/akrzemi1/Optional
|
https://github.com/akrzemi1/Optional
|
||||||
|
|||||||
147
dist/changes-4.6.0.md
vendored
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
Qt Creator version 4.6 contains bug fixes and new features.
|
||||||
|
|
||||||
|
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/4.5..v4.6.0
|
||||||
|
|
||||||
|
General
|
||||||
|
|
||||||
|
* Locator
|
||||||
|
* Added filter `b` for bookmarks
|
||||||
|
* Added filter `t` for triggering items from main menu
|
||||||
|
* Added filter `=` for evaluating JavaScript expressions
|
||||||
|
(QTCREATORBUG-14380)
|
||||||
|
* File System View
|
||||||
|
* Added bread crumbs for file path (QTCREATORBUG-19203)
|
||||||
|
* Added `Add New`, `Rename`, `Remove File`, `Diff Against Current File`
|
||||||
|
(QTCREATORBUG-19213, QTCREATORBUG-19209, QTCREATORBUG-19208,
|
||||||
|
QTCREATORBUG-19211)
|
||||||
|
* Added restoration of search flags when choosing search term from history
|
||||||
|
|
||||||
|
Editing
|
||||||
|
|
||||||
|
* Added option to display annotations between lines (QTCREATORBUG-19181)
|
||||||
|
* Fixed that editor could jump to end of file when editing in a different split
|
||||||
|
(QTCREATORBUG-19550)
|
||||||
|
|
||||||
|
All Projects
|
||||||
|
|
||||||
|
* Added filtering to project kit setup page
|
||||||
|
|
||||||
|
Qbs Projects
|
||||||
|
|
||||||
|
* Added option to add library paths to dependencies (QTCREATORBUG-19274)
|
||||||
|
|
||||||
|
C++ Support
|
||||||
|
|
||||||
|
* Clang Code Model
|
||||||
|
* Switched to Clang 5.0, adding support for C++17
|
||||||
|
* Implemented information tool tips, which improves type information
|
||||||
|
including resolution of `auto` types (QTCREATORBUG-11259), template arguments
|
||||||
|
for template types, and the first or `\brief` paragraph of documentation
|
||||||
|
comments (QTCREATORBUG-4557)
|
||||||
|
* Integrated Clang-Tidy and Clazy.
|
||||||
|
Enable checks in Options > C++ > Code Model > Clang Code Model Warnings
|
||||||
|
* Added separate highlighting for function definitions (QTCREATORBUG-16625)
|
||||||
|
|
||||||
|
QML Support
|
||||||
|
|
||||||
|
* Added inline annotations for issues from code model
|
||||||
|
|
||||||
|
Debugging
|
||||||
|
|
||||||
|
* Split `Expressions` view from `Locals` view (QTCREATORBUG-19167)
|
||||||
|
|
||||||
|
Qt Quick Designer
|
||||||
|
|
||||||
|
* Added font and text properties from Qt 5.10
|
||||||
|
* Fixed that items blurred when zooming in
|
||||||
|
* Fixed crash when changing control focus policy (QTCREATORBUG-19563)
|
||||||
|
|
||||||
|
Version Control Systems
|
||||||
|
|
||||||
|
* Git
|
||||||
|
* Added `Recover Deleted Files`
|
||||||
|
* Added `Reload` button to `git log` and `git blame`
|
||||||
|
* Gerrit
|
||||||
|
* Added support for private and work-in-progress changes for
|
||||||
|
Gerrit 2.15 and later
|
||||||
|
|
||||||
|
Diff Viewer
|
||||||
|
|
||||||
|
* Added folding for files and chunks
|
||||||
|
|
||||||
|
Test Integration
|
||||||
|
|
||||||
|
* Added grouping of test cases (QTCREATORBUG-17979)
|
||||||
|
* Google Test
|
||||||
|
* Fixed detection of crashed tests (QTCREATORBUG-19565)
|
||||||
|
|
||||||
|
Model Editor
|
||||||
|
|
||||||
|
* Added support for text alignment
|
||||||
|
* Added support for multi-line object names
|
||||||
|
* Added support for dragging items onto model editor from more panes
|
||||||
|
* Added `Export Selected Elements`
|
||||||
|
* Added `Flat` visual role
|
||||||
|
* Added `Add Related Elements` to diagram context menu
|
||||||
|
* Added wizard for scratch models
|
||||||
|
* Fixed issue with selecting items (QTCREATORBUG-18368)
|
||||||
|
|
||||||
|
Platform Specific
|
||||||
|
|
||||||
|
Windows
|
||||||
|
|
||||||
|
* Added support for the [heob](https://github.com/ssbssa/heob/releases)
|
||||||
|
memory analyzer
|
||||||
|
* Fixed detection of CDB in non-default installation roots
|
||||||
|
|
||||||
|
Android
|
||||||
|
|
||||||
|
* Fixed issues with GCC include directories in Clang code model
|
||||||
|
|
||||||
|
Remote Linux
|
||||||
|
|
||||||
|
* Fixed that remote application was not killed before deployment
|
||||||
|
(QTCREATORBUG-19326)
|
||||||
|
|
||||||
|
Credits for these changes go to:
|
||||||
|
Adam Treat
|
||||||
|
Alessandro Portale
|
||||||
|
Alexandru Croitor
|
||||||
|
Andre Hartmann
|
||||||
|
André Pönitz
|
||||||
|
Christian Gagneraud
|
||||||
|
Christian Kandeler
|
||||||
|
Christian Stenger
|
||||||
|
Daniel Engelke
|
||||||
|
David Schulz
|
||||||
|
Eike Ziller
|
||||||
|
Friedemann Kleint
|
||||||
|
Hannes Domani
|
||||||
|
Hugo Holgersson
|
||||||
|
Ivan Donchevskii
|
||||||
|
Jake Petroules
|
||||||
|
Jaroslaw Kobus
|
||||||
|
Jochen Becher
|
||||||
|
Jörg Bornemann
|
||||||
|
Marco Benelli
|
||||||
|
Marco Bubke
|
||||||
|
Mitch Curtis
|
||||||
|
Nikita Baryshnikov
|
||||||
|
Nikolai Kosjar
|
||||||
|
Oliver Wolff
|
||||||
|
Orgad Shaneh
|
||||||
|
Oswald Buddenhagen
|
||||||
|
Przemyslaw Gorszkowski
|
||||||
|
Robert Löhning
|
||||||
|
Thomas Hartmann
|
||||||
|
Tim Jenssen
|
||||||
|
Tobias Hunger
|
||||||
|
Tomasz Olszak
|
||||||
|
Tor Arne Vestbø
|
||||||
|
Ulf Hermann
|
||||||
|
Vikas Pachdha
|
||||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 22 KiB |
@@ -75,8 +75,8 @@
|
|||||||
useful if the code contains typos, for example.
|
useful if the code contains typos, for example.
|
||||||
|
|
||||||
Clang keeps up with the development of the C++ language. At the time of this
|
Clang keeps up with the development of the C++ language. At the time of this
|
||||||
writing, it supports C++98/03, C++11, C++14, C89, C99, Objective-C, and
|
writing, it supports C++98/03, C++11, C++14, C++17, C89, C99, Objective-C,
|
||||||
Objective-C++.
|
and Objective-C++.
|
||||||
|
|
||||||
On the downside, for large projects using Clang as code model is slower than
|
On the downside, for large projects using Clang as code model is slower than
|
||||||
using the built-in code model. Clang does not need to generate object files,
|
using the built-in code model. Clang does not need to generate object files,
|
||||||
@@ -94,11 +94,27 @@
|
|||||||
\li Syntactic and semantic highlighting
|
\li Syntactic and semantic highlighting
|
||||||
\li Diagnostics
|
\li Diagnostics
|
||||||
\li Tooltips
|
\li Tooltips
|
||||||
|
\li Clang-Tidy and Clazy checks
|
||||||
|
\li Renaming of local symbols
|
||||||
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
To use the plugin, you must activate it and configure it in \QC.
|
To use the plugin, you must activate it and configure it in \QC.
|
||||||
|
|
||||||
|
\section1 Using Clang-Tidy and Clazy
|
||||||
|
|
||||||
|
\l{https://clang.llvm.org/extra/clang-tidy/}{Clang-Tidy} and
|
||||||
|
\l{https://github.com/KDE/clazy/blob/master/README.md}{Clazy} are delivered
|
||||||
|
as parts of the Clang library delivered with \QC.
|
||||||
|
|
||||||
|
Clang-Tidy provides an extensible framework for diagnosing and fixing
|
||||||
|
typical programming errors, such as style violations, interface misuse, or
|
||||||
|
issues that can be found via static analysis.
|
||||||
|
|
||||||
|
Clazy helps Clang understand Qt semantics. It prints out Qt related compiler
|
||||||
|
warnings, ranging from unnecessary memory allocation to misuse of API and
|
||||||
|
provides refactoring actions for fixing some of the issues.
|
||||||
|
|
||||||
\section1 Activating Clang Code Model
|
\section1 Activating Clang Code Model
|
||||||
|
|
||||||
If you build \QC yourself, ensure that the plugin is also built, as
|
If you build \QC yourself, ensure that the plugin is also built, as
|
||||||
@@ -176,6 +192,9 @@
|
|||||||
{Options to Request or Suppress Warnings} or the GCC or Clang
|
{Options to Request or Suppress Warnings} or the GCC or Clang
|
||||||
manual pages.
|
manual pages.
|
||||||
|
|
||||||
|
\li In the \uicontrol {Clang Plugins} field, select the Clang-Tidy and
|
||||||
|
Clazy checks to perform.
|
||||||
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
You can specify Clang settings at project level in the build settings of
|
You can specify Clang settings at project level in the build settings of
|
||||||
|
|||||||
@@ -2851,6 +2851,9 @@
|
|||||||
\li Locating files belonging to your project (\c {p}), such as source,
|
\li Locating files belonging to your project (\c {p}), such as source,
|
||||||
header resource, and \c {.ui} files, or to any project (\c {a})
|
header resource, and \c {.ui} files, or to any project (\c {a})
|
||||||
|
|
||||||
|
\li Locating bookmarks (\c {b}).
|
||||||
|
For more information, see \l{Using Bookmarks}.
|
||||||
|
|
||||||
\li Locating class (\c {c}), enum, and function (m) definitions in your
|
\li Locating class (\c {c}), enum, and function (m) definitions in your
|
||||||
project or anywhere referenced from your project (\c {:})
|
project or anywhere referenced from your project (\c {:})
|
||||||
|
|
||||||
@@ -2874,6 +2877,8 @@
|
|||||||
\li Executing version control system commands (\c {git}). For more
|
\li Executing version control system commands (\c {git}). For more
|
||||||
information, see \l{Using Version Control Systems}
|
information, see \l{Using Version Control Systems}
|
||||||
|
|
||||||
|
\li Triggering menu items from the main menu (\c {t})
|
||||||
|
|
||||||
\li Running external tools (\c x)
|
\li Running external tools (\c x)
|
||||||
|
|
||||||
\endlist
|
\endlist
|
||||||
@@ -2914,6 +2919,10 @@
|
|||||||
followed by \key Space, followed by path and file name, and then press
|
followed by \key Space, followed by path and file name, and then press
|
||||||
\key Enter.
|
\key Enter.
|
||||||
|
|
||||||
|
You can use the filter that triggers menu commands to open sessions. Enter
|
||||||
|
\c {t yoursess} or \c {t sess yoursess} to trigger \uicontrol File >
|
||||||
|
\uicontrol Sessions > \e yoursessionname.
|
||||||
|
|
||||||
By default, the following filters are enabled and you do not need to use
|
By default, the following filters are enabled and you do not need to use
|
||||||
their prefixes explicitly:
|
their prefixes explicitly:
|
||||||
|
|
||||||
|
|||||||
@@ -98,6 +98,9 @@
|
|||||||
|
|
||||||
\image qtcreator-welcome-session.png
|
\image qtcreator-welcome-session.png
|
||||||
|
|
||||||
|
You can also use the \c t locator filter to open a session. For more
|
||||||
|
information, see \l{Searching with the Locator}.
|
||||||
|
|
||||||
To view more information about a session, select the down arrow icon that
|
To view more information about a session, select the down arrow icon that
|
||||||
appears when you move the mouse cursor over the session name. Select actions
|
appears when you move the mouse cursor over the session name. Select actions
|
||||||
to clone, rename, and delete sessions.
|
to clone, rename, and delete sessions.
|
||||||
|
|||||||
@@ -261,7 +261,11 @@
|
|||||||
\image qtcreator-filesystem-view.png
|
\image qtcreator-filesystem-view.png
|
||||||
|
|
||||||
By default, the contents of the directory that contains the file currently
|
By default, the contents of the directory that contains the file currently
|
||||||
active in the editor are displayed. To move to the root directory of the
|
active in the editor are displayed. The path to the active file is displayed
|
||||||
|
as bread crumbs. You can move to any directory along the path by clicking
|
||||||
|
it.
|
||||||
|
|
||||||
|
To move to the root directory of the
|
||||||
file system, select \uicontrol Computer in the menu (1). Select
|
file system, select \uicontrol Computer in the menu (1). Select
|
||||||
\uicontrol Home to move to the user's home directory. Further, you can
|
\uicontrol Home to move to the user's home directory. Further, you can
|
||||||
select a project to move to an open project or \uicontrol Projects to open
|
select a project to move to an open project or \uicontrol Projects to open
|
||||||
@@ -288,6 +292,14 @@
|
|||||||
|
|
||||||
\li Search from the selected directory.
|
\li Search from the selected directory.
|
||||||
|
|
||||||
|
\li Create new files. For more information, see
|
||||||
|
\l{Adding Files to Projects}.
|
||||||
|
|
||||||
|
\li Rename or remove existing files.
|
||||||
|
|
||||||
|
\li Compare the selected file with the currently open file in the diff
|
||||||
|
editor. For more information, see \l{Comparing Files}.
|
||||||
|
|
||||||
\li Display the contents of a particular directory in the view.
|
\li Display the contents of a particular directory in the view.
|
||||||
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
** Copyright (C) 2018 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -124,6 +124,9 @@
|
|||||||
\uicontrol {Fixup Previous Commit}. This operation is done using interactive
|
\uicontrol {Fixup Previous Commit}. This operation is done using interactive
|
||||||
rebase. In case of conflicts, a merge tool is suggested.
|
rebase. In case of conflicts, a merge tool is suggested.
|
||||||
|
|
||||||
|
To recover removed files, select \uicontrol Tools > \uicontrol Git >
|
||||||
|
\uicontrol {Recover Deleted Files}.
|
||||||
|
|
||||||
To change a series of commits in the local repository, select
|
To change a series of commits in the local repository, select
|
||||||
\uicontrol Tools > \uicontrol Git > \uicontrol {Local Repository} >
|
\uicontrol Tools > \uicontrol Git > \uicontrol {Local Repository} >
|
||||||
\uicontrol {Interactive Rebase}. You can reorder or discard commits, squash
|
\uicontrol {Interactive Rebase}. You can reorder or discard commits, squash
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
** Copyright (C) 2018 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -234,6 +234,9 @@
|
|||||||
show annotation views of previous versions (see \l{Annotating Files}).
|
show annotation views of previous versions (see \l{Annotating Files}).
|
||||||
With Git you can also choose to cherry-pick or revert a change.
|
With Git you can also choose to cherry-pick or revert a change.
|
||||||
|
|
||||||
|
With Git, you can click \inlineimage reload_gray.png
|
||||||
|
(\uicontrol Reload) to rescan the files.
|
||||||
|
|
||||||
\section2 Annotating Files
|
\section2 Annotating Files
|
||||||
|
|
||||||
Annotation views are obtained by selecting \uicontrol{Annotate} or \uicontrol{Blame}.
|
Annotation views are obtained by selecting \uicontrol{Annotate} or \uicontrol{Blame}.
|
||||||
@@ -250,6 +253,9 @@
|
|||||||
The same context menu is available when right-clicking on a version
|
The same context menu is available when right-clicking on a version
|
||||||
identifier in the file log view of a single file.
|
identifier in the file log view of a single file.
|
||||||
|
|
||||||
|
With Git, you can click \inlineimage reload_gray.png
|
||||||
|
(\uicontrol Reload) to rescan the files.
|
||||||
|
|
||||||
\section2 Committing Changes
|
\section2 Committing Changes
|
||||||
|
|
||||||
Once you have finished making changes, submit them to the version control
|
Once you have finished making changes, submit them to the version control
|
||||||
|
|||||||
@@ -16,7 +16,10 @@ function readOutput(executable, args)
|
|||||||
|
|
||||||
function readListOutput(executable, args)
|
function readListOutput(executable, args)
|
||||||
{
|
{
|
||||||
return readOutput(executable, args).split(/\s+/);
|
var list = readOutput(executable, args).split(/\s+/);
|
||||||
|
if (!list[list.length - 1])
|
||||||
|
list.pop();
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSuitableLLVMConfig(llvmConfigCandidate, qtcFunctions)
|
function isSuitableLLVMConfig(llvmConfigCandidate, qtcFunctions)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ Module {
|
|||||||
property bool enableUnitTests: false
|
property bool enableUnitTests: false
|
||||||
property bool enableProjectFileUpdates: true
|
property bool enableProjectFileUpdates: true
|
||||||
property bool installApiHeaders: false
|
property bool installApiHeaders: false
|
||||||
|
property bool enableBundledQt: false
|
||||||
property string libInstallDir: qtc.ide_library_path
|
property string libInstallDir: qtc.ide_library_path
|
||||||
property stringList libRPaths: qbs.targetOS.contains("macos")
|
property stringList libRPaths: qbs.targetOS.contains("macos")
|
||||||
? ["@loader_path/" + FileInfo.relativePath('/' + appInstallDir, '/' + libInstallDir)]
|
? ["@loader_path/" + FileInfo.relativePath('/' + appInstallDir, '/' + libInstallDir)]
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ macx {
|
|||||||
} else {
|
} else {
|
||||||
BINDIST_SOURCE = "$(INSTALL_ROOT)$$QTC_PREFIX"
|
BINDIST_SOURCE = "$(INSTALL_ROOT)$$QTC_PREFIX"
|
||||||
BINDIST_EXCLUDE_ARG = "--exclude-toplevel"
|
BINDIST_EXCLUDE_ARG = "--exclude-toplevel"
|
||||||
deployqt.commands = python -u $$PWD/scripts/deployqt.py -i \"$(INSTALL_ROOT)$$QTC_PREFIX\" \"$(QMAKE)\"
|
deployqt.commands = python -u $$PWD/scripts/deployqt.py -i \"$(INSTALL_ROOT)$$QTC_PREFIX/bin/$${IDE_APP_TARGET}\" \"$(QMAKE)\"
|
||||||
deployqt.depends = install
|
deployqt.depends = install
|
||||||
win32 {
|
win32 {
|
||||||
deployartifacts.depends = install
|
deployartifacts.depends = install
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ debug_build = False
|
|||||||
encoding = locale.getdefaultlocale()[1]
|
encoding = locale.getdefaultlocale()[1]
|
||||||
|
|
||||||
def usage():
|
def usage():
|
||||||
print("Usage: %s <creator_install_dir> [qmake_path]" % os.path.basename(sys.argv[0]))
|
print("Usage: %s <existing_qtcreator_binary> [qmake_path]" % os.path.basename(sys.argv[0]))
|
||||||
|
|
||||||
def which(program):
|
def which(program):
|
||||||
def is_exe(fpath):
|
def is_exe(fpath):
|
||||||
@@ -77,9 +77,6 @@ def is_debug(fpath):
|
|||||||
output = subprocess.check_output(['dumpbin', '/imports', fpath])
|
output = subprocess.check_output(['dumpbin', '/imports', fpath])
|
||||||
return coredebug.search(output.decode(encoding)) != None
|
return coredebug.search(output.decode(encoding)) != None
|
||||||
|
|
||||||
def is_debug_build(install_dir):
|
|
||||||
return is_debug(os.path.join(install_dir, 'bin', 'qtcreator.exe'))
|
|
||||||
|
|
||||||
def op_failed(details = None):
|
def op_failed(details = None):
|
||||||
if details != None:
|
if details != None:
|
||||||
print(details)
|
print(details)
|
||||||
@@ -274,11 +271,16 @@ def main():
|
|||||||
ignoreErrors = True
|
ignoreErrors = True
|
||||||
print("Note: Ignoring all errors")
|
print("Note: Ignoring all errors")
|
||||||
|
|
||||||
if len(args) < 1:
|
qtcreator_binary = os.path.abspath(args[0])
|
||||||
|
if common.is_windows_platform() and not qtcreator_binary.lower().endswith(".exe"):
|
||||||
|
qtcreator_binary = qtcreator_binary + ".exe"
|
||||||
|
|
||||||
|
if len(args) < 1 or not os.path.isfile(qtcreator_binary):
|
||||||
usage()
|
usage()
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
install_dir = args[0]
|
qtcreator_binary_path = os.path.dirname(qtcreator_binary)
|
||||||
|
install_dir = os.path.abspath(os.path.join(qtcreator_binary_path, '..'))
|
||||||
if common.is_linux_platform():
|
if common.is_linux_platform():
|
||||||
qt_deploy_prefix = os.path.join(install_dir, 'lib', 'Qt')
|
qt_deploy_prefix = os.path.join(install_dir, 'lib', 'Qt')
|
||||||
else:
|
else:
|
||||||
@@ -307,12 +309,14 @@ def main():
|
|||||||
QT_INSTALL_QML = qt_install_info['QT_INSTALL_QML']
|
QT_INSTALL_QML = qt_install_info['QT_INSTALL_QML']
|
||||||
QT_INSTALL_TRANSLATIONS = qt_install_info['QT_INSTALL_TRANSLATIONS']
|
QT_INSTALL_TRANSLATIONS = qt_install_info['QT_INSTALL_TRANSLATIONS']
|
||||||
|
|
||||||
plugins = ['accessible', 'codecs', 'designer', 'iconengines', 'imageformats', 'platformthemes', 'platforminputcontexts', 'platforms', 'printsupport', 'sqldrivers', 'styles', 'xcbglintegrations']
|
plugins = ['accessible', 'codecs', 'designer', 'iconengines', 'imageformats', 'platformthemes',
|
||||||
|
'platforminputcontexts', 'platforms', 'printsupport', 'sqldrivers', 'styles',
|
||||||
|
'xcbglintegrations', 'qmltooling']
|
||||||
imports = ['Qt', 'QtWebKit']
|
imports = ['Qt', 'QtWebKit']
|
||||||
|
|
||||||
if common.is_windows_platform():
|
if common.is_windows_platform():
|
||||||
global debug_build
|
global debug_build
|
||||||
debug_build = is_debug_build(install_dir)
|
debug_build = is_debug(qtcreator_binary)
|
||||||
|
|
||||||
if common.is_windows_platform():
|
if common.is_windows_platform():
|
||||||
copy_qt_libs(qt_deploy_prefix, QT_INSTALL_BINS, QT_INSTALL_BINS, QT_INSTALL_PLUGINS, QT_INSTALL_IMPORTS, QT_INSTALL_QML, plugins, imports)
|
copy_qt_libs(qt_deploy_prefix, QT_INSTALL_BINS, QT_INSTALL_BINS, QT_INSTALL_PLUGINS, QT_INSTALL_IMPORTS, QT_INSTALL_QML, plugins, imports)
|
||||||
|
|||||||
@@ -41,8 +41,9 @@ use warnings;
|
|||||||
while (my $line = <STDIN>) {
|
while (my $line = <STDIN>) {
|
||||||
chomp($line);
|
chomp($line);
|
||||||
# --- extract file name based matching:
|
# --- extract file name based matching:
|
||||||
# D:/.../qaxbase.cpp:3231: warning: Cannot tie this documentation to anything
|
# Qt 5.10: D:/.../qaxbase.cpp:3231: warning: Cannot tie this documentation to anything
|
||||||
if ($line =~ /^(..[^:]*):(\d+): warning: (.*)$/) {
|
# Qt 5.11: D:/.../qaxbase.cpp:3231: (qdoc) warning: Cannot tie this documentation to anything
|
||||||
|
if ($line =~ /^(..[^:]*):(\d+): (?:\(qdoc\) )?warning: (.*)$/) {
|
||||||
my $fileName = $1;
|
my $fileName = $1;
|
||||||
my $lineNumber = $2;
|
my $lineNumber = $2;
|
||||||
my $text = $3;
|
my $text = $3;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ Module {
|
|||||||
"QmlProject/Project 1.1"
|
"QmlProject/Project 1.1"
|
||||||
]
|
]
|
||||||
Property { name: "sourceDirectory"; type: "string" }
|
Property { name: "sourceDirectory"; type: "string" }
|
||||||
Property { name: "targetDirectory": type: "string" }
|
Property { name: "targetDirectory"; type: "string" }
|
||||||
Property { name: "mainFile"; type: "string" }
|
Property { name: "mainFile"; type: "string" }
|
||||||
Property { name: "importPaths"; type: "string"; isList: true }
|
Property { name: "importPaths"; type: "string"; isList: true }
|
||||||
Property { name: "content"; type: "QmlProjectItem"; isList: true }
|
Property { name: "content"; type: "QmlProjectItem"; isList: true }
|
||||||
@@ -70,4 +70,4 @@ Module {
|
|||||||
]
|
]
|
||||||
Property { name: "filter"; type: "string" }
|
Property { name: "filter"; type: "string" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,6 +155,12 @@ Item {
|
|||||||
}
|
}
|
||||||
checkable: true
|
checkable: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Controls.MenuItem {
|
||||||
|
text: qsTr("Insert keyframe")
|
||||||
|
visible: hasActiveTimeline
|
||||||
|
onTriggered: insertKeyframe(backendValue.name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
"trDescription": "Creates a scratch model using a temporary file.",
|
"trDescription": "Creates a scratch model using a temporary file.",
|
||||||
"trDisplayName": "Scratch Model",
|
"trDisplayName": "Scratch Model",
|
||||||
"trDisplayCategory": "Modeling",
|
"trDisplayCategory": "Modeling",
|
||||||
|
"iconText": "qmodel",
|
||||||
"platformIndependent": true,
|
"platformIndependent": true,
|
||||||
"enabled": "%{JS: [ %{Plugins} ].indexOf('ModelEditor') >= 0}",
|
"enabled": "%{JS: [ %{Plugins} ].indexOf('ModelEditor') >= 0}",
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.12)
|
cmake_minimum_required(VERSION 3.1)
|
||||||
|
|
||||||
project(%{ProjectName} LANGUAGES CXX)
|
project(%{ProjectName} LANGUAGES CXX)
|
||||||
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
find_package(Qt5 COMPONENTS Core Quick REQUIRED)
|
find_package(Qt5 COMPONENTS Core Quick REQUIRED)
|
||||||
|
|
||||||
|
|||||||
@@ -57589,7 +57589,7 @@ Má se to zkusit ještě jednou?</translation>
|
|||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>QmlProfiler::Internal::QmlProfilerEventsMainView</name>
|
<name>QmlProfiler::Internal::QmlProfilerStatisticsMainView</name>
|
||||||
<message>
|
<message>
|
||||||
<source>Location</source>
|
<source>Location</source>
|
||||||
<translation>Umístění</translation>
|
<translation>Umístění</translation>
|
||||||
|
|||||||
@@ -58942,7 +58942,7 @@ Voulez-vous la tuer ?</translation>
|
|||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>QmlProfiler::Internal::QmlProfilerEventsMainView</name>
|
<name>QmlProfiler::Internal::QmlProfilerStatisticsMainView</name>
|
||||||
<message>
|
<message>
|
||||||
<source>Location</source>
|
<source>Location</source>
|
||||||
<translation>Emplacement</translation>
|
<translation>Emplacement</translation>
|
||||||
|
|||||||
@@ -30492,7 +30492,7 @@ Do you want to kill it?</source>
|
|||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>QmlProfiler::Internal::QmlProfilerEventsMainView</name>
|
<name>QmlProfiler::Internal::QmlProfilerStatisticsMainView</name>
|
||||||
<message>
|
<message>
|
||||||
<source>Location</source>
|
<source>Location</source>
|
||||||
<translation type="vanished">Розташування</translation>
|
<translation type="vanished">Розташування</translation>
|
||||||
|
|||||||
@@ -55655,7 +55655,7 @@ Do you want to retry?</source>
|
|||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>QmlProfiler::Internal::QmlProfilerEventsMainView</name>
|
<name>QmlProfiler::Internal::QmlProfilerStatisticsMainView</name>
|
||||||
<message>
|
<message>
|
||||||
<source>Location</source>
|
<source>Location</source>
|
||||||
<translation>路径</translation>
|
<translation>路径</translation>
|
||||||
|
|||||||
@@ -32076,7 +32076,7 @@ Do you want to kill it?</source>
|
|||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>QmlProfiler::Internal::QmlProfilerEventsMainView</name>
|
<name>QmlProfiler::Internal::QmlProfilerStatisticsMainView</name>
|
||||||
<message>
|
<message>
|
||||||
<source>Location</source>
|
<source>Location</source>
|
||||||
<translation>位置</translation>
|
<translation>位置</translation>
|
||||||
|
|||||||
@@ -153,9 +153,10 @@ Item {
|
|||||||
spacing: innerMargin
|
spacing: innerMargin
|
||||||
columns: 2
|
columns: 2
|
||||||
property int minimumWidth: {
|
property int minimumWidth: {
|
||||||
|
// max(width of longest label * 2, minimumInnerWidth)
|
||||||
var result = minimumInnerWidth;
|
var result = minimumInnerWidth;
|
||||||
for (var i = 0; i < children.length; ++i)
|
for (var i = 0; i < children.length; i += 2)
|
||||||
result = Math.max(children[i].x, result);
|
result = Math.max(children[i].implicitWidth * 2 + innerMargin, result);
|
||||||
return result + 2 * outerMargin;
|
return result + 2 * outerMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,8 +171,8 @@ Item {
|
|||||||
property bool isLabel: index % 2 === 0
|
property bool isLabel: index % 2 === 0
|
||||||
font.bold: isLabel
|
font.bold: isLabel
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
width: text === "" ? 0 : (isLabel ? implicitWidth :
|
width: (text === "" || isLabel)
|
||||||
(dragHandle.x - x - innerMargin))
|
? implicitWidth : (dragHandle.x - col.minimumWidth / 2 - innerMargin)
|
||||||
text: isLabel ? (modelData + ":") : modelData
|
text: isLabel ? (modelData + ":") : modelData
|
||||||
color: contentTextColor
|
color: contentTextColor
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,9 +176,10 @@ Item {
|
|||||||
spacing: 5
|
spacing: 5
|
||||||
columns: 2
|
columns: 2
|
||||||
property int minimumWidth: {
|
property int minimumWidth: {
|
||||||
|
// max(width of longest label * 2, 150)
|
||||||
var result = 150;
|
var result = 150;
|
||||||
for (var i = 0; i < children.length; ++i)
|
for (var i = 0; i < children.length; i += 2)
|
||||||
result = Math.max(children[i].x, result);
|
result = Math.max(children[i].implicitWidth * 2 + spacing, result);
|
||||||
return result + 20;
|
return result + 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +191,7 @@ Item {
|
|||||||
Repeater {
|
Repeater {
|
||||||
model: eventInfo
|
model: eventInfo
|
||||||
Detail {
|
Detail {
|
||||||
valueWidth: dragHandle.x - x - 15
|
valueWidth: (dragHandle.x - col.minimumWidth / 2 - col.spacing)
|
||||||
isLabel: index % 2 === 0
|
isLabel: index % 2 === 0
|
||||||
text: (content === undefined) ? "" : (isLabel ? (content + ":") : content)
|
text: (content === undefined) ? "" : (isLabel ? (content + ":") : content)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -500,7 +500,7 @@ Environment::const_iterator Environment::constEnd() const
|
|||||||
|
|
||||||
Environment::const_iterator Environment::constFind(const QString &name) const
|
Environment::const_iterator Environment::constFind(const QString &name) const
|
||||||
{
|
{
|
||||||
return m_values.constFind(name);
|
return findKey(m_values, m_osType, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Environment::size() const
|
int Environment::size() const
|
||||||
@@ -567,6 +567,11 @@ bool Environment::hasKey(const QString &key) const
|
|||||||
return m_values.contains(key);
|
return m_values.contains(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OsType Environment::osType() const
|
||||||
|
{
|
||||||
|
return m_osType;
|
||||||
|
}
|
||||||
|
|
||||||
QString Environment::userName() const
|
QString Environment::userName() const
|
||||||
{
|
{
|
||||||
return value(QString::fromLatin1(m_osType == OsTypeWindows ? "USERNAME" : "USER"));
|
return value(QString::fromLatin1(m_osType == OsTypeWindows ? "USERNAME" : "USER"));
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ public:
|
|||||||
/// Return the Environment changes necessary to modify this into the other environment.
|
/// Return the Environment changes necessary to modify this into the other environment.
|
||||||
QList<EnvironmentItem> diff(const Environment &other, bool checkAppendPrepend = false) const;
|
QList<EnvironmentItem> diff(const Environment &other, bool checkAppendPrepend = false) const;
|
||||||
bool hasKey(const QString &key) const;
|
bool hasKey(const QString &key) const;
|
||||||
|
OsType osType() const;
|
||||||
|
|
||||||
QString userName() const;
|
QString userName() const;
|
||||||
|
|
||||||
|
|||||||
@@ -364,6 +364,13 @@ void EnvironmentModel::setUserChanges(QList<EnvironmentItem> list)
|
|||||||
name = name.trimmed();
|
name = name.trimmed();
|
||||||
if (name.startsWith(QLatin1String("export ")))
|
if (name.startsWith(QLatin1String("export ")))
|
||||||
name = name.mid(7).trimmed();
|
name = name.mid(7).trimmed();
|
||||||
|
if (d->m_baseEnvironment.osType() == OsTypeWindows) {
|
||||||
|
// Environment variable names are case-insensitive under windows, but we still
|
||||||
|
// want to preserve the case of pre-existing variables.
|
||||||
|
auto it = d->m_baseEnvironment.constFind(name);
|
||||||
|
if (it != d->m_baseEnvironment.constEnd())
|
||||||
|
name = d->m_baseEnvironment.key(it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d->updateResultEnvironment();
|
d->updateResultEnvironment();
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <cpptools/cppmodelmanager.h>
|
#include <cpptools/cppmodelmanager.h>
|
||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/asconst.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
@@ -122,35 +123,67 @@ TestConfiguration *GTestTreeItem::debugConfiguration() const
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
|
struct TestCases
|
||||||
|
{
|
||||||
|
QStringList filters;
|
||||||
|
int testSetCount = 0;
|
||||||
|
QSet<QString> internalTargets;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void collectTestInfo(const GTestTreeItem *item,
|
||||||
|
QHash<QString, TestCases> &testCasesForProFile,
|
||||||
|
bool ignoreCheckState)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(item, return);
|
||||||
|
if (item->type() == TestTreeItem::GroupNode) {
|
||||||
|
for (int row = 0, count = item->childCount(); row < count; ++row) {
|
||||||
|
auto child = static_cast<const GTestTreeItem *>(item->childItem(row));
|
||||||
|
collectTestInfo(child, testCasesForProFile, ignoreCheckState);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const int childCount = item->childCount();
|
||||||
|
QTC_ASSERT(childCount != 0, return);
|
||||||
|
QTC_ASSERT(item->type() == TestTreeItem::TestCase, return);
|
||||||
|
if (ignoreCheckState || item->checked() == Qt::Checked) {
|
||||||
|
const QString &projectFile = item->childItem(0)->proFile();
|
||||||
|
testCasesForProFile[projectFile].filters.append(
|
||||||
|
gtestFilter(item->state()).arg(item->name()).arg('*'));
|
||||||
|
testCasesForProFile[projectFile].testSetCount += childCount - 1;
|
||||||
|
testCasesForProFile[projectFile].internalTargets.unite(item->internalTargets());
|
||||||
|
} else if (item->checked() == Qt::PartiallyChecked) {
|
||||||
|
for (int childRow = 0; childRow < childCount; ++childRow) {
|
||||||
|
const TestTreeItem *child = item->childItem(childRow);
|
||||||
|
QTC_ASSERT(child->type() == TestTreeItem::TestFunctionOrSet, continue);
|
||||||
|
if (child->checked() == Qt::Checked) {
|
||||||
|
testCasesForProFile[child->proFile()].filters.append(
|
||||||
|
gtestFilter(item->state()).arg(item->name()).arg(child->name()));
|
||||||
|
testCasesForProFile[child->proFile()].internalTargets.unite(
|
||||||
|
child->internalTargets());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<TestConfiguration *> GTestTreeItem::getTestConfigurations(bool ignoreCheckState) const
|
||||||
{
|
{
|
||||||
QList<TestConfiguration *> result;
|
QList<TestConfiguration *> result;
|
||||||
|
|
||||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
||||||
if (!project || type() != Root)
|
if (!project || type() != Root)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
QHash<QString, int> proFilesWithTestSets;
|
QHash<QString, TestCases> testCasesForProFile;
|
||||||
QHash<QString, QSet<QString> > proFilesWithInternalTargets;
|
|
||||||
for (int row = 0, count = childCount(); row < count; ++row) {
|
for (int row = 0, count = childCount(); row < count; ++row) {
|
||||||
const GTestTreeItem *child = static_cast<const GTestTreeItem *>(childItem(row));
|
auto child = static_cast<const GTestTreeItem *>(childItem(row));
|
||||||
|
collectTestInfo(child, testCasesForProFile, ignoreCheckState);
|
||||||
const int grandChildCount = child->childCount();
|
|
||||||
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
|
|
||||||
const TestTreeItem *grandChild = child->childItem(grandChildRow);
|
|
||||||
const QString &key = grandChild->proFile();
|
|
||||||
proFilesWithTestSets.insert(key, proFilesWithTestSets[key] + 1);
|
|
||||||
proFilesWithInternalTargets[key].unite(grandChild->internalTargets());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<QString, int>::ConstIterator it = proFilesWithTestSets.begin();
|
for (auto it = testCasesForProFile.begin(), end = testCasesForProFile.end(); it != end; ++it) {
|
||||||
QHash<QString, int>::ConstIterator end = proFilesWithTestSets.end();
|
for (const QString &target : Utils::asConst(it.value().internalTargets)) {
|
||||||
for ( ; it != end; ++it) {
|
|
||||||
const QSet<QString> &internalTargets = proFilesWithInternalTargets[it.key()];
|
|
||||||
for (const QString &target : internalTargets) {
|
|
||||||
GTestConfiguration *tc = new GTestConfiguration;
|
GTestConfiguration *tc = new GTestConfiguration;
|
||||||
tc->setTestCaseCount(it.value());
|
if (!ignoreCheckState)
|
||||||
|
tc->setTestCases(it.value().filters);
|
||||||
|
tc->setTestCaseCount(tc->testCaseCount() + it.value().testSetCount);
|
||||||
tc->setProjectFile(it.key());
|
tc->setProjectFile(it.key());
|
||||||
tc->setProject(project);
|
tc->setProject(project);
|
||||||
tc->setInternalTarget(target);
|
tc->setInternalTarget(target);
|
||||||
@@ -161,69 +194,14 @@ QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TestCases
|
QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
|
||||||
{
|
{
|
||||||
QStringList filters;
|
return getTestConfigurations(true);
|
||||||
int additionalTestCaseCount = 0;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
|
QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
|
||||||
{
|
{
|
||||||
QList<TestConfiguration *> result;
|
return getTestConfigurations(false);
|
||||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
|
||||||
if (!project || type() != Root)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
QHash<QString, TestCases> proFilesWithCheckedTestSets;
|
|
||||||
QHash<QString, QSet<QString> > proFilesWithInternalTargets;
|
|
||||||
for (int row = 0, count = childCount(); row < count; ++row) {
|
|
||||||
const GTestTreeItem *child = static_cast<const GTestTreeItem *>(childItem(row));
|
|
||||||
|
|
||||||
const int grandChildCount = child->childCount();
|
|
||||||
QTC_ASSERT(grandChildCount != 0, continue);
|
|
||||||
|
|
||||||
switch (child->checked()) {
|
|
||||||
case Qt::Unchecked:
|
|
||||||
continue;
|
|
||||||
case Qt::Checked: {
|
|
||||||
auto &testCases = proFilesWithCheckedTestSets[child->childItem(0)->proFile()];
|
|
||||||
testCases.filters.append(gtestFilter(child->state()).arg(child->name()).arg('*'));
|
|
||||||
testCases.additionalTestCaseCount += grandChildCount - 1;
|
|
||||||
proFilesWithInternalTargets[child->childItem(0)->proFile()].unite(
|
|
||||||
child->internalTargets());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Qt::PartiallyChecked: {
|
|
||||||
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
|
|
||||||
const TestTreeItem *grandChild = child->childItem(grandChildRow);
|
|
||||||
if (grandChild->checked() == Qt::Checked) {
|
|
||||||
proFilesWithCheckedTestSets[grandChild->proFile()].filters.append(
|
|
||||||
gtestFilter(child->state()).arg(child->name()).arg(grandChild->name()));
|
|
||||||
proFilesWithInternalTargets[grandChild->proFile()].unite(
|
|
||||||
grandChild->internalTargets());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QHash<QString, TestCases>::ConstIterator it = proFilesWithCheckedTestSets.begin();
|
|
||||||
QHash<QString, TestCases>::ConstIterator end = proFilesWithCheckedTestSets.end();
|
|
||||||
for ( ; it != end; ++it) {
|
|
||||||
const QSet<QString> &internalTargets = proFilesWithInternalTargets[it.key()];
|
|
||||||
for (const QString &target : internalTargets) {
|
|
||||||
GTestConfiguration *tc = new GTestConfiguration;
|
|
||||||
tc->setTestCases(it.value().filters);
|
|
||||||
tc->setTestCaseCount(tc->testCaseCount() + it.value().additionalTestCaseCount);
|
|
||||||
tc->setProjectFile(it.key());
|
|
||||||
tc->setProject(project);
|
|
||||||
tc->setInternalTarget(target);
|
|
||||||
result << tc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TestTreeItem *GTestTreeItem::find(const TestParseResult *result)
|
TestTreeItem *GTestTreeItem::find(const TestParseResult *result)
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool modifyTestSetContent(const GTestParseResult *result);
|
bool modifyTestSetContent(const GTestParseResult *result);
|
||||||
|
QList<TestConfiguration *> getTestConfigurations(bool ignoreCheckState) const;
|
||||||
GTestTreeItem::TestStates m_state;
|
GTestTreeItem::TestStates m_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ QtTestTreeItem::QtTestTreeItem(const QString &name, const QString &filePath, Tes
|
|||||||
: TestTreeItem(name, filePath, type)
|
: TestTreeItem(name, filePath, type)
|
||||||
{
|
{
|
||||||
if (type == TestDataTag)
|
if (type == TestDataTag)
|
||||||
setChecked(Qt::Checked);
|
setData(0, Qt::Checked, Qt::CheckStateRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QtTestTreeItem::data(int column, int role) const
|
QVariant QtTestTreeItem::data(int column, int role) const
|
||||||
@@ -139,6 +139,53 @@ TestConfiguration *QtTestTreeItem::testConfiguration() const
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fillTestConfigurationsFromCheckState(const TestTreeItem *item,
|
||||||
|
QList<TestConfiguration *> &testConfigurations)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(item, return);
|
||||||
|
if (item->type() == TestTreeItem::GroupNode) {
|
||||||
|
for (int row = 0, count = item->childCount(); row < count; ++row)
|
||||||
|
fillTestConfigurationsFromCheckState(item->childItem(row), testConfigurations);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QTC_ASSERT(item->type() == TestTreeItem::TestCase, return);
|
||||||
|
QtTestConfiguration *testConfig = nullptr;
|
||||||
|
switch (item->checked()) {
|
||||||
|
case Qt::Unchecked:
|
||||||
|
return;
|
||||||
|
case Qt::Checked:
|
||||||
|
testConfig = static_cast<QtTestConfiguration *>(item->testConfiguration());
|
||||||
|
QTC_ASSERT(testConfig, return);
|
||||||
|
testConfigurations << testConfig;
|
||||||
|
return;
|
||||||
|
case Qt::PartiallyChecked:
|
||||||
|
default:
|
||||||
|
int grandChildCount = item->childCount();
|
||||||
|
QStringList testCases;
|
||||||
|
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
|
||||||
|
const TestTreeItem *grandChild = item->childItem(grandChildRow);
|
||||||
|
if (grandChild->checked() == Qt::Checked) {
|
||||||
|
testCases << grandChild->name();
|
||||||
|
} else if (grandChild->checked() == Qt::PartiallyChecked) {
|
||||||
|
const int dtCount = grandChild->childCount();
|
||||||
|
const QString funcName = grandChild->name();
|
||||||
|
for (int dtRow = 0; dtRow < dtCount; ++dtRow) {
|
||||||
|
const TestTreeItem *dataTag = grandChild->childItem(dtRow);
|
||||||
|
if (dataTag->checked() == Qt::Checked)
|
||||||
|
testCases << funcName + ':' + dataTag->name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testConfig = new QtTestConfiguration();
|
||||||
|
testConfig->setTestCases(testCases);
|
||||||
|
testConfig->setProjectFile(item->proFile());
|
||||||
|
testConfig->setProject(ProjectExplorer::SessionManager::startupProject());
|
||||||
|
testConfig->setInternalTargets(item->internalTargets());
|
||||||
|
testConfigurations << testConfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TestConfiguration *QtTestTreeItem::debugConfiguration() const
|
TestConfiguration *QtTestTreeItem::debugConfiguration() const
|
||||||
{
|
{
|
||||||
QtTestConfiguration *config = static_cast<QtTestConfiguration *>(testConfiguration());
|
QtTestConfiguration *config = static_cast<QtTestConfiguration *>(testConfiguration());
|
||||||
@@ -157,13 +204,19 @@ QList<TestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
|
|||||||
|
|
||||||
for (int row = 0, count = childCount(); row < count; ++row) {
|
for (int row = 0, count = childCount(); row < count; ++row) {
|
||||||
const TestTreeItem *child = childItem(row);
|
const TestTreeItem *child = childItem(row);
|
||||||
|
TestConfiguration *tc = nullptr;
|
||||||
TestConfiguration *tc = new QtTestConfiguration();
|
if (child->type() == TestCase) {
|
||||||
tc->setTestCaseCount(child->childCount());
|
tc = child->testConfiguration();
|
||||||
tc->setProjectFile(child->proFile());
|
QTC_ASSERT(tc, continue);
|
||||||
tc->setProject(project);
|
result << tc;
|
||||||
tc->setInternalTargets(child->internalTargets());
|
} else if (child->type() == GroupNode) {
|
||||||
result << tc;
|
const int groupChildCount = child->childCount();
|
||||||
|
for (int groupChildRow = 0; groupChildRow < groupChildCount; ++groupChildRow) {
|
||||||
|
tc = child->childItem(groupChildRow)->testConfiguration();
|
||||||
|
QTC_ASSERT(tc, continue);
|
||||||
|
result << tc;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -175,49 +228,8 @@ QList<TestConfiguration *> QtTestTreeItem::getSelectedTestConfigurations() const
|
|||||||
if (!project || type() != Root)
|
if (!project || type() != Root)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
QtTestConfiguration *testConfiguration = nullptr;
|
for (int row = 0, count = childCount(); row < count; ++row)
|
||||||
|
fillTestConfigurationsFromCheckState(childItem(row), result);
|
||||||
for (int row = 0, count = childCount(); row < count; ++row) {
|
|
||||||
const TestTreeItem *child = childItem(row);
|
|
||||||
|
|
||||||
switch (child->checked()) {
|
|
||||||
case Qt::Unchecked:
|
|
||||||
continue;
|
|
||||||
case Qt::Checked:
|
|
||||||
testConfiguration = new QtTestConfiguration();
|
|
||||||
testConfiguration->setTestCaseCount(child->childCount());
|
|
||||||
testConfiguration->setProjectFile(child->proFile());
|
|
||||||
testConfiguration->setProject(project);
|
|
||||||
testConfiguration->setInternalTargets(child->internalTargets());
|
|
||||||
result << testConfiguration;
|
|
||||||
continue;
|
|
||||||
case Qt::PartiallyChecked:
|
|
||||||
default:
|
|
||||||
int grandChildCount = child->childCount();
|
|
||||||
QStringList testCases;
|
|
||||||
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
|
|
||||||
const TestTreeItem *grandChild = child->childItem(grandChildRow);
|
|
||||||
if (grandChild->checked() == Qt::Checked) {
|
|
||||||
testCases << grandChild->name();
|
|
||||||
} else if (grandChild->checked() == Qt::PartiallyChecked) {
|
|
||||||
const int dtCount = grandChild->childCount();
|
|
||||||
const QString funcName = grandChild->name();
|
|
||||||
for (int dtRow = 0; dtRow < dtCount; ++dtRow) {
|
|
||||||
const TestTreeItem *dataTag = grandChild->childItem(dtRow);
|
|
||||||
if (dataTag->checked() == Qt::Checked)
|
|
||||||
testCases << funcName + ':' + dataTag->name();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
testConfiguration = new QtTestConfiguration();
|
|
||||||
testConfiguration->setTestCases(testCases);
|
|
||||||
testConfiguration->setProjectFile(child->proFile());
|
|
||||||
testConfiguration->setProject(project);
|
|
||||||
testConfiguration->setInternalTargets(child->internalTargets());
|
|
||||||
result << testConfiguration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,6 +153,43 @@ TestConfiguration *QuickTestTreeItem::testConfiguration() const
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void testConfigurationFromCheckState(const TestTreeItem *item,
|
||||||
|
QHash<QString, QuickTestConfiguration *> &foundProFiles)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(item, return);
|
||||||
|
if (item->type() == TestTreeItem::GroupNode) {
|
||||||
|
for (int row = 0, count = item->childCount(); row < count; ++row)
|
||||||
|
testConfigurationFromCheckState(item->childItem(row), foundProFiles);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QTC_ASSERT(item->type() == TestTreeItem::TestCase, return);
|
||||||
|
QuickTestConfiguration *tc = nullptr;
|
||||||
|
if (item->checked() == Qt::Unchecked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QStringList testFunctions;
|
||||||
|
const int childCount = item->childCount();
|
||||||
|
for (int childRow = 0; childRow < childCount; ++childRow) {
|
||||||
|
const TestTreeItem *child = item->childItem(childRow);
|
||||||
|
if (child->checked() != Qt::Checked || child->type() != TestTreeItem::TestFunctionOrSet)
|
||||||
|
continue;
|
||||||
|
testFunctions << item->name() + "::" + child->name();
|
||||||
|
}
|
||||||
|
if (foundProFiles.contains(item->proFile())) {
|
||||||
|
tc = foundProFiles[item->proFile()];
|
||||||
|
QStringList oldFunctions(tc->testCases());
|
||||||
|
oldFunctions << testFunctions;
|
||||||
|
tc->setTestCases(oldFunctions);
|
||||||
|
} else {
|
||||||
|
tc = new QuickTestConfiguration;
|
||||||
|
tc->setTestCases(testFunctions);
|
||||||
|
tc->setProjectFile(item->proFile());
|
||||||
|
tc->setProject(ProjectExplorer::SessionManager::startupProject());
|
||||||
|
tc->setInternalTargets(item->internalTargets());
|
||||||
|
foundProFiles.insert(item->proFile(), tc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TestConfiguration *QuickTestTreeItem::debugConfiguration() const
|
TestConfiguration *QuickTestTreeItem::debugConfiguration() const
|
||||||
{
|
{
|
||||||
QuickTestConfiguration *config = static_cast<QuickTestConfiguration *>(testConfiguration());
|
QuickTestConfiguration *config = static_cast<QuickTestConfiguration *>(testConfiguration());
|
||||||
@@ -161,6 +198,17 @@ TestConfiguration *QuickTestTreeItem::debugConfiguration() const
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Tests {
|
||||||
|
int testCount = 0;
|
||||||
|
QSet<QString> internalTargets;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void addTestsForItem(Tests &tests, const TestTreeItem *item)
|
||||||
|
{
|
||||||
|
tests.testCount += item->childCount();
|
||||||
|
tests.internalTargets = item->internalTargets();
|
||||||
|
}
|
||||||
|
|
||||||
QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
|
QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
|
||||||
{
|
{
|
||||||
QList<TestConfiguration *> result;
|
QList<TestConfiguration *> result;
|
||||||
@@ -169,8 +217,7 @@ QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
|
|||||||
if (!project || type() != Root)
|
if (!project || type() != Root)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
QHash<QString, int> foundProFiles;
|
QHash<QString, Tests> testsForProfile;
|
||||||
QHash<QString, QSet<QString> > proFilesWithTargets;
|
|
||||||
for (int row = 0, count = childCount(); row < count; ++row) {
|
for (int row = 0, count = childCount(); row < count; ++row) {
|
||||||
const TestTreeItem *child = childItem(row);
|
const TestTreeItem *child = childItem(row);
|
||||||
// unnamed Quick Tests must be handled separately
|
// unnamed Quick Tests must be handled separately
|
||||||
@@ -178,25 +225,29 @@ QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
|
|||||||
for (int childRow = 0, ccount = child->childCount(); childRow < ccount; ++ childRow) {
|
for (int childRow = 0, ccount = child->childCount(); childRow < ccount; ++ childRow) {
|
||||||
const TestTreeItem *grandChild = child->childItem(childRow);
|
const TestTreeItem *grandChild = child->childItem(childRow);
|
||||||
const QString &proFile = grandChild->proFile();
|
const QString &proFile = grandChild->proFile();
|
||||||
foundProFiles.insert(proFile, foundProFiles[proFile] + 1);
|
++(testsForProfile[proFile].testCount);
|
||||||
proFilesWithTargets.insert(proFile, grandChild->internalTargets());
|
testsForProfile[proFile].internalTargets = grandChild->internalTargets();
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// named Quick Test
|
// named Quick Test
|
||||||
const QString &proFile = child->proFile();
|
if (child->type() == TestCase) {
|
||||||
foundProFiles.insert(proFile, foundProFiles[proFile] + child->childCount());
|
addTestsForItem(testsForProfile[child->proFile()], child);
|
||||||
proFilesWithTargets.insert(proFile, child->internalTargets());
|
} else if (child->type() == GroupNode) {
|
||||||
|
const int groupCount = child->childCount();
|
||||||
|
for (int groupRow = 0; groupRow < groupCount; ++groupRow) {
|
||||||
|
const TestTreeItem *grandChild = child->childItem(groupRow);
|
||||||
|
addTestsForItem(testsForProfile[grandChild->proFile()], grandChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// create TestConfiguration for each project file
|
// create TestConfiguration for each project file
|
||||||
QHash<QString, int>::ConstIterator it = foundProFiles.begin();
|
for (auto it = testsForProfile.begin(), end = testsForProfile.end(); it != end; ++it) {
|
||||||
QHash<QString, int>::ConstIterator end = foundProFiles.end();
|
|
||||||
for ( ; it != end; ++it) {
|
|
||||||
QuickTestConfiguration *tc = new QuickTestConfiguration;
|
QuickTestConfiguration *tc = new QuickTestConfiguration;
|
||||||
tc->setTestCaseCount(it.value());
|
tc->setTestCaseCount(it.value().testCount);
|
||||||
tc->setProjectFile(it.key());
|
tc->setProjectFile(it.key());
|
||||||
tc->setProject(project);
|
tc->setProject(project);
|
||||||
tc->setInternalTargets(proFilesWithTargets[it.key()]);
|
tc->setInternalTargets(it.value().internalTargets);
|
||||||
result << tc;
|
result << tc;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -209,7 +260,6 @@ QList<TestConfiguration *> QuickTestTreeItem::getSelectedTestConfigurations() co
|
|||||||
if (!project || type() != Root)
|
if (!project || type() != Root)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
QuickTestConfiguration *tc = nullptr;
|
|
||||||
QHash<QString, QuickTestConfiguration *> foundProFiles;
|
QHash<QString, QuickTestConfiguration *> foundProFiles;
|
||||||
|
|
||||||
for (int row = 0, count = childCount(); row < count; ++row) {
|
for (int row = 0, count = childCount(); row < count; ++row) {
|
||||||
@@ -219,39 +269,10 @@ QList<TestConfiguration *> QuickTestTreeItem::getSelectedTestConfigurations() co
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// named Quick Tests
|
// named Quick Tests
|
||||||
switch (child->checked()) {
|
testConfigurationFromCheckState(child, foundProFiles);
|
||||||
case Qt::Unchecked:
|
|
||||||
continue;
|
|
||||||
case Qt::Checked:
|
|
||||||
case Qt::PartiallyChecked:
|
|
||||||
default:
|
|
||||||
QStringList testFunctions;
|
|
||||||
int grandChildCount = child->childCount();
|
|
||||||
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
|
|
||||||
const TestTreeItem *grandChild = child->childItem(grandChildRow);
|
|
||||||
if (grandChild->checked() != Qt::Checked || grandChild->type() != TestFunctionOrSet)
|
|
||||||
continue;
|
|
||||||
testFunctions << child->name() + "::" + grandChild->name();
|
|
||||||
}
|
|
||||||
if (foundProFiles.contains(child->proFile())) {
|
|
||||||
tc = foundProFiles[child->proFile()];
|
|
||||||
QStringList oldFunctions(tc->testCases());
|
|
||||||
oldFunctions << testFunctions;
|
|
||||||
tc->setTestCases(oldFunctions);
|
|
||||||
} else {
|
|
||||||
tc = new QuickTestConfiguration;
|
|
||||||
tc->setTestCases(testFunctions);
|
|
||||||
tc->setProjectFile(child->proFile());
|
|
||||||
tc->setProject(project);
|
|
||||||
tc->setInternalTargets(child->internalTargets());
|
|
||||||
foundProFiles.insert(child->proFile(), tc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
QHash<QString, QuickTestConfiguration *>::ConstIterator it = foundProFiles.begin();
|
|
||||||
QHash<QString, QuickTestConfiguration *>::ConstIterator end = foundProFiles.end();
|
for (auto it = foundProFiles.begin(), end = foundProFiles.end(); it != end; ++it) {
|
||||||
for ( ; it != end; ++it) {
|
|
||||||
QuickTestConfiguration *config = it.value();
|
QuickTestConfiguration *config = it.value();
|
||||||
if (!config->unnamedOnly())
|
if (!config->unnamedOnly())
|
||||||
result << config;
|
result << config;
|
||||||
@@ -327,6 +348,12 @@ bool QuickTestTreeItem::isGroupNodeFor(const TestTreeItem *other) const
|
|||||||
return TestTreeItem::isGroupNodeFor(other);
|
return TestTreeItem::isGroupNodeFor(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QuickTestTreeItem::removeOnSweepIfEmpty() const
|
||||||
|
{
|
||||||
|
return TestTreeItem::removeOnSweepIfEmpty()
|
||||||
|
|| (type() == TestCase && name().isEmpty()); // remove pseudo item '<unnamed>'
|
||||||
|
}
|
||||||
|
|
||||||
TestTreeItem *QuickTestTreeItem::createParentGroupNode() const
|
TestTreeItem *QuickTestTreeItem::createParentGroupNode() const
|
||||||
{
|
{
|
||||||
if (filePath().isEmpty() || name().isEmpty())
|
if (filePath().isEmpty() || name().isEmpty())
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public:
|
|||||||
bool modify(const TestParseResult *result) override;
|
bool modify(const TestParseResult *result) override;
|
||||||
bool lessThan(const TestTreeItem *other, SortMode mode) const override;
|
bool lessThan(const TestTreeItem *other, SortMode mode) const override;
|
||||||
bool isGroupNodeFor(const TestTreeItem *other) const override;
|
bool isGroupNodeFor(const TestTreeItem *other) const override;
|
||||||
|
bool removeOnSweepIfEmpty() const override;
|
||||||
TestTreeItem *createParentGroupNode() const override;
|
TestTreeItem *createParentGroupNode() const override;
|
||||||
QSet<QString> internalTargets() const override;
|
QSet<QString> internalTargets() const override;
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -55,13 +55,11 @@ void TestResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
|
|||||||
{
|
{
|
||||||
QStyleOptionViewItem opt = option;
|
QStyleOptionViewItem opt = option;
|
||||||
initStyleOption(&opt, index);
|
initStyleOption(&opt, index);
|
||||||
painter->save();
|
|
||||||
|
|
||||||
QFontMetrics fm(opt.font);
|
QFontMetrics fm(opt.font);
|
||||||
QBrush background;
|
QBrush background;
|
||||||
QColor foreground;
|
QColor foreground;
|
||||||
|
|
||||||
const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(opt.widget);
|
|
||||||
const bool selected = opt.state & QStyle::State_Selected;
|
const bool selected = opt.state & QStyle::State_Selected;
|
||||||
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
@@ -71,10 +69,14 @@ void TestResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
|
|||||||
background = opt.palette.window().color();
|
background = opt.palette.window().color();
|
||||||
foreground = opt.palette.text().color();
|
foreground = opt.palette.text().color();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto resultFilterModel = qobject_cast<const TestResultFilterModel *>(index.model());
|
||||||
|
if (!resultFilterModel)
|
||||||
|
return;
|
||||||
|
painter->save();
|
||||||
painter->fillRect(opt.rect, background);
|
painter->fillRect(opt.rect, background);
|
||||||
painter->setPen(foreground);
|
painter->setPen(foreground);
|
||||||
|
|
||||||
TestResultFilterModel *resultFilterModel = static_cast<TestResultFilterModel *>(view->model());
|
|
||||||
LayoutPositions positions(opt, resultFilterModel);
|
LayoutPositions positions(opt, resultFilterModel);
|
||||||
const TestResult *testResult = resultFilterModel->testResult(index);
|
const TestResult *testResult = resultFilterModel->testResult(index);
|
||||||
QTC_ASSERT(testResult, painter->restore();return);
|
QTC_ASSERT(testResult, painter->restore();return);
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ private:
|
|||||||
class LayoutPositions
|
class LayoutPositions
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LayoutPositions(QStyleOptionViewItem &options, TestResultFilterModel *filterModel)
|
LayoutPositions(QStyleOptionViewItem &options, const TestResultFilterModel *filterModel)
|
||||||
: m_totalWidth(options.rect.width()),
|
: m_totalWidth(options.rect.width()),
|
||||||
m_top(options.rect.top()),
|
m_top(options.rect.top()),
|
||||||
m_bottom(options.rect.bottom())
|
m_bottom(options.rect.bottom())
|
||||||
|
|||||||
@@ -106,9 +106,9 @@ QVariant TestTreeItem::data(int /*column*/, int role) const
|
|||||||
bool TestTreeItem::setData(int /*column*/, const QVariant &data, int role)
|
bool TestTreeItem::setData(int /*column*/, const QVariant &data, int role)
|
||||||
{
|
{
|
||||||
if (role == Qt::CheckStateRole) {
|
if (role == Qt::CheckStateRole) {
|
||||||
Qt::CheckState old = checked();
|
Qt::CheckState old = m_checked;
|
||||||
setChecked((Qt::CheckState)data.toInt());
|
m_checked = (Qt::CheckState)data.toInt();
|
||||||
return checked() != old;
|
return m_checked != old;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -168,34 +168,6 @@ bool TestTreeItem::modifyLineAndColumn(const TestParseResult *result)
|
|||||||
return hasBeenModified;
|
return hasBeenModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestTreeItem::setChecked(const Qt::CheckState checkState)
|
|
||||||
{
|
|
||||||
switch (m_type) {
|
|
||||||
case TestDataTag: {
|
|
||||||
m_checked = (checkState == Qt::Unchecked ? Qt::Unchecked : Qt::Checked);
|
|
||||||
if (auto parent = parentItem())
|
|
||||||
parent->revalidateCheckState();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Root:
|
|
||||||
case GroupNode:
|
|
||||||
case TestFunctionOrSet:
|
|
||||||
case TestCase: {
|
|
||||||
Qt::CheckState usedState = (checkState == Qt::Unchecked ? Qt::Unchecked : Qt::Checked);
|
|
||||||
for (int row = 0, count = childCount(); row < count; ++row)
|
|
||||||
childItem(row)->setChecked(usedState);
|
|
||||||
m_checked = usedState;
|
|
||||||
if (m_type != Root) {
|
|
||||||
if (auto parent = parentItem())
|
|
||||||
parent->revalidateCheckState();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::CheckState TestTreeItem::checked() const
|
Qt::CheckState TestTreeItem::checked() const
|
||||||
{
|
{
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
@@ -327,41 +299,6 @@ QSet<QString> TestTreeItem::internalTargets() const
|
|||||||
return targets;
|
return targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestTreeItem::revalidateCheckState()
|
|
||||||
{
|
|
||||||
const Type ttiType = type();
|
|
||||||
if (ttiType != TestCase && ttiType != TestFunctionOrSet && ttiType != Root && ttiType != GroupNode)
|
|
||||||
return;
|
|
||||||
if (childCount() == 0) // can this happen? (we're calling revalidateCS() on parentItem()
|
|
||||||
return;
|
|
||||||
bool foundChecked = false;
|
|
||||||
bool foundUnchecked = false;
|
|
||||||
bool foundPartiallyChecked = false;
|
|
||||||
for (int row = 0, count = childCount(); row < count; ++row) {
|
|
||||||
TestTreeItem *child = childItem(row);
|
|
||||||
switch (child->type()) {
|
|
||||||
case TestDataFunction:
|
|
||||||
case TestSpecialFunction:
|
|
||||||
continue;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
foundChecked |= (child->checked() == Qt::Checked);
|
|
||||||
foundUnchecked |= (child->checked() == Qt::Unchecked);
|
|
||||||
foundPartiallyChecked |= (child->checked() == Qt::PartiallyChecked);
|
|
||||||
if (foundPartiallyChecked || (foundChecked && foundUnchecked)) {
|
|
||||||
m_checked = Qt::PartiallyChecked;
|
|
||||||
if (ttiType == TestFunctionOrSet || ttiType == TestCase || ttiType == GroupNode)
|
|
||||||
parentItem()->revalidateCheckState();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_checked = (foundUnchecked ? Qt::Unchecked : Qt::Checked);
|
|
||||||
if (ttiType == TestFunctionOrSet || ttiType == TestCase || ttiType == GroupNode)
|
|
||||||
parentItem()->revalidateCheckState();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool TestTreeItem::modifyFilePath(const QString &filePath)
|
inline bool TestTreeItem::modifyFilePath(const QString &filePath)
|
||||||
{
|
{
|
||||||
if (m_filePath != filePath) {
|
if (m_filePath != filePath) {
|
||||||
|
|||||||
@@ -89,12 +89,12 @@ public:
|
|||||||
unsigned column() const { return m_column; }
|
unsigned column() const { return m_column; }
|
||||||
QString proFile() const { return m_proFile; }
|
QString proFile() const { return m_proFile; }
|
||||||
void setProFile(const QString &proFile) { m_proFile = proFile; }
|
void setProFile(const QString &proFile) { m_proFile = proFile; }
|
||||||
virtual void setChecked(const Qt::CheckState checked);
|
|
||||||
virtual Qt::CheckState checked() const;
|
virtual Qt::CheckState checked() const;
|
||||||
Type type() const { return m_type; }
|
Type type() const { return m_type; }
|
||||||
void markForRemoval(bool mark);
|
void markForRemoval(bool mark);
|
||||||
void markForRemovalRecursively(bool mark);
|
void markForRemovalRecursively(bool mark);
|
||||||
virtual void markForRemovalRecursively(const QString &filePath);
|
virtual void markForRemovalRecursively(const QString &filePath);
|
||||||
|
virtual bool removeOnSweepIfEmpty() const { return m_type == GroupNode; }
|
||||||
bool markedForRemoval() const { return m_status == MarkedForRemoval; }
|
bool markedForRemoval() const { return m_status == MarkedForRemoval; }
|
||||||
bool newlyAdded() const { return m_status == NewlyAdded; }
|
bool newlyAdded() const { return m_status == NewlyAdded; }
|
||||||
TestTreeItem *parentItem() const;
|
TestTreeItem *parentItem() const;
|
||||||
@@ -123,7 +123,6 @@ protected:
|
|||||||
const QString &file);
|
const QString &file);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void revalidateCheckState();
|
|
||||||
bool modifyFilePath(const QString &filePath);
|
bool modifyFilePath(const QString &filePath);
|
||||||
bool modifyName(const QString &name);
|
bool modifyName(const QString &name);
|
||||||
|
|
||||||
@@ -143,7 +142,7 @@ private:
|
|||||||
QString m_proFile;
|
QString m_proFile;
|
||||||
Status m_status = NewlyAdded;
|
Status m_status = NewlyAdded;
|
||||||
|
|
||||||
friend class TestTreeModel; // grant access to (private) revalidateCheckState()
|
friend class TestTreeModel; // grant access to (protected) findChildBy()
|
||||||
};
|
};
|
||||||
|
|
||||||
class TestCodeLocationAndType
|
class TestCodeLocationAndType
|
||||||
|
|||||||
@@ -108,21 +108,18 @@ bool TestTreeModel::setData(const QModelIndex &index, const QVariant &value, int
|
|||||||
if (item && item->setData(index.column(), value, role)) {
|
if (item && item->setData(index.column(), value, role)) {
|
||||||
emit dataChanged(index, index);
|
emit dataChanged(index, index);
|
||||||
if (role == Qt::CheckStateRole) {
|
if (role == Qt::CheckStateRole) {
|
||||||
switch (item->type()) {
|
Qt::CheckState checked = item->checked();
|
||||||
case TestTreeItem::Root:
|
if (item->hasChildren() && checked != Qt::PartiallyChecked) {
|
||||||
case TestTreeItem::GroupNode:
|
// handle the new checkstate for children as well...
|
||||||
case TestTreeItem::TestCase:
|
for (Utils::TreeItem *child : *item) {
|
||||||
if (item->childCount() > 0)
|
const QModelIndex &idx = indexForItem(child);
|
||||||
emit dataChanged(index.child(0, 0), index.child(item->childCount() - 1, 0));
|
setData(idx, checked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
|
||||||
break;
|
}
|
||||||
case TestTreeItem::TestFunctionOrSet:
|
|
||||||
emit dataChanged(index.parent(), index.parent());
|
|
||||||
break;
|
|
||||||
default: // avoid warning regarding unhandled enum member
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (item->parent() != rootItem() && item->parentItem()->checked() != checked)
|
||||||
|
revalidateCheckState(item->parentItem()); // handle parent too
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -254,10 +251,14 @@ bool TestTreeModel::sweepChildren(TestTreeItem *item)
|
|||||||
|
|
||||||
if (child->type() != TestTreeItem::Root && child->markedForRemoval()) {
|
if (child->type() != TestTreeItem::Root && child->markedForRemoval()) {
|
||||||
destroyItem(child);
|
destroyItem(child);
|
||||||
item->revalidateCheckState();
|
revalidateCheckState(item);
|
||||||
hasChanged = true;
|
hasChanged = true;
|
||||||
} else if (child->hasChildren()) {
|
} else if (child->hasChildren()) {
|
||||||
hasChanged |= sweepChildren(child);
|
hasChanged |= sweepChildren(child);
|
||||||
|
if (!child->hasChildren() && child->removeOnSweepIfEmpty()) {
|
||||||
|
destroyItem(child);
|
||||||
|
revalidateCheckState(item);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
hasChanged |= child->newlyAdded();
|
hasChanged |= child->newlyAdded();
|
||||||
}
|
}
|
||||||
@@ -281,6 +282,50 @@ void TestTreeModel::insertItemInParent(TestTreeItem *item, TestTreeItem *root, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
parentNode->appendChild(item);
|
parentNode->appendChild(item);
|
||||||
|
if (item->checked() != parentNode->checked())
|
||||||
|
revalidateCheckState(parentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestTreeModel::revalidateCheckState(TestTreeItem *item)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(item, return);
|
||||||
|
|
||||||
|
const TestTreeItem::Type type = item->type();
|
||||||
|
if (type == TestTreeItem::TestSpecialFunction || type == TestTreeItem::TestDataFunction
|
||||||
|
|| type == TestTreeItem::TestDataTag) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const Qt::CheckState oldState = (Qt::CheckState)item->data(0, Qt::CheckStateRole).toInt();
|
||||||
|
Qt::CheckState newState = Qt::Checked;
|
||||||
|
bool foundChecked = false;
|
||||||
|
bool foundUnchecked = false;
|
||||||
|
bool foundPartiallyChecked = false;
|
||||||
|
for (int row = 0, count = item->childCount(); row < count; ++row) {
|
||||||
|
TestTreeItem *child = item->childItem(row);
|
||||||
|
switch (child->type()) {
|
||||||
|
case TestTreeItem::TestDataFunction:
|
||||||
|
case TestTreeItem::TestSpecialFunction:
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foundChecked |= (child->checked() == Qt::Checked);
|
||||||
|
foundUnchecked |= (child->checked() == Qt::Unchecked);
|
||||||
|
foundPartiallyChecked |= (child->checked() == Qt::PartiallyChecked);
|
||||||
|
if (foundPartiallyChecked || (foundChecked && foundUnchecked)) {
|
||||||
|
newState = Qt::PartiallyChecked;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newState != Qt::PartiallyChecked)
|
||||||
|
newState = foundUnchecked ? Qt::Unchecked : Qt::Checked;
|
||||||
|
if (oldState != newState) {
|
||||||
|
item->setData(0, newState, Qt::CheckStateRole);
|
||||||
|
emit dataChanged(item->index(), item->index());
|
||||||
|
if (item->parent() != rootItem() && item->parentItem()->checked() != newState)
|
||||||
|
revalidateCheckState(item->parentItem());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestTreeModel::onParseResultReady(const TestParseResultPtr result)
|
void TestTreeModel::onParseResultReady(const TestParseResultPtr result)
|
||||||
@@ -321,12 +366,6 @@ void TestTreeModel::handleParseResult(const TestParseResult *result, TestTreeIte
|
|||||||
QTC_ASSERT(newItem, return);
|
QTC_ASSERT(newItem, return);
|
||||||
|
|
||||||
insertItemInParent(newItem, parentNode, groupingEnabled);
|
insertItemInParent(newItem, parentNode, groupingEnabled);
|
||||||
// new items are checked by default - revalidation of parents might be necessary
|
|
||||||
if (parentNode->checked() != Qt::Checked) {
|
|
||||||
parentNode->revalidateCheckState();
|
|
||||||
const QModelIndex &idx = indexForItem(parentNode);
|
|
||||||
emit dataChanged(idx, idx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestTreeModel::removeAllTestItems()
|
void TestTreeModel::removeAllTestItems()
|
||||||
@@ -335,7 +374,7 @@ void TestTreeModel::removeAllTestItems()
|
|||||||
item->removeChildren();
|
item->removeChildren();
|
||||||
TestTreeItem *testTreeItem = static_cast<TestTreeItem *>(item);
|
TestTreeItem *testTreeItem = static_cast<TestTreeItem *>(item);
|
||||||
if (testTreeItem->checked() == Qt::PartiallyChecked)
|
if (testTreeItem->checked() == Qt::PartiallyChecked)
|
||||||
testTreeItem->setChecked(Qt::Checked);
|
testTreeItem->setData(0, Qt::Checked, Qt::CheckStateRole);
|
||||||
}
|
}
|
||||||
emit testTreeModelChanged();
|
emit testTreeModelChanged();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,8 +87,8 @@ private:
|
|||||||
void removeTestRootNodes();
|
void removeTestRootNodes();
|
||||||
void removeFiles(const QStringList &files);
|
void removeFiles(const QStringList &files);
|
||||||
bool sweepChildren(TestTreeItem *item);
|
bool sweepChildren(TestTreeItem *item);
|
||||||
static void insertItemInParent(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled);
|
void insertItemInParent(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled);
|
||||||
|
void revalidateCheckState(TestTreeItem *item);
|
||||||
explicit TestTreeModel(QObject *parent = 0);
|
explicit TestTreeModel(QObject *parent = 0);
|
||||||
void setupParsingConnections();
|
void setupParsingConnections();
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,13 @@ TestTreeView::TestTreeView(QWidget *parent)
|
|||||||
Core::ICore::addContextObject(m_context);
|
Core::ICore::addContextObject(m_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void changeCheckStateAll(const Qt::CheckState checkState)
|
||||||
|
{
|
||||||
|
TestTreeModel *model = TestTreeModel::instance();
|
||||||
|
for (int row = 0, count = model->rowCount(); row < count; ++row)
|
||||||
|
model->setData(model->index(row, 0), checkState, Qt::CheckStateRole);
|
||||||
|
}
|
||||||
|
|
||||||
void TestTreeView::selectAll()
|
void TestTreeView::selectAll()
|
||||||
{
|
{
|
||||||
changeCheckStateAll(Qt::Checked);
|
changeCheckStateAll(Qt::Checked);
|
||||||
@@ -55,40 +62,5 @@ void TestTreeView::deselectAll()
|
|||||||
changeCheckStateAll(Qt::Unchecked);
|
changeCheckStateAll(Qt::Unchecked);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this avoids the re-evaluation of parent nodes when modifying the child nodes (setData())
|
|
||||||
void TestTreeView::changeCheckStateAll(const Qt::CheckState checkState)
|
|
||||||
{
|
|
||||||
const TestTreeModel *model = TestTreeModel::instance();
|
|
||||||
|
|
||||||
for (int rootRow = 0; rootRow < model->rowCount(rootIndex()); ++rootRow) {
|
|
||||||
QModelIndex currentRootIndex = model->index(rootRow, 0, rootIndex());
|
|
||||||
if (!currentRootIndex.isValid())
|
|
||||||
return;
|
|
||||||
int count = model->rowCount(currentRootIndex);
|
|
||||||
QModelIndex last;
|
|
||||||
for (int classesRow = 0; classesRow < count; ++classesRow) {
|
|
||||||
const QModelIndex classesIndex = model->index(classesRow, 0, currentRootIndex);
|
|
||||||
int funcCount = model->rowCount(classesIndex);
|
|
||||||
TestTreeItem *item = static_cast<TestTreeItem *>(classesIndex.internalPointer());
|
|
||||||
if (item) {
|
|
||||||
item->setChecked(checkState);
|
|
||||||
if (!item->childCount())
|
|
||||||
last = classesIndex;
|
|
||||||
}
|
|
||||||
for (int functionRow = 0; functionRow < funcCount; ++functionRow) {
|
|
||||||
last = model->index(functionRow, 0, classesIndex);
|
|
||||||
TestTreeItem *item = static_cast<TestTreeItem *>(last.internalPointer());
|
|
||||||
if (item)
|
|
||||||
item->setChecked(checkState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (count == 0) {
|
|
||||||
if (auto item = static_cast<TestTreeItem *>(currentRootIndex.internalPointer()))
|
|
||||||
item->setChecked(checkState);
|
|
||||||
}
|
|
||||||
emit dataChanged(currentRootIndex, last);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Autotest
|
} // namespace Autotest
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ public:
|
|||||||
void deselectAll();
|
void deselectAll();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void changeCheckStateAll(const Qt::CheckState checkState);
|
|
||||||
Core::IContext *m_context;
|
Core::IContext *m_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -368,26 +368,23 @@ QFuture<CppTools::CursorInfo> BackendCommunicator::requestReferences(
|
|||||||
const FileContainer &fileContainer,
|
const FileContainer &fileContainer,
|
||||||
quint32 line,
|
quint32 line,
|
||||||
quint32 column,
|
quint32 column,
|
||||||
QTextDocument *textDocument,
|
|
||||||
const CppTools::SemanticInfo::LocalUseMap &localUses)
|
const CppTools::SemanticInfo::LocalUseMap &localUses)
|
||||||
{
|
{
|
||||||
const RequestReferencesMessage message(fileContainer, line, column);
|
const RequestReferencesMessage message(fileContainer, line, column);
|
||||||
m_sender->requestReferences(message);
|
m_sender->requestReferences(message);
|
||||||
|
|
||||||
return m_receiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument,
|
return m_receiver.addExpectedReferencesMessage(message.ticketNumber(), localUses);
|
||||||
localUses);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QFuture<CppTools::CursorInfo> BackendCommunicator::requestLocalReferences(
|
QFuture<CppTools::CursorInfo> BackendCommunicator::requestLocalReferences(
|
||||||
const FileContainer &fileContainer,
|
const FileContainer &fileContainer,
|
||||||
quint32 line,
|
quint32 line,
|
||||||
quint32 column,
|
quint32 column)
|
||||||
QTextDocument *textDocument)
|
|
||||||
{
|
{
|
||||||
const RequestReferencesMessage message(fileContainer, line, column, true);
|
const RequestReferencesMessage message(fileContainer, line, column, true);
|
||||||
m_sender->requestReferences(message);
|
m_sender->requestReferences(message);
|
||||||
|
|
||||||
return m_receiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument);
|
return m_receiver.addExpectedReferencesMessage(message.ticketNumber());
|
||||||
}
|
}
|
||||||
|
|
||||||
QFuture<CppTools::ToolTipInfo> BackendCommunicator::requestToolTip(
|
QFuture<CppTools::ToolTipInfo> BackendCommunicator::requestToolTip(
|
||||||
|
|||||||
@@ -75,13 +75,11 @@ public:
|
|||||||
const FileContainer &fileContainer,
|
const FileContainer &fileContainer,
|
||||||
quint32 line,
|
quint32 line,
|
||||||
quint32 column,
|
quint32 column,
|
||||||
QTextDocument *textDocument,
|
|
||||||
const LocalUseMap &localUses);
|
const LocalUseMap &localUses);
|
||||||
QFuture<CppTools::CursorInfo> requestLocalReferences(
|
QFuture<CppTools::CursorInfo> requestLocalReferences(
|
||||||
const FileContainer &fileContainer,
|
const FileContainer &fileContainer,
|
||||||
quint32 line,
|
quint32 line,
|
||||||
quint32 column,
|
quint32 column);
|
||||||
QTextDocument *textDocument);
|
|
||||||
QFuture<CppTools::ToolTipInfo> requestToolTip(const FileContainer &fileContainer,
|
QFuture<CppTools::ToolTipInfo> requestToolTip(const FileContainer &fileContainer,
|
||||||
quint32 line,
|
quint32 line,
|
||||||
quint32 column);
|
quint32 column);
|
||||||
|
|||||||
@@ -101,16 +101,14 @@ void BackendReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidge
|
|||||||
|
|
||||||
QFuture<CppTools::CursorInfo> BackendReceiver::addExpectedReferencesMessage(
|
QFuture<CppTools::CursorInfo> BackendReceiver::addExpectedReferencesMessage(
|
||||||
quint64 ticket,
|
quint64 ticket,
|
||||||
QTextDocument *textDocument,
|
|
||||||
const CppTools::SemanticInfo::LocalUseMap &localUses)
|
const CppTools::SemanticInfo::LocalUseMap &localUses)
|
||||||
{
|
{
|
||||||
QTC_CHECK(textDocument);
|
|
||||||
QTC_CHECK(!m_referencesTable.contains(ticket));
|
QTC_CHECK(!m_referencesTable.contains(ticket));
|
||||||
|
|
||||||
QFutureInterface<CppTools::CursorInfo> futureInterface;
|
QFutureInterface<CppTools::CursorInfo> futureInterface;
|
||||||
futureInterface.reportStarted();
|
futureInterface.reportStarted();
|
||||||
|
|
||||||
const ReferencesEntry entry{futureInterface, textDocument, localUses};
|
const ReferencesEntry entry{futureInterface, localUses};
|
||||||
m_referencesTable.insert(ticket, entry);
|
m_referencesTable.insert(ticket, entry);
|
||||||
|
|
||||||
return futureInterface.future();
|
return futureInterface.future();
|
||||||
@@ -221,24 +219,17 @@ void BackendReceiver::documentAnnotationsChanged(const DocumentAnnotationsChange
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
CppTools::CursorInfo::Range toCursorInfoRange(const QTextDocument &textDocument,
|
CppTools::CursorInfo::Range toCursorInfoRange(const SourceRangeContainer &sourceRange)
|
||||||
const SourceRangeContainer &sourceRange)
|
|
||||||
{
|
{
|
||||||
const SourceLocationContainer start = sourceRange.start();
|
const SourceLocationContainer start = sourceRange.start();
|
||||||
const SourceLocationContainer end = sourceRange.end();
|
const SourceLocationContainer end = sourceRange.end();
|
||||||
const unsigned length = end.column() - start.column();
|
const unsigned length = end.column() - start.column();
|
||||||
|
|
||||||
const QTextBlock block = textDocument.findBlockByNumber(static_cast<int>(start.line()) - 1);
|
return CppTools::CursorInfo::Range(start.line(), start.column(), length);
|
||||||
const int shift = ClangCodeModel::Utils::extraUtf8CharsShift(block.text(),
|
|
||||||
static_cast<int>(start.column()));
|
|
||||||
const uint column = start.column() - static_cast<uint>(shift);
|
|
||||||
|
|
||||||
return CppTools::CursorInfo::Range(start.line(), column, length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
CppTools::CursorInfo toCursorInfo(const QTextDocument &textDocument,
|
CppTools::CursorInfo toCursorInfo(const CppTools::SemanticInfo::LocalUseMap &localUses,
|
||||||
const CppTools::SemanticInfo::LocalUseMap &localUses,
|
|
||||||
const ReferencesMessage &message)
|
const ReferencesMessage &message)
|
||||||
{
|
{
|
||||||
CppTools::CursorInfo result;
|
CppTools::CursorInfo result;
|
||||||
@@ -246,7 +237,7 @@ CppTools::CursorInfo toCursorInfo(const QTextDocument &textDocument,
|
|||||||
|
|
||||||
result.areUseRangesForLocalVariable = message.isLocalVariable();
|
result.areUseRangesForLocalVariable = message.isLocalVariable();
|
||||||
for (const SourceRangeContainer &reference : references)
|
for (const SourceRangeContainer &reference : references)
|
||||||
result.useRanges.append(toCursorInfoRange(textDocument, reference));
|
result.useRanges.append(toCursorInfoRange(reference));
|
||||||
|
|
||||||
result.useRanges.reserve(references.size());
|
result.useRanges.reserve(references.size());
|
||||||
result.localUses = localUses;
|
result.localUses = localUses;
|
||||||
@@ -284,8 +275,7 @@ void BackendReceiver::references(const ReferencesMessage &message)
|
|||||||
if (futureInterface.isCanceled())
|
if (futureInterface.isCanceled())
|
||||||
return; // Editor document closed or a new request was issued making this result outdated.
|
return; // Editor document closed or a new request was issued making this result outdated.
|
||||||
|
|
||||||
QTC_ASSERT(entry.textDocument, return);
|
futureInterface.reportResult(toCursorInfo(entry.localUses, message));
|
||||||
futureInterface.reportResult(toCursorInfo(*entry.textDocument, entry.localUses, message));
|
|
||||||
futureInterface.reportFinished();
|
futureInterface.reportFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ public:
|
|||||||
|
|
||||||
QFuture<CppTools::CursorInfo>
|
QFuture<CppTools::CursorInfo>
|
||||||
addExpectedReferencesMessage(quint64 ticket,
|
addExpectedReferencesMessage(quint64 ticket,
|
||||||
QTextDocument *textDocument,
|
|
||||||
const CppTools::SemanticInfo::LocalUseMap &localUses
|
const CppTools::SemanticInfo::LocalUseMap &localUses
|
||||||
= CppTools::SemanticInfo::LocalUseMap());
|
= CppTools::SemanticInfo::LocalUseMap());
|
||||||
QFuture<CppTools::SymbolInfo> addExpectedRequestFollowSymbolMessage(quint64 ticket);
|
QFuture<CppTools::SymbolInfo> addExpectedRequestFollowSymbolMessage(quint64 ticket);
|
||||||
@@ -82,13 +81,10 @@ private:
|
|||||||
struct ReferencesEntry {
|
struct ReferencesEntry {
|
||||||
ReferencesEntry() = default;
|
ReferencesEntry() = default;
|
||||||
ReferencesEntry(QFutureInterface<CppTools::CursorInfo> futureInterface,
|
ReferencesEntry(QFutureInterface<CppTools::CursorInfo> futureInterface,
|
||||||
QTextDocument *textDocument,
|
|
||||||
const CppTools::SemanticInfo::LocalUseMap &localUses)
|
const CppTools::SemanticInfo::LocalUseMap &localUses)
|
||||||
: futureInterface(futureInterface)
|
: futureInterface(futureInterface)
|
||||||
, textDocument(textDocument)
|
|
||||||
, localUses(localUses) {}
|
, localUses(localUses) {}
|
||||||
QFutureInterface<CppTools::CursorInfo> futureInterface;
|
QFutureInterface<CppTools::CursorInfo> futureInterface;
|
||||||
QPointer<QTextDocument> textDocument;
|
|
||||||
CppTools::SemanticInfo::LocalUseMap localUses;
|
CppTools::SemanticInfo::LocalUseMap localUses;
|
||||||
};
|
};
|
||||||
QHash<quint64, ReferencesEntry> m_referencesTable;
|
QHash<quint64, ReferencesEntry> m_referencesTable;
|
||||||
|
|||||||
@@ -559,7 +559,8 @@ ClangCompletionAssistProcessor::extractLineColumn(int position)
|
|||||||
int line = -1, column = -1;
|
int line = -1, column = -1;
|
||||||
::Utils::Text::convertPosition(m_interface->textDocument(), position, &line, &column);
|
::Utils::Text::convertPosition(m_interface->textDocument(), position, &line, &column);
|
||||||
const QTextBlock block = m_interface->textDocument()->findBlock(position);
|
const QTextBlock block = m_interface->textDocument()->findBlock(position);
|
||||||
column += ClangCodeModel::Utils::extraUtf8CharsShift(block.text(), column) + 1;
|
const QString stringOnTheLeft = block.text().left(column);
|
||||||
|
column = stringOnTheLeft.toUtf8().size() + 1; // '+ 1' is for 1-based columns
|
||||||
return {line, column};
|
return {line, column};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,8 +64,7 @@ int positionInText(QTextDocument *textDocument,
|
|||||||
{
|
{
|
||||||
auto textBlock = textDocument->findBlockByNumber(
|
auto textBlock = textDocument->findBlockByNumber(
|
||||||
static_cast<int>(sourceLocationContainer.line()) - 1);
|
static_cast<int>(sourceLocationContainer.line()) - 1);
|
||||||
int column = static_cast<int>(sourceLocationContainer.column()) - 1;
|
const int column = static_cast<int>(sourceLocationContainer.column()) - 1;
|
||||||
column -= ClangCodeModel::Utils::extraUtf8CharsShift(textBlock.text(), column);
|
|
||||||
return textBlock.position() + column;
|
return textBlock.position() + column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "clangdiagnostictooltipwidget.h"
|
#include "clangdiagnostictooltipwidget.h"
|
||||||
#include "clangfixitoperation.h"
|
#include "clangfixitoperation.h"
|
||||||
#include "clangfixitoperationsextractor.h"
|
#include "clangfixitoperationsextractor.h"
|
||||||
|
#include "clangmodelmanagersupport.h"
|
||||||
#include "clangtokeninfosreporter.h"
|
#include "clangtokeninfosreporter.h"
|
||||||
#include "clangprojectsettings.h"
|
#include "clangprojectsettings.h"
|
||||||
#include "clangutils.h"
|
#include "clangutils.h"
|
||||||
@@ -66,6 +67,12 @@
|
|||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
static ClangProjectSettings &getProjectSettings(ProjectExplorer::Project *project)
|
||||||
|
{
|
||||||
|
QTC_CHECK(project);
|
||||||
|
return ModelManagerSupportClang::instance()->projectSettings(project);
|
||||||
|
}
|
||||||
|
|
||||||
ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(
|
ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(
|
||||||
BackendCommunicator &communicator,
|
BackendCommunicator &communicator,
|
||||||
TextEditor::TextDocument *document)
|
TextEditor::TextDocument *document)
|
||||||
@@ -174,6 +181,11 @@ void ClangEditorDocumentProcessor::clearProjectPart()
|
|||||||
m_projectPart.clear();
|
m_projectPart.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Core::Id ClangEditorDocumentProcessor::diagnosticConfigId() const
|
||||||
|
{
|
||||||
|
return m_diagnosticConfigId;
|
||||||
|
}
|
||||||
|
|
||||||
void ClangEditorDocumentProcessor::updateCodeWarnings(
|
void ClangEditorDocumentProcessor::updateCodeWarnings(
|
||||||
const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||||
const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic,
|
const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic,
|
||||||
@@ -331,20 +343,19 @@ ClangEditorDocumentProcessor::cursorInfo(const CppTools::CursorInfoParams ¶m
|
|||||||
{
|
{
|
||||||
int line, column;
|
int line, column;
|
||||||
convertPosition(params.textCursor, &line, &column);
|
convertPosition(params.textCursor, &line, &column);
|
||||||
++column; // for 1-based columns
|
|
||||||
|
|
||||||
if (!isCursorOnIdentifier(params.textCursor))
|
if (!isCursorOnIdentifier(params.textCursor))
|
||||||
return defaultCursorInfoFuture();
|
return defaultCursorInfoFuture();
|
||||||
|
|
||||||
const QTextBlock block = params.textCursor.document()->findBlockByNumber(line - 1);
|
const QTextBlock block = params.textCursor.document()->findBlockByNumber(line - 1);
|
||||||
column += ClangCodeModel::Utils::extraUtf8CharsShift(block.text(), column);
|
const QString stringOnTheLeft = block.text().left(column);
|
||||||
|
column = stringOnTheLeft.toUtf8().size() + 1; // '+ 1' is for 1-based columns
|
||||||
const CppTools::SemanticInfo::LocalUseMap localUses
|
const CppTools::SemanticInfo::LocalUseMap localUses
|
||||||
= CppTools::BuiltinCursorInfo::findLocalUses(params.semanticInfo.doc, line, column);
|
= CppTools::BuiltinCursorInfo::findLocalUses(params.semanticInfo.doc, line, column);
|
||||||
|
|
||||||
return m_communicator.requestReferences(simpleFileContainer(),
|
return m_communicator.requestReferences(simpleFileContainer(),
|
||||||
static_cast<quint32>(line),
|
static_cast<quint32>(line),
|
||||||
static_cast<quint32>(column),
|
static_cast<quint32>(column),
|
||||||
textDocument(),
|
|
||||||
localUses);
|
localUses);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,8 +372,7 @@ QFuture<CppTools::CursorInfo> ClangEditorDocumentProcessor::requestLocalReferenc
|
|||||||
|
|
||||||
return m_communicator.requestLocalReferences(simpleFileContainer(),
|
return m_communicator.requestLocalReferences(simpleFileContainer(),
|
||||||
static_cast<quint32>(line),
|
static_cast<quint32>(line),
|
||||||
static_cast<quint32>(column),
|
static_cast<quint32>(column));
|
||||||
textDocument());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QFuture<CppTools::SymbolInfo>
|
QFuture<CppTools::SymbolInfo>
|
||||||
@@ -437,6 +447,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const QStringList &options() const { return m_options; }
|
const QStringList &options() const { return m_options; }
|
||||||
|
const Core::Id &diagnosticConfigId() const { return m_diagnosticConfigId; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addLanguageOptions()
|
void addLanguageOptions()
|
||||||
@@ -458,21 +469,28 @@ private:
|
|||||||
void addDiagnosticOptions()
|
void addDiagnosticOptions()
|
||||||
{
|
{
|
||||||
if (m_projectPart.project) {
|
if (m_projectPart.project) {
|
||||||
ClangProjectSettings projectSettings(m_projectPart.project);
|
ClangProjectSettings &projectSettings = getProjectSettings(m_projectPart.project);
|
||||||
if (!projectSettings.useGlobalConfig()) {
|
if (!projectSettings.useGlobalConfig()) {
|
||||||
const Core::Id warningConfigId = projectSettings.warningConfigId();
|
const Core::Id warningConfigId = projectSettings.warningConfigId();
|
||||||
const CppTools::ClangDiagnosticConfigsModel configsModel(
|
const CppTools::ClangDiagnosticConfigsModel configsModel(
|
||||||
CppTools::codeModelSettings()->clangCustomDiagnosticConfigs());
|
CppTools::codeModelSettings()->clangCustomDiagnosticConfigs());
|
||||||
if (configsModel.hasConfigWithId(warningConfigId)) {
|
if (configsModel.hasConfigWithId(warningConfigId)) {
|
||||||
m_options.append(
|
addDiagnosticOptionsForConfig(configsModel.configWithId(warningConfigId));
|
||||||
configsModel.configWithId(warningConfigId).commandLineWarnings());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_options.append(
|
addDiagnosticOptionsForConfig(CppTools::codeModelSettings()->clangDiagnosticConfig());
|
||||||
CppTools::codeModelSettings()->clangDiagnosticConfig().commandLineWarnings());
|
}
|
||||||
|
|
||||||
|
void addDiagnosticOptionsForConfig(const CppTools::ClangDiagnosticConfig &diagnosticConfig)
|
||||||
|
{
|
||||||
|
m_diagnosticConfigId = diagnosticConfig.id();
|
||||||
|
|
||||||
|
m_options.append(diagnosticConfig.clangOptions());
|
||||||
|
addClangTidyOptions(diagnosticConfig.clangTidyChecks());
|
||||||
|
addClazyOptions(diagnosticConfig.clazyChecks());
|
||||||
}
|
}
|
||||||
|
|
||||||
void addXclangArg(const QString &argName, const QString &argValue = QString())
|
void addXclangArg(const QString &argName, const QString &argValue = QString())
|
||||||
@@ -485,24 +503,22 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTidyOptions()
|
void addClangTidyOptions(const QString &checks)
|
||||||
{
|
{
|
||||||
const QString tidyChecks = CppTools::codeModelSettings()->tidyChecks();
|
if (checks.isEmpty())
|
||||||
if (tidyChecks.isEmpty())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
addXclangArg("-add-plugin", "clang-tidy");
|
addXclangArg("-add-plugin", "clang-tidy");
|
||||||
addXclangArg("-plugin-arg-clang-tidy", "-checks='-*" + tidyChecks + "'");
|
addXclangArg("-plugin-arg-clang-tidy", "-checks='-*" + checks + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
void addClazyOptions()
|
void addClazyOptions(const QString &checks)
|
||||||
{
|
{
|
||||||
const QString clazyChecks = CppTools::codeModelSettings()->clazyChecks();
|
if (checks.isEmpty())
|
||||||
if (clazyChecks.isEmpty())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
addXclangArg("-add-plugin", "clang-lazy");
|
addXclangArg("-add-plugin", "clang-lazy");
|
||||||
addXclangArg("-plugin-arg-clang-lazy", clazyChecks);
|
addXclangArg("-plugin-arg-clang-lazy", checks);
|
||||||
|
|
||||||
// NOTE: we already use -isystem for all include paths to make libclang skip diagnostics for
|
// NOTE: we already use -isystem for all include paths to make libclang skip diagnostics for
|
||||||
// all of them. That means that ignore-included-files will not change anything unless we decide
|
// all of them. That means that ignore-included-files will not change anything unless we decide
|
||||||
@@ -515,10 +531,7 @@ private:
|
|||||||
if (!m_projectPart.project)
|
if (!m_projectPart.project)
|
||||||
m_options.append(ClangProjectSettings::globalCommandLineOptions());
|
m_options.append(ClangProjectSettings::globalCommandLineOptions());
|
||||||
else
|
else
|
||||||
m_options.append(ClangProjectSettings{m_projectPart.project}.commandLineOptions());
|
m_options.append(getProjectSettings(m_projectPart.project).commandLineOptions());
|
||||||
|
|
||||||
addTidyOptions();
|
|
||||||
addClazyOptions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addPrecompiledHeaderOptions()
|
void addPrecompiledHeaderOptions()
|
||||||
@@ -541,6 +554,7 @@ private:
|
|||||||
const QString &m_filePath;
|
const QString &m_filePath;
|
||||||
const CppTools::ProjectPart &m_projectPart;
|
const CppTools::ProjectPart &m_projectPart;
|
||||||
|
|
||||||
|
Core::Id m_diagnosticConfigId;
|
||||||
QStringList m_options;
|
QStringList m_options;
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -563,6 +577,7 @@ void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FileOptionsBuilder fileOptions(filePath(), projectPart);
|
const FileOptionsBuilder fileOptions(filePath(), projectPart);
|
||||||
|
m_diagnosticConfigId = fileOptions.diagnosticConfigId();
|
||||||
m_communicator.registerTranslationUnitsForEditor(
|
m_communicator.registerTranslationUnitsForEditor(
|
||||||
{fileContainerWithOptionsAndDocumentContent(projectPart, fileOptions.options())});
|
{fileContainerWithOptionsAndDocumentContent(projectPart, fileOptions.options())});
|
||||||
ClangCodeModel::Utils::setLastSentDocumentRevision(filePath(), revision());
|
ClangCodeModel::Utils::setLastSentDocumentRevision(filePath(), revision());
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "clangdiagnosticmanager.h"
|
#include "clangdiagnosticmanager.h"
|
||||||
#include "clangeditordocumentparser.h"
|
#include "clangeditordocumentparser.h"
|
||||||
|
|
||||||
|
#include <coreplugin/id.h>
|
||||||
#include <cpptools/builtineditordocumentprocessor.h>
|
#include <cpptools/builtineditordocumentprocessor.h>
|
||||||
#include <cpptools/semantichighlighter.h>
|
#include <cpptools/semantichighlighter.h>
|
||||||
|
|
||||||
@@ -67,6 +68,8 @@ public:
|
|||||||
CppTools::ProjectPart::Ptr projectPart() const;
|
CppTools::ProjectPart::Ptr projectPart() const;
|
||||||
void clearProjectPart();
|
void clearProjectPart();
|
||||||
|
|
||||||
|
Core::Id diagnosticConfigId() const;
|
||||||
|
|
||||||
void updateCodeWarnings(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
void updateCodeWarnings(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||||
const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic,
|
const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic,
|
||||||
uint documentRevision);
|
uint documentRevision);
|
||||||
@@ -120,6 +123,7 @@ private:
|
|||||||
BackendCommunicator &m_communicator;
|
BackendCommunicator &m_communicator;
|
||||||
QSharedPointer<ClangEditorDocumentParser> m_parser;
|
QSharedPointer<ClangEditorDocumentParser> m_parser;
|
||||||
CppTools::ProjectPart::Ptr m_projectPart;
|
CppTools::ProjectPart::Ptr m_projectPart;
|
||||||
|
Core::Id m_diagnosticConfigId;
|
||||||
bool m_isProjectFile = false;
|
bool m_isProjectFile = false;
|
||||||
QFutureWatcher<void> m_parserWatcher;
|
QFutureWatcher<void> m_parserWatcher;
|
||||||
QTimer m_updateTranslationUnitTimer;
|
QTimer m_updateTranslationUnitTimer;
|
||||||
|
|||||||
@@ -133,7 +133,10 @@ void ClangHoverHandler::identifyMatch(TextEditorWidget *editorWidget,
|
|||||||
m_reportPriority = report;
|
m_reportPriority = report;
|
||||||
m_futureWatcher.reset(new QFutureWatcher<CppTools::ToolTipInfo>());
|
m_futureWatcher.reset(new QFutureWatcher<CppTools::ToolTipInfo>());
|
||||||
QObject::connect(m_futureWatcher.data(), &QFutureWatcherBase::finished, [this]() {
|
QObject::connect(m_futureWatcher.data(), &QFutureWatcherBase::finished, [this]() {
|
||||||
processToolTipInfo(m_futureWatcher->result());
|
if (m_futureWatcher->isCanceled())
|
||||||
|
m_reportPriority(Priority_None);
|
||||||
|
else
|
||||||
|
processToolTipInfo(m_futureWatcher->result());
|
||||||
});
|
});
|
||||||
m_futureWatcher->setFuture(future);
|
m_futureWatcher->setFuture(future);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -30,22 +30,27 @@
|
|||||||
#include "clangutils.h"
|
#include "clangutils.h"
|
||||||
#include "clangfollowsymbol.h"
|
#include "clangfollowsymbol.h"
|
||||||
#include "clanghoverhandler.h"
|
#include "clanghoverhandler.h"
|
||||||
|
#include "clangprojectsettings.h"
|
||||||
#include "clangrefactoringengine.h"
|
#include "clangrefactoringengine.h"
|
||||||
#include "clangcurrentdocumentfilter.h"
|
#include "clangcurrentdocumentfilter.h"
|
||||||
|
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
#include <cpptools/cppcodemodelsettings.h>
|
||||||
#include <cpptools/cppfollowsymbolundercursor.h>
|
#include <cpptools/cppfollowsymbolundercursor.h>
|
||||||
#include <cpptools/cppmodelmanager.h>
|
#include <cpptools/cppmodelmanager.h>
|
||||||
|
#include <cpptools/cpptoolsreuse.h>
|
||||||
#include <cpptools/editordocumenthandle.h>
|
#include <cpptools/editordocumenthandle.h>
|
||||||
#include <cpptools/projectinfo.h>
|
#include <cpptools/projectinfo.h>
|
||||||
|
|
||||||
#include <texteditor/quickfix.h>
|
#include <texteditor/quickfix.h>
|
||||||
|
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
|
#include <projectexplorer/session.h>
|
||||||
|
|
||||||
#include <clangsupport/cmbregisterprojectsforeditormessage.h>
|
#include <clangsupport/cmbregisterprojectsforeditormessage.h>
|
||||||
#include <clangsupport/filecontainer.h>
|
#include <clangsupport/filecontainer.h>
|
||||||
#include <clangsupport/projectpartcontainer.h>
|
#include <clangsupport/projectpartcontainer.h>
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
@@ -100,11 +105,22 @@ ModelManagerSupportClang::ModelManagerSupportClang()
|
|||||||
connect(modelManager, &CppTools::CppModelManager::projectPartsRemoved,
|
connect(modelManager, &CppTools::CppModelManager::projectPartsRemoved,
|
||||||
this, &ModelManagerSupportClang::onProjectPartsRemoved);
|
this, &ModelManagerSupportClang::onProjectPartsRemoved);
|
||||||
|
|
||||||
|
auto *sessionManager = ProjectExplorer::SessionManager::instance();
|
||||||
|
connect(sessionManager, &ProjectExplorer::SessionManager::projectAdded,
|
||||||
|
this, &ModelManagerSupportClang::onProjectAdded);
|
||||||
|
connect(sessionManager, &ProjectExplorer::SessionManager::aboutToRemoveProject,
|
||||||
|
this, &ModelManagerSupportClang::onAboutToRemoveProject);
|
||||||
|
|
||||||
|
CppTools::CppCodeModelSettings *settings = CppTools::codeModelSettings().data();
|
||||||
|
connect(settings, &CppTools::CppCodeModelSettings::clangDiagnosticConfigsInvalidated,
|
||||||
|
this, &ModelManagerSupportClang::onDiagnosticConfigsInvalidated);
|
||||||
|
|
||||||
m_communicator.registerFallbackProjectPart();
|
m_communicator.registerFallbackProjectPart();
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelManagerSupportClang::~ModelManagerSupportClang()
|
ModelManagerSupportClang::~ModelManagerSupportClang()
|
||||||
{
|
{
|
||||||
|
QTC_CHECK(m_projectSettings.isEmpty());
|
||||||
m_instance = 0;
|
m_instance = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,6 +352,52 @@ void ModelManagerSupportClang::onTextMarkContextMenuRequested(TextEditor::TextEd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using ClangEditorDocumentProcessors = QVector<ClangEditorDocumentProcessor *>;
|
||||||
|
static ClangEditorDocumentProcessors clangProcessors()
|
||||||
|
{
|
||||||
|
ClangEditorDocumentProcessors result;
|
||||||
|
foreach (auto *editorDocument, cppModelManager()->cppEditorDocuments())
|
||||||
|
result.append(qobject_cast<ClangEditorDocumentProcessor *>(editorDocument->processor()));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClangEditorDocumentProcessors
|
||||||
|
clangProcessorsWithProject(const ProjectExplorer::Project *project)
|
||||||
|
{
|
||||||
|
return ::Utils::filtered(clangProcessors(), [project](ClangEditorDocumentProcessor *p) {
|
||||||
|
return p->hasProjectPart() && p->projectPart()->project == project;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateProcessors(const ClangEditorDocumentProcessors &processors)
|
||||||
|
{
|
||||||
|
CppTools::CppModelManager *modelManager = cppModelManager();
|
||||||
|
for (ClangEditorDocumentProcessor *processor : processors)
|
||||||
|
modelManager->cppEditorDocument(processor->filePath())->resetProcessor();
|
||||||
|
modelManager->updateCppEditorDocuments(/*projectsUpdated=*/ false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelManagerSupportClang::onProjectAdded(ProjectExplorer::Project *project)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(!m_projectSettings.value(project), return);
|
||||||
|
|
||||||
|
auto *settings = new Internal::ClangProjectSettings(project);
|
||||||
|
connect(settings, &Internal::ClangProjectSettings::changed, [project]() {
|
||||||
|
updateProcessors(clangProcessorsWithProject(project));
|
||||||
|
});
|
||||||
|
|
||||||
|
m_projectSettings.insert(project, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelManagerSupportClang::onAboutToRemoveProject(ProjectExplorer::Project *project)
|
||||||
|
{
|
||||||
|
ClangProjectSettings * const settings = m_projectSettings.value(project);
|
||||||
|
QTC_ASSERT(settings, return);
|
||||||
|
m_projectSettings.remove(project);
|
||||||
|
delete settings;
|
||||||
|
}
|
||||||
|
|
||||||
void ModelManagerSupportClang::onProjectPartsUpdated(ProjectExplorer::Project *project)
|
void ModelManagerSupportClang::onProjectPartsUpdated(ProjectExplorer::Project *project)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(project, return);
|
QTC_ASSERT(project, return);
|
||||||
@@ -355,21 +417,25 @@ void ModelManagerSupportClang::onProjectPartsRemoved(const QStringList &projectP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static QVector<ClangEditorDocumentProcessor *>
|
static ClangEditorDocumentProcessors clangProcessorsWithDiagnosticConfig(
|
||||||
|
const QVector<Core::Id> &configIds)
|
||||||
|
{
|
||||||
|
return ::Utils::filtered(clangProcessors(), [configIds](ClangEditorDocumentProcessor *p) {
|
||||||
|
return configIds.contains(p->diagnosticConfigId());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelManagerSupportClang::onDiagnosticConfigsInvalidated(const QVector<Core::Id> &configIds)
|
||||||
|
{
|
||||||
|
updateProcessors(clangProcessorsWithDiagnosticConfig(configIds));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClangEditorDocumentProcessors
|
||||||
clangProcessorsWithProjectParts(const QStringList &projectPartIds)
|
clangProcessorsWithProjectParts(const QStringList &projectPartIds)
|
||||||
{
|
{
|
||||||
QVector<ClangEditorDocumentProcessor *> result;
|
return ::Utils::filtered(clangProcessors(), [projectPartIds](ClangEditorDocumentProcessor *p) {
|
||||||
|
return p->hasProjectPart() && projectPartIds.contains(p->projectPart()->id());
|
||||||
foreach (auto *editorDocument, cppModelManager()->cppEditorDocuments()) {
|
});
|
||||||
auto *processor = editorDocument->processor();
|
|
||||||
auto *clangProcessor = qobject_cast<ClangEditorDocumentProcessor *>(processor);
|
|
||||||
if (clangProcessor && clangProcessor->hasProjectPart()) {
|
|
||||||
if (projectPartIds.contains(clangProcessor->projectPart()->id()))
|
|
||||||
result.append(clangProcessor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelManagerSupportClang::unregisterTranslationUnitsWithProjectParts(
|
void ModelManagerSupportClang::unregisterTranslationUnitsWithProjectParts(
|
||||||
@@ -398,6 +464,12 @@ QString ModelManagerSupportClang::dummyUiHeaderOnDiskPath(const QString &filePat
|
|||||||
return m_uiHeaderOnDiskManager.mapPath(filePath);
|
return m_uiHeaderOnDiskManager.mapPath(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClangProjectSettings &ModelManagerSupportClang::projectSettings(
|
||||||
|
ProjectExplorer::Project *project) const
|
||||||
|
{
|
||||||
|
return *m_projectSettings.value(project);
|
||||||
|
}
|
||||||
|
|
||||||
QString ModelManagerSupportClang::dummyUiHeaderOnDiskDirPath() const
|
QString ModelManagerSupportClang::dummyUiHeaderOnDiskDirPath() const
|
||||||
{
|
{
|
||||||
return m_uiHeaderOnDiskManager.directoryPath();
|
return m_uiHeaderOnDiskManager.directoryPath();
|
||||||
|
|||||||
@@ -40,7 +40,10 @@ class QMenu;
|
|||||||
class QWidget;
|
class QWidget;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace Core { class IDocument; }
|
namespace Core {
|
||||||
|
class IDocument;
|
||||||
|
class Id;
|
||||||
|
} // namespace Core
|
||||||
namespace TextEditor { class TextEditorWidget; }
|
namespace TextEditor { class TextEditorWidget; }
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
class FollowSymbolInterface;
|
class FollowSymbolInterface;
|
||||||
@@ -50,6 +53,8 @@ class RefactoringEngineInterface;
|
|||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
class ClangProjectSettings;
|
||||||
|
|
||||||
class ModelManagerSupportClang:
|
class ModelManagerSupportClang:
|
||||||
public QObject,
|
public QObject,
|
||||||
public CppTools::ModelManagerSupport
|
public CppTools::ModelManagerSupport
|
||||||
@@ -71,6 +76,8 @@ public:
|
|||||||
QString dummyUiHeaderOnDiskDirPath() const;
|
QString dummyUiHeaderOnDiskDirPath() const;
|
||||||
QString dummyUiHeaderOnDiskPath(const QString &filePath) const;
|
QString dummyUiHeaderOnDiskPath(const QString &filePath) const;
|
||||||
|
|
||||||
|
ClangProjectSettings &projectSettings(ProjectExplorer::Project *project) const;
|
||||||
|
|
||||||
static ModelManagerSupportClang *instance();
|
static ModelManagerSupportClang *instance();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -93,9 +100,14 @@ private:
|
|||||||
int lineNumber,
|
int lineNumber,
|
||||||
QMenu *menu);
|
QMenu *menu);
|
||||||
|
|
||||||
|
void onProjectAdded(ProjectExplorer::Project *project);
|
||||||
|
void onAboutToRemoveProject(ProjectExplorer::Project *project);
|
||||||
|
|
||||||
void onProjectPartsUpdated(ProjectExplorer::Project *project);
|
void onProjectPartsUpdated(ProjectExplorer::Project *project);
|
||||||
void onProjectPartsRemoved(const QStringList &projectPartIds);
|
void onProjectPartsRemoved(const QStringList &projectPartIds);
|
||||||
|
|
||||||
|
void onDiagnosticConfigsInvalidated(const QVector<Core::Id> &configIds);
|
||||||
|
|
||||||
void unregisterTranslationUnitsWithProjectParts(const QStringList &projectPartIds);
|
void unregisterTranslationUnitsWithProjectParts(const QStringList &projectPartIds);
|
||||||
|
|
||||||
void connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument);
|
void connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument);
|
||||||
@@ -111,6 +123,8 @@ private:
|
|||||||
ClangCompletionAssistProvider m_completionAssistProvider;
|
ClangCompletionAssistProvider m_completionAssistProvider;
|
||||||
std::unique_ptr<CppTools::FollowSymbolInterface> m_followSymbol;
|
std::unique_ptr<CppTools::FollowSymbolInterface> m_followSymbol;
|
||||||
std::unique_ptr<CppTools::RefactoringEngineInterface> m_refactoringEngine;
|
std::unique_ptr<CppTools::RefactoringEngineInterface> m_refactoringEngine;
|
||||||
|
|
||||||
|
QHash<ProjectExplorer::Project *, ClangProjectSettings *> m_projectSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModelManagerSupportProviderClang : public CppTools::ModelManagerSupportProvider
|
class ModelManagerSupportProviderClang : public CppTools::ModelManagerSupportProvider
|
||||||
|
|||||||
@@ -42,6 +42,25 @@ static QString warningConfigIdKey()
|
|||||||
static QString customCommandLineKey()
|
static QString customCommandLineKey()
|
||||||
{ return QLatin1String("ClangCodeModel.CustomCommandLineKey"); }
|
{ return QLatin1String("ClangCodeModel.CustomCommandLineKey"); }
|
||||||
|
|
||||||
|
static bool useGlobalConfigFromSettings(ProjectExplorer::Project *project)
|
||||||
|
{
|
||||||
|
const QVariant useGlobalConfigVariant = project->namedSettings(useGlobalConfigKey());
|
||||||
|
return useGlobalConfigVariant.isValid() ? useGlobalConfigVariant.toBool() : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Core::Id warningConfigIdFromSettings(ProjectExplorer::Project *project)
|
||||||
|
{
|
||||||
|
return Core::Id::fromSetting(project->namedSettings(warningConfigIdKey()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static QStringList customCommandLineFromSettings(ProjectExplorer::Project *project)
|
||||||
|
{
|
||||||
|
QStringList options = project->namedSettings(customCommandLineKey()).toStringList();
|
||||||
|
if (options.empty())
|
||||||
|
options = ClangProjectSettings::globalCommandLineOptions();
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
ClangProjectSettings::ClangProjectSettings(ProjectExplorer::Project *project)
|
ClangProjectSettings::ClangProjectSettings(ProjectExplorer::Project *project)
|
||||||
: m_project(project)
|
: m_project(project)
|
||||||
{
|
{
|
||||||
@@ -88,23 +107,27 @@ void ClangProjectSettings::setCommandLineOptions(const QStringList &options)
|
|||||||
|
|
||||||
void ClangProjectSettings::load()
|
void ClangProjectSettings::load()
|
||||||
{
|
{
|
||||||
const QVariant useGlobalConfigVariant = m_project->namedSettings(useGlobalConfigKey());
|
setUseGlobalConfig(useGlobalConfigFromSettings(m_project));
|
||||||
const bool useGlobalConfig = useGlobalConfigVariant.isValid()
|
setWarningConfigId(warningConfigIdFromSettings(m_project));
|
||||||
? useGlobalConfigVariant.toBool()
|
m_customCommandLineOptions = customCommandLineFromSettings(m_project);
|
||||||
: true;
|
|
||||||
|
|
||||||
setUseGlobalConfig(useGlobalConfig);
|
|
||||||
setWarningConfigId(Core::Id::fromSetting(m_project->namedSettings(warningConfigIdKey())));
|
|
||||||
m_customCommandLineOptions = m_project->namedSettings(customCommandLineKey()).toStringList();
|
|
||||||
if (m_customCommandLineOptions.empty())
|
|
||||||
m_customCommandLineOptions = globalCommandLineOptions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangProjectSettings::store()
|
void ClangProjectSettings::store()
|
||||||
{
|
{
|
||||||
|
bool settingsChanged = false;
|
||||||
|
if (useGlobalConfig() != useGlobalConfigFromSettings(m_project))
|
||||||
|
settingsChanged = true;
|
||||||
|
if (warningConfigId() != warningConfigIdFromSettings(m_project))
|
||||||
|
settingsChanged = true;
|
||||||
|
if (commandLineOptions() != customCommandLineFromSettings(m_project))
|
||||||
|
settingsChanged = true;
|
||||||
|
|
||||||
m_project->setNamedSettings(useGlobalConfigKey(), useGlobalConfig());
|
m_project->setNamedSettings(useGlobalConfigKey(), useGlobalConfig());
|
||||||
m_project->setNamedSettings(warningConfigIdKey(), warningConfigId().toSetting());
|
m_project->setNamedSettings(warningConfigIdKey(), warningConfigId().toSetting());
|
||||||
m_project->setNamedSettings(customCommandLineKey(), m_customCommandLineOptions);
|
m_project->setNamedSettings(customCommandLineKey(), m_customCommandLineOptions);
|
||||||
|
|
||||||
|
if (settingsChanged)
|
||||||
|
emit changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList ClangProjectSettings::globalCommandLineOptions()
|
QStringList ClangProjectSettings::globalCommandLineOptions()
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ public:
|
|||||||
|
|
||||||
static QStringList globalCommandLineOptions();
|
static QStringList globalCommandLineOptions();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void changed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProjectExplorer::Project *m_project;
|
ProjectExplorer::Project *m_project;
|
||||||
bool m_useGlobalConfig = true;
|
bool m_useGlobalConfig = true;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "clangprojectsettingswidget.h"
|
#include "clangprojectsettingswidget.h"
|
||||||
|
|
||||||
|
#include "clangmodelmanagersupport.h"
|
||||||
#include "clangprojectsettings.h"
|
#include "clangprojectsettings.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
@@ -52,7 +53,7 @@ static Core::Id configIdForProject(ClangProjectSettings &projectSettings)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClangProjectSettingsWidget::ClangProjectSettingsWidget(ProjectExplorer::Project *project)
|
ClangProjectSettingsWidget::ClangProjectSettingsWidget(ProjectExplorer::Project *project)
|
||||||
: m_projectSettings(project)
|
: m_projectSettings(ModelManagerSupportClang::instance()->projectSettings(project))
|
||||||
{
|
{
|
||||||
m_ui.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
|
|
||||||
@@ -76,6 +77,8 @@ ClangProjectSettingsWidget::ClangProjectSettingsWidget(ProjectExplorer::Project
|
|||||||
connect(m_ui.clangSettings,
|
connect(m_ui.clangSettings,
|
||||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||||
this, &ClangProjectSettingsWidget::onClangSettingsChanged);
|
this, &ClangProjectSettingsWidget::onClangSettingsChanged);
|
||||||
|
connect(project, &ProjectExplorer::Project::aboutToSaveSettings,
|
||||||
|
this, &ClangProjectSettingsWidget::onAboutToSaveProjectSettings);
|
||||||
|
|
||||||
m_ui.diagnosticConfigurationGroupBox->layout()->addWidget(m_diagnosticConfigWidget);
|
m_ui.diagnosticConfigurationGroupBox->layout()->addWidget(m_diagnosticConfigWidget);
|
||||||
}
|
}
|
||||||
@@ -86,7 +89,6 @@ void ClangProjectSettingsWidget::onCurrentWarningConfigChanged(const Core::Id &c
|
|||||||
if (m_projectSettings.useGlobalConfig())
|
if (m_projectSettings.useGlobalConfig())
|
||||||
return;
|
return;
|
||||||
m_projectSettings.setWarningConfigId(currentConfigId);
|
m_projectSettings.setWarningConfigId(currentConfigId);
|
||||||
m_projectSettings.store();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangProjectSettingsWidget::onCustomWarningConfigsChanged(
|
void ClangProjectSettingsWidget::onCustomWarningConfigsChanged(
|
||||||
@@ -97,7 +99,6 @@ void ClangProjectSettingsWidget::onCustomWarningConfigsChanged(
|
|||||||
const QSharedPointer<CppTools::CppCodeModelSettings> codeModelSettings
|
const QSharedPointer<CppTools::CppCodeModelSettings> codeModelSettings
|
||||||
= CppTools::codeModelSettings();
|
= CppTools::codeModelSettings();
|
||||||
codeModelSettings->setClangCustomDiagnosticConfigs(customConfigs);
|
codeModelSettings->setClangCustomDiagnosticConfigs(customConfigs);
|
||||||
codeModelSettings->toSettings(Core::ICore::settings());
|
|
||||||
|
|
||||||
connectToCppCodeModelSettingsChanged();
|
connectToCppCodeModelSettingsChanged();
|
||||||
}
|
}
|
||||||
@@ -115,16 +116,19 @@ void ClangProjectSettingsWidget::onDelayedTemplateParseClicked(bool checked)
|
|||||||
options.removeAll(QLatin1String{ClangProjectSettings::NoDelayedTemplateParsing});
|
options.removeAll(QLatin1String{ClangProjectSettings::NoDelayedTemplateParsing});
|
||||||
options.append(extraFlag);
|
options.append(extraFlag);
|
||||||
m_projectSettings.setCommandLineOptions(options);
|
m_projectSettings.setCommandLineOptions(options);
|
||||||
m_projectSettings.store();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangProjectSettingsWidget::onClangSettingsChanged(int index)
|
void ClangProjectSettingsWidget::onClangSettingsChanged(int index)
|
||||||
{
|
{
|
||||||
m_projectSettings.setUseGlobalConfig(index == 0 ? true : false);
|
m_projectSettings.setUseGlobalConfig(index == 0 ? true : false);
|
||||||
m_projectSettings.store();
|
|
||||||
syncOtherWidgetsToComboBox();
|
syncOtherWidgetsToComboBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClangProjectSettingsWidget::onAboutToSaveProjectSettings()
|
||||||
|
{
|
||||||
|
CppTools::codeModelSettings()->toSettings(Core::ICore::settings());
|
||||||
|
}
|
||||||
|
|
||||||
void ClangProjectSettingsWidget::syncOtherWidgetsToComboBox()
|
void ClangProjectSettingsWidget::syncOtherWidgetsToComboBox()
|
||||||
{
|
{
|
||||||
const QStringList options = m_projectSettings.commandLineOptions();
|
const QStringList options = m_projectSettings.commandLineOptions();
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ private:
|
|||||||
void onCustomWarningConfigsChanged(const CppTools::ClangDiagnosticConfigs &customConfigs);
|
void onCustomWarningConfigsChanged(const CppTools::ClangDiagnosticConfigs &customConfigs);
|
||||||
void onDelayedTemplateParseClicked(bool);
|
void onDelayedTemplateParseClicked(bool);
|
||||||
void onClangSettingsChanged(int index);
|
void onClangSettingsChanged(int index);
|
||||||
|
void onAboutToSaveProjectSettings();
|
||||||
void refreshDiagnosticConfigsWidgetFromSettings();
|
void refreshDiagnosticConfigsWidgetFromSettings();
|
||||||
void connectToCppCodeModelSettingsChanged();
|
void connectToCppCodeModelSettingsChanged();
|
||||||
void disconnectFromCppCodeModelSettingsChanged();
|
void disconnectFromCppCodeModelSettingsChanged();
|
||||||
@@ -58,7 +59,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ClangProjectSettingsWidget m_ui;
|
Ui::ClangProjectSettingsWidget m_ui;
|
||||||
ClangProjectSettings m_projectSettings;
|
ClangProjectSettings &m_projectSettings;
|
||||||
QPointer<CppTools::ClangDiagnosticConfigsWidget> m_diagnosticConfigWidget;
|
QPointer<CppTools::ClangDiagnosticConfigsWidget> m_diagnosticConfigWidget;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -190,31 +190,5 @@ void setLastSentDocumentRevision(const QString &filePath, uint revision)
|
|||||||
document->sendTracker().setLastSentRevision(int(revision));
|
document->sendTracker().setLastSentRevision(int(revision));
|
||||||
}
|
}
|
||||||
|
|
||||||
// CLANG-UPGRADE-CHECK: Workaround still needed?
|
|
||||||
// Remove once clang reports correct columns for lines with multi-byte utf8.
|
|
||||||
int extraUtf8CharsShift(const QString &str, int column)
|
|
||||||
{
|
|
||||||
int shift = 0;
|
|
||||||
const QByteArray byteArray = str.toUtf8();
|
|
||||||
for (int i = 0; i < qMin(str.length(), column); ++i) {
|
|
||||||
const uchar firstByte = static_cast<uchar>(byteArray.at(i));
|
|
||||||
// Skip different amount of bytes depending on value
|
|
||||||
if (firstByte < 0xC0) {
|
|
||||||
continue;
|
|
||||||
} else if (firstByte < 0xE0) {
|
|
||||||
++shift;
|
|
||||||
++i;
|
|
||||||
} else if (firstByte < 0xF0) {
|
|
||||||
shift += 2;
|
|
||||||
i += 2;
|
|
||||||
} else {
|
|
||||||
shift += 3;
|
|
||||||
i += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return shift;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
} // namespace Clang
|
} // namespace Clang
|
||||||
|
|||||||
@@ -47,7 +47,5 @@ CppTools::ProjectPart::Ptr projectPartForFileBasedOnProcessor(const QString &fil
|
|||||||
bool isProjectPartLoaded(const CppTools::ProjectPart::Ptr projectPart);
|
bool isProjectPartLoaded(const CppTools::ProjectPart::Ptr projectPart);
|
||||||
QString projectPartIdForFile(const QString &filePath);
|
QString projectPartIdForFile(const QString &filePath);
|
||||||
|
|
||||||
int extraUtf8CharsShift(const QString &str, int column);
|
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
} // namespace Clang
|
} // namespace Clang
|
||||||
|
|||||||
@@ -460,7 +460,6 @@ int ServerModeReader::calculateProgress(const int minRange, const int min, const
|
|||||||
void ServerModeReader::extractCodeModelData(const QVariantMap &data)
|
void ServerModeReader::extractCodeModelData(const QVariantMap &data)
|
||||||
{
|
{
|
||||||
const QVariantList configs = data.value("configurations").toList();
|
const QVariantList configs = data.value("configurations").toList();
|
||||||
QTC_CHECK(configs.count() == 1); // FIXME: Support several configurations!
|
|
||||||
for (const QVariant &c : configs) {
|
for (const QVariant &c : configs) {
|
||||||
const QVariantMap &cData = c.toMap();
|
const QVariantMap &cData = c.toMap();
|
||||||
extractConfigurationData(cData);
|
extractConfigurationData(cData);
|
||||||
@@ -842,6 +841,11 @@ void ServerModeReader::addFileGroups(ProjectNode *targetRoot,
|
|||||||
{
|
{
|
||||||
QList<FileNode *> toList;
|
QList<FileNode *> toList;
|
||||||
QSet<Utils::FileName> alreadyListed;
|
QSet<Utils::FileName> alreadyListed;
|
||||||
|
// Files already added by other configurations:
|
||||||
|
targetRoot->forEachGenericNode([&alreadyListed](const Node *n) {
|
||||||
|
alreadyListed.insert(n->filePath());
|
||||||
|
});
|
||||||
|
|
||||||
for (const FileGroup *f : fileGroups) {
|
for (const FileGroup *f : fileGroups) {
|
||||||
const QList<FileName> newSources = Utils::filtered(f->sources, [&alreadyListed](const Utils::FileName &fn) {
|
const QList<FileName> newSources = Utils::filtered(f->sources, [&alreadyListed](const Utils::FileName &fn) {
|
||||||
const int count = alreadyListed.count();
|
const int count = alreadyListed.count();
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ public:
|
|||||||
virtual QFuture<SymbolInfo> requestFollowSymbol(int line, int column) = 0;
|
virtual QFuture<SymbolInfo> requestFollowSymbol(int line, int column) = 0;
|
||||||
virtual QFuture<ToolTipInfo> toolTipInfo(const QByteArray &codecName, int line, int column);
|
virtual QFuture<ToolTipInfo> toolTipInfo(const QByteArray &codecName, int line, int column);
|
||||||
|
|
||||||
|
QString filePath() const { return m_filePath; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using HeaderErrorDiagnosticWidgetCreator = std::function<QWidget*()>;
|
using HeaderErrorDiagnosticWidgetCreator = std::function<QWidget*()>;
|
||||||
|
|
||||||
@@ -117,7 +119,6 @@ protected:
|
|||||||
BaseEditorDocumentParser::UpdateParams updateParams);
|
BaseEditorDocumentParser::UpdateParams updateParams);
|
||||||
|
|
||||||
// Convenience
|
// Convenience
|
||||||
QString filePath() const { return m_filePath; }
|
|
||||||
unsigned revision() const { return static_cast<unsigned>(m_textDocument->revision()); }
|
unsigned revision() const { return static_cast<unsigned>(m_textDocument->revision()); }
|
||||||
QTextDocument *textDocument() const { return m_textDocument; }
|
QTextDocument *textDocument() const { return m_textDocument; }
|
||||||
|
|
||||||
|
|||||||
@@ -47,14 +47,14 @@ void ClangDiagnosticConfig::setDisplayName(const QString &displayName)
|
|||||||
m_displayName = displayName;
|
m_displayName = displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList ClangDiagnosticConfig::commandLineWarnings() const
|
QStringList ClangDiagnosticConfig::clangOptions() const
|
||||||
{
|
{
|
||||||
return m_commandLineWarnings;
|
return m_clangOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangDiagnosticConfig::setCommandLineWarnings(const QStringList &warnings)
|
void ClangDiagnosticConfig::setClangOptions(const QStringList &options)
|
||||||
{
|
{
|
||||||
m_commandLineWarnings = warnings;
|
m_clangOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClangDiagnosticConfig::isReadOnly() const
|
bool ClangDiagnosticConfig::isReadOnly() const
|
||||||
@@ -71,8 +71,35 @@ bool ClangDiagnosticConfig::operator==(const ClangDiagnosticConfig &other) const
|
|||||||
{
|
{
|
||||||
return m_id == other.m_id
|
return m_id == other.m_id
|
||||||
&& m_displayName == other.m_displayName
|
&& m_displayName == other.m_displayName
|
||||||
&& m_commandLineWarnings == other.m_commandLineWarnings
|
&& m_clangOptions == other.m_clangOptions
|
||||||
|
&& m_clangTidyChecks == other.m_clangTidyChecks
|
||||||
|
&& m_clazyChecks == other.m_clazyChecks
|
||||||
&& m_isReadOnly == other.m_isReadOnly;
|
&& m_isReadOnly == other.m_isReadOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClangDiagnosticConfig::operator!=(const ClangDiagnosticConfig &other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ClangDiagnosticConfig::clangTidyChecks() const
|
||||||
|
{
|
||||||
|
return m_clangTidyChecks;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClangDiagnosticConfig::setClangTidyChecks(const QString &checks)
|
||||||
|
{
|
||||||
|
m_clangTidyChecks = checks;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ClangDiagnosticConfig::clazyChecks() const
|
||||||
|
{
|
||||||
|
return m_clazyChecks;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClangDiagnosticConfig::setClazyChecks(const QString &checks)
|
||||||
|
{
|
||||||
|
m_clazyChecks = checks;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace CppTools
|
} // namespace CppTools
|
||||||
|
|||||||
@@ -43,18 +43,27 @@ public:
|
|||||||
QString displayName() const;
|
QString displayName() const;
|
||||||
void setDisplayName(const QString &displayName);
|
void setDisplayName(const QString &displayName);
|
||||||
|
|
||||||
QStringList commandLineWarnings() const;
|
QStringList clangOptions() const;
|
||||||
void setCommandLineWarnings(const QStringList &commandLineWarnings);
|
void setClangOptions(const QStringList &options);
|
||||||
|
|
||||||
|
QString clangTidyChecks() const;
|
||||||
|
void setClangTidyChecks(const QString &checks);
|
||||||
|
|
||||||
|
QString clazyChecks() const;
|
||||||
|
void setClazyChecks(const QString &checks);
|
||||||
|
|
||||||
bool isReadOnly() const;
|
bool isReadOnly() const;
|
||||||
void setIsReadOnly(bool isReadOnly);
|
void setIsReadOnly(bool isReadOnly);
|
||||||
|
|
||||||
bool operator==(const ClangDiagnosticConfig &other) const;
|
bool operator==(const ClangDiagnosticConfig &other) const;
|
||||||
|
bool operator!=(const ClangDiagnosticConfig &other) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Core::Id m_id;
|
Core::Id m_id;
|
||||||
QString m_displayName;
|
QString m_displayName;
|
||||||
QStringList m_commandLineWarnings;
|
QStringList m_clangOptions;
|
||||||
|
QString m_clangTidyChecks;
|
||||||
|
QString m_clazyChecks;
|
||||||
bool m_isReadOnly = false;
|
bool m_isReadOnly = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ static void addConfigForQuestionableConstructs(ClangDiagnosticConfigsModel &mode
|
|||||||
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
|
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
|
||||||
"Warnings for questionable constructs"));
|
"Warnings for questionable constructs"));
|
||||||
config.setIsReadOnly(true);
|
config.setIsReadOnly(true);
|
||||||
config.setCommandLineWarnings(QStringList{
|
config.setClangOptions(QStringList{
|
||||||
QStringLiteral("-Wall"),
|
QStringLiteral("-Wall"),
|
||||||
QStringLiteral("-Wextra"),
|
QStringLiteral("-Wextra"),
|
||||||
} + commonWarnings());
|
} + commonWarnings());
|
||||||
@@ -60,7 +60,7 @@ static void addConfigForPedanticWarnings(ClangDiagnosticConfigsModel &model)
|
|||||||
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
|
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
|
||||||
"Pedantic Warnings"));
|
"Pedantic Warnings"));
|
||||||
config.setIsReadOnly(true);
|
config.setIsReadOnly(true);
|
||||||
config.setCommandLineWarnings(QStringList{QStringLiteral("-Wpedantic")} + commonWarnings());
|
config.setClangOptions(QStringList{QStringLiteral("-Wpedantic")} + commonWarnings());
|
||||||
|
|
||||||
model.appendOrUpdate(config);
|
model.appendOrUpdate(config);
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ static void addConfigForAlmostEveryWarning(ClangDiagnosticConfigsModel &model)
|
|||||||
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
|
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
|
||||||
"Warnings for almost everything"));
|
"Warnings for almost everything"));
|
||||||
config.setIsReadOnly(true);
|
config.setIsReadOnly(true);
|
||||||
config.setCommandLineWarnings(QStringList{
|
config.setClangOptions(QStringList{
|
||||||
QStringLiteral("-Weverything"),
|
QStringLiteral("-Weverything"),
|
||||||
QStringLiteral("-Wno-c++98-compat"),
|
QStringLiteral("-Wno-c++98-compat"),
|
||||||
QStringLiteral("-Wno-c++98-compat-pedantic"),
|
QStringLiteral("-Wno-c++98-compat-pedantic"),
|
||||||
@@ -158,6 +158,23 @@ ClangDiagnosticConfigsModel::displayNameWithBuiltinIndication(const ClangDiagnos
|
|||||||
: config.displayName();
|
: config.displayName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<Core::Id> ClangDiagnosticConfigsModel::changedOrRemovedConfigs(
|
||||||
|
const ClangDiagnosticConfigs &oldConfigs, const ClangDiagnosticConfigs &newConfigs)
|
||||||
|
{
|
||||||
|
ClangDiagnosticConfigsModel newConfigsModel(newConfigs);
|
||||||
|
QVector<Core::Id> changedConfigs;
|
||||||
|
|
||||||
|
for (const ClangDiagnosticConfig &old: oldConfigs) {
|
||||||
|
const int i = newConfigsModel.indexOfConfig(old.id());
|
||||||
|
if (i == -1)
|
||||||
|
changedConfigs.append(old.id()); // Removed
|
||||||
|
else if (newConfigsModel.configs()[i] != old)
|
||||||
|
changedConfigs.append(old.id()); // Changed
|
||||||
|
}
|
||||||
|
|
||||||
|
return changedConfigs;
|
||||||
|
}
|
||||||
|
|
||||||
int ClangDiagnosticConfigsModel::indexOfConfig(const Core::Id &id) const
|
int ClangDiagnosticConfigsModel::indexOfConfig(const Core::Id &id) const
|
||||||
{
|
{
|
||||||
return Utils::indexOf(m_diagnosticConfigs, [&](const ClangDiagnosticConfig &config) {
|
return Utils::indexOf(m_diagnosticConfigs, [&](const ClangDiagnosticConfig &config) {
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
#include "clangdiagnosticconfig.h"
|
#include "clangdiagnosticconfig.h"
|
||||||
|
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
|
|
||||||
class CPPTOOLS_EXPORT ClangDiagnosticConfigsModel
|
class CPPTOOLS_EXPORT ClangDiagnosticConfigsModel
|
||||||
@@ -47,11 +49,11 @@ public:
|
|||||||
ClangDiagnosticConfigs configs() const;
|
ClangDiagnosticConfigs configs() const;
|
||||||
bool hasConfigWithId(const Core::Id &id) const;
|
bool hasConfigWithId(const Core::Id &id) const;
|
||||||
const ClangDiagnosticConfig &configWithId(const Core::Id &id) const;
|
const ClangDiagnosticConfig &configWithId(const Core::Id &id) const;
|
||||||
|
int indexOfConfig(const Core::Id &id) const;
|
||||||
|
|
||||||
static QString displayNameWithBuiltinIndication(const ClangDiagnosticConfig &config);
|
static QString displayNameWithBuiltinIndication(const ClangDiagnosticConfig &config);
|
||||||
|
static QVector<Core::Id> changedOrRemovedConfigs(const ClangDiagnosticConfigs &oldConfigs,
|
||||||
private:
|
const ClangDiagnosticConfigs &newConfigs);
|
||||||
int indexOfConfig(const Core::Id &id) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClangDiagnosticConfigs m_diagnosticConfigs;
|
ClangDiagnosticConfigs m_diagnosticConfigs;
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include "clangdiagnosticconfigswidget.h"
|
#include "clangdiagnosticconfigswidget.h"
|
||||||
#include "ui_clangdiagnosticconfigswidget.h"
|
#include "ui_clangdiagnosticconfigswidget.h"
|
||||||
|
#include "ui_clazychecks.h"
|
||||||
|
#include "ui_tidychecks.h"
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -45,6 +47,7 @@ ClangDiagnosticConfigsWidget::ClangDiagnosticConfigsWidget(
|
|||||||
, m_diagnosticConfigsModel(diagnosticConfigsModel)
|
, m_diagnosticConfigsModel(diagnosticConfigsModel)
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
setupPluginsWidgets();
|
||||||
|
|
||||||
connectConfigChooserCurrentIndex();
|
connectConfigChooserCurrentIndex();
|
||||||
connect(m_ui->copyButton, &QPushButton::clicked,
|
connect(m_ui->copyButton, &QPushButton::clicked,
|
||||||
@@ -108,6 +111,18 @@ void ClangDiagnosticConfigsWidget::onRemoveButtonClicked()
|
|||||||
syncConfigChooserToModel();
|
syncConfigChooserToModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClangDiagnosticConfigsWidget::onClangTidyItemChanged(QListWidgetItem *item)
|
||||||
|
{
|
||||||
|
const QString prefix = item->text();
|
||||||
|
ClangDiagnosticConfig config = currentConfig();
|
||||||
|
QString checks = config.clangTidyChecks();
|
||||||
|
item->checkState() == Qt::Checked
|
||||||
|
? checks.append(',' + prefix)
|
||||||
|
: checks.remove(',' + prefix);
|
||||||
|
config.setClangTidyChecks(checks);
|
||||||
|
updateConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
static bool isAcceptedWarningOption(const QString &option)
|
static bool isAcceptedWarningOption(const QString &option)
|
||||||
{
|
{
|
||||||
return option == "-w"
|
return option == "-w"
|
||||||
@@ -162,10 +177,8 @@ void ClangDiagnosticConfigsWidget::onDiagnosticOptionsEdited()
|
|||||||
|
|
||||||
// Commit valid changes
|
// Commit valid changes
|
||||||
ClangDiagnosticConfig updatedConfig = currentConfig();
|
ClangDiagnosticConfig updatedConfig = currentConfig();
|
||||||
updatedConfig.setCommandLineWarnings(normalizedOptions);
|
updatedConfig.setClangOptions(normalizedOptions);
|
||||||
|
updateConfig(updatedConfig);
|
||||||
m_diagnosticConfigsModel.appendOrUpdate(updatedConfig);
|
|
||||||
emit customConfigsChanged(customConfigs());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangDiagnosticConfigsWidget::syncWidgetsToModel(const Core::Id &configToSelect)
|
void ClangDiagnosticConfigsWidget::syncWidgetsToModel(const Core::Id &configToSelect)
|
||||||
@@ -213,12 +226,74 @@ void ClangDiagnosticConfigsWidget::syncOtherWidgetsToComboBox()
|
|||||||
// Update main button row
|
// Update main button row
|
||||||
m_ui->removeButton->setEnabled(!config.isReadOnly());
|
m_ui->removeButton->setEnabled(!config.isReadOnly());
|
||||||
|
|
||||||
// Update child widgets
|
// Update Text Edit
|
||||||
const QString options = m_notAcceptedOptions.contains(config.id())
|
const QString options = m_notAcceptedOptions.contains(config.id())
|
||||||
? m_notAcceptedOptions.value(config.id())
|
? m_notAcceptedOptions.value(config.id())
|
||||||
: config.commandLineWarnings().join(QLatin1Char(' '));
|
: config.clangOptions().join(QLatin1Char(' '));
|
||||||
setDiagnosticOptions(options);
|
setDiagnosticOptions(options);
|
||||||
m_ui->diagnosticOptionsTextEdit->setReadOnly(config.isReadOnly());
|
m_ui->diagnosticOptionsTextEdit->setReadOnly(config.isReadOnly());
|
||||||
|
|
||||||
|
syncClangTidyWidgets(config);
|
||||||
|
syncClazyWidgets(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClangDiagnosticConfigsWidget::syncClangTidyWidgets(const ClangDiagnosticConfig &config)
|
||||||
|
{
|
||||||
|
disconnectClangTidyItemChanged();
|
||||||
|
|
||||||
|
const QString tidyChecks = config.clangTidyChecks();
|
||||||
|
for (int row = 0; row < m_tidyChecks->checksList->count(); ++row) {
|
||||||
|
QListWidgetItem *item = m_tidyChecks->checksList->item(row);
|
||||||
|
|
||||||
|
Qt::ItemFlags flags = item->flags();
|
||||||
|
flags |= Qt::ItemIsUserCheckable;
|
||||||
|
if (config.isReadOnly())
|
||||||
|
flags &= ~Qt::ItemIsEnabled;
|
||||||
|
else
|
||||||
|
flags |= Qt::ItemIsEnabled;
|
||||||
|
item->setFlags(flags);
|
||||||
|
|
||||||
|
if (tidyChecks.indexOf(item->text()) != -1)
|
||||||
|
item->setCheckState(Qt::Checked);
|
||||||
|
else
|
||||||
|
item->setCheckState(Qt::Unchecked);
|
||||||
|
}
|
||||||
|
|
||||||
|
connectClangTidyItemChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClangDiagnosticConfigsWidget::syncClazyWidgets(const ClangDiagnosticConfig &config)
|
||||||
|
{
|
||||||
|
const QString clazyChecks = config.clazyChecks();
|
||||||
|
if (clazyChecks.isEmpty())
|
||||||
|
m_clazyChecks->clazyLevel->setCurrentIndex(0);
|
||||||
|
else
|
||||||
|
m_clazyChecks->clazyLevel->setCurrentText(clazyChecks);
|
||||||
|
m_clazyChecksWidget->setEnabled(!config.isReadOnly());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClangDiagnosticConfigsWidget::setClazyLevelDescription(int index)
|
||||||
|
{
|
||||||
|
// Levels descriptions are taken from https://github.com/KDE/clazy
|
||||||
|
static const QString levelDescriptions[] {
|
||||||
|
QString(),
|
||||||
|
tr("Very stable checks, 99.99% safe, no false-positives."),
|
||||||
|
tr("Similar to level 0, but sometimes (rarely) there might be\n"
|
||||||
|
"some false-positives."),
|
||||||
|
tr("Sometimes has false-positives (20-30%)."),
|
||||||
|
tr("Not always correct, possibly very noisy, might require\n"
|
||||||
|
"a knowledgeable developer to review, might have a very big\n"
|
||||||
|
"rate of false-positives, might have bugs.")
|
||||||
|
};
|
||||||
|
|
||||||
|
QTC_ASSERT(m_clazyChecks, return);
|
||||||
|
m_clazyChecks->levelDescription->setText(levelDescriptions[static_cast<unsigned>(index)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClangDiagnosticConfigsWidget::updateConfig(const ClangDiagnosticConfig &config)
|
||||||
|
{
|
||||||
|
m_diagnosticConfigsModel.appendOrUpdate(config);
|
||||||
|
emit customConfigsChanged(customConfigs());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClangDiagnosticConfigsWidget::isConfigChooserEmpty() const
|
bool ClangDiagnosticConfigsWidget::isConfigChooserEmpty() const
|
||||||
@@ -264,6 +339,18 @@ void ClangDiagnosticConfigsWidget::updateValidityWidgets(const QString &errorMes
|
|||||||
m_ui->validationResultLabel->setStyleSheet(styleSheet);
|
m_ui->validationResultLabel->setStyleSheet(styleSheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClangDiagnosticConfigsWidget::connectClangTidyItemChanged()
|
||||||
|
{
|
||||||
|
connect(m_tidyChecks->checksList, &QListWidget::itemChanged,
|
||||||
|
this, &ClangDiagnosticConfigsWidget::onClangTidyItemChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClangDiagnosticConfigsWidget::disconnectClangTidyItemChanged()
|
||||||
|
{
|
||||||
|
disconnect(m_tidyChecks->checksList, &QListWidget::itemChanged,
|
||||||
|
this, &ClangDiagnosticConfigsWidget::onClangTidyItemChanged);
|
||||||
|
}
|
||||||
|
|
||||||
void ClangDiagnosticConfigsWidget::connectConfigChooserCurrentIndex()
|
void ClangDiagnosticConfigsWidget::connectConfigChooserCurrentIndex()
|
||||||
{
|
{
|
||||||
connect(m_ui->configChooserComboBox,
|
connect(m_ui->configChooserComboBox,
|
||||||
@@ -314,4 +401,31 @@ void ClangDiagnosticConfigsWidget::refresh(
|
|||||||
syncWidgetsToModel(configToSelect);
|
syncWidgetsToModel(configToSelect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClangDiagnosticConfigsWidget::setupPluginsWidgets()
|
||||||
|
{
|
||||||
|
m_clazyChecks.reset(new CppTools::Ui::ClazyChecks);
|
||||||
|
m_clazyChecksWidget = new QWidget();
|
||||||
|
m_clazyChecks->setupUi(m_clazyChecksWidget);
|
||||||
|
connect(m_clazyChecks->clazyLevel,
|
||||||
|
static_cast<void (QComboBox::*)(int index)>(&QComboBox::currentIndexChanged),
|
||||||
|
[this](int index) {
|
||||||
|
setClazyLevelDescription(index);
|
||||||
|
ClangDiagnosticConfig config = currentConfig();
|
||||||
|
if (index == 0)
|
||||||
|
config.setClazyChecks(QString());
|
||||||
|
else
|
||||||
|
config.setClazyChecks(m_clazyChecks->clazyLevel->itemText(index));
|
||||||
|
updateConfig(config);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_tidyChecks.reset(new CppTools::Ui::TidyChecks);
|
||||||
|
m_tidyChecksWidget = new QWidget();
|
||||||
|
m_tidyChecks->setupUi(m_tidyChecksWidget);
|
||||||
|
connectClangTidyItemChanged();
|
||||||
|
|
||||||
|
m_ui->pluginChecksTabs->addTab(m_tidyChecksWidget, tr("Clang-Tidy"));
|
||||||
|
m_ui->pluginChecksTabs->addTab(m_clazyChecksWidget, tr("Clazy"));
|
||||||
|
m_ui->pluginChecksTabs->setCurrentIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
} // CppTools namespace
|
} // CppTools namespace
|
||||||
|
|||||||
@@ -33,9 +33,17 @@
|
|||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QListWidgetItem)
|
||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
|
|
||||||
namespace Ui { class ClangDiagnosticConfigsWidget; }
|
namespace Ui {
|
||||||
|
class ClangDiagnosticConfigsWidget;
|
||||||
|
class ClazyChecks;
|
||||||
|
class TidyChecks;
|
||||||
|
}
|
||||||
|
|
||||||
class CPPTOOLS_EXPORT ClangDiagnosticConfigsWidget : public QWidget
|
class CPPTOOLS_EXPORT ClangDiagnosticConfigsWidget : public QWidget
|
||||||
{
|
{
|
||||||
@@ -59,15 +67,23 @@ signals:
|
|||||||
void customConfigsChanged(const CppTools::ClangDiagnosticConfigs &customConfigs);
|
void customConfigsChanged(const CppTools::ClangDiagnosticConfigs &customConfigs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void setupPluginsWidgets();
|
||||||
|
|
||||||
void onCurrentConfigChanged(int);
|
void onCurrentConfigChanged(int);
|
||||||
void onCopyButtonClicked();
|
void onCopyButtonClicked();
|
||||||
void onRemoveButtonClicked();
|
void onRemoveButtonClicked();
|
||||||
|
void onClangTidyItemChanged(QListWidgetItem *item);
|
||||||
|
|
||||||
void onDiagnosticOptionsEdited();
|
void onDiagnosticOptionsEdited();
|
||||||
|
|
||||||
void syncWidgetsToModel(const Core::Id &configToSelect = Core::Id());
|
void syncWidgetsToModel(const Core::Id &configToSelect = Core::Id());
|
||||||
void syncConfigChooserToModel(const Core::Id &configToSelect = Core::Id());
|
void syncConfigChooserToModel(const Core::Id &configToSelect = Core::Id());
|
||||||
void syncOtherWidgetsToComboBox();
|
void syncOtherWidgetsToComboBox();
|
||||||
|
void syncClangTidyWidgets(const ClangDiagnosticConfig &config);
|
||||||
|
void syncClazyWidgets(const ClangDiagnosticConfig &config);
|
||||||
|
|
||||||
|
void setClazyLevelDescription(int index);
|
||||||
|
void updateConfig(const CppTools::ClangDiagnosticConfig &config);
|
||||||
|
|
||||||
bool isConfigChooserEmpty() const;
|
bool isConfigChooserEmpty() const;
|
||||||
const ClangDiagnosticConfig ¤tConfig() const;
|
const ClangDiagnosticConfig ¤tConfig() const;
|
||||||
@@ -75,6 +91,9 @@ private:
|
|||||||
void setDiagnosticOptions(const QString &options);
|
void setDiagnosticOptions(const QString &options);
|
||||||
void updateValidityWidgets(const QString &errorMessage);
|
void updateValidityWidgets(const QString &errorMessage);
|
||||||
|
|
||||||
|
void connectClangTidyItemChanged();
|
||||||
|
void disconnectClangTidyItemChanged();
|
||||||
|
|
||||||
void connectConfigChooserCurrentIndex();
|
void connectConfigChooserCurrentIndex();
|
||||||
void disconnectConfigChooserCurrentIndex();
|
void disconnectConfigChooserCurrentIndex();
|
||||||
void connectDiagnosticOptionsChanged();
|
void connectDiagnosticOptionsChanged();
|
||||||
@@ -84,6 +103,12 @@ private:
|
|||||||
Ui::ClangDiagnosticConfigsWidget *m_ui;
|
Ui::ClangDiagnosticConfigsWidget *m_ui;
|
||||||
ClangDiagnosticConfigsModel m_diagnosticConfigsModel;
|
ClangDiagnosticConfigsModel m_diagnosticConfigsModel;
|
||||||
QHash<Core::Id, QString> m_notAcceptedOptions;
|
QHash<Core::Id, QString> m_notAcceptedOptions;
|
||||||
|
|
||||||
|
std::unique_ptr<CppTools::Ui::ClazyChecks> m_clazyChecks;
|
||||||
|
QWidget *m_clazyChecksWidget = nullptr;
|
||||||
|
|
||||||
|
std::unique_ptr<CppTools::Ui::TidyChecks> m_tidyChecks;
|
||||||
|
QWidget *m_tidyChecksWidget = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // CppTools namespace
|
} // CppTools namespace
|
||||||
|
|||||||
@@ -93,6 +93,9 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="pluginChecksTabs"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
|||||||
@@ -27,8 +27,10 @@
|
|||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
|
||||||
|
#include <utils/fileutils.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/qtcfallthrough.h>
|
#include <utils/qtcfallthrough.h>
|
||||||
|
|
||||||
@@ -37,6 +39,8 @@
|
|||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
|
|
||||||
|
static constexpr char SYSTEM_INCLUDE_PREFIX[] = "-isystem";
|
||||||
|
|
||||||
CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart,
|
CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart,
|
||||||
const QString &clangVersion,
|
const QString &clangVersion,
|
||||||
const QString &clangResourceDirectory)
|
const QString &clangResourceDirectory)
|
||||||
@@ -119,10 +123,23 @@ void CompilerOptionsBuilder::enableExceptions()
|
|||||||
add(QLatin1String("-fexceptions"));
|
add(QLatin1String("-fexceptions"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Utils::FileName absoluteDirectory(const QString &filePath)
|
||||||
|
{
|
||||||
|
return Utils::FileName::fromString(QFileInfo(filePath + '/').absolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
static Utils::FileName projectTopLevelDirectory(const ProjectPart &projectPart)
|
||||||
|
{
|
||||||
|
if (!projectPart.project)
|
||||||
|
return Utils::FileName();
|
||||||
|
return projectPart.project->projectDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
void CompilerOptionsBuilder::addHeaderPathOptions()
|
void CompilerOptionsBuilder::addHeaderPathOptions()
|
||||||
{
|
{
|
||||||
typedef ProjectPartHeaderPath HeaderPath;
|
typedef ProjectPartHeaderPath HeaderPath;
|
||||||
const QString defaultPrefix = includeDirOption();
|
const QString defaultPrefix = includeDirOption();
|
||||||
|
const Utils::FileName projectDirectory = projectTopLevelDirectory(m_projectPart);
|
||||||
|
|
||||||
QStringList result;
|
QStringList result;
|
||||||
|
|
||||||
@@ -134,6 +151,7 @@ void CompilerOptionsBuilder::addHeaderPathOptions()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
QString prefix;
|
QString prefix;
|
||||||
|
Utils::FileName path;
|
||||||
switch (headerPath.type) {
|
switch (headerPath.type) {
|
||||||
case HeaderPath::FrameworkPath:
|
case HeaderPath::FrameworkPath:
|
||||||
prefix = QLatin1String("-F");
|
prefix = QLatin1String("-F");
|
||||||
@@ -141,7 +159,11 @@ void CompilerOptionsBuilder::addHeaderPathOptions()
|
|||||||
default: // This shouldn't happen, but let's be nice..:
|
default: // This shouldn't happen, but let's be nice..:
|
||||||
// intentional fall-through:
|
// intentional fall-through:
|
||||||
case HeaderPath::IncludePath:
|
case HeaderPath::IncludePath:
|
||||||
prefix = defaultPrefix;
|
path = absoluteDirectory(headerPath.path);
|
||||||
|
if (path == projectDirectory || path.isChildOf(projectDirectory))
|
||||||
|
prefix = defaultPrefix;
|
||||||
|
else
|
||||||
|
prefix = SYSTEM_INCLUDE_PREFIX;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,7 +431,7 @@ void CompilerOptionsBuilder::addDefineFunctionMacrosMsvc()
|
|||||||
|
|
||||||
QString CompilerOptionsBuilder::includeDirOption() const
|
QString CompilerOptionsBuilder::includeDirOption() const
|
||||||
{
|
{
|
||||||
return QLatin1String("-isystem");
|
return QLatin1String("-I");
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray CompilerOptionsBuilder::macroOption(const ProjectExplorer::Macro ¯o) const
|
QByteArray CompilerOptionsBuilder::macroOption(const ProjectExplorer::Macro ¯o) const
|
||||||
@@ -506,7 +528,7 @@ void CompilerOptionsBuilder::addPredefinedHeaderPathsOptions()
|
|||||||
void CompilerOptionsBuilder::addClangIncludeFolder()
|
void CompilerOptionsBuilder::addClangIncludeFolder()
|
||||||
{
|
{
|
||||||
QTC_CHECK(!m_clangVersion.isEmpty());
|
QTC_CHECK(!m_clangVersion.isEmpty());
|
||||||
add(includeDirOption());
|
add(SYSTEM_INCLUDE_PREFIX);
|
||||||
add(clangIncludeDirectory());
|
add(clangIncludeDirectory());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,12 @@ static QString clangDiagnosticConfigsArrayDisplayNameKey()
|
|||||||
static QString clangDiagnosticConfigsArrayWarningsKey()
|
static QString clangDiagnosticConfigsArrayWarningsKey()
|
||||||
{ return QLatin1String("diagnosticOptions"); }
|
{ return QLatin1String("diagnosticOptions"); }
|
||||||
|
|
||||||
|
static QString clangDiagnosticConfigsArrayClangTidyChecksKey()
|
||||||
|
{ return QLatin1String("clangTidyChecks"); }
|
||||||
|
|
||||||
|
static QString clangDiagnosticConfigsArrayClazyChecksKey()
|
||||||
|
{ return QLatin1String("clazyChecks"); }
|
||||||
|
|
||||||
static QString pchUsageKey()
|
static QString pchUsageKey()
|
||||||
{ return QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_PCH_USAGE); }
|
{ return QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_PCH_USAGE); }
|
||||||
|
|
||||||
@@ -67,15 +73,12 @@ static QString skipIndexingBigFilesKey()
|
|||||||
static QString indexerFileSizeLimitKey()
|
static QString indexerFileSizeLimitKey()
|
||||||
{ return QLatin1String(Constants::CPPTOOLS_INDEXER_FILE_SIZE_LIMIT); }
|
{ return QLatin1String(Constants::CPPTOOLS_INDEXER_FILE_SIZE_LIMIT); }
|
||||||
|
|
||||||
static QString tidyChecksKey()
|
static ClangDiagnosticConfigs customDiagnosticConfigsFromSettings(QSettings *s)
|
||||||
{ return QLatin1String(Constants::CPPTOOLS_TIDY_CHECKS); }
|
|
||||||
|
|
||||||
static QString clazyChecksKey()
|
|
||||||
{ return QLatin1String(Constants::CPPTOOLS_CLAZY_CHECKS); }
|
|
||||||
|
|
||||||
void CppCodeModelSettings::fromSettings(QSettings *s)
|
|
||||||
{
|
{
|
||||||
s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
|
QTC_ASSERT(s->group() == QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP),
|
||||||
|
return ClangDiagnosticConfigs());
|
||||||
|
|
||||||
|
ClangDiagnosticConfigs configs;
|
||||||
|
|
||||||
const int size = s->beginReadArray(clangDiagnosticConfigsArrayKey());
|
const int size = s->beginReadArray(clangDiagnosticConfigsArrayKey());
|
||||||
for (int i = 0; i < size; ++i) {
|
for (int i = 0; i < size; ++i) {
|
||||||
@@ -84,15 +87,30 @@ void CppCodeModelSettings::fromSettings(QSettings *s)
|
|||||||
ClangDiagnosticConfig config;
|
ClangDiagnosticConfig config;
|
||||||
config.setId(Core::Id::fromSetting(s->value(clangDiagnosticConfigsArrayIdKey())));
|
config.setId(Core::Id::fromSetting(s->value(clangDiagnosticConfigsArrayIdKey())));
|
||||||
config.setDisplayName(s->value(clangDiagnosticConfigsArrayDisplayNameKey()).toString());
|
config.setDisplayName(s->value(clangDiagnosticConfigsArrayDisplayNameKey()).toString());
|
||||||
config.setCommandLineWarnings(s->value(clangDiagnosticConfigsArrayWarningsKey()).toStringList());
|
config.setClangOptions(s->value(clangDiagnosticConfigsArrayWarningsKey()).toStringList());
|
||||||
m_clangCustomDiagnosticConfigs.append(config);
|
config.setClangTidyChecks(s->value(clangDiagnosticConfigsArrayClangTidyChecksKey()).toString());
|
||||||
|
config.setClazyChecks(s->value(clangDiagnosticConfigsArrayClazyChecksKey()).toString());
|
||||||
|
configs.append(config);
|
||||||
}
|
}
|
||||||
s->endArray();
|
s->endArray();
|
||||||
|
|
||||||
const Core::Id diagnosticConfigId = Core::Id::fromSetting(
|
return configs;
|
||||||
s->value(clangDiagnosticConfigKey(),
|
}
|
||||||
initialClangDiagnosticConfigId().toSetting()));
|
|
||||||
setClangDiagnosticConfigId(diagnosticConfigId);
|
static Core::Id clangDiagnosticConfigIdFromSettings(QSettings *s)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(s->group() == QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP), return Core::Id());
|
||||||
|
|
||||||
|
return Core::Id::fromSetting(
|
||||||
|
s->value(clangDiagnosticConfigKey(), initialClangDiagnosticConfigId().toSetting()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppCodeModelSettings::fromSettings(QSettings *s)
|
||||||
|
{
|
||||||
|
s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
|
||||||
|
|
||||||
|
setClangCustomDiagnosticConfigs(customDiagnosticConfigsFromSettings(s));
|
||||||
|
setClangDiagnosticConfigId(clangDiagnosticConfigIdFromSettings(s));
|
||||||
|
|
||||||
const QVariant pchUsageVariant = s->value(pchUsageKey(), initialPchUsage());
|
const QVariant pchUsageVariant = s->value(pchUsageKey(), initialPchUsage());
|
||||||
setPCHUsage(static_cast<PCHUsage>(pchUsageVariant.toInt()));
|
setPCHUsage(static_cast<PCHUsage>(pchUsageVariant.toInt()));
|
||||||
@@ -107,11 +125,6 @@ void CppCodeModelSettings::fromSettings(QSettings *s)
|
|||||||
const QVariant indexerFileSizeLimit = s->value(indexerFileSizeLimitKey(), 5);
|
const QVariant indexerFileSizeLimit = s->value(indexerFileSizeLimitKey(), 5);
|
||||||
setIndexerFileSizeLimitInMb(indexerFileSizeLimit.toInt());
|
setIndexerFileSizeLimitInMb(indexerFileSizeLimit.toInt());
|
||||||
|
|
||||||
const QVariant tidyChecks = s->value(tidyChecksKey(), QString());
|
|
||||||
setTidyChecks(tidyChecks.toString());
|
|
||||||
const QVariant clazyChecks = s->value(clazyChecksKey(), QString());
|
|
||||||
setClazyChecks(clazyChecks.toString());
|
|
||||||
|
|
||||||
s->endGroup();
|
s->endGroup();
|
||||||
|
|
||||||
emit changed();
|
emit changed();
|
||||||
@@ -120,6 +133,8 @@ void CppCodeModelSettings::fromSettings(QSettings *s)
|
|||||||
void CppCodeModelSettings::toSettings(QSettings *s)
|
void CppCodeModelSettings::toSettings(QSettings *s)
|
||||||
{
|
{
|
||||||
s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
|
s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
|
||||||
|
const ClangDiagnosticConfigs previousConfigs = customDiagnosticConfigsFromSettings(s);
|
||||||
|
const Core::Id previousConfigId = clangDiagnosticConfigIdFromSettings(s);
|
||||||
|
|
||||||
s->beginWriteArray(clangDiagnosticConfigsArrayKey());
|
s->beginWriteArray(clangDiagnosticConfigsArrayKey());
|
||||||
for (int i = 0, size = m_clangCustomDiagnosticConfigs.size(); i < size; ++i) {
|
for (int i = 0, size = m_clangCustomDiagnosticConfigs.size(); i < size; ++i) {
|
||||||
@@ -128,7 +143,9 @@ void CppCodeModelSettings::toSettings(QSettings *s)
|
|||||||
s->setArrayIndex(i);
|
s->setArrayIndex(i);
|
||||||
s->setValue(clangDiagnosticConfigsArrayIdKey(), config.id().toSetting());
|
s->setValue(clangDiagnosticConfigsArrayIdKey(), config.id().toSetting());
|
||||||
s->setValue(clangDiagnosticConfigsArrayDisplayNameKey(), config.displayName());
|
s->setValue(clangDiagnosticConfigsArrayDisplayNameKey(), config.displayName());
|
||||||
s->setValue(clangDiagnosticConfigsArrayWarningsKey(), config.commandLineWarnings());
|
s->setValue(clangDiagnosticConfigsArrayWarningsKey(), config.clangOptions());
|
||||||
|
s->setValue(clangDiagnosticConfigsArrayClangTidyChecksKey(), config.clangTidyChecks());
|
||||||
|
s->setValue(clangDiagnosticConfigsArrayClazyChecksKey(), config.clazyChecks());
|
||||||
}
|
}
|
||||||
s->endArray();
|
s->endArray();
|
||||||
|
|
||||||
@@ -138,11 +155,18 @@ void CppCodeModelSettings::toSettings(QSettings *s)
|
|||||||
s->setValue(interpretAmbiguousHeadersAsCHeadersKey(), interpretAmbigiousHeadersAsCHeaders());
|
s->setValue(interpretAmbiguousHeadersAsCHeadersKey(), interpretAmbigiousHeadersAsCHeaders());
|
||||||
s->setValue(skipIndexingBigFilesKey(), skipIndexingBigFiles());
|
s->setValue(skipIndexingBigFilesKey(), skipIndexingBigFiles());
|
||||||
s->setValue(indexerFileSizeLimitKey(), indexerFileSizeLimitInMb());
|
s->setValue(indexerFileSizeLimitKey(), indexerFileSizeLimitInMb());
|
||||||
s->setValue(tidyChecksKey(), tidyChecks());
|
|
||||||
s->setValue(clazyChecksKey(), clazyChecks());
|
|
||||||
|
|
||||||
s->endGroup();
|
s->endGroup();
|
||||||
|
|
||||||
|
QVector<Core::Id> invalidated
|
||||||
|
= ClangDiagnosticConfigsModel::changedOrRemovedConfigs(previousConfigs,
|
||||||
|
m_clangCustomDiagnosticConfigs);
|
||||||
|
|
||||||
|
if (previousConfigId != clangDiagnosticConfigId() && !invalidated.contains(previousConfigId))
|
||||||
|
invalidated.append(previousConfigId);
|
||||||
|
|
||||||
|
if (!invalidated.isEmpty())
|
||||||
|
emit clangDiagnosticConfigsInvalidated(invalidated);
|
||||||
emit changed();
|
emit changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,23 +236,3 @@ void CppCodeModelSettings::setIndexerFileSizeLimitInMb(int sizeInMB)
|
|||||||
{
|
{
|
||||||
m_indexerFileSizeLimitInMB = sizeInMB;
|
m_indexerFileSizeLimitInMB = sizeInMB;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CppCodeModelSettings::tidyChecks() const
|
|
||||||
{
|
|
||||||
return m_tidyChecks;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppCodeModelSettings::setTidyChecks(QString checks)
|
|
||||||
{
|
|
||||||
m_tidyChecks = checks;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CppCodeModelSettings::clazyChecks() const
|
|
||||||
{
|
|
||||||
return m_clazyChecks;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppCodeModelSettings::setClazyChecks(QString checks)
|
|
||||||
{
|
|
||||||
m_clazyChecks = checks;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -72,13 +72,8 @@ public:
|
|||||||
int indexerFileSizeLimitInMb() const;
|
int indexerFileSizeLimitInMb() const;
|
||||||
void setIndexerFileSizeLimitInMb(int sizeInMB);
|
void setIndexerFileSizeLimitInMb(int sizeInMB);
|
||||||
|
|
||||||
QString tidyChecks() const;
|
|
||||||
void setTidyChecks(QString checks);
|
|
||||||
|
|
||||||
QString clazyChecks() const;
|
|
||||||
void setClazyChecks(QString checks);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void clangDiagnosticConfigsInvalidated(const QVector<Core::Id> &configId);
|
||||||
void changed();
|
void changed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -88,9 +83,6 @@ private:
|
|||||||
int m_indexerFileSizeLimitInMB = 5;
|
int m_indexerFileSizeLimitInMB = 5;
|
||||||
ClangDiagnosticConfigs m_clangCustomDiagnosticConfigs;
|
ClangDiagnosticConfigs m_clangCustomDiagnosticConfigs;
|
||||||
Core::Id m_clangDiagnosticConfigId;
|
Core::Id m_clangDiagnosticConfigId;
|
||||||
|
|
||||||
QString m_tidyChecks;
|
|
||||||
QString m_clazyChecks;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace CppTools
|
} // namespace CppTools
|
||||||
|
|||||||
@@ -29,8 +29,6 @@
|
|||||||
#include "cppmodelmanager.h"
|
#include "cppmodelmanager.h"
|
||||||
#include "cpptoolsconstants.h"
|
#include "cpptoolsconstants.h"
|
||||||
#include "ui_cppcodemodelsettingspage.h"
|
#include "ui_cppcodemodelsettingspage.h"
|
||||||
#include "ui_clazychecks.h"
|
|
||||||
#include "ui_tidychecks.h"
|
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
@@ -86,79 +84,6 @@ void CppCodeModelSettingsWidget::setupClangCodeModelWidgets()
|
|||||||
diagnosticConfigsModel,
|
diagnosticConfigsModel,
|
||||||
m_settings->clangDiagnosticConfigId());
|
m_settings->clangDiagnosticConfigId());
|
||||||
m_ui->clangSettingsGroupBox->layout()->addWidget(m_clangDiagnosticConfigsWidget);
|
m_ui->clangSettingsGroupBox->layout()->addWidget(m_clangDiagnosticConfigsWidget);
|
||||||
|
|
||||||
m_ui->clangPlugins->setEnabled(isClangActive);
|
|
||||||
setupPluginsWidgets();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppCodeModelSettingsWidget::setupPluginsWidgets()
|
|
||||||
{
|
|
||||||
m_clazyChecks.reset(new CppTools::Ui::ClazyChecks);
|
|
||||||
m_clazyChecksWidget = new QWidget();
|
|
||||||
m_clazyChecks->setupUi(m_clazyChecksWidget);
|
|
||||||
|
|
||||||
m_tidyChecks.reset(new CppTools::Ui::TidyChecks);
|
|
||||||
m_tidyChecksWidget = new QWidget();
|
|
||||||
m_tidyChecks->setupUi(m_tidyChecksWidget);
|
|
||||||
|
|
||||||
m_ui->pluginChecks->addTab(m_tidyChecksWidget, tr("ClangTidy"));
|
|
||||||
m_ui->pluginChecks->addTab(m_clazyChecksWidget, tr("Clazy"));
|
|
||||||
m_ui->pluginChecks->setCurrentIndex(0);
|
|
||||||
|
|
||||||
setupTidyChecks();
|
|
||||||
setupClazyChecks();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppCodeModelSettingsWidget::setupTidyChecks()
|
|
||||||
{
|
|
||||||
m_currentTidyChecks = m_settings->tidyChecks();
|
|
||||||
for (int row = 0; row < m_tidyChecks->checksList->count(); ++row) {
|
|
||||||
QListWidgetItem *item = m_tidyChecks->checksList->item(row);
|
|
||||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
|
||||||
if (m_currentTidyChecks.indexOf(item->text()) != -1)
|
|
||||||
item->setCheckState(Qt::Checked);
|
|
||||||
else
|
|
||||||
item->setCheckState(Qt::Unchecked);
|
|
||||||
}
|
|
||||||
connect(m_tidyChecks->checksList, &QListWidget::itemChanged, [this](QListWidgetItem *item) {
|
|
||||||
const QString prefix = item->text();
|
|
||||||
item->checkState() == Qt::Checked
|
|
||||||
? m_currentTidyChecks.append(',' + prefix)
|
|
||||||
: m_currentTidyChecks.remove(',' + prefix);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppCodeModelSettingsWidget::setupClazyChecks()
|
|
||||||
{
|
|
||||||
// Levels descriptions are taken from https://github.com/KDE/clazy
|
|
||||||
static const std::array<QString, 5> levelDescriptions {{
|
|
||||||
QString(),
|
|
||||||
tr("Very stable checks, 99.99% safe, no false-positives."),
|
|
||||||
tr("Similar to level0, but sometimes (rarely) there might be\n"
|
|
||||||
"some false-positives."),
|
|
||||||
tr("Sometimes has false-positives (20-30%)."),
|
|
||||||
tr("Not always correct, possibly very noisy, might require\n"
|
|
||||||
"a knowledgeable developer to review, might have a very big\n"
|
|
||||||
"rate of false-positives, might have bugs.")
|
|
||||||
}};
|
|
||||||
|
|
||||||
m_currentClazyChecks = m_settings->clazyChecks();
|
|
||||||
if (!m_currentClazyChecks.isEmpty()) {
|
|
||||||
m_clazyChecks->clazyLevel->setCurrentText(m_currentClazyChecks);
|
|
||||||
const unsigned index = static_cast<unsigned>(m_clazyChecks->clazyLevel->currentIndex());
|
|
||||||
m_clazyChecks->levelDescription->setText(levelDescriptions[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(m_clazyChecks->clazyLevel,
|
|
||||||
static_cast<void (QComboBox::*)(int index)>(&QComboBox::currentIndexChanged),
|
|
||||||
[this](int index) {
|
|
||||||
m_clazyChecks->levelDescription->setText(levelDescriptions[static_cast<unsigned>(index)]);
|
|
||||||
if (index == 0) {
|
|
||||||
m_currentClazyChecks.clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_currentClazyChecks = m_clazyChecks->clazyLevel->itemText(index);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppCodeModelSettingsWidget::setupGeneralWidgets()
|
void CppCodeModelSettingsWidget::setupGeneralWidgets()
|
||||||
@@ -192,16 +117,6 @@ bool CppCodeModelSettingsWidget::applyClangCodeModelWidgetsToSettings() const
|
|||||||
settingsChanged = true;
|
settingsChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_settings->tidyChecks() != m_currentTidyChecks) {
|
|
||||||
m_settings->setTidyChecks(m_currentTidyChecks);
|
|
||||||
settingsChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_settings->clazyChecks() != m_currentClazyChecks) {
|
|
||||||
m_settings->setClazyChecks(m_currentClazyChecks);
|
|
||||||
settingsChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return settingsChanged;
|
return settingsChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,6 @@
|
|||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QComboBox)
|
QT_FORWARD_DECLARE_CLASS(QComboBox)
|
||||||
QT_FORWARD_DECLARE_CLASS(QSettings)
|
QT_FORWARD_DECLARE_CLASS(QSettings)
|
||||||
|
|
||||||
@@ -41,11 +39,6 @@ namespace CppTools {
|
|||||||
|
|
||||||
class ClangDiagnosticConfigsWidget;
|
class ClangDiagnosticConfigsWidget;
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class ClazyChecks;
|
|
||||||
class TidyChecks;
|
|
||||||
} // namespace Ui
|
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
namespace Ui { class CppCodeModelSettingsPage; }
|
namespace Ui { class CppCodeModelSettingsPage; }
|
||||||
@@ -64,9 +57,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
void setupGeneralWidgets();
|
void setupGeneralWidgets();
|
||||||
void setupClangCodeModelWidgets();
|
void setupClangCodeModelWidgets();
|
||||||
void setupPluginsWidgets();
|
|
||||||
void setupTidyChecks();
|
|
||||||
void setupClazyChecks();
|
|
||||||
|
|
||||||
bool applyGeneralWidgetsToSettings() const;
|
bool applyGeneralWidgetsToSettings() const;
|
||||||
bool applyClangCodeModelWidgetsToSettings() const;
|
bool applyClangCodeModelWidgetsToSettings() const;
|
||||||
@@ -75,14 +65,6 @@ private:
|
|||||||
Ui::CppCodeModelSettingsPage *m_ui = nullptr;
|
Ui::CppCodeModelSettingsPage *m_ui = nullptr;
|
||||||
QPointer<ClangDiagnosticConfigsWidget> m_clangDiagnosticConfigsWidget;
|
QPointer<ClangDiagnosticConfigsWidget> m_clangDiagnosticConfigsWidget;
|
||||||
QSharedPointer<CppCodeModelSettings> m_settings;
|
QSharedPointer<CppCodeModelSettings> m_settings;
|
||||||
|
|
||||||
std::unique_ptr<CppTools::Ui::ClazyChecks> m_clazyChecks;
|
|
||||||
QWidget *m_clazyChecksWidget = nullptr;
|
|
||||||
QString m_currentClazyChecks;
|
|
||||||
|
|
||||||
std::unique_ptr<CppTools::Ui::TidyChecks> m_tidyChecks;
|
|
||||||
QWidget *m_tidyChecksWidget = nullptr;
|
|
||||||
QString m_currentTidyChecks;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CppCodeModelSettingsPage: public Core::IOptionsPage
|
class CppCodeModelSettingsPage: public Core::IOptionsPage
|
||||||
|
|||||||
@@ -114,18 +114,6 @@
|
|||||||
<layout class="QVBoxLayout" name="verticalLayout_3"/>
|
<layout class="QVBoxLayout" name="verticalLayout_3"/>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="clangPlugins">
|
|
||||||
<property name="title">
|
|
||||||
<string>Clang Plugins</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QTabWidget" name="pluginChecks"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|||||||
@@ -56,8 +56,6 @@ const char CPPTOOLS_INTERPRET_AMBIGIUOUS_HEADERS_AS_C_HEADERS[]
|
|||||||
= "InterpretAmbiguousHeadersAsCHeaders";
|
= "InterpretAmbiguousHeadersAsCHeaders";
|
||||||
const char CPPTOOLS_SKIP_INDEXING_BIG_FILES[] = "SkipIndexingBigFiles";
|
const char CPPTOOLS_SKIP_INDEXING_BIG_FILES[] = "SkipIndexingBigFiles";
|
||||||
const char CPPTOOLS_INDEXER_FILE_SIZE_LIMIT[] = "IndexerFileSizeLimit";
|
const char CPPTOOLS_INDEXER_FILE_SIZE_LIMIT[] = "IndexerFileSizeLimit";
|
||||||
const char CPPTOOLS_TIDY_CHECKS[] = "TidyChecks";
|
|
||||||
const char CPPTOOLS_CLAZY_CHECKS[] = "ClazyChecks";
|
|
||||||
|
|
||||||
const char CPP_CLANG_BUILTIN_CONFIG_ID_EVERYTHING_WITH_EXCEPTIONS[]
|
const char CPP_CLANG_BUILTIN_CONFIG_ID_EVERYTHING_WITH_EXCEPTIONS[]
|
||||||
= "Builtin.EverythingWithExceptions";
|
= "Builtin.EverythingWithExceptions";
|
||||||
|
|||||||
@@ -530,7 +530,7 @@ DebuggerSettings::DebuggerSettings()
|
|||||||
insertItem(UseToolTipsInBreakpointsView, item);
|
insertItem(UseToolTipsInBreakpointsView, item);
|
||||||
|
|
||||||
item = new SavedAction(this);
|
item = new SavedAction(this);
|
||||||
item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTipsInBreakpointsView"));
|
item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTipsInStackView"));
|
||||||
item->setText(tr("Use Tooltips in Stack View when Debugging"));
|
item->setText(tr("Use Tooltips in Stack View when Debugging"));
|
||||||
item->setToolTip(tr("<p>Checking this will enable tooltips in the stack "
|
item->setToolTip(tr("<p>Checking this will enable tooltips in the stack "
|
||||||
"view during debugging."));
|
"view during debugging."));
|
||||||
|
|||||||
@@ -365,7 +365,13 @@ void DebuggerRunTool::setBreakOnMain(bool on)
|
|||||||
|
|
||||||
void DebuggerRunTool::setUseTerminal(bool on)
|
void DebuggerRunTool::setUseTerminal(bool on)
|
||||||
{
|
{
|
||||||
if (on && !d->terminalRunner && m_runParameters.cppEngineType == GdbEngineType) {
|
// CDB has a built-in console that might be preferred by some.
|
||||||
|
bool useCdbConsole = m_runParameters.cppEngineType == CdbEngineType
|
||||||
|
&& (m_runParameters.startMode == StartInternal
|
||||||
|
|| m_runParameters.startMode == StartExternal)
|
||||||
|
&& boolSetting(UseCdbConsole);
|
||||||
|
|
||||||
|
if (on && !d->terminalRunner && !useCdbConsole) {
|
||||||
d->terminalRunner = new TerminalRunner(this);
|
d->terminalRunner = new TerminalRunner(this);
|
||||||
addStartDependency(d->terminalRunner);
|
addStartDependency(d->terminalRunner);
|
||||||
}
|
}
|
||||||
@@ -891,15 +897,6 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit, bool allowTer
|
|||||||
m_engine = createPdbEngine();
|
m_engine = createPdbEngine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_runParameters.cppEngineType == CdbEngineType
|
|
||||||
&& !boolSetting(UseCdbConsole)
|
|
||||||
&& m_runParameters.inferior.runMode == ApplicationLauncher::Console
|
|
||||||
&& (m_runParameters.startMode == StartInternal
|
|
||||||
|| m_runParameters.startMode == StartExternal)) {
|
|
||||||
d->terminalRunner = new TerminalRunner(this);
|
|
||||||
addStartDependency(d->terminalRunner);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerEngine *DebuggerRunTool::activeEngine() const
|
DebuggerEngine *DebuggerRunTool::activeEngine() const
|
||||||
|
|||||||
@@ -292,7 +292,6 @@ void LldbEngine::setupEngine()
|
|||||||
.arg(bp.id().toString()).arg(bp.state()));
|
.arg(bp.id().toString()).arg(bp.state()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
notifyEngineSetupOk();
|
|
||||||
} else {
|
} else {
|
||||||
notifyEngineSetupFailed();
|
notifyEngineSetupFailed();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,16 +88,9 @@ bool ModelEditorPlugin::initialize(const QStringList &arguments, QString *errorS
|
|||||||
Q_UNUSED(errorString);
|
Q_UNUSED(errorString);
|
||||||
|
|
||||||
d->modelsManager = new ModelsManager(this);
|
d->modelsManager = new ModelsManager(this);
|
||||||
addAutoReleasedObject(d->modelsManager);
|
|
||||||
|
|
||||||
d->uiController = new UiController(this);
|
d->uiController = new UiController(this);
|
||||||
addAutoReleasedObject(d->uiController);
|
|
||||||
|
|
||||||
d->modelFactory = new ModelEditorFactory(d->uiController, this);
|
d->modelFactory = new ModelEditorFactory(d->uiController, this);
|
||||||
addAutoReleasedObject(d->modelFactory);
|
|
||||||
|
|
||||||
d->settingsController = new SettingsController(this);
|
d->settingsController = new SettingsController(this);
|
||||||
addAutoReleasedObject(d->settingsController);
|
|
||||||
|
|
||||||
Core::JsExpander::registerQObjectForJs(QLatin1String("Modeling"), new JsExtension(this));
|
Core::JsExpander::registerQObjectForJs(QLatin1String("Modeling"), new JsExtension(this));
|
||||||
|
|
||||||
|
|||||||
@@ -63,11 +63,9 @@ AndroidQmakeBuildConfiguration::AndroidQmakeBuildConfiguration(Target *target)
|
|||||||
: QmakeBuildConfiguration(target)
|
: QmakeBuildConfiguration(target)
|
||||||
{
|
{
|
||||||
updateCacheAndEmitEnvironmentChanged();
|
updateCacheAndEmitEnvironmentChanged();
|
||||||
|
connect(target->project(), &Project::parsingFinished, this, [this] {
|
||||||
auto updateGradle = [this] { AndroidManager::updateGradleProperties(BuildConfiguration::target()); };
|
AndroidManager::updateGradleProperties(BuildConfiguration::target());
|
||||||
|
});
|
||||||
connect(target->project(), &Project::parsingFinished, this, updateGradle);
|
|
||||||
connect(this, &AndroidQmakeBuildConfiguration::enabledChanged, this, updateGradle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidQmakeBuildConfiguration::initialize(const BuildInfo *info)
|
void AndroidQmakeBuildConfiguration::initialize(const BuildInfo *info)
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ QWidget *ChangeStyleWidgetAction::createWidget(QWidget *parent)
|
|||||||
QComboBox *comboBox = new QComboBox(parent);
|
QComboBox *comboBox = new QComboBox(parent);
|
||||||
comboBox->setToolTip(tr(enabledTooltip));
|
comboBox->setToolTip(tr(enabledTooltip));
|
||||||
comboBox->addItem("Default");
|
comboBox->addItem("Default");
|
||||||
|
comboBox->addItem("Fusion");
|
||||||
|
comboBox->addItem("Imagine");
|
||||||
comboBox->addItem("Material");
|
comboBox->addItem("Material");
|
||||||
comboBox->addItem("Universal");
|
comboBox->addItem("Universal");
|
||||||
comboBox->setEditable(true);
|
comboBox->setEditable(true);
|
||||||
|
|||||||
@@ -164,6 +164,8 @@ const int priorityGoIntoComponent = 40;
|
|||||||
const int priorityGenericToolBar = 50;
|
const int priorityGenericToolBar = 50;
|
||||||
const int priorityLast = 60;
|
const int priorityLast = 60;
|
||||||
|
|
||||||
|
const char addImagesDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Image Files");
|
||||||
|
|
||||||
} //ComponentCoreConstants
|
} //ComponentCoreConstants
|
||||||
|
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
|||||||
@@ -178,6 +178,16 @@ void DesignerActionManager::setupContext()
|
|||||||
m_designerActionManagerView->setupContext();
|
m_designerActionManagerView->setupContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<AddResourceHandler> DesignerActionManager::addResourceHandler() const
|
||||||
|
{
|
||||||
|
return m_addResourceHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesignerActionManager::registerAddResourceHandler(const AddResourceHandler &handler)
|
||||||
|
{
|
||||||
|
m_addResourceHandler.append(handler);
|
||||||
|
}
|
||||||
|
|
||||||
class VisiblityModelNodeAction : public ModelNodeContextMenuAction
|
class VisiblityModelNodeAction : public ModelNodeContextMenuAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -359,7 +369,7 @@ bool selectionHasSameParentAndInBaseState(const SelectionContext &context)
|
|||||||
bool isNotInLayout(const SelectionContext &context)
|
bool isNotInLayout(const SelectionContext &context)
|
||||||
{
|
{
|
||||||
if (selectionNotEmpty(context)) {
|
if (selectionNotEmpty(context)) {
|
||||||
const ModelNode &selectedModelNode = context.selectedModelNodes().constFirst();
|
const ModelNode selectedModelNode = context.selectedModelNodes().constFirst();
|
||||||
ModelNode parentModelNode;
|
ModelNode parentModelNode;
|
||||||
|
|
||||||
if (selectedModelNode.hasParentProperty())
|
if (selectedModelNode.hasParentProperty())
|
||||||
@@ -983,6 +993,22 @@ void DesignerActionManager::createDefaultDesignerActions()
|
|||||||
addDesignerAction(new ChangeStyleAction());
|
addDesignerAction(new ChangeStyleAction());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DesignerActionManager::createDefaultAddResourceHandler()
|
||||||
|
{
|
||||||
|
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addImagesDisplayString,
|
||||||
|
"*.png",
|
||||||
|
ModelNodeOperations::addImageToProject));
|
||||||
|
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addImagesDisplayString,
|
||||||
|
"*.jpg",
|
||||||
|
ModelNodeOperations::addImageToProject));
|
||||||
|
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addImagesDisplayString,
|
||||||
|
"*.bmp",
|
||||||
|
ModelNodeOperations::addImageToProject));
|
||||||
|
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addImagesDisplayString,
|
||||||
|
"*.svg",
|
||||||
|
ModelNodeOperations::addImageToProject));
|
||||||
|
}
|
||||||
|
|
||||||
void DesignerActionManager::addDesignerAction(ActionInterface *newAction)
|
void DesignerActionManager::addDesignerAction(ActionInterface *newAction)
|
||||||
{
|
{
|
||||||
m_designerActions.append(QSharedPointer<ActionInterface>(newAction));
|
m_designerActions.append(QSharedPointer<ActionInterface>(newAction));
|
||||||
|
|||||||
@@ -42,6 +42,25 @@ namespace QmlDesigner {
|
|||||||
|
|
||||||
class DesignerActionManagerView;
|
class DesignerActionManagerView;
|
||||||
|
|
||||||
|
typedef std::function<bool (const QString &filename, const QString &targetDirectory)> AddResourceOperation;
|
||||||
|
|
||||||
|
struct AddResourceHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AddResourceHandler( const QString &_category,
|
||||||
|
const QString &_filter,
|
||||||
|
AddResourceOperation _operation)
|
||||||
|
: category(_category)
|
||||||
|
,filter(_filter)
|
||||||
|
,operation(_operation)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString category;
|
||||||
|
QString filter;
|
||||||
|
AddResourceOperation operation;
|
||||||
|
};
|
||||||
|
|
||||||
class DesignerActionToolBar : public Utils::StyledBar
|
class DesignerActionToolBar : public Utils::StyledBar
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -64,6 +83,7 @@ public:
|
|||||||
QList<ActionInterface* > designerActions() const;
|
QList<ActionInterface* > designerActions() const;
|
||||||
|
|
||||||
void createDefaultDesignerActions();
|
void createDefaultDesignerActions();
|
||||||
|
void createDefaultAddResourceHandler();
|
||||||
DesignerActionManagerView *view();
|
DesignerActionManagerView *view();
|
||||||
|
|
||||||
DesignerActionToolBar *createToolBar(QWidget *parent = 0) const;
|
DesignerActionToolBar *createToolBar(QWidget *parent = 0) const;
|
||||||
@@ -76,9 +96,13 @@ public:
|
|||||||
DesignerActionManager(const DesignerActionManager&) = delete;
|
DesignerActionManager(const DesignerActionManager&) = delete;
|
||||||
DesignerActionManager & operator=(const DesignerActionManager&) = delete;
|
DesignerActionManager & operator=(const DesignerActionManager&) = delete;
|
||||||
|
|
||||||
|
QList<AddResourceHandler> addResourceHandler() const;
|
||||||
|
void registerAddResourceHandler(const AddResourceHandler &handler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<QSharedPointer<ActionInterface> > m_designerActions;
|
QList<QSharedPointer<ActionInterface> > m_designerActions;
|
||||||
DesignerActionManagerView *m_designerActionManagerView;
|
DesignerActionManagerView *m_designerActionManagerView;
|
||||||
|
QList<AddResourceHandler> m_addResourceHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ void DesignerActionManagerView::modelAboutToBeDetached(Model *model)
|
|||||||
|
|
||||||
void DesignerActionManagerView::nodeCreated(const ModelNode &)
|
void DesignerActionManagerView::nodeCreated(const ModelNode &)
|
||||||
{
|
{
|
||||||
setupContext();
|
setupContext(SelectionContext::UpdateMode::Fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManagerView::nodeRemoved(const ModelNode &, const NodeAbstractProperty &, AbstractView::PropertyChangeFlags)
|
void DesignerActionManagerView::nodeRemoved(const ModelNode &, const NodeAbstractProperty &, AbstractView::PropertyChangeFlags)
|
||||||
@@ -63,17 +63,17 @@ void DesignerActionManagerView::nodeRemoved(const ModelNode &, const NodeAbstrac
|
|||||||
|
|
||||||
void DesignerActionManagerView::nodeAboutToBeReparented(const ModelNode &, const NodeAbstractProperty &, const NodeAbstractProperty &, AbstractView::PropertyChangeFlags)
|
void DesignerActionManagerView::nodeAboutToBeReparented(const ModelNode &, const NodeAbstractProperty &, const NodeAbstractProperty &, AbstractView::PropertyChangeFlags)
|
||||||
{
|
{
|
||||||
setupContext();
|
setupContext(SelectionContext::UpdateMode::Fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManagerView::nodeReparented(const ModelNode &, const NodeAbstractProperty &, const NodeAbstractProperty &, AbstractView::PropertyChangeFlags)
|
void DesignerActionManagerView::nodeReparented(const ModelNode &, const NodeAbstractProperty &, const NodeAbstractProperty &, AbstractView::PropertyChangeFlags)
|
||||||
{
|
{
|
||||||
setupContext();
|
setupContext(SelectionContext::UpdateMode::Fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManagerView::propertiesRemoved(const QList<AbstractProperty> &)
|
void DesignerActionManagerView::propertiesRemoved(const QList<AbstractProperty> &)
|
||||||
{
|
{
|
||||||
setupContext();
|
setupContext(SelectionContext::UpdateMode::Fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManagerView::rootNodeTypeChanged(const QString &, int, int)
|
void DesignerActionManagerView::rootNodeTypeChanged(const QString &, int, int)
|
||||||
@@ -96,7 +96,7 @@ void DesignerActionManagerView::rewriterEndTransaction()
|
|||||||
|
|
||||||
void DesignerActionManagerView::currentStateChanged(const ModelNode &)
|
void DesignerActionManagerView::currentStateChanged(const ModelNode &)
|
||||||
{
|
{
|
||||||
setupContext();
|
setupContext(SelectionContext::UpdateMode::Fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManagerView::selectedNodesChanged(const QList<ModelNode> &selectedNodes, const QList<ModelNode> &)
|
void DesignerActionManagerView::selectedNodesChanged(const QList<ModelNode> &selectedNodes, const QList<ModelNode> &)
|
||||||
@@ -112,7 +112,7 @@ void DesignerActionManagerView::selectedNodesChanged(const QList<ModelNode> &sel
|
|||||||
|
|
||||||
void DesignerActionManagerView::nodeOrderChanged(const NodeListProperty &, const ModelNode &, int)
|
void DesignerActionManagerView::nodeOrderChanged(const NodeListProperty &, const ModelNode &, int)
|
||||||
{
|
{
|
||||||
setupContext();
|
setupContext(SelectionContext::UpdateMode::Fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManagerView::importsChanged(const QList<Import> &, const QList<Import> &)
|
void DesignerActionManagerView::importsChanged(const QList<Import> &, const QList<Import> &)
|
||||||
@@ -127,21 +127,21 @@ void DesignerActionManagerView::setDesignerActionList(const QList<ActionInterfac
|
|||||||
|
|
||||||
void DesignerActionManagerView::signalHandlerPropertiesChanged(const QVector<SignalHandlerProperty> &, AbstractView::PropertyChangeFlags)
|
void DesignerActionManagerView::signalHandlerPropertiesChanged(const QVector<SignalHandlerProperty> &, AbstractView::PropertyChangeFlags)
|
||||||
{
|
{
|
||||||
setupContext();
|
setupContext(SelectionContext::UpdateMode::Fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManagerView::variantPropertiesChanged(const QList<VariantProperty> &, AbstractView::PropertyChangeFlags propertyChangeFlag)
|
void DesignerActionManagerView::variantPropertiesChanged(const QList<VariantProperty> &, AbstractView::PropertyChangeFlags propertyChangeFlag)
|
||||||
{
|
{
|
||||||
if (propertyChangeFlag == AbstractView::PropertiesAdded)
|
if (propertyChangeFlag == AbstractView::PropertiesAdded)
|
||||||
setupContext();
|
setupContext(SelectionContext::UpdateMode::Fast);
|
||||||
else if (hasSingleSelectedModelNode())
|
else if (hasSingleSelectedModelNode())
|
||||||
setupContext();
|
setupContext(SelectionContext::UpdateMode::Fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManagerView::bindingPropertiesChanged(const QList<BindingProperty> &, AbstractView::PropertyChangeFlags propertyChangeFlag)
|
void DesignerActionManagerView::bindingPropertiesChanged(const QList<BindingProperty> &, AbstractView::PropertyChangeFlags propertyChangeFlag)
|
||||||
{
|
{
|
||||||
if (propertyChangeFlag == AbstractView::PropertiesAdded)
|
if (propertyChangeFlag == AbstractView::PropertiesAdded)
|
||||||
setupContext();
|
setupContext(SelectionContext::UpdateMode::Fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManagerView::instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &)
|
void DesignerActionManagerView::instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &)
|
||||||
|
|||||||
@@ -56,6 +56,10 @@
|
|||||||
|
|
||||||
#include <qmljseditor/qmljsfindreferences.h>
|
#include <qmljseditor/qmljsfindreferences.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/project.h>
|
||||||
|
#include <projectexplorer/projectnodes.h>
|
||||||
|
#include <projectexplorer/projecttree.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
@@ -1020,6 +1024,27 @@ void addTabBarToStackedContainer(const SelectionContext &selectionContext)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool addImageToProject(const QString &fileName, const QString &directory)
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Mode
|
} // namespace Mode
|
||||||
|
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ void addItemToStackedContainer(const SelectionContext &selectionContext);
|
|||||||
void increaseIndexOfStackedContainer(const SelectionContext &selectionContext);
|
void increaseIndexOfStackedContainer(const SelectionContext &selectionContext);
|
||||||
void decreaseIndexOfStackedContainer(const SelectionContext &selectionContext);
|
void decreaseIndexOfStackedContainer(const SelectionContext &selectionContext);
|
||||||
void addTabBarToStackedContainer(const SelectionContext &selectionContext);
|
void addTabBarToStackedContainer(const SelectionContext &selectionContext);
|
||||||
|
bool addImageToProject(const QString &fileName, const QString &directory);
|
||||||
|
|
||||||
} // namespace ModelNodeOperationso
|
} // namespace ModelNodeOperationso
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
|||||||
@@ -397,7 +397,7 @@ void FormEditorView::changeToCustomTool()
|
|||||||
int handlingRank = 0;
|
int handlingRank = 0;
|
||||||
AbstractCustomTool *selectedCustomTool = 0;
|
AbstractCustomTool *selectedCustomTool = 0;
|
||||||
|
|
||||||
const ModelNode &selectedModelNode = selectedModelNodes().constFirst();
|
const ModelNode selectedModelNode = selectedModelNodes().constFirst();
|
||||||
|
|
||||||
foreach (AbstractCustomTool *customTool, m_customToolList) {
|
foreach (AbstractCustomTool *customTool, m_customToolList) {
|
||||||
if (customTool->wantHandleItem(selectedModelNode) > handlingRank) {
|
if (customTool->wantHandleItem(selectedModelNode) > handlingRank) {
|
||||||
|
|||||||
@@ -45,9 +45,11 @@
|
|||||||
|
|
||||||
#include <coreplugin/coreconstants.h>
|
#include <coreplugin/coreconstants.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
#include <coreplugin/messagebox.h>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDrag>
|
#include <QDrag>
|
||||||
|
#include <QFileDialog>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QFileSystemModel>
|
#include <QFileSystemModel>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
@@ -76,6 +78,7 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
|||||||
m_itemViewQuickWidget(new QQuickWidget),
|
m_itemViewQuickWidget(new QQuickWidget),
|
||||||
m_resourcesView(new ItemLibraryResourceView(this)),
|
m_resourcesView(new ItemLibraryResourceView(this)),
|
||||||
m_importTagsWidget(new QWidget(this)),
|
m_importTagsWidget(new QWidget(this)),
|
||||||
|
m_addResourcesWidget(new QWidget(this)),
|
||||||
m_filterFlag(QtBasic)
|
m_filterFlag(QtBasic)
|
||||||
{
|
{
|
||||||
m_compressionTimer.setInterval(200);
|
m_compressionTimer.setInterval(200);
|
||||||
@@ -148,7 +151,8 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
|||||||
layout->addWidget(spacer, 1, 0);
|
layout->addWidget(spacer, 1, 0);
|
||||||
layout->addWidget(lineEditFrame, 2, 0, 1, 1);
|
layout->addWidget(lineEditFrame, 2, 0, 1, 1);
|
||||||
layout->addWidget(m_importTagsWidget.data(), 3, 0, 1, 1);
|
layout->addWidget(m_importTagsWidget.data(), 3, 0, 1, 1);
|
||||||
layout->addWidget(m_stackedWidget.data(), 4, 0, 1, 1);
|
layout->addWidget(m_addResourcesWidget.data(), 4, 0, 1, 1);
|
||||||
|
layout->addWidget(m_stackedWidget.data(), 5, 0, 1, 1);
|
||||||
|
|
||||||
setSearchFilter(QString());
|
setSearchFilter(QString());
|
||||||
|
|
||||||
@@ -164,6 +168,20 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
|||||||
auto *flowLayout = new Utils::FlowLayout(m_importTagsWidget.data());
|
auto *flowLayout = new Utils::FlowLayout(m_importTagsWidget.data());
|
||||||
flowLayout->setMargin(4);
|
flowLayout->setMargin(4);
|
||||||
|
|
||||||
|
m_addResourcesWidget->setVisible(false);
|
||||||
|
flowLayout = new Utils::FlowLayout(m_addResourcesWidget.data());
|
||||||
|
flowLayout->setMargin(4);
|
||||||
|
auto button = new QToolButton(m_addResourcesWidget.data());
|
||||||
|
auto font = button->font();
|
||||||
|
font.setPixelSize(9);
|
||||||
|
button->setFont(font);
|
||||||
|
button->setIcon(Utils::Icons::PLUS.icon());
|
||||||
|
button->setText(tr("Add New Resources..."));
|
||||||
|
button->setToolTip(tr("Add new resources to project."));
|
||||||
|
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||||
|
flowLayout->addWidget(button);
|
||||||
|
connect(button, &QToolButton::clicked, this, &ItemLibraryWidget::addResources);
|
||||||
|
|
||||||
// init the first load of the QML UI elements
|
// init the first load of the QML UI elements
|
||||||
reloadQmlSource();
|
reloadQmlSource();
|
||||||
}
|
}
|
||||||
@@ -232,12 +250,15 @@ void ItemLibraryWidget::setCurrentIndexOfStackedWidget(int index)
|
|||||||
if (index == 2) {
|
if (index == 2) {
|
||||||
m_filterLineEdit->setVisible(false);
|
m_filterLineEdit->setVisible(false);
|
||||||
m_importTagsWidget->setVisible(true);
|
m_importTagsWidget->setVisible(true);
|
||||||
|
m_addResourcesWidget->setVisible(false);
|
||||||
} if (index == 1) {
|
} if (index == 1) {
|
||||||
m_filterLineEdit->setVisible(true);
|
m_filterLineEdit->setVisible(true);
|
||||||
m_importTagsWidget->setVisible(false);
|
m_importTagsWidget->setVisible(false);
|
||||||
|
m_addResourcesWidget->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
m_filterLineEdit->setVisible(true);
|
m_filterLineEdit->setVisible(true);
|
||||||
m_importTagsWidget->setVisible(true);
|
m_importTagsWidget->setVisible(true);
|
||||||
|
m_addResourcesWidget->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stackedWidget->setCurrentIndex(index);
|
m_stackedWidget->setCurrentIndex(index);
|
||||||
@@ -279,6 +300,7 @@ void ItemLibraryWidget::setupImportTagWidget()
|
|||||||
button->setIcon(Utils::Icons::PLUS.icon());
|
button->setIcon(Utils::Icons::PLUS.icon());
|
||||||
button->setText(import);
|
button->setText(import);
|
||||||
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||||
|
button->setToolTip(tr("Add import %1").arg(import));
|
||||||
connect(button, &QToolButton::clicked, this, [this, import]() {
|
connect(button, &QToolButton::clicked, this, [this, import]() {
|
||||||
addPossibleImport(import);
|
addPossibleImport(import);
|
||||||
});
|
});
|
||||||
@@ -366,4 +388,47 @@ void ItemLibraryWidget::addPossibleImport(const QString &name)
|
|||||||
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
|
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemLibraryWidget::addResources()
|
||||||
|
{
|
||||||
|
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||||
|
|
||||||
|
QTC_ASSERT(document, return);
|
||||||
|
|
||||||
|
QList<AddResourceHandler> handlers = QmlDesignerPlugin::instance()->viewManager().designerActionManager().addResourceHandler();
|
||||||
|
QMultiMap<QString, QString> map;
|
||||||
|
for (const AddResourceHandler &handler : handlers) {
|
||||||
|
map.insert(handler.category, handler.filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList filters;
|
||||||
|
|
||||||
|
for (const QString &key : map.uniqueKeys()) {
|
||||||
|
QString str = key + " (";
|
||||||
|
str.append(map.values(key).join(" "));
|
||||||
|
str.append(")");
|
||||||
|
filters.append(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto fileNames = QFileDialog::getOpenFileNames(this,
|
||||||
|
tr("Add Resources"),
|
||||||
|
document->fileName().parentDir().toString(),
|
||||||
|
filters.join(";;"));
|
||||||
|
|
||||||
|
if (!fileNames.isEmpty()) {
|
||||||
|
const auto directory = QFileDialog::getExistingDirectory(this,
|
||||||
|
tr("Target Direcotry"),
|
||||||
|
document->fileName().parentDir().toString());
|
||||||
|
|
||||||
|
for (const QString &fileName : fileNames) {
|
||||||
|
for (const AddResourceHandler &handler : handlers) {
|
||||||
|
QString postfix = handler.filter;
|
||||||
|
postfix.remove(0, 1);
|
||||||
|
if (fileName.endsWith(postfix))
|
||||||
|
if (!handler.operation(fileName, directory))
|
||||||
|
Core::AsynchronousMessageBox::warning(tr("Failed to add File"), tr("Could not add %1 to project.").arg(fileName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ private:
|
|||||||
void removeImport(const QString &name);
|
void removeImport(const QString &name);
|
||||||
void addImport(const QString &name, const QString &version);
|
void addImport(const QString &name, const QString &version);
|
||||||
void addPossibleImport(const QString &name);
|
void addPossibleImport(const QString &name);
|
||||||
|
void addResources();
|
||||||
|
|
||||||
QTimer m_compressionTimer;
|
QTimer m_compressionTimer;
|
||||||
QSize m_itemIconSize;
|
QSize m_itemIconSize;
|
||||||
@@ -111,6 +112,7 @@ private:
|
|||||||
QScopedPointer<QQuickWidget> m_itemViewQuickWidget;
|
QScopedPointer<QQuickWidget> m_itemViewQuickWidget;
|
||||||
QScopedPointer<ItemLibraryResourceView> m_resourcesView;
|
QScopedPointer<ItemLibraryResourceView> m_resourcesView;
|
||||||
QScopedPointer<QWidget> m_importTagsWidget;
|
QScopedPointer<QWidget> m_importTagsWidget;
|
||||||
|
QScopedPointer<QWidget> m_addResourcesWidget;
|
||||||
|
|
||||||
QShortcut *m_qmlSourceUpdateShortcut;
|
QShortcut *m_qmlSourceUpdateShortcut;
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "navigatorview.h"
|
#include "navigatorview.h"
|
||||||
|
|
||||||
#include <bindingproperty.h>
|
#include <bindingproperty.h>
|
||||||
|
#include <designersettings.h>
|
||||||
#include <nodeabstractproperty.h>
|
#include <nodeabstractproperty.h>
|
||||||
#include <nodehints.h>
|
#include <nodehints.h>
|
||||||
#include <nodelistproperty.h>
|
#include <nodelistproperty.h>
|
||||||
@@ -207,7 +208,8 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
|
|||||||
} else if (role == Qt::ToolTipRole) {
|
} else if (role == Qt::ToolTipRole) {
|
||||||
if (currentQmlObjectNode.hasError()) {
|
if (currentQmlObjectNode.hasError()) {
|
||||||
QString errorString = currentQmlObjectNode.error();
|
QString errorString = currentQmlObjectNode.error();
|
||||||
if (currentQmlObjectNode.isRootNode())
|
if (DesignerSettings::getValue(DesignerSettingsKey::STANDALONE_MODE).toBool() &&
|
||||||
|
currentQmlObjectNode.isRootNode())
|
||||||
errorString.append(QString("\n%1").arg(tr("Changing the setting \"%1\" might solve the issue.").arg(
|
errorString.append(QString("\n%1").arg(tr("Changing the setting \"%1\" might solve the issue.").arg(
|
||||||
tr("Use QML emulation layer that is built with the selected Qt"))));
|
tr("Use QML emulation layer that is built with the selected Qt"))));
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ void PropertyEditorContextObject::toogleExportAlias()
|
|||||||
if (rewriterView->selectedModelNodes().isEmpty())
|
if (rewriterView->selectedModelNodes().isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ModelNode &selectedNode = rewriterView->selectedModelNodes().constFirst();
|
const ModelNode selectedNode = rewriterView->selectedModelNodes().constFirst();
|
||||||
|
|
||||||
if (QmlObjectNode::isValidQmlObjectNode(selectedNode)) {
|
if (QmlObjectNode::isValidQmlObjectNode(selectedNode)) {
|
||||||
QmlObjectNode objectNode(selectedNode);
|
QmlObjectNode objectNode(selectedNode);
|
||||||
@@ -208,6 +208,25 @@ void PropertyEditorContextObject::changeTypeName(const QString &typeName)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PropertyEditorContextObject::insertKeyframe(const QString &propertyName)
|
||||||
|
{
|
||||||
|
if (!m_model || !m_model->rewriterView())
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Ideally we should not missuse the rewriterView
|
||||||
|
* If we add more code here we have to forward the property editor view */
|
||||||
|
RewriterView *rewriterView = m_model->rewriterView();
|
||||||
|
|
||||||
|
if (rewriterView->selectedModelNodes().isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ModelNode selectedNode = rewriterView->selectedModelNodes().constFirst();
|
||||||
|
|
||||||
|
rewriterView->emitCustomNotification("INSERT_KEYFRAME",
|
||||||
|
{ selectedNode },
|
||||||
|
{ propertyName });
|
||||||
|
}
|
||||||
|
|
||||||
int PropertyEditorContextObject::majorVersion() const
|
int PropertyEditorContextObject::majorVersion() const
|
||||||
{
|
{
|
||||||
return m_majorVersion;
|
return m_majorVersion;
|
||||||
@@ -270,6 +289,20 @@ void PropertyEditorContextObject::setMinorVersion(int minorVersion)
|
|||||||
emit minorVersionChanged();
|
emit minorVersionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PropertyEditorContextObject::hasActiveTimeline() const
|
||||||
|
{
|
||||||
|
return m_setHasActiveTimeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropertyEditorContextObject::setHasActiveTimeline(bool b)
|
||||||
|
{
|
||||||
|
if (b == m_setHasActiveTimeline)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_setHasActiveTimeline = b;
|
||||||
|
emit hasActiveTimelineChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void PropertyEditorContextObject::insertInQmlContext(QQmlContext *context)
|
void PropertyEditorContextObject::insertInQmlContext(QQmlContext *context)
|
||||||
{
|
{
|
||||||
m_qmlContext = context;
|
m_qmlContext = context;
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ class PropertyEditorContextObject : public QObject
|
|||||||
|
|
||||||
Q_PROPERTY(bool hasAliasExport READ hasAliasExport NOTIFY hasAliasExportChanged)
|
Q_PROPERTY(bool hasAliasExport READ hasAliasExport NOTIFY hasAliasExportChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool hasActiveTimeline READ hasActiveTimeline NOTIFY hasActiveTimelineChanged)
|
||||||
|
|
||||||
Q_PROPERTY(QQmlPropertyMap* backendValues READ backendValues WRITE setBackendValues NOTIFY backendValuesChanged)
|
Q_PROPERTY(QQmlPropertyMap* backendValues READ backendValues WRITE setBackendValues NOTIFY backendValuesChanged)
|
||||||
|
|
||||||
Q_PROPERTY(QQmlComponent* specificQmlComponent READ specificQmlComponent NOTIFY specificQmlComponentChanged)
|
Q_PROPERTY(QQmlComponent* specificQmlComponent READ specificQmlComponent NOTIFY specificQmlComponentChanged)
|
||||||
@@ -81,6 +83,7 @@ public:
|
|||||||
Q_INVOKABLE void toogleExportAlias();
|
Q_INVOKABLE void toogleExportAlias();
|
||||||
|
|
||||||
Q_INVOKABLE void changeTypeName(const QString &typeName);
|
Q_INVOKABLE void changeTypeName(const QString &typeName);
|
||||||
|
Q_INVOKABLE void insertKeyframe(const QString &propertyName);
|
||||||
|
|
||||||
int majorVersion() const;
|
int majorVersion() const;
|
||||||
int majorQtQuickVersion() const;
|
int majorQtQuickVersion() const;
|
||||||
@@ -91,6 +94,9 @@ public:
|
|||||||
int minorVersion() const;
|
int minorVersion() const;
|
||||||
void setMinorVersion(int minorVersion);
|
void setMinorVersion(int minorVersion);
|
||||||
|
|
||||||
|
bool hasActiveTimeline() const;
|
||||||
|
void setHasActiveTimeline(bool b);
|
||||||
|
|
||||||
void insertInQmlContext(QQmlContext *context);
|
void insertInQmlContext(QQmlContext *context);
|
||||||
QQmlComponent *specificQmlComponent();
|
QQmlComponent *specificQmlComponent();
|
||||||
|
|
||||||
@@ -110,6 +116,7 @@ signals:
|
|||||||
void minorQtQuickVersionChanged();
|
void minorQtQuickVersionChanged();
|
||||||
void specificQmlComponentChanged();
|
void specificQmlComponentChanged();
|
||||||
void hasAliasExportChanged();
|
void hasAliasExportChanged();
|
||||||
|
void hasActiveTimelineChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setGlobalBaseUrl(const QUrl &newBaseUrl);
|
void setGlobalBaseUrl(const QUrl &newBaseUrl);
|
||||||
@@ -153,6 +160,8 @@ private:
|
|||||||
Model *m_model = nullptr;
|
Model *m_model = nullptr;
|
||||||
|
|
||||||
bool m_aliasExport = false;
|
bool m_aliasExport = false;
|
||||||
|
|
||||||
|
bool m_setHasActiveTimeline = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //QmlDesigner {
|
} //QmlDesigner {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "propertyeditortransaction.h"
|
#include "propertyeditortransaction.h"
|
||||||
#include <qmldesignerconstants.h>
|
#include <qmldesignerconstants.h>
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
|
#include <qmltimelinemutator.h>
|
||||||
|
|
||||||
#include <qmlobjectnode.h>
|
#include <qmlobjectnode.h>
|
||||||
#include <nodemetainfo.h>
|
#include <nodemetainfo.h>
|
||||||
@@ -328,6 +329,9 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
|
|||||||
contextObject()->setIsBaseState(qmlObjectNode.isInBaseState());
|
contextObject()->setIsBaseState(qmlObjectNode.isInBaseState());
|
||||||
|
|
||||||
contextObject()->setHasAliasExport(qmlObjectNode.isAliasExported());
|
contextObject()->setHasAliasExport(qmlObjectNode.isAliasExported());
|
||||||
|
|
||||||
|
contextObject()->setHasActiveTimeline(QmlTimelineMutator::hasActiveTimeline(qmlObjectNode.view()));
|
||||||
|
|
||||||
contextObject()->setSelectionChanged(false);
|
contextObject()->setSelectionChanged(false);
|
||||||
|
|
||||||
contextObject()->setSelectionChanged(false);
|
contextObject()->setSelectionChanged(false);
|
||||||
|
|||||||