forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.9'
Conflicts: qbs/modules/qtc/qtc.qbs qtcreator.pri src/plugins/debugger/debuggerkitinformation.cpp src/plugins/languageclient/languageclientmanager.cpp src/plugins/plugins.pro src/plugins/projectexplorer/kit.cpp src/plugins/projectexplorer/kitmanager.cpp Change-Id: I66fb941202991f35f7d7761430b21e42dfc678a8
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
# Use ../../tests/manual/clang-format-for-qtc/test.cpp for documenting problems
|
||||
# or testing changes.
|
||||
#
|
||||
# In case you update this configuration please also update the qtcStyle() in src\plugins\clangformat\clangformatutils.cpp
|
||||
#
|
||||
# [1] https://doc-snapshots.qt.io/qtcreator-extending/coding-style.html
|
||||
# [2] https://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
#
|
||||
|
17
README.md
17
README.md
@@ -34,9 +34,10 @@ Prerequisites:
|
||||
* Python 3.5 or later (optional, needed for the python enabled debug helper)
|
||||
* On Mac OS X: latest Xcode
|
||||
* On Linux: g++ 5.3 or later
|
||||
* LLVM/Clang 6.0.0 or later (optional, needed for the Clang Code Model, see the
|
||||
section "Get LLVM/Clang for the Clang Code Model")
|
||||
* CMake (only for manual builds of LLVM/Clang)
|
||||
* LLVM/Clang 7.0.0 or later (optional, needed for the Clang Code Model, Clang Tools, ClangFormat,
|
||||
Clang PCH Manager and Clang Refactoring plugins, see the section
|
||||
"Get LLVM/Clang for the Clang Code Model")
|
||||
* CMake (only for manual builds of LLVM/Clang)
|
||||
* Qbs 1.7.x (optional, sources also contain Qbs itself)
|
||||
|
||||
The installed toolchains have to match the one Qt was compiled with.
|
||||
@@ -49,6 +50,10 @@ You can build Qt Creator with
|
||||
export QBS_INSTALL_DIR=/path/to/qbs
|
||||
# Optional, needed for the Python enabled dumper on Windows
|
||||
set PYTHON_INSTALL_DIR=C:\path\to\python
|
||||
# Optional, needed to use system KSyntaxHighlighting:
|
||||
set KSYNTAXHIGHLIGHTING_LIB_DIR to folder holding the KSyntaxHighlighting library
|
||||
# if automatic deducing of include folder fails set KSYNTAXHIGHLIGHTING_INCLUDE_DIR as well
|
||||
# both variables can also be passed as qmake variables
|
||||
|
||||
cd $SOURCE_DIRECTORY
|
||||
qmake -r
|
||||
@@ -220,7 +225,7 @@ or using shadow builds.
|
||||
## Get LLVM/Clang for the Clang Code Model
|
||||
|
||||
The Clang Code Model depends on the LLVM/Clang libraries. The currently
|
||||
supported LLVM/Clang version is 6.0.
|
||||
supported LLVM/Clang version is 7.0.
|
||||
|
||||
### Prebuilt LLVM/Clang packages
|
||||
|
||||
@@ -247,9 +252,9 @@ GCC 4 binaries. On Ubuntu, you can download the package from
|
||||
http://apt.llvm.org/ with:
|
||||
|
||||
wget -O - http://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||
sudo apt-add-repository "deb http://apt.llvm.org/`lsb_release -cs`/ llvm-toolchain-`lsb_release -cs`-6.0 main"
|
||||
sudo apt-add-repository "deb http://apt.llvm.org/`lsb_release -cs`/ llvm-toolchain-`lsb_release -cs`-7.0 main"
|
||||
sudo apt-get update
|
||||
sudo apt-get install llvm-6.0 libclang-6.0-dev
|
||||
sudo apt-get install llvm-7.0 libclang-7.0-dev
|
||||
|
||||
There is a workaround to set _GLIBCXX_USE_CXX11_ABI to 1 or 0, but we recommend
|
||||
to download the package from http://apt.llvm.org/.
|
||||
|
10
dist/changes-4.9.0.md
vendored
10
dist/changes-4.9.0.md
vendored
@@ -52,6 +52,10 @@ QMake Projects
|
||||
* Fixed updating of `LD_LIBRARY_PATH` environment variable (QTCREATORBUG-21475)
|
||||
* Fixed updating of project tree in case of wildcards in corresponding QMake
|
||||
variable (QTCREATORBUG-21603)
|
||||
* Fixed issues with project tree when files are directly added to `RESOURCES`
|
||||
(QTCREATORBUG-20103)
|
||||
* Fixed that importing build unnecessarily created temporary kit
|
||||
(QTCREATORBUG-18153)
|
||||
|
||||
CMake Projects
|
||||
|
||||
@@ -78,6 +82,8 @@ C++ Support
|
||||
* Clang Code Model
|
||||
* Added buttons for copying and ignoring diagnostics to tooltip
|
||||
* Fixed issue with high memory consumption (QTCREATORBUG-19543)
|
||||
* Fixed inconsistency between `Follow Symbol` and `Ctrl + Click`
|
||||
(QTCREATORBUG-21637)
|
||||
* Clang Format
|
||||
* Added option to format code instead of only indenting code
|
||||
|
||||
@@ -98,6 +104,9 @@ Nim Support
|
||||
|
||||
Debugging
|
||||
|
||||
* Fixed that debugger toolbar could force large minimum window size
|
||||
(QTCREATORBUG-21885)
|
||||
* Added pretty printing of `QSizePolicy`
|
||||
* GDB
|
||||
* Added support for rvalue references in function arguments
|
||||
* LLDB
|
||||
@@ -167,6 +176,7 @@ Windows
|
||||
* Added support for MSVC 2019
|
||||
* Changed toolchain detection to use `vswhere` by default, which is recommended
|
||||
by Microsoft
|
||||
* Fixed issue with UNC paths in `.pro` files (QTCREATORBUG-21881)
|
||||
|
||||
Linux
|
||||
|
||||
|
@@ -109,15 +109,19 @@ linux {
|
||||
|
||||
macx {
|
||||
APPBUNDLE = "$$OUT_PWD/bin/$${IDE_APP_TARGET}.app"
|
||||
BINDIST_SOURCE = "$$OUT_PWD/bin/$${IDE_APP_TARGET}.app"
|
||||
BINDIST_SOURCE.release = "$$OUT_PWD/bin/$${IDE_APP_TARGET}.app"
|
||||
BINDIST_SOURCE.debug = "$$OUT_PWD/bin"
|
||||
BINDIST_EXCLUDE_ARG.debug = "--exclude-toplevel"
|
||||
deployqt.commands = $$PWD/scripts/deployqtHelper_mac.sh \"$${APPBUNDLE}\" \"$$[QT_INSTALL_BINS]\" \"$$[QT_INSTALL_TRANSLATIONS]\" \"$$[QT_INSTALL_PLUGINS]\" \"$$[QT_INSTALL_IMPORTS]\" \"$$[QT_INSTALL_QML]\"
|
||||
codesign.commands = codesign --deep -s \"$(SIGNING_IDENTITY)\" $(SIGNING_FLAGS) \"$${APPBUNDLE}\"
|
||||
dmg.commands = python -u \"$$PWD/scripts/makedmg.py\" \"$${BASENAME}.dmg\" \"Qt Creator\" \"$$IDE_SOURCE_TREE\" \"$$OUT_PWD/bin\"
|
||||
#dmg.depends = deployqt
|
||||
QMAKE_EXTRA_TARGETS += codesign dmg
|
||||
} else {
|
||||
BINDIST_SOURCE = "$(INSTALL_ROOT)$$QTC_PREFIX"
|
||||
BINDIST_EXCLUDE_ARG = "--exclude-toplevel"
|
||||
BINDIST_SOURCE.release = "$(INSTALL_ROOT)$$QTC_PREFIX"
|
||||
BINDIST_EXCLUDE_ARG.release = "--exclude-toplevel"
|
||||
BINDIST_SOURCE.debug = $${BINDIST_SOURCE.release}
|
||||
BINDIST_EXCLUDE_ARG.debug = $${BINDIST_EXCLUDE_ARG.release}
|
||||
deployqt.commands = python -u $$PWD/scripts/deployqt.py -i \"$(INSTALL_ROOT)$$QTC_PREFIX/bin/$${IDE_APP_TARGET}\" \"$(QMAKE)\"
|
||||
deployqt.depends = install
|
||||
win32 {
|
||||
@@ -140,9 +144,9 @@ isEmpty(INSTALLER_ARCHIVE_FROM_ENV) {
|
||||
INSTALLER_ARCHIVE_DEBUG = $$INSTALLER_ARCHIVE
|
||||
INSTALLER_ARCHIVE_DEBUG ~= s/(.*)[.]7z/\1-debug.7z
|
||||
|
||||
bindist.commands = python -u $$PWD/scripts/createDistPackage.py $$OUT_PWD/$${BASENAME}.7z \"$$BINDIST_SOURCE\"
|
||||
bindist_installer.commands = python -u $$PWD/scripts/createDistPackage.py $$BINDIST_EXCLUDE_ARG $${INSTALLER_ARCHIVE} \"$$BINDIST_SOURCE\"
|
||||
bindist_debug.commands = python -u $$PWD/scripts/createDistPackage.py --debug $$BINDIST_EXCLUDE_ARG $${INSTALLER_ARCHIVE_DEBUG} \"$$BINDIST_SOURCE\"
|
||||
bindist.commands = python -u $$PWD/scripts/createDistPackage.py $$OUT_PWD/$${BASENAME}.7z \"$${BINDIST_SOURCE.release}\"
|
||||
bindist_installer.commands = python -u $$PWD/scripts/createDistPackage.py $${BINDIST_EXCLUDE_ARG.release} $${INSTALLER_ARCHIVE} \"$${BINDIST_SOURCE.release}\"
|
||||
bindist_debug.commands = python -u $$PWD/scripts/createDistPackage.py --debug $${BINDIST_EXCLUDE_ARG.debug} $${INSTALLER_ARCHIVE_DEBUG} \"$${BINDIST_SOURCE.debug}\"
|
||||
|
||||
win32 {
|
||||
deployqt.commands ~= s,/,\\\\,g
|
||||
|
50
scripts/flake2tasks.py
Executable file
50
scripts/flake2tasks.py
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python
|
||||
############################################################################
|
||||
#
|
||||
# Copyright (C) 2019 The Qt Company Ltd.
|
||||
# Contact: https://www.qt.io/licensing/
|
||||
#
|
||||
# This file is part of Qt Creator.
|
||||
#
|
||||
# Commercial License Usage
|
||||
# Licensees holding valid commercial Qt licenses may use this file in
|
||||
# accordance with the commercial license agreement provided with the
|
||||
# Software or, alternatively, in accordance with the terms contained in
|
||||
# a written agreement between you and The Qt Company. For licensing terms
|
||||
# and conditions see https://www.qt.io/terms-conditions. For further
|
||||
# information use the contact form at https://www.qt.io/contact-us.
|
||||
#
|
||||
# GNU General Public License Usage
|
||||
# Alternatively, this file may be used under the terms of the GNU
|
||||
# General Public License version 3 as published by the Free Software
|
||||
# Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
# included in the packaging of this file. Please review the following
|
||||
# information to ensure the GNU General Public License requirements will
|
||||
# be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
'''
|
||||
flake2tasks.py - Convert flake8 warnings into Qt Creator task files.
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
flake2tasks.py < logfile > taskfile
|
||||
'''
|
||||
|
||||
import sys
|
||||
import re
|
||||
|
||||
if __name__ == '__main__':
|
||||
pattern = re.compile(r'^([^:]+):(\d+):\d+: E\d+ (.*)$')
|
||||
while True:
|
||||
line = sys.stdin.readline().rstrip()
|
||||
if not line:
|
||||
break
|
||||
match = pattern.match(line)
|
||||
if match:
|
||||
file_name = match.group(1).replace('\\', '/')
|
||||
line_number = match.group(2)
|
||||
text = match.group(3)
|
||||
output = "{}\t{}\twarn\t{}".format(file_name, line_number, text)
|
||||
print(output)
|
@@ -957,6 +957,12 @@ class Dumper(DumperBase):
|
||||
return
|
||||
self.report('pid="%s"' % self.process.GetProcessID())
|
||||
self.reportState('enginerunandinferiorrunok')
|
||||
if self.target is not None:
|
||||
broadcaster = self.target.GetBroadcaster()
|
||||
listener = self.debugger.GetListener()
|
||||
broadcaster.AddListener(listener, lldb.SBTarget.eBroadcastBitBreakpointChanged)
|
||||
listener.StartListeningForEvents(broadcaster, lldb.SBTarget.eBroadcastBitBreakpointChanged)
|
||||
|
||||
|
||||
def loop(self):
|
||||
event = lldb.SBEvent()
|
||||
@@ -1116,6 +1122,11 @@ class Dumper(DumperBase):
|
||||
# logview pane feature.
|
||||
self.report('token(\"%s\")' % args["token"])
|
||||
|
||||
|
||||
def reportBreakpointUpdate(self, bp):
|
||||
self.report('breakpointmodified={%s}' % self.describeBreakpoint(bp))
|
||||
|
||||
|
||||
def readRawMemory(self, address, size):
|
||||
if size == 0:
|
||||
return bytes()
|
||||
@@ -1288,7 +1299,20 @@ class Dumper(DumperBase):
|
||||
self.process.Kill()
|
||||
self.reportResult('', args)
|
||||
|
||||
|
||||
def handleBreakpointEvent(self, event):
|
||||
eventType = lldb.SBBreakpoint.GetBreakpointEventTypeFromEvent(event)
|
||||
# handle only the resolved locations for now..
|
||||
if eventType & lldb.eBreakpointEventTypeLocationsResolved:
|
||||
bp = lldb.SBBreakpoint.GetBreakpointFromEvent(event)
|
||||
if bp is not None:
|
||||
self.reportBreakpointUpdate(bp)
|
||||
|
||||
|
||||
def handleEvent(self, event):
|
||||
if lldb.SBBreakpoint.EventIsBreakpointEvent(event):
|
||||
self.handleBreakpointEvent(event)
|
||||
return
|
||||
out = lldb.SBStream()
|
||||
event.GetDescription(out)
|
||||
#warn("EVENT: %s" % event)
|
||||
|
@@ -3,7 +3,7 @@
|
||||
"supportedProjectTypes": [ "PythonProject" ],
|
||||
"id": "U.QtForPythonApplicationEmpty",
|
||||
"category": "F.Application",
|
||||
"trDescription": "Creates a Qt for Python application that only the main code for a QApplication",
|
||||
"trDescription": "Creates a Qt for Python application that contains only the main code for a QApplication.",
|
||||
"trDisplayName": "Qt for Python - Empty",
|
||||
"trDisplayCategory": "Application",
|
||||
"icon": "icon.png",
|
||||
|
@@ -5,8 +5,9 @@ TEMPLATE = app
|
||||
CONFIG += qtc_runnable sliced_bundle
|
||||
TARGET = $$IDE_APP_TARGET
|
||||
DESTDIR = $$IDE_APP_PATH
|
||||
VERSION = $$QTCREATOR_VERSION
|
||||
QT -= testlib
|
||||
# work around QTBUG-74265
|
||||
win32: VERSION=
|
||||
|
||||
HEADERS += ../tools/qtcreatorcrashhandler/crashhandlersetup.h
|
||||
SOURCES += main.cpp ../tools/qtcreatorcrashhandler/crashhandlersetup.cpp
|
||||
|
@@ -51,6 +51,7 @@ public:
|
||||
commandLine.reserve(1024);
|
||||
|
||||
addCompiler(projectInfo.language);
|
||||
disableWarnings();
|
||||
addToolChainArguments(toolChainArguments);
|
||||
addExtraFlags();
|
||||
addLanguage(projectInfo, sourceType);
|
||||
@@ -74,6 +75,8 @@ public:
|
||||
commandLine.emplace_back("clang");
|
||||
}
|
||||
|
||||
void disableWarnings() { commandLine.emplace_back("-w"); }
|
||||
|
||||
void addToolChainArguments(const Utils::SmallStringVector &toolChainArguments)
|
||||
{
|
||||
for (Utils::SmallStringView argument : toolChainArguments)
|
||||
|
@@ -143,6 +143,8 @@ public:
|
||||
const Sqlite::Column &projectPartIdColumn = table.addColumn("projectPartId", Sqlite::ColumnType::Integer);
|
||||
const Sqlite::Column &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("sourceType", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("pchCreationTimeStamp", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("hasMissingIncludes", Sqlite::ColumnType::Integer);
|
||||
table.addUniqueIndex({sourceIdColumn, projectPartIdColumn});
|
||||
table.addIndex({projectPartIdColumn});
|
||||
|
||||
@@ -168,11 +170,11 @@ public:
|
||||
Sqlite::Table table;
|
||||
table.setUseIfNotExists(true);
|
||||
table.setName("fileStatuses");
|
||||
table.addColumn("sourceId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
|
||||
table.addColumn("sourceId",
|
||||
Sqlite::ColumnType::Integer,
|
||||
Sqlite::Contraint::PrimaryKey);
|
||||
table.addColumn("size", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("lastModified", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("buildDependencyTimeStamp", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("isInPrecompiledHeader", Sqlite::ColumnType::Integer);
|
||||
table.initialize(database);
|
||||
}
|
||||
|
||||
|
@@ -264,7 +264,7 @@ int ExpressionUnderCursor::startOfFunctionCall(const QTextCursor &cursor) const
|
||||
break;
|
||||
} else if (tk.is(T_LPAREN) || tk.is(T_LBRACE)) {
|
||||
return scanner.startPosition() + tk.utf16charsBegin();
|
||||
} else if (tk.is(T_RPAREN)) {
|
||||
} else if (tk.is(T_RPAREN) || tk.is(T_RBRACE)) {
|
||||
int matchingBrace = scanner.startOfMatchingBrace(index);
|
||||
|
||||
if (matchingBrace == index) // If no matching brace found
|
||||
|
@@ -31,9 +31,27 @@ for(l, SUBDIRS) {
|
||||
}
|
||||
|
||||
SUBDIRS += \
|
||||
utils/process_stub.pro \
|
||||
3rdparty/syntax-highlighting \
|
||||
3rdparty/syntax-highlighting/data
|
||||
utils/process_stub.pro
|
||||
|
||||
isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR): KSYNTAXHIGHLIGHTING_LIB_DIR=$$(KSYNTAXHIGHLIGHTING_LIB_DIR)
|
||||
!isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR) {
|
||||
# enable short information message
|
||||
KSYNTAX_WARN_ON = 1
|
||||
}
|
||||
|
||||
include(../shared/syntax/syntax_shared.pri)
|
||||
isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR) {
|
||||
SUBDIRS += \
|
||||
3rdparty/syntax-highlighting \
|
||||
3rdparty/syntax-highlighting/data
|
||||
|
||||
equals(KSYNTAX_WARN_ON, 1) {
|
||||
message("Either KSYNTAXHIGHLIGHTING_LIB_DIR does not exist or include path could not be deduced.")
|
||||
unset(KSYNTAX_WARN_ON)
|
||||
}
|
||||
} else {
|
||||
message("Using KSyntaxHighlighting provided at $${KSYNTAXHIGHLIGHTING_LIB_DIR}.")
|
||||
}
|
||||
|
||||
win32:SUBDIRS += utils/process_ctrlc_stub.pro
|
||||
|
||||
|
@@ -748,8 +748,8 @@ void Check::endVisit(UiObjectInitializer *)
|
||||
{
|
||||
m_propertyStack.pop();
|
||||
m_typeStack.pop();
|
||||
UiObjectDefinition *objectDenition = cast<UiObjectDefinition *>(parent());
|
||||
if (objectDenition && objectDenition->qualifiedTypeNameId->name == "Component")
|
||||
UiObjectDefinition *objectDefinition = cast<UiObjectDefinition *>(parent());
|
||||
if (objectDefinition && objectDefinition->qualifiedTypeNameId->name == "Component")
|
||||
m_idStack.pop();
|
||||
UiObjectBinding *objectBinding = cast<UiObjectBinding *>(parent());
|
||||
if (objectBinding && objectBinding->qualifiedTypeNameId->name == "Component")
|
||||
|
@@ -69,7 +69,7 @@ SshRemoteProcess::SshRemoteProcess(const QByteArray &command, const QStringList
|
||||
connect(this, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this] {
|
||||
QString error;
|
||||
if (exitStatus() == QProcess::CrashExit)
|
||||
error = tr("The ssh binary crashed: %1").arg(errorString());
|
||||
error = tr("The ssh process crashed: %1").arg(errorString());
|
||||
else if (exitCode() == 255)
|
||||
error = tr("Remote process crashed.");
|
||||
emit done(error);
|
||||
|
@@ -311,9 +311,10 @@ QString FileUtils::normalizePathName(const QString &name)
|
||||
if (FAILED(hr))
|
||||
return name;
|
||||
TCHAR buffer[MAX_PATH];
|
||||
if (!SHGetPathFromIDList(file, buffer))
|
||||
return name;
|
||||
return QDir::fromNativeSeparators(QString::fromUtf16(reinterpret_cast<const ushort *>(buffer)));
|
||||
const bool success = SHGetPathFromIDList(file, buffer);
|
||||
ILFree(file);
|
||||
return success ? QDir::fromNativeSeparators(QString::fromUtf16(reinterpret_cast<const ushort *>(buffer)))
|
||||
: name;
|
||||
#elif defined(Q_OS_OSX)
|
||||
return Internal::normalizePathName(name);
|
||||
#else // do not try to handle case-insensitive file systems on Linux
|
||||
|
@@ -63,9 +63,9 @@ QVariant Utils::JsonTreeItem::data(int column, int role) const
|
||||
if (column == 2)
|
||||
return typeName(m_value.type());
|
||||
if (m_value.isObject())
|
||||
return QString('[' + QString::number(m_value.toObject().size()) + ' ' + tr("Items") + ']');
|
||||
return QString('[' + tr("%n Items", nullptr, m_value.toObject().size()) + ']');
|
||||
if (m_value.isArray())
|
||||
return QString('[' + QString::number(m_value.toArray().size()) + ' ' + tr("Items") + ']');
|
||||
return QString('[' + tr("%n Items", nullptr, m_value.toArray().size()) + ']');
|
||||
return m_value.toVariant();
|
||||
}
|
||||
|
||||
|
@@ -171,7 +171,8 @@ LineColumn utf16LineColumn(const QByteArray &utf8Buffer, int utf8Offset)
|
||||
lineColumn.line = static_cast<int>(
|
||||
std::count(utf8Buffer.begin(), utf8Buffer.begin() + utf8Offset, '\n'))
|
||||
+ 1;
|
||||
const int startOfLineOffset = utf8Buffer.lastIndexOf('\n', utf8Offset - 1) + 1;
|
||||
const int startOfLineOffset = utf8Offset ? (utf8Buffer.lastIndexOf('\n', utf8Offset - 1) + 1)
|
||||
: 0;
|
||||
lineColumn.column = QString::fromUtf8(
|
||||
utf8Buffer.mid(startOfLineOffset, utf8Offset - startOfLineOffset))
|
||||
.length()
|
||||
@@ -181,7 +182,9 @@ LineColumn utf16LineColumn(const QByteArray &utf8Buffer, int utf8Offset)
|
||||
|
||||
QString utf16LineTextInUtf8Buffer(const QByteArray &utf8Buffer, int currentUtf8Offset)
|
||||
{
|
||||
const int lineStartUtf8Offset = utf8Buffer.lastIndexOf('\n', currentUtf8Offset - 1) + 1;
|
||||
const int lineStartUtf8Offset = currentUtf8Offset
|
||||
? (utf8Buffer.lastIndexOf('\n', currentUtf8Offset - 1) + 1)
|
||||
: 0;
|
||||
const int lineEndUtf8Offset = utf8Buffer.indexOf('\n', currentUtf8Offset);
|
||||
return QString::fromUtf8(
|
||||
utf8Buffer.mid(lineStartUtf8Offset, lineEndUtf8Offset - lineStartUtf8Offset));
|
||||
|
@@ -101,7 +101,7 @@ public:
|
||||
setSummaryText(displayName());
|
||||
|
||||
auto uninstallPreviousPackage = new QCheckBox(this);
|
||||
uninstallPreviousPackage->setText(tr("Uninstall previous package"));
|
||||
uninstallPreviousPackage->setText(AndroidDeployQtStep::tr("Uninstall previous package"));
|
||||
uninstallPreviousPackage->setChecked(step->uninstallPreviousPackage() > AndroidDeployQtStep::Keep);
|
||||
uninstallPreviousPackage->setEnabled(step->uninstallPreviousPackage() != AndroidDeployQtStep::ForceUnintall);
|
||||
|
||||
|
@@ -68,13 +68,12 @@ void ClangCodeModelPlugin::generateCompilationDB() {
|
||||
using namespace CppTools;
|
||||
|
||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
||||
if (!project)
|
||||
if (!project || !project->activeTarget())
|
||||
return;
|
||||
|
||||
m_generatorWatcher.setFuture(QtConcurrent::run(
|
||||
&Utils::generateCompilationDB,
|
||||
project->projectDirectory(),
|
||||
CppModelManager::instance()->projectInfo(project)));
|
||||
m_generatorWatcher.setFuture(
|
||||
QtConcurrent::run(&Utils::generateCompilationDB,
|
||||
CppModelManager::instance()->projectInfo(project)));
|
||||
}
|
||||
|
||||
static bool isDBGenerationEnabled(ProjectExplorer::Project *project)
|
||||
|
@@ -214,6 +214,9 @@ void ClangCompletionAssistProcessor::handleAvailableCompletions(const CodeComple
|
||||
setAsyncProposalAvailable(createFunctionHintProposal(completions));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_fallbackToNormalCompletion)
|
||||
return;
|
||||
// else: Proceed with a normal completion in case:
|
||||
// 1) it was not a function call, but e.g. a function declaration like "void f("
|
||||
// 2) '{' meant not a constructor call.
|
||||
@@ -286,6 +289,14 @@ static QByteArray modifyInput(QTextDocument *doc, int endOfExpression) {
|
||||
return modifiedInput;
|
||||
}
|
||||
|
||||
static QChar lastPrecedingNonWhitespaceChar(const ClangCompletionAssistInterface *interface)
|
||||
{
|
||||
int pos = interface->position();
|
||||
while (pos >= 0 && interface->characterAt(pos).isSpace())
|
||||
--pos;
|
||||
return pos >= 0 ? interface->characterAt(pos) : QChar::Null;
|
||||
}
|
||||
|
||||
IAssistProposal *ClangCompletionAssistProcessor::startCompletionHelper()
|
||||
{
|
||||
ClangCompletionContextAnalyzer analyzer(m_interface.data(), m_interface->languageFeatures());
|
||||
@@ -323,6 +334,8 @@ IAssistProposal *ClangCompletionAssistProcessor::startCompletionHelper()
|
||||
}
|
||||
case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen: {
|
||||
m_sentRequestType = FunctionHintCompletion;
|
||||
if (lastPrecedingNonWhitespaceChar(m_interface.data()) == ',')
|
||||
m_fallbackToNormalCompletion = false;
|
||||
m_requestSent = sendCompletionRequest(analyzer.positionForClang(), QByteArray(),
|
||||
analyzer.functionNameStart());
|
||||
break;
|
||||
|
@@ -97,6 +97,7 @@ private:
|
||||
CompletionRequestType m_sentRequestType = NormalCompletion;
|
||||
bool m_requestSent = false;
|
||||
bool m_addSnippets = false; // For type == Type::NormalCompletion
|
||||
bool m_fallbackToNormalCompletion = true;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -110,6 +110,8 @@ int ClangCompletionContextAnalyzer::startOfFunctionCall(int endOfOperator) const
|
||||
functionNameSelector.setPosition(functionNameStart);
|
||||
functionNameSelector.setPosition(index, QTextCursor::KeepAnchor);
|
||||
const QString functionName = functionNameSelector.selectedText().trimmed();
|
||||
if (functionName.isEmpty() && m_completionOperator == T_LBRACE)
|
||||
return endOfOperator;
|
||||
|
||||
return functionName.isEmpty() ? -1 : functionNameStart;
|
||||
}
|
||||
@@ -139,7 +141,10 @@ void ClangCompletionContextAnalyzer::handleCommaInFunctionCall()
|
||||
const int start = expressionUnderCursor.startOfFunctionCall(textCursor);
|
||||
m_positionEndOfExpression = start;
|
||||
m_positionForProposal = start + 1; // After '(' of function call
|
||||
m_completionOperator = T_LPAREN;
|
||||
if (m_interface->characterAt(start) == '(')
|
||||
m_completionOperator = T_LPAREN;
|
||||
else
|
||||
m_completionOperator = T_LBRACE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -34,12 +34,13 @@
|
||||
#include <coreplugin/idocument.h>
|
||||
#include <cpptools/baseeditordocumentparser.h>
|
||||
#include <cpptools/compileroptionsbuilder.h>
|
||||
#include <cpptools/cppcodemodelsettings.h>
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
#include <cpptools/cpptoolsreuse.h>
|
||||
#include <cpptools/editordocumenthandle.h>
|
||||
#include <cpptools/projectpart.h>
|
||||
#include <cpptools/cppcodemodelsettings.h>
|
||||
#include <cpptools/cpptoolsreuse.h>
|
||||
#include <projectexplorer/buildconfiguration.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
@@ -300,12 +301,24 @@ QString diagnosticCategoryPrefixRemoved(const QString &text)
|
||||
return text;
|
||||
}
|
||||
|
||||
static ::Utils::FileName buildDirectory(const CppTools::ProjectPart &projectPart)
|
||||
static ::Utils::FileName compilerPath(const CppTools::ProjectPart &projectPart)
|
||||
{
|
||||
ProjectExplorer::Target *target = projectPart.project->activeTarget();
|
||||
if (!target)
|
||||
return ::Utils::FileName();
|
||||
|
||||
ProjectExplorer::ToolChain *toolchain = ProjectExplorer::ToolChainKitAspect::toolChain(
|
||||
target->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID);
|
||||
|
||||
return toolchain->compilerCommand();
|
||||
}
|
||||
|
||||
static ::Utils::FileName buildDirectory(const ProjectExplorer::Project &project)
|
||||
{
|
||||
ProjectExplorer::Target *target = project.activeTarget();
|
||||
if (!target)
|
||||
return ::Utils::FileName();
|
||||
|
||||
ProjectExplorer::BuildConfiguration *buildConfig = target->activeBuildConfiguration();
|
||||
if (!buildConfig)
|
||||
return ::Utils::FileName();
|
||||
@@ -313,42 +326,84 @@ static ::Utils::FileName buildDirectory(const CppTools::ProjectPart &projectPart
|
||||
return buildConfig->buildDirectory();
|
||||
}
|
||||
|
||||
static QJsonObject createFileObject(CompilerOptionsBuilder &optionsBuilder,
|
||||
const ProjectFile &projFile,
|
||||
const ::Utils::FileName &buildDir)
|
||||
static QStringList projectPartArguments(const ProjectPart &projectPart)
|
||||
{
|
||||
const ProjectFile::Kind kind = ProjectFile::classify(projFile.path);
|
||||
optionsBuilder.updateFileLanguage(kind);
|
||||
QStringList args;
|
||||
args << compilerPath(projectPart).toString();
|
||||
args << "-c";
|
||||
if (projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
|
||||
args << "--target=" + projectPart.toolChainTargetTriple;
|
||||
args << (projectPart.toolChainWordWidth == ProjectPart::WordWidth64Bit
|
||||
? QLatin1String("-m64")
|
||||
: QLatin1String("-m32"));
|
||||
}
|
||||
args << projectPart.compilerFlags;
|
||||
for (const ProjectExplorer::HeaderPath &headerPath : projectPart.headerPaths) {
|
||||
if (headerPath.type == ProjectExplorer::HeaderPathType::User) {
|
||||
args << "-I" + headerPath.path;
|
||||
} else if (headerPath.type == ProjectExplorer::HeaderPathType::System) {
|
||||
args << (projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
|
||||
? "-I"
|
||||
: "-isystem")
|
||||
+ headerPath.path;
|
||||
}
|
||||
}
|
||||
for (const ProjectExplorer::Macro ¯o : projectPart.projectMacros) {
|
||||
args.append(QString::fromUtf8(
|
||||
macro.toKeyValue(macro.type == ProjectExplorer::MacroType::Define ? "-D" : "-U")));
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
static QJsonObject createFileObject(const ::Utils::FileName &buildDir,
|
||||
const QStringList &arguments,
|
||||
const ProjectPart &projectPart,
|
||||
const ProjectFile &projFile)
|
||||
{
|
||||
QJsonObject fileObject;
|
||||
fileObject["file"] = projFile.path;
|
||||
QJsonArray args = QJsonArray::fromStringList(optionsBuilder.options());
|
||||
args.prepend(kind == ProjectFile::CXXSource ? "clang++" : "clang");
|
||||
QJsonArray args = QJsonArray::fromStringList(arguments);
|
||||
|
||||
const ProjectFile::Kind kind = ProjectFile::classify(projFile.path);
|
||||
if (projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
|
||||
|| projectPart.toolchainType == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID) {
|
||||
if (ProjectFile::isC(kind))
|
||||
args.append("/TC");
|
||||
else if (ProjectFile::isCxx(kind))
|
||||
args.append("/TP");
|
||||
} else {
|
||||
QStringList langOption
|
||||
= createLanguageOptionGcc(kind,
|
||||
projectPart.languageExtensions
|
||||
& ::Utils::LanguageExtension::ObjectiveC);
|
||||
for (const QString &langOptionPart : langOption)
|
||||
args.append(langOptionPart);
|
||||
}
|
||||
args.append(QDir::toNativeSeparators(projFile.path));
|
||||
fileObject["arguments"] = args;
|
||||
fileObject["directory"] = buildDir.toString();
|
||||
return fileObject;
|
||||
}
|
||||
|
||||
void generateCompilationDB(::Utils::FileName projectDir, CppTools::ProjectInfo projectInfo)
|
||||
void generateCompilationDB(CppTools::ProjectInfo projectInfo)
|
||||
{
|
||||
QFile compileCommandsFile(projectDir.toString() + "/compile_commands.json");
|
||||
const ::Utils::FileName buildDir = buildDirectory(*projectInfo.project());
|
||||
QTC_ASSERT(!buildDir.isEmpty(), return;);
|
||||
|
||||
QDir dir(buildDir.toString());
|
||||
if (!dir.exists())
|
||||
dir.mkpath(dir.path());
|
||||
QFile compileCommandsFile(buildDir.toString() + "/compile_commands.json");
|
||||
const bool fileOpened = compileCommandsFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
||||
if (!fileOpened)
|
||||
return;
|
||||
compileCommandsFile.write("[");
|
||||
|
||||
for (ProjectPart::Ptr projectPart : projectInfo.projectParts()) {
|
||||
const ::Utils::FileName buildDir = buildDirectory(*projectPart);
|
||||
|
||||
CompilerOptionsBuilder optionsBuilder(*projectPart,
|
||||
UseSystemHeader::No,
|
||||
UseTweakedHeaderPaths::No);
|
||||
optionsBuilder.build(CppTools::ProjectFile::Unclassified,
|
||||
CppTools::UsePrecompiledHeaders::No);
|
||||
|
||||
const QStringList args = projectPartArguments(*projectPart);
|
||||
for (const ProjectFile &projFile : projectPart->files) {
|
||||
const QJsonObject json = createFileObject(optionsBuilder, projFile, buildDir);
|
||||
const QJsonObject json = createFileObject(buildDir, args, *projectPart, projFile);
|
||||
if (compileCommandsFile.size() > 1)
|
||||
compileCommandsFile.write(",");
|
||||
compileCommandsFile.write('\n' + QJsonDocument(json).toJson().trimmed());
|
||||
|
@@ -70,7 +70,7 @@ QString diagnosticCategoryPrefixRemoved(const QString &text);
|
||||
|
||||
::Utils::CodeModelIcon::Type iconTypeForToken(const ClangBackEnd::TokenInfoContainer &token);
|
||||
|
||||
void generateCompilationDB(::Utils::FileName projectDir, CppTools::ProjectInfo projectInfo);
|
||||
void generateCompilationDB(CppTools::ProjectInfo projectInfo);
|
||||
|
||||
class DiagnosticTextInfo
|
||||
{
|
||||
|
@@ -2,7 +2,7 @@
|
||||
\"Name\" : \"ClangFormat\",
|
||||
\"Version\" : \"$$QTCREATOR_VERSION\",
|
||||
\"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
|
||||
\"Experimental\" : true,
|
||||
\"DisabledByDefault\" : true,
|
||||
\"Vendor\" : \"The Qt Company Ltd\",
|
||||
\"Copyright\" : \"(C) $$QTCREATOR_COPYRIGHT_YEAR The Qt Company Ltd\",
|
||||
\"License\" : [ \"Commercial Usage\",
|
||||
|
@@ -29,9 +29,10 @@
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/textutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/textutils.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTextDocument>
|
||||
|
||||
namespace ClangFormat {
|
||||
@@ -126,9 +127,85 @@ void trimRHSWhitespace(const QTextBlock &block)
|
||||
cursor.endEditBlock();
|
||||
}
|
||||
|
||||
QTextBlock reverseFindLastEmptyBlock(QTextBlock start)
|
||||
{
|
||||
if (start.position() > 0) {
|
||||
start = start.previous();
|
||||
while (start.position() > 0 && start.text().trimmed().isEmpty())
|
||||
start = start.previous();
|
||||
if (!start.text().trimmed().isEmpty())
|
||||
start = start.next();
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
enum class CharacterContext { AfterComma, LastAfterComma, NewStatement, Continuation, Unknown };
|
||||
|
||||
QChar findFirstNonWhitespaceCharacter(const QTextBlock ¤tBlock)
|
||||
{
|
||||
const QTextDocument *doc = currentBlock.document();
|
||||
int currentPos = currentBlock.position();
|
||||
while (currentPos < doc->characterCount() && doc->characterAt(currentPos).isSpace())
|
||||
++currentPos;
|
||||
return currentPos < doc->characterCount() ? doc->characterAt(currentPos) : QChar::Null;
|
||||
}
|
||||
|
||||
CharacterContext characterContext(const QTextBlock ¤tBlock,
|
||||
const QTextBlock &previousNonEmptyBlock)
|
||||
{
|
||||
const QString prevLineText = previousNonEmptyBlock.text().trimmed();
|
||||
const QChar firstNonWhitespaceChar = findFirstNonWhitespaceCharacter(currentBlock);
|
||||
if (prevLineText.endsWith(',')) {
|
||||
// We don't need to add comma in case it's the last argument.
|
||||
if (firstNonWhitespaceChar == '}' || firstNonWhitespaceChar == ')')
|
||||
return CharacterContext::LastAfterComma;
|
||||
return CharacterContext::AfterComma;
|
||||
}
|
||||
|
||||
if (prevLineText.endsWith(';') || prevLineText.endsWith('{') || prevLineText.endsWith('}')
|
||||
|| firstNonWhitespaceChar == QChar::Null) {
|
||||
return CharacterContext::NewStatement;
|
||||
}
|
||||
|
||||
return CharacterContext::Continuation;
|
||||
}
|
||||
|
||||
bool nextBlockExistsAndEmpty(const QTextBlock ¤tBlock)
|
||||
{
|
||||
QTextBlock nextBlock = currentBlock.next();
|
||||
if (!nextBlock.isValid() || nextBlock.position() == currentBlock.position())
|
||||
return false;
|
||||
|
||||
return nextBlock.text().trimmed().isEmpty();
|
||||
}
|
||||
|
||||
QByteArray dummyTextForContext(CharacterContext context, bool closingBraceBlock)
|
||||
{
|
||||
if (closingBraceBlock
|
||||
&& (context == CharacterContext::NewStatement
|
||||
|| context == CharacterContext::Continuation)) {
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
switch (context) {
|
||||
case CharacterContext::Unknown:
|
||||
QTC_ASSERT(false, return "";);
|
||||
case CharacterContext::AfterComma:
|
||||
return "a,";
|
||||
case CharacterContext::NewStatement:
|
||||
return "a;";
|
||||
case CharacterContext::Continuation:
|
||||
case CharacterContext::LastAfterComma:
|
||||
return "& a &";
|
||||
}
|
||||
}
|
||||
|
||||
// Add extra text in case of the empty line or the line starting with ')'.
|
||||
// Track such extra pieces of text in isInsideModifiedLine().
|
||||
int forceIndentWithExtraText(QByteArray &buffer, const QTextBlock &block, bool secondTry)
|
||||
int forceIndentWithExtraText(QByteArray &buffer,
|
||||
CharacterContext &charContext,
|
||||
const QTextBlock &block,
|
||||
bool secondTry)
|
||||
{
|
||||
const QString blockText = block.text();
|
||||
int firstNonWhitespace = Utils::indexOf(blockText,
|
||||
@@ -143,26 +220,33 @@ int forceIndentWithExtraText(QByteArray &buffer, const QTextBlock &block, bool s
|
||||
|
||||
const bool closingParenBlock = firstNonWhitespace >= 0
|
||||
&& blockText.at(firstNonWhitespace) == ')';
|
||||
const bool closingBraceBlock = firstNonWhitespace >= 0
|
||||
&& blockText.at(firstNonWhitespace) == '}';
|
||||
|
||||
int extraLength = 0;
|
||||
if (firstNonWhitespace < 0 || closingParenBlock) {
|
||||
//This extra text works for the most cases.
|
||||
QByteArray dummyText("a;a;");
|
||||
QByteArray dummyText;
|
||||
if (firstNonWhitespace < 0 && charContext != CharacterContext::Unknown
|
||||
&& nextBlockExistsAndEmpty(block)) {
|
||||
// If the next line is also empty it's safer to use a comment line.
|
||||
dummyText = "//";
|
||||
} else if (firstNonWhitespace < 0 || closingParenBlock || closingBraceBlock) {
|
||||
if (charContext == CharacterContext::LastAfterComma) {
|
||||
charContext = CharacterContext::AfterComma;
|
||||
} else if (charContext == CharacterContext::Unknown || firstNonWhitespace >= 0) {
|
||||
QTextBlock lastBlock = reverseFindLastEmptyBlock(block);
|
||||
if (lastBlock.position() > 0)
|
||||
lastBlock = lastBlock.previous();
|
||||
|
||||
// Search for previous character
|
||||
QTextBlock prevBlock = block.previous();
|
||||
bool prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
|
||||
while (prevBlockIsEmpty) {
|
||||
prevBlock = prevBlock.previous();
|
||||
prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
|
||||
// If we don't know yet the dummy text, let's guess it and use for this line and before.
|
||||
charContext = characterContext(block, lastBlock);
|
||||
}
|
||||
if (closingParenBlock || prevBlock.text().endsWith(','))
|
||||
dummyText = "&& a";
|
||||
|
||||
buffer.insert(utf8Offset, dummyText);
|
||||
extraLength += dummyText.length();
|
||||
dummyText = dummyTextForContext(charContext, closingBraceBlock);
|
||||
}
|
||||
|
||||
buffer.insert(utf8Offset, dummyText);
|
||||
extraLength += dummyText.length();
|
||||
|
||||
if (secondTry) {
|
||||
int nextLinePos = buffer.indexOf('\n', utf8Offset);
|
||||
if (nextLinePos < 0)
|
||||
@@ -170,7 +254,7 @@ int forceIndentWithExtraText(QByteArray &buffer, const QTextBlock &block, bool s
|
||||
|
||||
if (nextLinePos > 0) {
|
||||
// If first try was not successful try to put ')' in the end of the line to close possibly
|
||||
// unclosed parentheses.
|
||||
// unclosed parenthesis.
|
||||
// TODO: Does it help to add different endings depending on the context?
|
||||
buffer.insert(nextLinePos, ')');
|
||||
extraLength += 1;
|
||||
@@ -300,18 +384,6 @@ bool doNotIndentInContext(QTextDocument *doc, int pos)
|
||||
return false;
|
||||
}
|
||||
|
||||
QTextBlock reverseFindLastEmptyBlock(QTextBlock start)
|
||||
{
|
||||
if (start.position() > 0) {
|
||||
start = start.previous();
|
||||
while (start.position() > 0 && start.text().trimmed().isEmpty())
|
||||
start = start.previous();
|
||||
if (!start.text().trimmed().isEmpty())
|
||||
start = start.next();
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
int formattingRangeStart(const QTextBlock ¤tBlock,
|
||||
const QByteArray &buffer,
|
||||
int documentRevision)
|
||||
@@ -355,23 +427,14 @@ TextEditor::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffer
|
||||
rangeStart = formattingRangeStart(startBlock, buffer, lastSaveRevision());
|
||||
|
||||
adjustFormatStyleForLineBreak(style, replacementsToKeep);
|
||||
if (typedChar == QChar::Null) {
|
||||
if (replacementsToKeep == ReplacementsToKeep::IndentAndBefore) {
|
||||
if (utf8Offset > 0) {
|
||||
buffer.insert(utf8Offset - 1, " //");
|
||||
utf8Offset += 3;
|
||||
}
|
||||
if (replacementsToKeep == ReplacementsToKeep::OnlyIndent) {
|
||||
CharacterContext currentCharContext = CharacterContext::Unknown;
|
||||
// Iterate backwards to reuse the same dummy text for all empty lines.
|
||||
for (int index = endBlock.blockNumber(); index >= startBlock.blockNumber(); --index) {
|
||||
utf8Length += forceIndentWithExtraText(buffer,
|
||||
cursorPositionInEditor < 0
|
||||
? endBlock
|
||||
: m_doc->findBlock(cursorPositionInEditor),
|
||||
currentCharContext,
|
||||
m_doc->findBlockByNumber(index),
|
||||
secondTry);
|
||||
} else {
|
||||
for (int index = startBlock.blockNumber(); index <= endBlock.blockNumber(); ++index) {
|
||||
utf8Length += forceIndentWithExtraText(buffer,
|
||||
m_doc->findBlockByNumber(index),
|
||||
secondTry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,9 +495,24 @@ TextEditor::Replacements ClangFormatBaseIndenter::format(
|
||||
static_cast<unsigned int>(utf8RangeLength));
|
||||
}
|
||||
|
||||
clang::format::FormatStyle style = styleForFile();
|
||||
const std::string assumedFileName = m_fileName.toString().toStdString();
|
||||
clang::tooling::Replacements clangReplacements = clang::format::sortIncludes(style,
|
||||
buffer.data(),
|
||||
ranges,
|
||||
assumedFileName);
|
||||
auto changedCode = clang::tooling::applyAllReplacements(buffer.data(), clangReplacements);
|
||||
QTC_ASSERT(changedCode, {
|
||||
qDebug() << QString::fromStdString(llvm::toString(changedCode.takeError()));
|
||||
return TextEditor::Replacements();
|
||||
});
|
||||
ranges = clang::tooling::calculateRangesAfterReplacements(clangReplacements, ranges);
|
||||
|
||||
clang::format::FormattingAttemptStatus status;
|
||||
const clang::tooling::Replacements clangReplacements
|
||||
= reformat(styleForFile(), buffer.data(), ranges, m_fileName.toString().toStdString(), &status);
|
||||
const clang::tooling::Replacements formatReplacements
|
||||
= reformat(style, *changedCode, ranges, m_fileName.toString().toStdString(), &status);
|
||||
clangReplacements = clangReplacements.merge(formatReplacements);
|
||||
|
||||
const TextEditor::Replacements toReplace = utf16Replacements(m_doc, buffer, clangReplacements);
|
||||
applyReplacements(m_doc, toReplace);
|
||||
|
||||
@@ -443,7 +521,6 @@ TextEditor::Replacements ClangFormatBaseIndenter::format(
|
||||
|
||||
TextEditor::Replacements ClangFormatBaseIndenter::indentsFor(QTextBlock startBlock,
|
||||
const QTextBlock &endBlock,
|
||||
const QByteArray &buffer,
|
||||
const QChar &typedChar,
|
||||
int cursorPositionInEditor)
|
||||
{
|
||||
@@ -461,10 +538,12 @@ TextEditor::Replacements ClangFormatBaseIndenter::indentsFor(QTextBlock startBlo
|
||||
cursorPositionInEditor += startBlock.position() - startBlockPosition;
|
||||
}
|
||||
|
||||
const QByteArray buffer = m_doc->toPlainText().toUtf8();
|
||||
|
||||
ReplacementsToKeep replacementsToKeep = ReplacementsToKeep::OnlyIndent;
|
||||
if (formatWhileTyping()
|
||||
&& (cursorPositionInEditor == -1 || cursorPositionInEditor >= startBlockPosition)
|
||||
&& (typedChar == QChar::Null || typedChar == ';' || typedChar == '}')) {
|
||||
&& (typedChar == ';' || typedChar == '}')) {
|
||||
// Format before current position only in case the cursor is inside the indented block.
|
||||
// So if cursor position is less then the block position then the current line is before
|
||||
// the indented block - don't trigger extra formatting in this case.
|
||||
@@ -487,9 +566,7 @@ void ClangFormatBaseIndenter::indentBlocks(const QTextBlock &startBlock,
|
||||
const QChar &typedChar,
|
||||
int cursorPositionInEditor)
|
||||
{
|
||||
const QByteArray buffer = m_doc->toPlainText().toUtf8();
|
||||
applyReplacements(m_doc,
|
||||
indentsFor(startBlock, endBlock, buffer, typedChar, cursorPositionInEditor));
|
||||
applyReplacements(m_doc, indentsFor(startBlock, endBlock, typedChar, cursorPositionInEditor));
|
||||
}
|
||||
|
||||
void ClangFormatBaseIndenter::indent(const QTextCursor &cursor,
|
||||
@@ -533,15 +610,14 @@ int ClangFormatBaseIndenter::indentFor(const QTextBlock &block,
|
||||
const TextEditor::TabSettings & /*tabSettings*/,
|
||||
int cursorPositionInEditor)
|
||||
{
|
||||
const QByteArray buffer = m_doc->toPlainText().toUtf8();
|
||||
TextEditor::Replacements toReplace = indentsFor(block,
|
||||
block,
|
||||
buffer,
|
||||
QChar::Null,
|
||||
cursorPositionInEditor);
|
||||
if (toReplace.empty())
|
||||
return -1;
|
||||
|
||||
const QByteArray buffer = m_doc->toPlainText().toUtf8();
|
||||
return indentationForBlock(toReplace, buffer, block);
|
||||
}
|
||||
|
||||
@@ -553,13 +629,12 @@ TextEditor::IndentationForBlock ClangFormatBaseIndenter::indentationForBlocks(
|
||||
TextEditor::IndentationForBlock ret;
|
||||
if (blocks.isEmpty())
|
||||
return ret;
|
||||
const QByteArray buffer = m_doc->toPlainText().toUtf8();
|
||||
TextEditor::Replacements toReplace = indentsFor(blocks.front(),
|
||||
blocks.back(),
|
||||
buffer,
|
||||
QChar::Null,
|
||||
cursorPositionInEditor);
|
||||
|
||||
const QByteArray buffer = m_doc->toPlainText().toUtf8();
|
||||
for (const QTextBlock &block : blocks)
|
||||
ret.insert(block.blockNumber(), indentationForBlock(toReplace, buffer, block));
|
||||
return ret;
|
||||
|
@@ -81,7 +81,6 @@ private:
|
||||
int cursorPositionInEditor);
|
||||
TextEditor::Replacements indentsFor(QTextBlock startBlock,
|
||||
const QTextBlock &endBlock,
|
||||
const QByteArray &buffer,
|
||||
const QChar &typedChar,
|
||||
int cursorPositionInEditor);
|
||||
TextEditor::Replacements replacements(QByteArray buffer,
|
||||
|
@@ -59,6 +59,24 @@ ClangFormatConfigWidget::ClangFormatConfigWidget(ProjectExplorer::Project *proje
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_preview = new TextEditor::SnippetEditorWidget(this);
|
||||
m_ui->horizontalLayout_2->addWidget(m_preview);
|
||||
if (m_project) {
|
||||
m_ui->applyButton->show();
|
||||
hideGlobalCheckboxes();
|
||||
m_ui->overrideDefault->setChecked(
|
||||
m_project->namedSettings(Constants::OVERRIDE_FILE_ID).toBool());
|
||||
} else {
|
||||
m_ui->applyButton->hide();
|
||||
showGlobalCheckboxes();
|
||||
m_ui->overrideDefault->setChecked(ClangFormatSettings::instance().overrideDefaultFile());
|
||||
}
|
||||
|
||||
connect(m_ui->overrideDefault, &QCheckBox::toggled, this, [this](bool checked) {
|
||||
if (checked)
|
||||
createStyleFileIfNeeded(!m_project);
|
||||
initialize();
|
||||
});
|
||||
initialize();
|
||||
}
|
||||
|
||||
@@ -81,15 +99,19 @@ void ClangFormatConfigWidget::showGlobalCheckboxes()
|
||||
m_ui->formatOnSave->show();
|
||||
}
|
||||
|
||||
static bool projectConfigExists()
|
||||
{
|
||||
return Utils::FileName::fromString(Core::ICore::userResourcePath())
|
||||
.appendPath("clang-format")
|
||||
.appendPath(currentProjectUniqueId())
|
||||
.appendPath((Constants::SETTINGS_FILE_NAME))
|
||||
.exists();
|
||||
}
|
||||
|
||||
void ClangFormatConfigWidget::initialize()
|
||||
{
|
||||
m_ui->projectHasClangFormat->show();
|
||||
m_ui->clangFormatOptionsTable->show();
|
||||
m_ui->applyButton->show();
|
||||
hideGlobalCheckboxes();
|
||||
m_ui->projectHasClangFormat->hide();
|
||||
|
||||
m_preview = new TextEditor::SnippetEditorWidget(this);
|
||||
m_ui->horizontalLayout_2->addWidget(m_preview);
|
||||
m_preview->setPlainText(QLatin1String(CppTools::Constants::DEFAULT_CODE_STYLE_SNIPPETS[0]));
|
||||
m_preview->textDocument()->setIndenter(new ClangFormatIndenter(m_preview->document()));
|
||||
m_preview->textDocument()->setFontSettings(TextEditor::TextEditorSettings::fontSettings());
|
||||
@@ -103,21 +125,15 @@ void ClangFormatConfigWidget::initialize()
|
||||
if (lastItem->spacerItem())
|
||||
m_ui->verticalLayout->removeItem(lastItem);
|
||||
|
||||
if (m_project
|
||||
&& !m_project->projectDirectory().appendPath(Constants::SETTINGS_FILE_NAME).exists()) {
|
||||
m_ui->projectHasClangFormat->setText(tr("No .clang-format file for the project."));
|
||||
if (!m_ui->overrideDefault->isChecked()) {
|
||||
m_ui->clangFormatOptionsTable->hide();
|
||||
m_ui->applyButton->hide();
|
||||
m_preview->hide();
|
||||
m_ui->verticalLayout->addStretch(1);
|
||||
|
||||
connect(m_ui->createFileButton, &QPushButton::clicked, this, [this]() {
|
||||
createStyleFileIfNeeded(false);
|
||||
initialize();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
m_ui->createFileButton->hide();
|
||||
m_ui->clangFormatOptionsTable->show();
|
||||
m_preview->show();
|
||||
|
||||
Utils::FileName fileName;
|
||||
if (m_project) {
|
||||
@@ -126,19 +142,13 @@ void ClangFormatConfigWidget::initialize()
|
||||
fileName = m_project->projectFilePath().appendPath("snippet.cpp");
|
||||
} else {
|
||||
const Project *currentProject = SessionManager::startupProject();
|
||||
if (!currentProject
|
||||
|| !currentProject->projectDirectory()
|
||||
.appendPath(Constants::SETTINGS_FILE_NAME)
|
||||
.exists()) {
|
||||
if (!currentProject || !projectConfigExists()) {
|
||||
m_ui->projectHasClangFormat->hide();
|
||||
} else {
|
||||
m_ui->projectHasClangFormat->setText(
|
||||
tr("Current project has its own .clang-format file "
|
||||
tr("Current project has its own overridden .clang-format file "
|
||||
"and can be configured in Projects > Code Style > C++."));
|
||||
}
|
||||
createStyleFileIfNeeded(true);
|
||||
showGlobalCheckboxes();
|
||||
m_ui->applyButton->hide();
|
||||
fileName = Utils::FileName::fromString(Core::ICore::userResourcePath())
|
||||
.appendPath("snippet.cpp");
|
||||
}
|
||||
@@ -160,7 +170,7 @@ void ClangFormatConfigWidget::fillTable()
|
||||
{
|
||||
clang::format::FormatStyle style = m_project ? currentProjectStyle() : currentGlobalStyle();
|
||||
|
||||
std::string configText = clang::format::configurationAsText(style);
|
||||
const std::string configText = clang::format::configurationAsText(style);
|
||||
m_ui->clangFormatOptionsTable->setPlainText(QString::fromStdString(configText));
|
||||
}
|
||||
|
||||
@@ -168,13 +178,19 @@ ClangFormatConfigWidget::~ClangFormatConfigWidget() = default;
|
||||
|
||||
void ClangFormatConfigWidget::apply()
|
||||
{
|
||||
ClangFormatSettings &settings = ClangFormatSettings::instance();
|
||||
if (!m_project) {
|
||||
ClangFormatSettings &settings = ClangFormatSettings::instance();
|
||||
settings.setFormatCodeInsteadOfIndent(m_ui->formatAlways->isChecked());
|
||||
settings.setFormatWhileTyping(m_ui->formatWhileTyping->isChecked());
|
||||
settings.setFormatOnSave(m_ui->formatOnSave->isChecked());
|
||||
settings.write();
|
||||
settings.setOverrideDefaultFile(m_ui->overrideDefault->isChecked());
|
||||
} else {
|
||||
m_project->setNamedSettings(Constants::OVERRIDE_FILE_ID, m_ui->overrideDefault->isChecked());
|
||||
}
|
||||
settings.write();
|
||||
|
||||
if (!m_ui->overrideDefault->isChecked())
|
||||
return;
|
||||
|
||||
const QString text = m_ui->clangFormatOptionsTable->toPlainText();
|
||||
clang::format::FormatStyle style;
|
||||
@@ -184,16 +200,18 @@ void ClangFormatConfigWidget::apply()
|
||||
QMessageBox::warning(this,
|
||||
tr("Error in ClangFormat configuration"),
|
||||
QString::fromStdString(error.message()));
|
||||
fillTable();
|
||||
updatePreview();
|
||||
if (m_ui->overrideDefault->isChecked()) {
|
||||
fillTable();
|
||||
updatePreview();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
QString filePath;
|
||||
QString filePath = Core::ICore::userResourcePath();
|
||||
if (m_project)
|
||||
filePath = m_project->projectDirectory().appendPath(Constants::SETTINGS_FILE_NAME).toString();
|
||||
else
|
||||
filePath = Core::ICore::userResourcePath() + "/" + Constants::SETTINGS_FILE_NAME;
|
||||
filePath += "/clang-format/" + currentProjectUniqueId();
|
||||
filePath += "/" + QLatin1String(Constants::SETTINGS_FILE_NAME);
|
||||
|
||||
QFile file(filePath);
|
||||
if (!file.open(QFile::WriteOnly))
|
||||
return;
|
||||
@@ -201,7 +219,8 @@ void ClangFormatConfigWidget::apply()
|
||||
file.write(text.toUtf8());
|
||||
file.close();
|
||||
|
||||
updatePreview();
|
||||
if (m_ui->overrideDefault->isChecked())
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
} // namespace ClangFormat
|
||||
|
@@ -54,6 +54,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="overrideDefault">
|
||||
<property name="text">
|
||||
<string>Override Clang Format configuration file</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
@@ -63,13 +70,6 @@
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="createFileButton">
|
||||
<property name="text">
|
||||
<string>Create Clang Format Configuration File</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="applyButton">
|
||||
<property name="text">
|
||||
|
@@ -34,5 +34,7 @@ static const char SETTINGS_ID[] = "ClangFormat";
|
||||
static const char FORMAT_CODE_INSTEAD_OF_INDENT_ID[] = "ClangFormat.FormatCodeInsteadOfIndent";
|
||||
static const char FORMAT_WHILE_TYPING_ID[] = "ClangFormat.FormatWhileTyping";
|
||||
static const char FORMAT_CODE_ON_SAVE_ID[] = "ClangFormat.FormatCodeOnSave";
|
||||
static const char OVERRIDE_FILE_ID[] = "ClangFormat.OverrideFile";
|
||||
static const char OPEN_CURRENT_CONFIG_ID[] = "ClangFormat.OpenCurrentConfig";
|
||||
} // namespace Constants
|
||||
} // namespace ClangFormat
|
||||
|
@@ -57,7 +57,7 @@ bool ClangFormatIndenter::formatWhileTyping() const
|
||||
|
||||
Utils::optional<TabSettings> ClangFormatIndenter::tabSettings() const
|
||||
{
|
||||
FormatStyle style = currentProjectStyle();
|
||||
FormatStyle style = styleForFile();
|
||||
TabSettings tabSettings;
|
||||
|
||||
switch (style.UseTab) {
|
||||
|
@@ -26,16 +26,23 @@
|
||||
#include "clangformatplugin.h"
|
||||
|
||||
#include "clangformatconfigwidget.h"
|
||||
#include "clangformatconstants.h"
|
||||
#include "clangformatindenter.h"
|
||||
#include "clangformatutils.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/idocument.h>
|
||||
|
||||
#include <cppeditor/cppeditorconstants.h>
|
||||
|
||||
#include <cpptools/cppcodestylepreferencesfactory.h>
|
||||
#include <cpptools/cpptoolsconstants.h>
|
||||
@@ -103,6 +110,48 @@ bool ClangFormatPlugin::initialize(const QStringList &arguments, QString *errorS
|
||||
Q_UNUSED(errorString);
|
||||
#ifdef KEEP_LINE_BREAKS_FOR_NON_EMPTY_LINES_BACKPORTED
|
||||
replaceCppCodeStyle();
|
||||
|
||||
Core::ActionContainer *contextMenu = Core::ActionManager::actionContainer(
|
||||
CppEditor::Constants::M_CONTEXT);
|
||||
if (contextMenu) {
|
||||
auto openClangFormatConfigAction
|
||||
= new QAction(tr("Open Used .clang-format Configuration File"), this);
|
||||
Core::Command *command
|
||||
= Core::ActionManager::registerAction(openClangFormatConfigAction,
|
||||
Constants::OPEN_CURRENT_CONFIG_ID);
|
||||
contextMenu->addSeparator();
|
||||
contextMenu->addAction(command);
|
||||
|
||||
if (Core::EditorManager::currentEditor()) {
|
||||
const Core::IDocument *doc = Core::EditorManager::currentEditor()->document();
|
||||
if (doc)
|
||||
openClangFormatConfigAction->setData(doc->filePath().toString());
|
||||
}
|
||||
|
||||
connect(openClangFormatConfigAction,
|
||||
&QAction::triggered,
|
||||
this,
|
||||
[openClangFormatConfigAction]() {
|
||||
const QString fileName = openClangFormatConfigAction->data().toString();
|
||||
if (!fileName.isEmpty()) {
|
||||
const QString clangFormatConfigPath = configForFile(
|
||||
Utils::FileName::fromString(fileName));
|
||||
Core::EditorManager::openEditor(clangFormatConfigPath);
|
||||
}
|
||||
});
|
||||
|
||||
connect(Core::EditorManager::instance(),
|
||||
&Core::EditorManager::currentEditorChanged,
|
||||
this,
|
||||
[openClangFormatConfigAction](Core::IEditor *editor) {
|
||||
if (!editor)
|
||||
return;
|
||||
|
||||
const Core::IDocument *doc = editor->document();
|
||||
if (doc)
|
||||
openClangFormatConfigAction->setData(doc->filePath().toString());
|
||||
});
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
@@ -46,6 +46,8 @@ ClangFormatSettings::ClangFormatSettings()
|
||||
.toBool();
|
||||
m_formatOnSave = settings->value(QLatin1String(Constants::FORMAT_CODE_ON_SAVE_ID), false)
|
||||
.toBool();
|
||||
m_overrideDefaultFile = settings->value(QLatin1String(Constants::OVERRIDE_FILE_ID), false)
|
||||
.toBool();
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
@@ -57,6 +59,7 @@ void ClangFormatSettings::write() const
|
||||
m_formatCodeInsteadOfIndent);
|
||||
settings->setValue(QLatin1String(Constants::FORMAT_WHILE_TYPING_ID), m_formatWhileTyping);
|
||||
settings->setValue(QLatin1String(Constants::FORMAT_CODE_ON_SAVE_ID), m_formatOnSave);
|
||||
settings->setValue(QLatin1String(Constants::OVERRIDE_FILE_ID), m_overrideDefaultFile);
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
@@ -90,4 +93,14 @@ bool ClangFormatSettings::formatOnSave() const
|
||||
return m_formatOnSave;
|
||||
}
|
||||
|
||||
void ClangFormatSettings::setOverrideDefaultFile(bool enable)
|
||||
{
|
||||
m_overrideDefaultFile = enable;
|
||||
}
|
||||
|
||||
bool ClangFormatSettings::overrideDefaultFile() const
|
||||
{
|
||||
return m_overrideDefaultFile;
|
||||
}
|
||||
|
||||
} // namespace ClangFormat
|
||||
|
@@ -25,6 +25,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace ClangFormat {
|
||||
|
||||
class ClangFormatSettings
|
||||
@@ -43,10 +45,14 @@ public:
|
||||
|
||||
void setFormatOnSave(bool enable);
|
||||
bool formatOnSave() const;
|
||||
|
||||
void setOverrideDefaultFile(bool enable);
|
||||
bool overrideDefaultFile() const;
|
||||
private:
|
||||
bool m_formatCodeInsteadOfIndent = false;
|
||||
bool m_formatWhileTyping = false;
|
||||
bool m_formatOnSave = false;
|
||||
bool m_overrideDefaultFile = false;
|
||||
};
|
||||
|
||||
} // namespace ClangFormat
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "clangformatutils.h"
|
||||
|
||||
#include "clangformatconstants.h"
|
||||
#include "clangformatsettings.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <cpptools/cppcodestylesettings.h>
|
||||
@@ -33,6 +34,8 @@
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/session.h>
|
||||
|
||||
#include <QCryptographicHash>
|
||||
|
||||
using namespace clang;
|
||||
using namespace format;
|
||||
using namespace llvm;
|
||||
@@ -42,6 +45,104 @@ using namespace TextEditor;
|
||||
|
||||
namespace ClangFormat {
|
||||
|
||||
static clang::format::FormatStyle qtcStyle()
|
||||
{
|
||||
clang::format::FormatStyle style = getLLVMStyle();
|
||||
style.Language = FormatStyle::LK_Cpp;
|
||||
style.AccessModifierOffset = -4;
|
||||
style.AlignAfterOpenBracket = FormatStyle::BAS_Align;
|
||||
style.AlignConsecutiveAssignments = false;
|
||||
style.AlignConsecutiveDeclarations = false;
|
||||
style.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign;
|
||||
style.AlignOperands = true;
|
||||
style.AlignTrailingComments = true;
|
||||
style.AllowAllParametersOfDeclarationOnNextLine = true;
|
||||
style.AllowShortBlocksOnASingleLine = false;
|
||||
style.AllowShortCaseLabelsOnASingleLine = false;
|
||||
style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
|
||||
style.AllowShortIfStatementsOnASingleLine = false;
|
||||
style.AllowShortLoopsOnASingleLine = false;
|
||||
style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
|
||||
style.AlwaysBreakBeforeMultilineStrings = false;
|
||||
style.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
|
||||
style.BinPackArguments = false;
|
||||
style.BinPackParameters = false;
|
||||
style.BraceWrapping.AfterClass = true;
|
||||
style.BraceWrapping.AfterControlStatement = false;
|
||||
style.BraceWrapping.AfterEnum = false;
|
||||
style.BraceWrapping.AfterFunction = true;
|
||||
style.BraceWrapping.AfterNamespace = false;
|
||||
style.BraceWrapping.AfterObjCDeclaration = false;
|
||||
style.BraceWrapping.AfterStruct = true;
|
||||
style.BraceWrapping.AfterUnion = false;
|
||||
style.BraceWrapping.BeforeCatch = false;
|
||||
style.BraceWrapping.BeforeElse = false;
|
||||
style.BraceWrapping.IndentBraces = false;
|
||||
style.BraceWrapping.SplitEmptyFunction = false;
|
||||
style.BraceWrapping.SplitEmptyRecord = false;
|
||||
style.BraceWrapping.SplitEmptyNamespace = false;
|
||||
style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
|
||||
style.BreakBeforeBraces = FormatStyle::BS_Custom;
|
||||
style.BreakBeforeTernaryOperators = true;
|
||||
style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
|
||||
style.BreakAfterJavaFieldAnnotations = false;
|
||||
style.BreakStringLiterals = true;
|
||||
style.ColumnLimit = 100;
|
||||
style.CommentPragmas = "^ IWYU pragma:";
|
||||
style.CompactNamespaces = false;
|
||||
style.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
|
||||
style.ConstructorInitializerIndentWidth = 4;
|
||||
style.ContinuationIndentWidth = 4;
|
||||
style.Cpp11BracedListStyle = true;
|
||||
style.DerivePointerAlignment = false;
|
||||
style.DisableFormat = false;
|
||||
style.ExperimentalAutoDetectBinPacking = false;
|
||||
style.FixNamespaceComments = true;
|
||||
style.ForEachMacros = {"forever", "foreach", "Q_FOREACH", "BOOST_FOREACH"};
|
||||
style.IncludeStyle.IncludeCategories = {{"^<Q.*", 200}};
|
||||
style.IncludeStyle.IncludeIsMainRegex = "(Test)?$";
|
||||
style.IndentCaseLabels = false;
|
||||
style.IndentWidth = 4;
|
||||
style.IndentWrappedFunctionNames = false;
|
||||
style.JavaScriptQuotes = FormatStyle::JSQS_Leave;
|
||||
style.JavaScriptWrapImports = true;
|
||||
style.KeepEmptyLinesAtTheStartOfBlocks = false;
|
||||
// Do not add QT_BEGIN_NAMESPACE/QT_END_NAMESPACE as this will indent lines in between.
|
||||
style.MacroBlockBegin = "";
|
||||
style.MacroBlockEnd = "";
|
||||
style.MaxEmptyLinesToKeep = 1;
|
||||
style.NamespaceIndentation = FormatStyle::NI_None;
|
||||
style.ObjCBlockIndentWidth = 4;
|
||||
style.ObjCSpaceAfterProperty = false;
|
||||
style.ObjCSpaceBeforeProtocolList = true;
|
||||
style.PenaltyBreakAssignment = 150;
|
||||
style.PenaltyBreakBeforeFirstCallParameter = 300;
|
||||
style.PenaltyBreakComment = 500;
|
||||
style.PenaltyBreakFirstLessLess = 400;
|
||||
style.PenaltyBreakString = 600;
|
||||
style.PenaltyExcessCharacter = 50;
|
||||
style.PenaltyReturnTypeOnItsOwnLine = 300;
|
||||
style.PointerAlignment = FormatStyle::PAS_Right;
|
||||
style.ReflowComments = false;
|
||||
style.SortIncludes = true;
|
||||
style.SortUsingDeclarations = true;
|
||||
style.SpaceAfterCStyleCast = true;
|
||||
style.SpaceAfterTemplateKeyword = false;
|
||||
style.SpaceBeforeAssignmentOperators = true;
|
||||
style.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
|
||||
style.SpaceInEmptyParentheses = false;
|
||||
style.SpacesBeforeTrailingComments = 1;
|
||||
style.SpacesInAngles = false;
|
||||
style.SpacesInContainerLiterals = false;
|
||||
style.SpacesInCStyleCastParentheses = false;
|
||||
style.SpacesInParentheses = false;
|
||||
style.SpacesInSquareBrackets = false;
|
||||
style.Standard = FormatStyle::LS_Cpp11;
|
||||
style.TabWidth = 4;
|
||||
style.UseTab = FormatStyle::UT_Never;
|
||||
return style;
|
||||
}
|
||||
|
||||
static void applyTabSettings(clang::format::FormatStyle &style, const TabSettings &settings)
|
||||
{
|
||||
style.IndentWidth = static_cast<unsigned>(settings.m_indentSize);
|
||||
@@ -63,42 +164,26 @@ static void applyTabSettings(clang::format::FormatStyle &style, const TabSetting
|
||||
}
|
||||
}
|
||||
|
||||
static void applyCppCodeStyleSettings(clang::format::FormatStyle &style,
|
||||
const CppCodeStyleSettings &settings)
|
||||
static bool useGlobalOverriddenSettings()
|
||||
{
|
||||
style.IndentCaseLabels = settings.indentSwitchLabels;
|
||||
style.AlignOperands = settings.alignAssignments;
|
||||
style.NamespaceIndentation = FormatStyle::NI_None;
|
||||
if (settings.indentNamespaceBody)
|
||||
style.NamespaceIndentation = FormatStyle::NI_All;
|
||||
|
||||
style.BraceWrapping.IndentBraces = false;
|
||||
if (settings.indentBlockBraces) {
|
||||
if (settings.indentClassBraces && settings.indentEnumBraces
|
||||
&& settings.indentNamespaceBraces && settings.indentFunctionBraces) {
|
||||
style.BraceWrapping.IndentBraces = true;
|
||||
} else {
|
||||
style.BreakBeforeBraces = FormatStyle::BS_GNU;
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.bindStarToIdentifier || settings.bindStarToRightSpecifier)
|
||||
style.PointerAlignment = FormatStyle::PAS_Right;
|
||||
else
|
||||
style.PointerAlignment = FormatStyle::PAS_Left;
|
||||
|
||||
style.AccessModifierOffset = settings.indentAccessSpecifiers
|
||||
? 0
|
||||
: - static_cast<int>(style.IndentWidth);
|
||||
return ClangFormatSettings::instance().overrideDefaultFile();
|
||||
}
|
||||
|
||||
static Utils::FileName projectPath()
|
||||
QString currentProjectUniqueId()
|
||||
{
|
||||
const Project *project = SessionManager::startupProject();
|
||||
if (project)
|
||||
return project->projectDirectory();
|
||||
if (!project)
|
||||
return QString();
|
||||
|
||||
return Utils::FileName();
|
||||
return QString::fromUtf8(QCryptographicHash::hash(project->projectFilePath().toString().toUtf8(),
|
||||
QCryptographicHash::Md5)
|
||||
.toHex(0));
|
||||
}
|
||||
|
||||
static bool useProjectOverriddenSettings()
|
||||
{
|
||||
const Project *project = SessionManager::startupProject();
|
||||
return project ? project->namedSettings(Constants::OVERRIDE_FILE_ID).toBool() : false;
|
||||
}
|
||||
|
||||
static Utils::FileName globalPath()
|
||||
@@ -106,29 +191,59 @@ static Utils::FileName globalPath()
|
||||
return Utils::FileName::fromString(Core::ICore::userResourcePath());
|
||||
}
|
||||
|
||||
static QString configForFile(Utils::FileName fileName)
|
||||
static Utils::FileName projectPath()
|
||||
{
|
||||
Utils::FileName topProjectPath = projectPath();
|
||||
if (topProjectPath.isEmpty())
|
||||
return QString();
|
||||
const Project *project = SessionManager::startupProject();
|
||||
if (project)
|
||||
return globalPath().appendPath("clang-format").appendPath(currentProjectUniqueId());
|
||||
|
||||
QDir projectDir(fileName.parentDir().toString());
|
||||
while (!projectDir.exists(Constants::SETTINGS_FILE_NAME)
|
||||
&& !projectDir.exists(Constants::SETTINGS_FILE_ALT_NAME)) {
|
||||
if (projectDir.path() == topProjectPath.toString()
|
||||
|| !Utils::FileName::fromString(projectDir.path()).isChildOf(topProjectPath)
|
||||
|| !projectDir.cdUp()) {
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
if (projectDir.exists(Constants::SETTINGS_FILE_NAME))
|
||||
return projectDir.filePath(Constants::SETTINGS_FILE_NAME);
|
||||
return projectDir.filePath(Constants::SETTINGS_FILE_ALT_NAME);
|
||||
return Utils::FileName();
|
||||
}
|
||||
|
||||
static clang::format::FormatStyle constructStyle(bool isGlobal,
|
||||
const QByteArray &baseStyle = QByteArray())
|
||||
static QString findConfig(Utils::FileName fileName)
|
||||
{
|
||||
QDir parentDir(fileName.parentDir().toString());
|
||||
while (!parentDir.exists(Constants::SETTINGS_FILE_NAME)
|
||||
&& !parentDir.exists(Constants::SETTINGS_FILE_ALT_NAME)) {
|
||||
if (!parentDir.cdUp())
|
||||
return QString();
|
||||
}
|
||||
|
||||
if (parentDir.exists(Constants::SETTINGS_FILE_NAME))
|
||||
return parentDir.filePath(Constants::SETTINGS_FILE_NAME);
|
||||
return parentDir.filePath(Constants::SETTINGS_FILE_ALT_NAME);
|
||||
}
|
||||
|
||||
static QString configForFile(Utils::FileName fileName, bool checkForSettings)
|
||||
{
|
||||
QDir overrideDir;
|
||||
if (!checkForSettings || useProjectOverriddenSettings()) {
|
||||
overrideDir = projectPath().toString();
|
||||
if (!overrideDir.isEmpty() && overrideDir.exists(Constants::SETTINGS_FILE_NAME))
|
||||
return overrideDir.filePath(Constants::SETTINGS_FILE_NAME);
|
||||
}
|
||||
|
||||
if (!checkForSettings || useGlobalOverriddenSettings()) {
|
||||
overrideDir = globalPath().toString();
|
||||
if (!overrideDir.isEmpty() && overrideDir.exists(Constants::SETTINGS_FILE_NAME))
|
||||
return overrideDir.filePath(Constants::SETTINGS_FILE_NAME);
|
||||
}
|
||||
|
||||
return findConfig(fileName);
|
||||
}
|
||||
|
||||
QString configForFile(Utils::FileName fileName)
|
||||
{
|
||||
return configForFile(fileName, true);
|
||||
}
|
||||
|
||||
Utils::FileName assumedPathForConfig(const QString &configFile)
|
||||
{
|
||||
Utils::FileName fileName = Utils::FileName::fromString(configFile);
|
||||
return fileName.parentDir().appendPath("test.cpp");
|
||||
}
|
||||
|
||||
static clang::format::FormatStyle constructStyle(const QByteArray &baseStyle = QByteArray())
|
||||
{
|
||||
if (!baseStyle.isEmpty()) {
|
||||
// Try to get the style for this base style.
|
||||
@@ -144,21 +259,7 @@ static clang::format::FormatStyle constructStyle(bool isGlobal,
|
||||
// Fallthrough to the default style.
|
||||
}
|
||||
|
||||
FormatStyle style = getLLVMStyle();
|
||||
style.BreakBeforeBraces = FormatStyle::BS_Custom;
|
||||
|
||||
const CppCodeStyleSettings codeStyleSettings = isGlobal
|
||||
? CppCodeStyleSettings::currentGlobalCodeStyle()
|
||||
: CppCodeStyleSettings::currentProjectCodeStyle()
|
||||
.value_or(CppCodeStyleSettings::currentGlobalCodeStyle());
|
||||
const TabSettings tabSettings = isGlobal
|
||||
? CppCodeStyleSettings::currentGlobalTabSettings()
|
||||
: CppCodeStyleSettings::currentProjectTabSettings();
|
||||
|
||||
applyTabSettings(style, tabSettings);
|
||||
applyCppCodeStyleSettings(style, codeStyleSettings);
|
||||
|
||||
return style;
|
||||
return qtcStyle();
|
||||
}
|
||||
|
||||
void createStyleFileIfNeeded(bool isGlobal)
|
||||
@@ -169,9 +270,21 @@ void createStyleFileIfNeeded(bool isGlobal)
|
||||
if (QFile::exists(configFile))
|
||||
return;
|
||||
|
||||
QDir().mkpath(path.parentDir().toString());
|
||||
if (!isGlobal) {
|
||||
const Project *project = SessionManager::startupProject();
|
||||
Utils::FileName possibleProjectConfig = project->rootProjectDirectory().appendPath(
|
||||
Constants::SETTINGS_FILE_NAME);
|
||||
if (possibleProjectConfig.exists()) {
|
||||
// Just copy th .clang-format if current project has one.
|
||||
QFile::copy(possibleProjectConfig.toString(), configFile);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::fstream newStyleFile(configFile.toStdString(), std::fstream::out);
|
||||
if (newStyleFile.is_open()) {
|
||||
newStyleFile << clang::format::configurationAsText(constructStyle(isGlobal));
|
||||
newStyleFile << clang::format::configurationAsText(constructStyle());
|
||||
newStyleFile.close();
|
||||
}
|
||||
}
|
||||
@@ -198,17 +311,13 @@ static QByteArray configBaseStyleName(const QString &configFile)
|
||||
.trimmed();
|
||||
}
|
||||
|
||||
clang::format::FormatStyle styleForFile(Utils::FileName fileName)
|
||||
static clang::format::FormatStyle styleForFile(Utils::FileName fileName, bool checkForSettings)
|
||||
{
|
||||
bool isGlobal = false;
|
||||
QString configFile = configForFile(fileName);
|
||||
if (configFile.isEmpty()) {
|
||||
Utils::FileName path = fileName = globalPath();
|
||||
fileName.appendPath(Constants::SAMPLE_FILE_NAME);
|
||||
createStyleFileIfNeeded(true);
|
||||
configFile = path.appendPath(Constants::SETTINGS_FILE_NAME).toString();
|
||||
}
|
||||
QString configFile = configForFile(fileName, checkForSettings);
|
||||
if (configFile.isEmpty())
|
||||
return constructStyle();
|
||||
|
||||
fileName = assumedPathForConfig(configFile);
|
||||
Expected<FormatStyle> style = format::getStyle("file",
|
||||
fileName.toString().toStdString(),
|
||||
"none");
|
||||
@@ -219,17 +328,21 @@ clang::format::FormatStyle styleForFile(Utils::FileName fileName)
|
||||
// do nothing
|
||||
});
|
||||
|
||||
return constructStyle(isGlobal, configBaseStyleName(configFile));
|
||||
return constructStyle(configBaseStyleName(configFile));
|
||||
}
|
||||
|
||||
clang::format::FormatStyle styleForFile(Utils::FileName fileName)
|
||||
{
|
||||
return styleForFile(fileName, true);
|
||||
}
|
||||
|
||||
clang::format::FormatStyle currentProjectStyle()
|
||||
{
|
||||
return styleForFile(projectPath().appendPath(Constants::SAMPLE_FILE_NAME));
|
||||
return styleForFile(projectPath().appendPath(Constants::SAMPLE_FILE_NAME), false);
|
||||
}
|
||||
|
||||
clang::format::FormatStyle currentGlobalStyle()
|
||||
{
|
||||
return styleForFile(globalPath().appendPath(Constants::SAMPLE_FILE_NAME));
|
||||
}
|
||||
|
||||
return styleForFile(globalPath().appendPath(Constants::SAMPLE_FILE_NAME), false);
|
||||
}
|
||||
} // namespace ClangFormat
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <coreplugin/id.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <clang/Format/Format.h>
|
||||
|
||||
@@ -37,10 +38,13 @@ namespace ClangFormat {
|
||||
// Creates the style for the current project or the global style if needed.
|
||||
void createStyleFileIfNeeded(bool isGlobal);
|
||||
|
||||
QString currentProjectUniqueId();
|
||||
|
||||
clang::format::FormatStyle currentProjectStyle();
|
||||
clang::format::FormatStyle currentGlobalStyle();
|
||||
|
||||
// Is the style from the matching .clang-format file or global one if it's not found.
|
||||
QString configForFile(Utils::FileName fileName);
|
||||
clang::format::FormatStyle styleForFile(Utils::FileName fileName);
|
||||
|
||||
}
|
||||
|
@@ -452,12 +452,12 @@ void ClangTidyClazyTool::handleStateUpdate()
|
||||
if (issuesFound)
|
||||
message = tr("Running - %n diagnostics", nullptr, issuesFound);
|
||||
else
|
||||
message = tr("Running - No diagnostics", nullptr, issuesFound);
|
||||
message = tr("Running - No diagnostics");
|
||||
} else {
|
||||
if (issuesFound)
|
||||
message = tr("Finished - %n diagnostics", nullptr, issuesFound);
|
||||
else
|
||||
message = tr("Finished - No diagnostics", nullptr, issuesFound);
|
||||
message = tr("Finished - No diagnostics");
|
||||
}
|
||||
|
||||
Debugger::showPermanentStatusMessage(message);
|
||||
|
@@ -78,6 +78,21 @@ void SearchResultTreeView::addResults(const QList<SearchResultItem> &items, Sear
|
||||
}
|
||||
}
|
||||
|
||||
void SearchResultTreeView::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if ((event->key() == Qt::Key_Return
|
||||
|| event->key() == Qt::Key_Enter)
|
||||
&& event->modifiers() == 0
|
||||
&& currentIndex().isValid()
|
||||
&& state() != QAbstractItemView::EditingState) {
|
||||
const SearchResultItem item
|
||||
= model()->data(currentIndex(), ItemDataRoles::ResultItemRole).value<SearchResultItem>();
|
||||
emit jumpToSearchResult(item);
|
||||
return;
|
||||
}
|
||||
TreeView::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void SearchResultTreeView::emitJumpToSearchResult(const QModelIndex &index)
|
||||
{
|
||||
if (model()->data(index, ItemDataRoles::IsGeneratedRole).toBool())
|
||||
|
@@ -49,6 +49,8 @@ public:
|
||||
SearchResultTreeModel *model() const;
|
||||
void addResults(const QList<SearchResultItem> &items, SearchResult::AddMode mode);
|
||||
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
signals:
|
||||
void jumpToSearchResult(const SearchResultItem &item);
|
||||
|
||||
|
@@ -84,10 +84,9 @@ public:
|
||||
const Links &links() const;
|
||||
const Links bestLinks() const;
|
||||
const QString keyword() const;
|
||||
|
||||
private:
|
||||
bool isFuzzyMatch() const;
|
||||
|
||||
private:
|
||||
QUrl m_helpUrl;
|
||||
QStringList m_helpIds;
|
||||
QString m_docMark;
|
||||
|
@@ -252,6 +252,14 @@ void LocatorModel::addEntries(const QList<LocatorFilterEntry> &entries)
|
||||
CompletionList::CompletionList(QWidget *parent)
|
||||
: Utils::TreeView(parent)
|
||||
{
|
||||
// on macOS and Windows the popup doesn't really get focus, so fake the selection color
|
||||
// which would then just be a very light gray, but should look as if it had focus
|
||||
QPalette p = palette();
|
||||
p.setBrush(QPalette::Inactive,
|
||||
QPalette::Highlight,
|
||||
p.brush(QPalette::Normal, QPalette::Highlight));
|
||||
setPalette(p);
|
||||
|
||||
setItemDelegate(new CompletionDelegate(this));
|
||||
setRootIsDecorated(false);
|
||||
setUniformRowHeights(true);
|
||||
|
@@ -507,7 +507,6 @@ void OutputPaneManager::showPage(int idx, int flags)
|
||||
|
||||
ensurePageVisible(idx);
|
||||
IOutputPane *out = g_outputPanes.at(idx).pane;
|
||||
out->visibilityChanged(true);
|
||||
if (flags & IOutputPane::WithFocus) {
|
||||
if (out->canFocus())
|
||||
out->setFocus();
|
||||
@@ -538,7 +537,10 @@ void OutputPaneManager::setCurrentIndex(int idx)
|
||||
m_outputWidgetPane->setCurrentIndex(idx);
|
||||
m_opToolBarWidgets->setCurrentIndex(idx);
|
||||
|
||||
IOutputPane *pane = g_outputPanes.at(idx).pane;
|
||||
OutputPaneData &data = g_outputPanes[idx];
|
||||
IOutputPane *pane = data.pane;
|
||||
data.button->show();
|
||||
data.buttonVisible = true;
|
||||
pane->visibilityChanged(true);
|
||||
|
||||
bool canNavigate = pane->canNavigate();
|
||||
@@ -574,8 +576,6 @@ void OutputPaneManager::popupMenu()
|
||||
data.button->hide();
|
||||
data.buttonVisible = false;
|
||||
} else {
|
||||
data.button->show();
|
||||
data.buttonVisible = true;
|
||||
showPage(idx, IOutputPane::ModeSwitch);
|
||||
}
|
||||
}
|
||||
|
@@ -860,11 +860,11 @@ void ClangDiagnosticConfigsWidget::syncClazyChecksGroupBox()
|
||||
return !m_clazySortFilterProxyModel->filterAcceptsRow(index.row(), index.parent());
|
||||
};
|
||||
const bool hasEnabledButHidden = m_clazyTreeModel->hasEnabledButNotVisibleChecks(isHidden);
|
||||
const QString title = hasEnabledButHidden ? tr("Checks (%1 enabled, some are filtered out)")
|
||||
: tr("Checks (%1 enabled)");
|
||||
|
||||
const QStringList checks = m_clazyTreeModel->enabledChecks();
|
||||
m_clazyChecks->checksGroupBox->setTitle(title.arg(checks.count()));
|
||||
const int checksCount = m_clazyTreeModel->enabledChecks().count();
|
||||
const QString title = hasEnabledButHidden ? tr("Checks (%n enabled, some are filtered out)",
|
||||
nullptr, checksCount)
|
||||
: tr("Checks (%n enabled)", nullptr, checksCount);
|
||||
m_clazyChecks->checksGroupBox->setTitle(title);
|
||||
}
|
||||
|
||||
void ClangDiagnosticConfigsWidget::updateConfig(const ClangDiagnosticConfig &config)
|
||||
|
@@ -172,7 +172,7 @@ void CompilerOptionsBuilder::addSyntaxOnly()
|
||||
isClStyle() ? add("/Zs") : add("-fsyntax-only");
|
||||
}
|
||||
|
||||
static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt)
|
||||
QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt)
|
||||
{
|
||||
QStringList options;
|
||||
|
||||
@@ -741,6 +741,15 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (option.startsWith("/Y", Qt::CaseSensitive)
|
||||
|| (option.startsWith("/F", Qt::CaseSensitive) && option != "/F")) {
|
||||
// Precompiled header flags.
|
||||
// Skip also the next option if it's not glued to the current one.
|
||||
if (option.size() > 3)
|
||||
skipNext = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check whether a language version is already used.
|
||||
QString theOption = option;
|
||||
if (theOption.startsWith("-std=")) {
|
||||
|
@@ -40,6 +40,7 @@ enum class UseBuildSystemWarnings : char { Yes, No };
|
||||
|
||||
CPPTOOLS_EXPORT QStringList XclangArgs(const QStringList &args);
|
||||
CPPTOOLS_EXPORT QStringList clangArgsForCl(const QStringList &args);
|
||||
CPPTOOLS_EXPORT QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt);
|
||||
|
||||
class CPPTOOLS_EXPORT CompilerOptionsBuilder
|
||||
{
|
||||
|
@@ -99,10 +99,10 @@ These prefixes are used in addition to current file name on Switch Header/Source
|
||||
<item row="7" column="1">
|
||||
<widget class="QCheckBox" name="headerPragmaOnceCheckBox">
|
||||
<property name="toolTip">
|
||||
<string>Uses #pragma once instead of #ifndef include guards.</string>
|
||||
<string>Uses "#pragma once" instead of "#ifndef" include guards.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use '#pragma once' instead of '#ifndef' guards</string>
|
||||
<string>Use "#pragma once" instead of "#ifndef" guards</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@@ -211,7 +211,7 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
|
||||
|
||||
expander->registerVariable(
|
||||
"Cpp:PragmaOnce",
|
||||
tr("Insert #pragma once instead of #ifndef include guards into header file"),
|
||||
tr("Insert \"#pragma once\" instead of \"#ifndef\" include guards into header file"),
|
||||
[] { return usePragmaOnce() ? QString("true") : QString(); });
|
||||
|
||||
return true;
|
||||
|
@@ -58,7 +58,7 @@ public:
|
||||
|
||||
QWidget *outputWidget(QWidget *) override;
|
||||
QList<QWidget *> toolBarWidgets() const override;
|
||||
QString displayName() const override { return tr("Debugger Console"); }
|
||||
QString displayName() const override { return tr("QML Debugger Console"); }
|
||||
int priorityInStatusBar() const override;
|
||||
void clearContents() override;
|
||||
void visibilityChanged(bool visible) override;
|
||||
|
@@ -748,7 +748,8 @@ void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers()
|
||||
dir.setPath(base.toFileInfo().absoluteFilePath());
|
||||
foreach (const QString &entry, dir.entryList()) {
|
||||
if (entry.startsWith("lldb-platform-")
|
||||
|| entry.startsWith("lldb-gdbserver-")) {
|
||||
|| entry.startsWith("lldb-gdbserver-")
|
||||
|| entry.startsWith("lldb-mi-")) {
|
||||
continue;
|
||||
}
|
||||
suspects.append(FileName::fromString(dir.absoluteFilePath(entry)));
|
||||
|
@@ -152,24 +152,7 @@ DebuggerKitAspect::DebuggerKitAspect()
|
||||
setPriority(28000);
|
||||
}
|
||||
|
||||
QVariant DebuggerKitAspect::defaultValue(const Kit *k) const
|
||||
{
|
||||
const Abi toolChainAbi = ToolChainKitAspect::targetAbi(k);
|
||||
const Utils::FileNameList paths = Environment::systemEnvironment().path();
|
||||
QVariant nextBestFit;
|
||||
for (const DebuggerItem &item : DebuggerItemManager::debuggers()) {
|
||||
for (const Abi &targetAbi : item.abis()) {
|
||||
if (targetAbi.isCompatibleWith(toolChainAbi)) {
|
||||
if (paths.contains(item.command()))
|
||||
return item.id(); // prefer debuggers found in PATH over those found elsewhere
|
||||
if (nextBestFit.isNull())
|
||||
nextBestFit = item.id();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nextBestFit;
|
||||
}
|
||||
QVariant DebuggerKitAspect::defaultValue(const Kit *) const { return QVariant(); }
|
||||
|
||||
void DebuggerKitAspect::setup(Kit *k)
|
||||
{
|
||||
|
@@ -119,6 +119,7 @@ public:
|
||||
void resetCurrentPerspective();
|
||||
int indexInChooser(Perspective *perspective) const;
|
||||
void fixupLayoutIfNeeded();
|
||||
void updatePerspectiveChooserWidth();
|
||||
|
||||
DebuggerMainWindow *q = nullptr;
|
||||
Perspective *m_currentPerspective = nullptr;
|
||||
@@ -416,10 +417,17 @@ void DebuggerMainWindowPrivate::selectPerspective(Perspective *perspective)
|
||||
fixupLayoutIfNeeded();
|
||||
}
|
||||
|
||||
updatePerspectiveChooserWidth();
|
||||
}
|
||||
|
||||
void DebuggerMainWindowPrivate::updatePerspectiveChooserWidth()
|
||||
{
|
||||
Perspective *perspective = m_currentPerspective;
|
||||
int index = indexInChooser(m_currentPerspective);
|
||||
if (index == -1) {
|
||||
if (Perspective *parent = Perspective::findPerspective(m_currentPerspective->d->m_parentPerspectiveId))
|
||||
index = indexInChooser(parent);
|
||||
perspective = Perspective::findPerspective(m_currentPerspective->d->m_parentPerspectiveId);
|
||||
if (perspective)
|
||||
index = indexInChooser(perspective);
|
||||
}
|
||||
|
||||
if (index != -1) {
|
||||
|
@@ -61,6 +61,7 @@
|
||||
#include <utils/temporarydirectory.h>
|
||||
#include <utils/temporaryfile.h>
|
||||
#include <utils/url.h>
|
||||
#include <utils/winutils.h>
|
||||
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <coreplugin/icore.h>
|
||||
@@ -565,6 +566,17 @@ void DebuggerRunTool::start()
|
||||
if (!fixupParameters())
|
||||
return;
|
||||
|
||||
if (m_runParameters.cppEngineType == CdbEngineType
|
||||
&& Utils::is64BitWindowsBinary(m_runParameters.inferior.executable)
|
||||
&& !Utils::is64BitWindowsBinary(m_runParameters.debugger.executable)) {
|
||||
reportFailure(
|
||||
DebuggerPlugin::tr(
|
||||
"%1 is a 64 bit executable which can not be debugged by a 32 bit Debugger.\n"
|
||||
"Please select a 64 bit Debugger in the kit settings for this kit.")
|
||||
.arg(m_runParameters.inferior.executable));
|
||||
return;
|
||||
}
|
||||
|
||||
Utils::globalMacroExpander()->registerFileVariables(
|
||||
"DebuggedExecutable", tr("Debugged executable"),
|
||||
[this] { return m_runParameters.inferior.executable; }
|
||||
|
@@ -395,6 +395,8 @@ void LldbEngine::handleResponse(const QString &response)
|
||||
handleOutputNotification(item);
|
||||
else if (name == "pid")
|
||||
notifyInferiorPid(item.toProcessHandle());
|
||||
else if (name == "breakpointmodified")
|
||||
handleInterpreterBreakpointModified(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -607,6 +609,31 @@ void LldbEngine::handleOutputNotification(const GdbMi &output)
|
||||
showMessage(data, ch);
|
||||
}
|
||||
|
||||
void LldbEngine::handleInterpreterBreakpointModified(const GdbMi &bpItem)
|
||||
{
|
||||
QTC_ASSERT(bpItem.childCount(), return);
|
||||
QString id = bpItem.childAt(0).m_data;
|
||||
|
||||
Breakpoint bp = breakHandler()->findBreakpointByResponseId(id);
|
||||
if (!bp) // FIXME adapt whole bp handling and turn into soft assert
|
||||
return;
|
||||
|
||||
// this function got triggered by a lldb internal breakpoint event
|
||||
// avoid asserts regarding unexpected state transitions
|
||||
switch (bp->state()) {
|
||||
case BreakpointInsertionRequested: // was a pending bp
|
||||
bp->gotoState(BreakpointInsertionProceeding, BreakpointInsertionRequested);
|
||||
break;
|
||||
case BreakpointInserted: // was an inserted, gets updated now
|
||||
bp->gotoState(BreakpointUpdateRequested, BreakpointInserted);
|
||||
notifyBreakpointChangeProceeding(bp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
updateBreakpointData(bp, bpItem, false);
|
||||
}
|
||||
|
||||
void LldbEngine::loadSymbols(const QString &moduleName)
|
||||
{
|
||||
Q_UNUSED(moduleName)
|
||||
|
@@ -120,6 +120,7 @@ private:
|
||||
void handleStateNotification(const GdbMi &item);
|
||||
void handleLocationNotification(const GdbMi &location);
|
||||
void handleOutputNotification(const GdbMi &output);
|
||||
void handleInterpreterBreakpointModified(const GdbMi &item);
|
||||
|
||||
void handleResponse(const QString &data);
|
||||
void updateAll() override;
|
||||
|
@@ -657,7 +657,7 @@ void HelpPluginPrivate::showContextHelp(const HelpItem &contextHelp)
|
||||
.arg(contextHelp.helpIds().join(", "))
|
||||
.arg(HelpPlugin::tr("No documentation available.")));
|
||||
}
|
||||
} else if (links.size() == 1) {
|
||||
} else if (links.size() == 1 && !contextHelp.isFuzzyMatch()) {
|
||||
showHelpUrl(links.front().second, LocalHelpManager::contextHelpOption());
|
||||
} else {
|
||||
QMap<QString, QUrl> map;
|
||||
|
@@ -208,17 +208,6 @@ void Client::openDocument(Core::IDocument *document)
|
||||
connect(textDocument, &QObject::destroyed, this, [this, textDocument]{
|
||||
m_resetAssistProvider.remove(textDocument);
|
||||
});
|
||||
if (BaseTextEditor *editor = BaseTextEditor::textEditorForDocument(textDocument)) {
|
||||
if (QPointer<TextEditorWidget> widget = editor->editorWidget()) {
|
||||
connect(widget, &TextEditorWidget::cursorPositionChanged, this, [this, widget](){
|
||||
// TODO This would better be a compressing timer
|
||||
QTimer::singleShot(50, this, [this, widget]() {
|
||||
if (widget)
|
||||
cursorPositionChanged(widget);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_openedDocument.append(document->filePath());
|
||||
@@ -344,7 +333,7 @@ void Client::documentContentsChanged(Core::IDocument *document)
|
||||
|
||||
if (textDocument) {
|
||||
using namespace TextEditor;
|
||||
if (BaseTextEditor *editor = BaseTextEditor::textEditorForDocument(textDocument))
|
||||
for (BaseTextEditor *editor : BaseTextEditor::textEditorsForDocument(textDocument))
|
||||
if (TextEditorWidget *widget = editor->editorWidget())
|
||||
widget->setRefactorMarkers(RefactorMarker::filterOutType(widget->refactorMarkers(), id()));
|
||||
requestDocumentSymbols(textDocument);
|
||||
@@ -766,6 +755,11 @@ const DynamicCapabilities &Client::dynamicCapabilities() const
|
||||
return m_dynamicCapabilities;
|
||||
}
|
||||
|
||||
const BaseClientInterface *Client::clientInterface() const
|
||||
{
|
||||
return m_clientInterface.data();
|
||||
}
|
||||
|
||||
void Client::log(const ShowMessageParams &message,
|
||||
Core::MessageManager::PrintToOutputPaneFlag flag)
|
||||
{
|
||||
|
@@ -147,6 +147,7 @@ public:
|
||||
|
||||
const LanguageServerProtocol::ServerCapabilities &capabilities() const;
|
||||
const DynamicCapabilities &dynamicCapabilities() const;
|
||||
const BaseClientInterface *clientInterface() const;
|
||||
|
||||
signals:
|
||||
void initialized(LanguageServerProtocol::ServerCapabilities capabilities);
|
||||
|
@@ -110,7 +110,7 @@ StdIOClientInterface::~StdIOClientInterface()
|
||||
Utils::SynchronousProcess::stopProcess(m_process);
|
||||
}
|
||||
|
||||
bool StdIOClientInterface::needsRestart(const StdIOSettings *settings)
|
||||
bool StdIOClientInterface::needsRestart(const StdIOSettings *settings) const
|
||||
{
|
||||
return m_executable != settings->m_executable || m_arguments != settings->m_arguments;
|
||||
}
|
||||
|
@@ -74,7 +74,7 @@ public:
|
||||
StdIOClientInterface &operator=(const StdIOClientInterface &) = delete;
|
||||
StdIOClientInterface &operator=(StdIOClientInterface &&) = delete;
|
||||
|
||||
bool needsRestart(const StdIOSettings *settings);
|
||||
bool needsRestart(const StdIOSettings *settings) const;
|
||||
|
||||
bool start() override;
|
||||
|
||||
|
@@ -125,7 +125,10 @@ void LanguageClientManager::deleteClient(Client *client)
|
||||
QTC_ASSERT(client, return);
|
||||
client->disconnect();
|
||||
managerInstance->m_clients.removeAll(client);
|
||||
client->deleteLater();
|
||||
if (managerInstance->m_shuttingDown)
|
||||
delete client;
|
||||
else
|
||||
client->deleteLater();
|
||||
}
|
||||
|
||||
void LanguageClientManager::shutdown()
|
||||
@@ -210,6 +213,18 @@ void LanguageClientManager::editorOpened(Core::IEditor *editor)
|
||||
(const QTextCursor &cursor){
|
||||
findUsages(filePath, cursor);
|
||||
});
|
||||
connect(widget, &TextEditorWidget::cursorPositionChanged, this, [this, widget](){
|
||||
// TODO This would better be a compressing timer
|
||||
QTimer::singleShot(50, this,
|
||||
[this, widget = QPointer<TextEditorWidget>(widget)]() {
|
||||
if (widget) {
|
||||
for (Client *client : this->reachableClients()) {
|
||||
if (client->isSupportedDocument(widget->textDocument()))
|
||||
client->cursorPositionChanged(widget);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -491,7 +491,9 @@ bool StdIOSettings::needsRestart() const
|
||||
{
|
||||
if (BaseSettings::needsRestart())
|
||||
return true;
|
||||
if (auto stdIOInterface = qobject_cast<StdIOClientInterface *>(m_client))
|
||||
if (m_client.isNull())
|
||||
return false;
|
||||
if (auto stdIOInterface = qobject_cast<const StdIOClientInterface *>(m_client->clientInterface()))
|
||||
return stdIOInterface->needsRestart(this);
|
||||
return false;
|
||||
}
|
||||
|
@@ -133,12 +133,10 @@ void updateCodeActionRefactoringMarker(Client *client,
|
||||
TextDocument* doc = TextDocument::textDocumentForFileName(uri.toFileName());
|
||||
if (!doc)
|
||||
return;
|
||||
BaseTextEditor *editor = BaseTextEditor::textEditorForDocument(doc);
|
||||
if (!editor)
|
||||
const QVector<BaseTextEditor *> editors = BaseTextEditor::textEditorsForDocument(doc);
|
||||
if (editors.isEmpty())
|
||||
return;
|
||||
|
||||
TextEditorWidget *editorWidget = editor->editorWidget();
|
||||
|
||||
const QList<Diagnostic> &diagnostics = action.diagnostics().value_or(QList<Diagnostic>());
|
||||
|
||||
RefactorMarkers markers;
|
||||
@@ -181,7 +179,10 @@ void updateCodeActionRefactoringMarker(Client *client,
|
||||
marker.cursor = endOfLineCursor(diagnostic.range().start().toTextCursor(doc->document()));
|
||||
markers << marker;
|
||||
}
|
||||
editorWidget->setRefactorMarkers(markers + editorWidget->refactorMarkers());
|
||||
for (BaseTextEditor *editor : editors) {
|
||||
if (TextEditorWidget *editorWidget = editor->editorWidget())
|
||||
editorWidget->setRefactorMarkers(markers + editorWidget->refactorMarkers());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LanguageClient
|
||||
|
@@ -10,9 +10,6 @@
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
|
@@ -96,7 +96,7 @@ PerfTracePointDialog::~PerfTracePointDialog()
|
||||
|
||||
void PerfTracePointDialog::runScript()
|
||||
{
|
||||
m_ui->label->setText(tr("Executing script ..."));
|
||||
m_ui->label->setText(tr("Executing script..."));
|
||||
m_ui->textEdit->setReadOnly(true);
|
||||
m_ui->privilegesChooser->setEnabled(false);
|
||||
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
|
@@ -41,6 +41,8 @@ namespace Ui { class PerfTracePointDialog; }
|
||||
|
||||
class PerfTracePointDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PerfTracePointDialog();
|
||||
~PerfTracePointDialog();
|
||||
|
@@ -59,7 +59,6 @@ SUBDIRS = \
|
||||
languageclient \
|
||||
cppcheck \
|
||||
compilationdatabaseprojectmanager \
|
||||
perfprofiler \
|
||||
qmlpreview \
|
||||
studiowelcome
|
||||
|
||||
@@ -70,9 +69,9 @@ qtHaveModule(serialport) {
|
||||
}
|
||||
|
||||
qtHaveModule(quick) {
|
||||
SUBDIRS += qmlprofiler
|
||||
SUBDIRS += qmlprofiler perfprofiler
|
||||
} else {
|
||||
warning("QmlProfiler plugin has been disabled since the Qt Quick module is not available.")
|
||||
warning("QmlProfiler and PerfProfiler plugins have been disabled since the Qt Quick module is not available.")
|
||||
}
|
||||
|
||||
qtHaveModule(help) {
|
||||
|
@@ -32,6 +32,8 @@ namespace Internal {
|
||||
|
||||
class DesktopDeviceFactory : public IDeviceFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DesktopDeviceFactory();
|
||||
};
|
||||
|
@@ -275,11 +275,9 @@ void Kit::fix()
|
||||
void Kit::setup()
|
||||
{
|
||||
KitGuard g(this);
|
||||
// Process the KitAspects in reverse order: They may only be based on other information
|
||||
// lower in the stack.
|
||||
const QList<KitAspect *> aspects = KitManager::kitAspects();
|
||||
for (int i = aspects.count() - 1; i >= 0; --i)
|
||||
aspects.at(i)->setup(this);
|
||||
for (KitAspect * const aspect : aspects)
|
||||
aspect->setup(this);
|
||||
}
|
||||
|
||||
void Kit::upgrade()
|
||||
|
@@ -71,10 +71,12 @@ class KitManagerPrivate
|
||||
public:
|
||||
Kit *m_defaultKit = nullptr;
|
||||
bool m_initialized = false;
|
||||
std::vector<std::unique_ptr<KitAspect>> m_informationList;
|
||||
std::vector<std::unique_ptr<Kit>> m_kitList;
|
||||
std::unique_ptr<PersistentSettingsWriter> m_writer;
|
||||
QSet<Id> m_irrelevantAspects;
|
||||
|
||||
// Sorted by priority, in descending order.
|
||||
std::vector<std::unique_ptr<KitAspect>> m_informationList;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -1027,6 +1027,8 @@ bool static hasFlagEffectOnMacros(const QString &flag)
|
||||
return false; // Skip include paths
|
||||
if (f.startsWith("w", Qt::CaseInsensitive))
|
||||
return false; // Skip warning options
|
||||
if (f.startsWith("Y") || (f.startsWith("F") && f != "F"))
|
||||
return false; // Skip pch-related flags
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@@ -2045,8 +2045,12 @@ void ProjectExplorerPluginPrivate::updateWelcomePage()
|
||||
|
||||
void ProjectExplorerPluginPrivate::currentModeChanged(Id mode, Id oldMode)
|
||||
{
|
||||
if (oldMode == Constants::MODE_SESSION)
|
||||
ICore::saveSettings();
|
||||
if (oldMode == Constants::MODE_SESSION) {
|
||||
// Saving settings directly in a mode change is not a good idea, since the mode change
|
||||
// can be part of a bigger change. Save settings after that bigger change had a chance to
|
||||
// complete.
|
||||
QTimer::singleShot(0, ICore::instance(), &ICore::saveSettings);
|
||||
}
|
||||
if (mode == Core::Constants::MODE_WELCOME)
|
||||
updateWelcomePage();
|
||||
}
|
||||
|
@@ -363,7 +363,7 @@ static QStringList readLinesJson(const Utils::FileName &projectFile,
|
||||
// This assumes te project file is formed with only one field called
|
||||
// 'files' that has a list associated of the files to include in the project.
|
||||
if (content.isEmpty()) {
|
||||
*errorMessage = PythonProject::tr("Unable read \"%1\": The file is empty.")
|
||||
*errorMessage = PythonProject::tr("Unable to read \"%1\": The file is empty.")
|
||||
.arg(projectFile.toUserOutput());
|
||||
return lines;
|
||||
}
|
||||
@@ -372,7 +372,7 @@ static QStringList readLinesJson(const Utils::FileName &projectFile,
|
||||
const QJsonDocument doc = QJsonDocument::fromJson(content, &error);
|
||||
if (doc.isNull()) {
|
||||
const int line = content.left(error.offset).count('\n') + 1;
|
||||
*errorMessage = PythonProject::tr("Unable parse %1:%2: %3")
|
||||
*errorMessage = PythonProject::tr("Unable to parse \"%1\":%2: %3")
|
||||
.arg(projectFile.toUserOutput()).arg(line)
|
||||
.arg(error.errorString());
|
||||
return lines;
|
||||
|
@@ -71,10 +71,10 @@ public:
|
||||
void toogleRecording(bool b) const;
|
||||
|
||||
void resetGroupRecording() const;
|
||||
bool hasKeyframeGroup(const ModelNode &node, const PropertyName &propertyName) const;
|
||||
|
||||
private:
|
||||
void addKeyframeGroupIfNotExists(const ModelNode &node, const PropertyName &propertyName);
|
||||
bool hasKeyframeGroup(const ModelNode &node, const PropertyName &propertyName) const;
|
||||
QList<QmlTimelineKeyframeGroup> allKeyframeGroups() const;
|
||||
};
|
||||
|
||||
|
@@ -63,7 +63,7 @@ void QmlObjectNode::setVariantProperty(const PropertyName &name, const QVariant
|
||||
timelineFrames.setValue(value, frame);
|
||||
|
||||
return;
|
||||
} else if (modelNode().hasId() && timelineIsActive()) {
|
||||
} else if (modelNode().hasId() && timelineIsActive() && currentTimeline().hasKeyframeGroup(modelNode(), name)) {
|
||||
QmlTimelineKeyframeGroup timelineFrames(currentTimeline().keyframeGroup(modelNode(), name));
|
||||
|
||||
Q_ASSERT(timelineFrames.isValid());
|
||||
|
@@ -65,7 +65,6 @@ const char REFORMAT_UI_QML_FILES[] = "ReformatUiQmlFiles"; /* These setti
|
||||
const char IGNORE_DEVICE_PIXEL_RATIO[] = "IgnoreDevicePixelRaio"; /* The settings can be used to turn off the feature, if there are serious issues */
|
||||
const char STANDALONE_MODE[] = "StandAloneMode";
|
||||
const char ENABLE_TIMELINEVIEW[] = "EnableTimelineView";
|
||||
const char ENABLE_TIMELINEVIEW_ENVVAR[] = "QTC_ENABLE_QTQUICKTIMELINE_EDITOR";
|
||||
}
|
||||
|
||||
class DesignerSettings : public QHash<QByteArray, QVariant>
|
||||
|
@@ -10,14 +10,11 @@
|
||||
<height>176</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="4" column="3">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Loops</string>
|
||||
<string>Loops:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -117,7 +114,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Animation ID</string>
|
||||
<string>Animation ID:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -162,14 +159,14 @@
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="label_23">
|
||||
<property name="text">
|
||||
<string>Finished</string>
|
||||
<string>Finished:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="7">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="text">
|
||||
<string>Ping Pong</string>
|
||||
<string>Ping pong</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -205,7 +202,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Transition to state</string>
|
||||
<string>Transition to state:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -222,7 +219,7 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Running in Base State</string>
|
||||
<string>Running in base state</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -257,7 +254,7 @@
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Start Frame</string>
|
||||
<string>Start frame:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -290,14 +287,14 @@
|
||||
<item row="3" column="7">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Duration</string>
|
||||
<string>Duration:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>End Frame</string>
|
||||
<string>End frame:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
@@ -46,13 +46,13 @@ const int priorityTimelineCategory = 110;
|
||||
const char timelineCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Timeline");
|
||||
|
||||
const char timelineCopyKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
|
||||
"Copy All Keyframes from item");
|
||||
"Copy All Keyframes");
|
||||
const char timelinePasteKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
|
||||
"Paste Keyframes to item");
|
||||
"Paste Keyframes");
|
||||
const char timelineInsertKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
|
||||
"Insert Keyframes for item");
|
||||
"Add Keyframes at Current Frame");
|
||||
const char timelineDeleteKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
|
||||
"Delete All Keyframes for item");
|
||||
"Delete All Keyframes");
|
||||
|
||||
const char timelineStatusBarFrameNumber[] = QT_TRANSLATE_NOOP("QmlDesignerTimeline", "Frame %1");
|
||||
|
||||
|
@@ -10,9 +10,6 @@
|
||||
<height>170</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="8" colspan="2">
|
||||
<spacer name="horizontalSpacer_11">
|
||||
@@ -84,7 +81,7 @@
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Expression Binding</string>
|
||||
<string>Expression binding:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
@@ -107,7 +104,7 @@
|
||||
<item row="2" column="4">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>End Frame</string>
|
||||
<string>End frame:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
@@ -200,7 +197,7 @@
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Expression Binding</string>
|
||||
<string>Expression binding</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -214,7 +211,7 @@
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Timeline ID</string>
|
||||
<string>Timeline ID:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
@@ -243,7 +240,7 @@
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Start Frame</string>
|
||||
<string>Start frame:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
|
@@ -44,6 +44,8 @@ class TimelineToolButton;
|
||||
|
||||
class TimelineKeyframeItem : public TimelineMovableAbstractItem
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(TimelineKeyframeItem)
|
||||
|
||||
public:
|
||||
explicit TimelineKeyframeItem(TimelinePropertyItem *parent, const ModelNode &frame);
|
||||
~TimelineKeyframeItem() override;
|
||||
@@ -84,6 +86,8 @@ private:
|
||||
|
||||
class TimelinePropertyItem : public TimelineItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum { Type = TimelineConstants::timelinePropertyItemUserType };
|
||||
|
||||
|
@@ -40,6 +40,8 @@ class TimelineSectionItem;
|
||||
|
||||
class TimelineBarItem : public TimelineMovableAbstractItem
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(TimelineBarItem)
|
||||
|
||||
enum class Location { Undefined, Center, Left, Right };
|
||||
|
||||
public:
|
||||
|
@@ -103,7 +103,7 @@ QWidget *TimelineEditorDelegate::createEditor(QWidget *parent,
|
||||
switch (index.column()) {
|
||||
case TimelineSettingsModel::TimelineRow: {
|
||||
QTC_ASSERT(comboBox, return widget);
|
||||
comboBox->addItem(tr("None"));
|
||||
comboBox->addItem(TimelineSettingsModel::tr("None"));
|
||||
for (const auto &timeline : timelineSettingsModel->timelineView()->getTimelines()) {
|
||||
if (!timeline.modelNode().id().isEmpty())
|
||||
comboBox->addItem(timeline.modelNode().id());
|
||||
@@ -111,7 +111,7 @@ QWidget *TimelineEditorDelegate::createEditor(QWidget *parent,
|
||||
} break;
|
||||
case TimelineSettingsModel::AnimationRow: {
|
||||
QTC_ASSERT(comboBox, return widget);
|
||||
comboBox->addItem(tr("None"));
|
||||
comboBox->addItem(TimelineSettingsModel::tr("None"));
|
||||
for (const auto &animation :
|
||||
timelineSettingsModel->timelineView()->getAnimations(qmlTimeline)) {
|
||||
if (!animation.id().isEmpty())
|
||||
|
@@ -194,8 +194,7 @@ bool QmlDesignerPlugin::delayedInitialize()
|
||||
d->settings.fromSettings(Core::ICore::settings());
|
||||
|
||||
d->viewManager.registerViewTakingOwnership(new QmlDesigner::Internal::ConnectionView);
|
||||
if (DesignerSettings::getValue(DesignerSettingsKey::ENABLE_TIMELINEVIEW).toBool()
|
||||
|| qEnvironmentVariableIsSet(DesignerSettingsKey::ENABLE_TIMELINEVIEW_ENVVAR))
|
||||
if (DesignerSettings::getValue(DesignerSettingsKey::ENABLE_TIMELINEVIEW).toBool())
|
||||
d->viewManager.registerViewTakingOwnership(new QmlDesigner::TimelineView);
|
||||
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::SourceTool);
|
||||
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::ColorTool);
|
||||
|
@@ -159,6 +159,8 @@ DesignerSettings SettingsPageWidget::settings() const
|
||||
m_ui.showPropertyEditorWarningsCheckBox->isChecked());
|
||||
settings.insert(DesignerSettingsKey::ENABLE_MODEL_EXCEPTION_OUTPUT,
|
||||
m_ui.showWarnExceptionsCheckBox->isChecked());
|
||||
settings.insert(DesignerSettingsKey::ENABLE_TIMELINEVIEW,
|
||||
m_ui.featureTimelineEditorCheckBox->isChecked());
|
||||
|
||||
return settings;
|
||||
}
|
||||
@@ -224,9 +226,13 @@ void SettingsPageWidget::setSettings(const DesignerSettings &settings)
|
||||
|
||||
m_ui.controls2StyleComboBox->setCurrentText(m_ui.styleLineEdit->text());
|
||||
|
||||
m_ui.featureTimelineEditorCheckBox->setChecked(settings.value(
|
||||
DesignerSettingsKey::ENABLE_TIMELINEVIEW).toBool());
|
||||
|
||||
if (settings.value(DesignerSettingsKey::STANDALONE_MODE).toBool()) {
|
||||
m_ui.emulationGroupBox->hide();
|
||||
m_ui.debugGroupBox->hide();
|
||||
m_ui.featuresGroupBox->hide();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,7 +268,8 @@ void SettingsPage::apply()
|
||||
<< DesignerSettingsKey::PUPPET_KILL_TIMEOUT
|
||||
<< DesignerSettingsKey::FORWARD_PUPPET_OUTPUT
|
||||
<< DesignerSettingsKey::DEBUG_PUPPET
|
||||
<< DesignerSettingsKey::ENABLE_MODEL_EXCEPTION_OUTPUT;
|
||||
<< DesignerSettingsKey::ENABLE_MODEL_EXCEPTION_OUTPUT
|
||||
<< DesignerSettingsKey::ENABLE_TIMELINEVIEW;
|
||||
|
||||
foreach (const QByteArray &key, restartNecessaryKeys) {
|
||||
if (currentSettings.value(key) != newSettings.value(key)) {
|
||||
|
@@ -410,6 +410,22 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="featuresGroupBox">
|
||||
<property name="title">
|
||||
<string>Features</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="featureTimelineEditorCheckBox">
|
||||
<property name="text">
|
||||
<string>Enable Timeline editor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="debugGroupBox">
|
||||
<property name="title">
|
||||
|
@@ -287,10 +287,10 @@ void QmlProfilerTool::updateRunActions()
|
||||
d->m_startAction->setToolTip(tr("A QML Profiler analysis is still in progress."));
|
||||
d->m_stopAction->setEnabled(true);
|
||||
} else {
|
||||
QString whyNot = tr("Start QML Profiler analysis.");
|
||||
QString tooltip = tr("Start QML Profiler analysis.");
|
||||
bool canRun = ProjectExplorerPlugin::canRunStartupProject
|
||||
(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, &whyNot);
|
||||
d->m_startAction->setToolTip(whyNot);
|
||||
(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, &tooltip);
|
||||
d->m_startAction->setToolTip(tooltip);
|
||||
d->m_startAction->setEnabled(canRun);
|
||||
d->m_stopAction->setEnabled(false);
|
||||
}
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/ansiescapecodehandler.h>
|
||||
#include <utils/fileinprojectfinder.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/theme/theme.h>
|
||||
|
||||
#include <QPlainTextEdit>
|
||||
@@ -412,16 +413,16 @@ void QtSupportPlugin::testQtOutputFormatter_data()
|
||||
<< " Loc: [../TestProject/test.cpp(123)]"
|
||||
<< 9 << 37 << "../TestProject/test.cpp(123)"
|
||||
<< "../TestProject/test.cpp" << 123 << -1;
|
||||
|
||||
QTest::newRow("Windows failed QTest link")
|
||||
<< "..\\TestProject\\test.cpp(123) : failure location"
|
||||
<< 0 << 28 << "..\\TestProject\\test.cpp(123)"
|
||||
<< "..\\TestProject\\test.cpp" << 123 << -1;
|
||||
|
||||
QTest::newRow("Windows failed QTest link with carriage return")
|
||||
<< "..\\TestProject\\test.cpp(123) : failure location\r"
|
||||
<< 0 << 28 << "..\\TestProject\\test.cpp(123)"
|
||||
<< "..\\TestProject\\test.cpp" << 123 << -1;
|
||||
if (HostOsInfo::isWindowsHost()) {
|
||||
QTest::newRow("Windows failed QTest link")
|
||||
<< "..\\TestProject\\test.cpp(123) : failure location"
|
||||
<< 0 << 28 << "..\\TestProject\\test.cpp(123)"
|
||||
<< "../TestProject/test.cpp" << 123 << -1;
|
||||
QTest::newRow("Windows failed QTest link with carriage return")
|
||||
<< "..\\TestProject\\test.cpp(123) : failure location\r"
|
||||
<< 0 << 28 << "..\\TestProject\\test.cpp(123)"
|
||||
<< "../TestProject/test.cpp" << 123 << -1;
|
||||
}
|
||||
}
|
||||
|
||||
void QtSupportPlugin::testQtOutputFormatter()
|
||||
|
@@ -203,7 +203,7 @@ void AbstractRemoteLinuxDeployService::handleDeviceSetupDone(bool success)
|
||||
} else {
|
||||
connect(d->connection, &SshConnection::connected,
|
||||
this, &AbstractRemoteLinuxDeployService::handleConnected);
|
||||
emit progressMessage(tr("Connecting to device '%1' (%2)")
|
||||
emit progressMessage(tr("Connecting to device \"%1\" (%2).")
|
||||
.arg(deviceConfiguration()->displayName())
|
||||
.arg(deviceConfiguration()->sshParameters().host()));
|
||||
if (d->connection->state() == SshConnection::Unconnected)
|
||||
|
@@ -145,7 +145,7 @@ void BaseHoverHandler::decorateToolTip()
|
||||
if (Qt::mightBeRichText(toolTip()))
|
||||
setToolTip(toolTip().toHtmlEscaped());
|
||||
|
||||
if (lastHelpItemIdentified().isValid()) {
|
||||
if (lastHelpItemIdentified().isValid() && !lastHelpItemIdentified().isFuzzyMatch()) {
|
||||
const QString &helpContents = lastHelpItemIdentified().extractContent(false);
|
||||
if (!helpContents.isEmpty()) {
|
||||
m_toolTip = toolTip().toHtmlEscaped();
|
||||
|
@@ -258,6 +258,16 @@ void Highlighter::handleShutdown()
|
||||
delete highlightRepository();
|
||||
}
|
||||
|
||||
static bool isOpeningParenthesis(QChar c)
|
||||
{
|
||||
return c == QLatin1Char('{') || c == QLatin1Char('[') || c == QLatin1Char('(');
|
||||
}
|
||||
|
||||
static bool isClosingParenthesis(QChar c)
|
||||
{
|
||||
return c == QLatin1Char('}') || c == QLatin1Char(']') || c == QLatin1Char(')');
|
||||
}
|
||||
|
||||
void Highlighter::highlightBlock(const QString &text)
|
||||
{
|
||||
if (!definition().isValid())
|
||||
@@ -266,8 +276,21 @@ void Highlighter::highlightBlock(const QString &text)
|
||||
KSyntaxHighlighting::State state = TextDocumentLayout::userData(block)->syntaxState();
|
||||
state = highlightLine(text, state);
|
||||
block = block.next();
|
||||
|
||||
Parentheses parentheses;
|
||||
int pos = 0;
|
||||
for (const QChar &c : text) {
|
||||
if (isOpeningParenthesis(c))
|
||||
parentheses.push_back(Parenthesis(Parenthesis::Opened, c, pos));
|
||||
else if (isClosingParenthesis(c))
|
||||
parentheses.push_back(Parenthesis(Parenthesis::Closed, c, pos));
|
||||
pos++;
|
||||
}
|
||||
TextDocumentLayout::setParentheses(currentBlock(), parentheses);
|
||||
|
||||
if (block.isValid())
|
||||
TextDocumentLayout::userData(block)->setSyntaxState(state);
|
||||
formatSpaces(text);
|
||||
}
|
||||
|
||||
void Highlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format)
|
||||
|
@@ -127,6 +127,9 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="resetCache">
|
||||
<property name="toolTip">
|
||||
<string>Reset definitions remembered for files that can be associated with more than one highlighter definition.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reset Remembered Definitions</string>
|
||||
</property>
|
||||
|
@@ -8508,13 +8508,14 @@ BaseTextEditor *BaseTextEditor::currentTextEditor()
|
||||
return qobject_cast<BaseTextEditor *>(EditorManager::currentEditor());
|
||||
}
|
||||
|
||||
BaseTextEditor *BaseTextEditor::textEditorForDocument(TextDocument *textDocument)
|
||||
QVector<BaseTextEditor *> BaseTextEditor::textEditorsForDocument(TextDocument *textDocument)
|
||||
{
|
||||
QVector<BaseTextEditor *> ret;
|
||||
for (IEditor *editor : Core::DocumentModel::editorsForDocument(textDocument)) {
|
||||
if (auto textEditor = qobject_cast<BaseTextEditor *>(editor))
|
||||
return textEditor;
|
||||
ret << textEditor;
|
||||
}
|
||||
return nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
TextEditorWidget *BaseTextEditor::editorWidget() const
|
||||
|
@@ -111,7 +111,7 @@ public:
|
||||
virtual void finalizeInitialization() {}
|
||||
|
||||
static BaseTextEditor *currentTextEditor();
|
||||
static BaseTextEditor *textEditorForDocument(TextDocument *textDocument);
|
||||
static QVector<BaseTextEditor *> textEditorsForDocument(TextDocument *textDocument);
|
||||
|
||||
TextEditorWidget *editorWidget() const;
|
||||
TextDocument *textDocument() const;
|
||||
|
@@ -2,7 +2,19 @@ DEFINES += TEXTEDITOR_LIBRARY
|
||||
QT += gui-private network printsupport xml
|
||||
CONFIG += exceptions
|
||||
CONFIG += include_source_dir # For the highlighter autotest.
|
||||
|
||||
include(../../shared/syntax/syntax_shared.pri)
|
||||
isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR) | isEmpty(KSYNTAXHIGHLIGHTING_INCLUDE_DIR) {
|
||||
QTC_LIB_DEPENDS += syntax-highlighting
|
||||
} else {
|
||||
unix:!disable_external_rpath {
|
||||
!macos: QMAKE_LFLAGS += -Wl,-z,origin
|
||||
QMAKE_LFLAGS += -Wl,-rpath,$$shell_quote($${KSYNTAXHIGHLIGHTING_LIB_DIR})
|
||||
}
|
||||
}
|
||||
|
||||
include(../../qtcreatorplugin.pri)
|
||||
|
||||
SOURCES += texteditorplugin.cpp \
|
||||
plaintexteditorfactory.cpp \
|
||||
textdocument.cpp \
|
||||
|
@@ -2,7 +2,21 @@ QTC_PLUGIN_NAME = TextEditor
|
||||
QTC_LIB_DEPENDS += \
|
||||
aggregation \
|
||||
extensionsystem \
|
||||
utils \
|
||||
syntax-highlighting
|
||||
utils
|
||||
|
||||
QTC_PLUGIN_DEPENDS += \
|
||||
coreplugin
|
||||
|
||||
# needed for plugins that depend on TextEditor plugin
|
||||
include(../../shared/syntax/syntax_shared.pri)
|
||||
!isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR):!isEmpty(KSYNTAXHIGHLIGHTING_INCLUDE_DIR) {
|
||||
INCLUDEPATH *= $${KSYNTAXHIGHLIGHTING_INCLUDE_DIR}
|
||||
LIBS *= -L$$KSYNTAXHIGHLIGHTING_LIB_DIR -lKF5SyntaxHighlighting
|
||||
|
||||
linux {
|
||||
QMAKE_LFLAGS += -Wl,-z,origin
|
||||
QMAKE_LFLAGS += -Wl,-rpath,$$shell_quote($${KSYNTAXHIGHLIGHTING_LIB_DIR})
|
||||
}
|
||||
} else {
|
||||
QTC_LIB_DEPENDS += syntax-highlighting
|
||||
}
|
||||
|
@@ -96,7 +96,16 @@ defineReplace(splitFlags) {
|
||||
flag ~= s,-I\S*,,
|
||||
flag ~= s,/D\S*,,
|
||||
flag ~= s,/Z\S*,,
|
||||
result += $$split(flag, " ")
|
||||
separate_flags = $$split(flag, " ")
|
||||
for (separate_flag, separate_flags) {
|
||||
starting_substr = $$str_member($$separate_flag, 0, 0)
|
||||
win32:equals(starting_substr, "/") {
|
||||
result += $$separate_flag
|
||||
}
|
||||
equals(starting_substr, "-") {
|
||||
result += $$separate_flag
|
||||
}
|
||||
}
|
||||
} else {
|
||||
inside_quotes = 0
|
||||
starting_substr = $$str_member($$flag, 0, 0)
|
||||
|
21
src/shared/syntax/syntax_shared.pri
Normal file
21
src/shared/syntax/syntax_shared.pri
Normal file
@@ -0,0 +1,21 @@
|
||||
# KSyntaxHighlighting uses a special folder structure (may contain target arch triple for the lib),
|
||||
# so expect lib folder to be specified by the user - generate include path based on this
|
||||
isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR): KSYNTAXHIGHLIGHTING_LIB_DIR=$$(KSYNTAXHIGHLIGHTING_LIB_DIR)
|
||||
isEmpty(KSYNTAXHIGHLIGHTING_INCLUDE_DIR): KSYNTAXHIGHLIGHTING_INCLUDE_DIR=$$(KSYNTAXHIGHLIGHTING_INCLUDE_DIR)
|
||||
|
||||
!isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR) {
|
||||
!exists($$KSYNTAXHIGHLIGHTING_LIB_DIR) {
|
||||
unset(KSYNTAXHIGHLIGHTING_LIB_DIR)
|
||||
unset(KSYNTAXHIGHLIGHTING_INCLUDE_DIR)
|
||||
} else {
|
||||
isEmpty(KSYNTAXHIGHLIGHTING_INCLUDE_DIR) {
|
||||
!linux: KSYNTAXHIGHLIGHTING_INCLUDE_DIR=$$absolute_path('../include/KF5/KSyntaxHighlighting/', $$KSYNTAXHIGHLIGHTING_LIB_DIR)
|
||||
else: KSYNTAXHIGHLIGHTING_INCLUDE_DIR=$$absolute_path('../../include/KF5/KSyntaxHighlighting/', $$KSYNTAXHIGHLIGHTING_LIB_DIR)
|
||||
}
|
||||
|
||||
!exists($$KSYNTAXHIGHLIGHTING_INCLUDE_DIR) {
|
||||
unset(KSYNTAXHIGHLIGHTING_INCLUDE_DIR)
|
||||
unset(KSYNTAXHIGHLIGHTING_LIB_DIR)
|
||||
}
|
||||
}
|
||||
}
|
@@ -181,6 +181,7 @@ void FullTokenInfo::variableKind(const Cursor &cursor)
|
||||
{
|
||||
TokenInfo::variableKind(cursor);
|
||||
|
||||
m_extraInfo.accessSpecifier = cursor.accessSpecifier();
|
||||
m_extraInfo.storageClass = cursor.storageClass();
|
||||
}
|
||||
|
||||
|
@@ -41,7 +41,7 @@
|
||||
#include <precompiledheaderstorage.h>
|
||||
#include <processormanager.h>
|
||||
#include <progresscounter.h>
|
||||
#include <projectparts.h>
|
||||
#include <projectpartsmanager.h>
|
||||
#include <filepathcaching.h>
|
||||
#include <refactoringdatabaseinitializer.h>
|
||||
#include <sqlitedatabase.h>
|
||||
@@ -68,7 +68,7 @@ using ClangBackEnd::PchCreator;
|
||||
using ClangBackEnd::PchManagerClientProxy;
|
||||
using ClangBackEnd::PchManagerServer;
|
||||
using ClangBackEnd::PrecompiledHeaderStorage;
|
||||
using ClangBackEnd::ProjectParts;
|
||||
using ClangBackEnd::ProjectPartsManager;
|
||||
using ClangBackEnd::FilePathCache;
|
||||
using ClangBackEnd::FilePathView;
|
||||
using ClangBackEnd::TimeStamp;
|
||||
@@ -138,12 +138,14 @@ public:
|
||||
ClangBackEnd::Environment &environment,
|
||||
Sqlite::Database &database,
|
||||
PchManagerServer &pchManagerServer,
|
||||
ClangBackEnd::ClangPathWatcherInterface &pathWatcher)
|
||||
: ProcessorManager(generatedFiles),
|
||||
m_environment(environment),
|
||||
m_database(database),
|
||||
m_pchManagerServer(pchManagerServer),
|
||||
m_pathWatcher(pathWatcher)
|
||||
ClangBackEnd::ClangPathWatcherInterface &pathWatcher,
|
||||
ClangBackEnd::BuildDependenciesStorageInterface &buildDependenciesStorage)
|
||||
: ProcessorManager(generatedFiles)
|
||||
, m_environment(environment)
|
||||
, m_database(database)
|
||||
, m_pchManagerServer(pchManagerServer)
|
||||
, m_pathWatcher(pathWatcher)
|
||||
, m_buildDependenciesStorage(buildDependenciesStorage)
|
||||
{}
|
||||
|
||||
protected:
|
||||
@@ -152,7 +154,8 @@ protected:
|
||||
return std::make_unique<PchCreator>(m_environment,
|
||||
m_database,
|
||||
*m_pchManagerServer.client(),
|
||||
m_pathWatcher);
|
||||
m_pathWatcher,
|
||||
m_buildDependenciesStorage);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -160,6 +163,7 @@ private:
|
||||
Sqlite::Database &m_database;
|
||||
ClangBackEnd::PchManagerServer &m_pchManagerServer;
|
||||
ClangBackEnd::ClangPathWatcherInterface &m_pathWatcher;
|
||||
ClangBackEnd::BuildDependenciesStorageInterface &m_buildDependenciesStorage;
|
||||
};
|
||||
|
||||
struct Data // because we have a cycle dependency
|
||||
@@ -175,13 +179,14 @@ struct Data // because we have a cycle dependency
|
||||
ClangBackEnd::FilePathCaching filePathCache{database};
|
||||
ClangPathWatcher<QFileSystemWatcher, QTimer> includeWatcher{filePathCache};
|
||||
ApplicationEnvironment environment;
|
||||
ProjectParts projectParts;
|
||||
ProjectPartsManager projectParts;
|
||||
GeneratedFiles generatedFiles;
|
||||
PchCreatorManager pchCreatorManager{generatedFiles,
|
||||
environment,
|
||||
database,
|
||||
clangPchManagerServer,
|
||||
includeWatcher};
|
||||
includeWatcher,
|
||||
buildDependencyStorage};
|
||||
PrecompiledHeaderStorage<> preCompiledHeaderStorage{database};
|
||||
ClangBackEnd::ProgressCounter pchCreationProgressCounter{[&](int progress, int total) {
|
||||
executeInLoop([&] {
|
||||
|
@@ -55,19 +55,19 @@ OutputContainer setUnion(InputContainer1 &&input1,
|
||||
|
||||
BuildDependency BuildDependenciesProvider::create(const ProjectPartContainer &projectPart)
|
||||
{
|
||||
SourceEntries includes = createSourceEntriesFromStorage(projectPart.sourcePathIds,
|
||||
projectPart.projectPartId);
|
||||
auto sourcesAndProjectPart = createSourceEntriesFromStorage(
|
||||
projectPart.sourcePathIds, projectPart.projectPartId);
|
||||
|
||||
if (!m_modifiedTimeChecker.isUpToDate(includes)) {
|
||||
if (!m_modifiedTimeChecker.isUpToDate(sourcesAndProjectPart.first)) {
|
||||
BuildDependency buildDependency = m_generator.create(projectPart);
|
||||
|
||||
storeBuildDependency(buildDependency);
|
||||
storeBuildDependency(buildDependency, sourcesAndProjectPart.second);
|
||||
|
||||
return buildDependency;
|
||||
}
|
||||
|
||||
return createBuildDependencyFromStorage(std::move(includes));
|
||||
|
||||
return createBuildDependencyFromStorage(
|
||||
std::move(sourcesAndProjectPart.first));
|
||||
}
|
||||
|
||||
BuildDependency BuildDependenciesProvider::createBuildDependencyFromStorage(
|
||||
@@ -76,7 +76,7 @@ BuildDependency BuildDependenciesProvider::createBuildDependencyFromStorage(
|
||||
BuildDependency buildDependency;
|
||||
|
||||
buildDependency.usedMacros = createUsedMacrosFromStorage(includes);
|
||||
buildDependency.includes = std::move(includes);
|
||||
buildDependency.sources = std::move(includes);
|
||||
|
||||
return buildDependency;
|
||||
}
|
||||
@@ -101,16 +101,19 @@ UsedMacros BuildDependenciesProvider::createUsedMacrosFromStorage(const SourceEn
|
||||
return usedMacros;
|
||||
}
|
||||
|
||||
SourceEntries BuildDependenciesProvider::createSourceEntriesFromStorage(
|
||||
const FilePathIds &sourcePathIds, Utils::SmallStringView projectPartId) const
|
||||
{
|
||||
std::pair<SourceEntries, int>
|
||||
BuildDependenciesProvider::createSourceEntriesFromStorage(
|
||||
const FilePathIds &sourcePathIds,
|
||||
Utils::SmallStringView projectPartName) const {
|
||||
SourceEntries includes;
|
||||
|
||||
Sqlite::DeferredTransaction transaction(m_transactionBackend);
|
||||
|
||||
int projectPartId = m_storage.fetchProjectPartId(projectPartName);
|
||||
|
||||
for (FilePathId sourcePathId : sourcePathIds) {
|
||||
SourceEntries entries = m_storage.fetchDependSources(sourcePathId,
|
||||
projectPartId);
|
||||
SourceEntries entries =
|
||||
m_storage.fetchDependSources(sourcePathId, projectPartId);
|
||||
SourceEntries mergedEntries = setUnion<SourceEntries>(includes, entries);
|
||||
|
||||
includes = std::move(mergedEntries);
|
||||
@@ -118,15 +121,14 @@ SourceEntries BuildDependenciesProvider::createSourceEntriesFromStorage(
|
||||
|
||||
transaction.commit();
|
||||
|
||||
return includes;
|
||||
return {includes, projectPartId};
|
||||
}
|
||||
|
||||
void BuildDependenciesProvider::storeBuildDependency(const BuildDependency &buildDependency)
|
||||
{
|
||||
void BuildDependenciesProvider::storeBuildDependency(
|
||||
const BuildDependency &buildDependency, int projectPartId) {
|
||||
Sqlite::ImmediateTransaction transaction(m_transactionBackend);
|
||||
|
||||
m_storage.updateSources(buildDependency.includes);
|
||||
m_storage.insertFileStatuses(buildDependency.fileStatuses);
|
||||
m_storage.insertOrUpdateSources(buildDependency.sources, projectPartId);
|
||||
m_storage.insertOrUpdateFileStatuses(buildDependency.fileStatuses);
|
||||
m_storage.insertOrUpdateSourceDependencies(buildDependency.sourceDependencies);
|
||||
m_storage.insertOrUpdateUsedMacros(buildDependency.usedMacros);
|
||||
|
||||
|
@@ -55,9 +55,9 @@ public:
|
||||
private:
|
||||
BuildDependency createBuildDependencyFromStorage(SourceEntries &&includes) const;
|
||||
UsedMacros createUsedMacrosFromStorage(const SourceEntries &includes) const;
|
||||
SourceEntries createSourceEntriesFromStorage(const FilePathIds &sourcePathIds,
|
||||
Utils::SmallStringView projectPartId) const;
|
||||
void storeBuildDependency(const BuildDependency &buildDependency);
|
||||
std::pair<SourceEntries, int> createSourceEntriesFromStorage(
|
||||
const FilePathIds &sourcePathIds, Utils::SmallStringView projectPartName) const;
|
||||
void storeBuildDependency(const BuildDependency &buildDependency, int projectPartId);
|
||||
|
||||
private:
|
||||
BuildDependenciesStorageInterface &m_storage;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user