Merge remote-tracking branch 'origin/4.9'

Change-Id: I801042a53ae4d02d1891ea582ca9ea89b00d3181
This commit is contained in:
Orgad Shaneh
2019-03-01 12:20:57 +02:00
129 changed files with 1253 additions and 709 deletions

13
dist/changes-4.8.2.md vendored
View File

@@ -7,6 +7,10 @@ you can check out from the public Git repository. For example:
git clone git://code.qt.io/qt-creator/qt-creator.git git clone git://code.qt.io/qt-creator/qt-creator.git
git log --cherry-pick --pretty=oneline origin/v4.8.1..v4.8.2 git log --cherry-pick --pretty=oneline origin/v4.8.1..v4.8.2
General
* Fixed UI for choosing executable for external tools (QTCREATORBUG-21937)
Editing Editing
* Fixed highlighting of search results of regular expression search * Fixed highlighting of search results of regular expression search
@@ -20,6 +24,10 @@ Autotools Projects
C++ Support C++ Support
* Fixed crash when expanding macros (QTCREATORBUG-21642) * Fixed crash when expanding macros (QTCREATORBUG-21642)
* Fixed crash in preprocessor (QTCREATORBUG-21981)
* Fixed infinite loop when resolving pointer types (QTCREATORBUG-22010)
* Fixed cursor position after completion of functions without arguments
(QTCREATORBUG-21841)
QML Support QML Support
@@ -38,6 +46,7 @@ Debugging
Qt Quick Designer Qt Quick Designer
* Added support for more JavaScript functions in `.ui.qml` files * Added support for more JavaScript functions in `.ui.qml` files
* Fixed crash with gradients and Qt Quick 5.12 (QDS-472)
Test Integration Test Integration
@@ -55,16 +64,20 @@ macOS
Android Android
* Fixed upload of GDB server on some devices (QTCREATORBUG-21317) * Fixed upload of GDB server on some devices (QTCREATORBUG-21317)
* Fixed crash on exiting debugger (QTCREATORBUG-21684)
Credits for these changes go to: Credits for these changes go to:
Andre Hartmann
André Pönitz André Pönitz
Christian Kandeler Christian Kandeler
Christian Stenger Christian Stenger
David Schulz David Schulz
Eike Ziller Eike Ziller
Ivan Donchevskii Ivan Donchevskii
Kirill Burtsev
Leena Miettinen Leena Miettinen
Liang Qi Liang Qi
Nikolai Kosjar
Oliver Wolff Oliver Wolff
Raoul Hecky Raoul Hecky
Robert Löhning Robert Löhning

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@@ -242,9 +242,16 @@
You can add filters to specify the directories within the current project You can add filters to specify the directories within the current project
to scan for tests. Select the \uicontrol {Global Filters} check box, and to scan for tests. Select the \uicontrol {Global Filters} check box, and
the select \uicontrol Add to specify paths to the directories to scan for then select \uicontrol Add to specify paths to the directories to scan for
tests. Wildcards are not supported in the filter expressions. tests. Wildcards are not supported in the filter expressions.
In some special setups, \QC cannot deduce which executable or run
configuration it should use. If \QC repeatedly asks you to select the
tests to run when trying to execute tests, you can enable it to cache
your choices and use them were appropriate. The cached information is
cleared when you switch to another project, close the current one, or
select \uicontrol {Reset Cached Choices}.
To show or hide init and cleanup or data functions in the \uicontrol Tests To show or hide init and cleanup or data functions in the \uicontrol Tests
view, select \inlineimage filtericon.png view, select \inlineimage filtericon.png
(\uicontrol {Filter Test Tree}), and then select \uicontrol {Show Init and (\uicontrol {Filter Test Tree}), and then select \uicontrol {Show Init and
@@ -333,22 +340,9 @@
\row \row
\li BENCH \li BENCH
\li Benchmark test. \li Benchmark test.
\row
\li BFAIL
\li Blacklisted test case failed. Since Qt 5.4, you can
provide a BLACKLIST file for tests. It is mainly used internally
by the Qt CI system.
\row
\li BPASS
\li Blacklisted test case passed.
\row \row
\li DEBUG \li DEBUG
\li Debug message. \li Debug message.
\row
\li XFAIL
\li Test case is expected to fail, so it is marked by using the
QEXPECT_FAIL macro. If the test case passes instead, an
unexpected pass (XPASS) is written to the test log.
\row \row
\li FAIL \li FAIL
\li Test case failed. Double-click the line for more information. \li Test case failed. Double-click the line for more information.
@@ -371,12 +365,40 @@
\row \row
\li SYSTEM \li SYSTEM
\li An error message received from or influenced by the OS. \li An error message received from or influenced by the OS.
\row
\li XFAIL
\li Test case is expected to fail, so it is marked by using the
QEXPECT_FAIL macro. If the test case passes instead, an
unexpected pass (XPASS) is written to the test log.
\row \row
\li XPASS \li XPASS
\li Test case passed even though it was expected to fail. \li Test case passed even though it was expected to fail.
\row \row
\li WARN \li WARN
\li Warning message. \li Warning message.
\endtable
Since Qt 5.4, you can provide a BLACKLIST file for tests. It is mainly used
internally by the Qt CI system.
\table
\header
\li Result
\li Description
\row
\li BFAIL
\li Blacklisted test case failed.
\row
\li BPASS
\li Blacklisted test case passed.
\row
\li BXFAIL
\li Blacklisted test case failed but was marked to be expected to fail.
\row
\li BXPASS
\li Blacklisted test case passed even though it was expected to fail.
\endtable \endtable
To view only messages of a particular type, select To view only messages of a particular type, select
@@ -391,6 +413,11 @@
\uicontrol {Limit result output} check box. To disable automatic scrolling, \uicontrol {Limit result output} check box. To disable automatic scrolling,
deselect the \uicontrol {Automatically scroll results} check box. deselect the \uicontrol {Automatically scroll results} check box.
Test results can be grouped by the executable path that was used to run the
tests. This is useful if you have multiple test executables and run them all
at once. To enable this functionality you need to select the
\uicontrol {Group results by application} check box.
Internal messages and run configuration warnings for deduced configurations Internal messages and run configuration warnings for deduced configurations
are omitted by default. To view them, deselect the \uicontrol {Omit internal are omitted by default. To view them, deselect the \uicontrol {Omit internal
messages} and \uicontrol {Omit run configuration warnings} check boxes. messages} and \uicontrol {Omit run configuration warnings} check boxes.

View File

@@ -163,7 +163,7 @@
Property bindings are created implicitly in QML whenever a property is Property bindings are created implicitly in QML whenever a property is
assigned a JavaScript expression. To set JavaScript expressions as values assigned a JavaScript expression. To set JavaScript expressions as values
of properties in the Design mode, select the \uicontrol Nut menu next to of properties in the Design mode, select the \uicontrol Settings menu next to
a property, and then select \uicontrol {Set Binding}. a property, and then select \uicontrol {Set Binding}.
\image qmldesigner-set-expression.png "Type properties context menu" \image qmldesigner-set-expression.png "Type properties context menu"
@@ -269,9 +269,9 @@
arranges its child items side by side, wrapping as necessary. arranges its child items side by side, wrapping as necessary.
\endlist \endlist
To lay out several items in a \uicontrol Column, \uicontrol Row, To position several items in a \uicontrol Column, \uicontrol Row,
\uicontrol Grid, or \uicontrol Flow, select the items on the canvas, and \uicontrol Grid, or \uicontrol Flow, select the items on the canvas, and
then select \uicontrol Layout in the context menu. then select \uicontrol Position in the context menu.
\section2 Using Layouts \section2 Using Layouts
@@ -284,8 +284,7 @@
\list \list
\li \l{Layout} provides attached properties for items pushed onto a \li \l{Layout} provides attached properties for items pushed onto a
\uicontrol {Column Layout}, \uicontrol {Row Layout}, or column, row, or grid layout.
\uicontrol {Grid Layout}.
\li \l{ColumnLayout}{Column Layout} provides a grid layout with only \li \l{ColumnLayout}{Column Layout} provides a grid layout with only
one column. one column.
\li \l{RowLayout}{Row Layout} provides a grid layout with only one row. \li \l{RowLayout}{Row Layout} provides a grid layout with only one row.
@@ -295,8 +294,7 @@
one item is visible at a time. one item is visible at a time.
\endlist \endlist
To lay out several items in a \uicontrol {Column Layout}, To lay out several items in a column, row, grid, or
\uicontrol {Row Layout}, \uicontrol {Grid Layout}, or
\uicontrol {Stack Layout}, select the items in the \uicontrol {Form Editor}, \uicontrol {Stack Layout}, select the items in the \uicontrol {Form Editor},
and then select \uicontrol Layout in the context menu. and then select \uicontrol Layout in the context menu.

View File

@@ -50,7 +50,7 @@
\uicontrol Properties pane, and enter the name of another QML type in the \uicontrol Properties pane, and enter the name of another QML type in the
field. If you have specified properties for the item that are not supported field. If you have specified properties for the item that are not supported
for the new type, the type cannot be changed and an error message is for the new type, the type cannot be changed and an error message is
displayed. Select the \uicontrol Nut menu next to the property name, and displayed. Select the \uicontrol Settings menu next to the property name, and
then select \uicontrol Reset to remove the property values before trying then select \uicontrol Reset to remove the property values before trying
again. again.

View File

@@ -63,12 +63,12 @@
\li Show a different view or screen. \li Show a different view or screen.
\endlist \endlist
The \uicontrol State pane displays the different \l{State}{states} The \uicontrol States pane displays the different \l{State}{states}
of the component in the Design mode. The \uicontrol State pane is of the component in the Design mode. The \uicontrol States pane is
collapsed by default to save space. Select \uicontrol Expand in collapsed by default to save space. Select \uicontrol Expand in
the context menu to view the whole pane. the context menu to view the whole pane.
\image qmldesigner-transitions.png "State pane" \image qmldesigner-transitions.png "States pane"
To add states, click the \inlineimage plus.png To add states, click the \inlineimage plus.png
button. Then modify the new state in the editor. For example, to change the button. Then modify the new state in the editor. For example, to change the
@@ -81,7 +81,7 @@
\uicontrol {Set when Condition} in the menu and specify a \uicontrol {Set when Condition} in the menu and specify a
\l [QtQuick]{State::when}{when} property for the state. \l [QtQuick]{State::when}{when} property for the state.
You can preview the states in the \uicontrol State pane and click them to You can preview the states in the \uicontrol States pane and click them to
switch between states on the canvas. switch between states on the canvas.
\section1 Using States \section1 Using States

View File

@@ -103,6 +103,10 @@ function extraLibraries(llvmConfig, targetOS)
function formattingLibs(llvmConfig, qtcFunctions, targetOS) function formattingLibs(llvmConfig, qtcFunctions, targetOS)
{ {
var llvmIncludeDir = includeDir(llvmConfig);
if (!File.exists(llvmIncludeDir.concat("/clang/Format/Format.h")))
return [];
var clangVersion = version(llvmConfig) var clangVersion = version(llvmConfig)
var libs = [] var libs = []
if (qtcFunctions.versionIsAtLeast(clangVersion, MinimumLLVMVersion)) { if (qtcFunctions.versionIsAtLeast(clangVersion, MinimumLLVMVersion)) {

View File

@@ -25,7 +25,7 @@ Module {
property string relativeLibexecPath: FileInfo.relativePath('/' + appInstallDir, property string relativeLibexecPath: FileInfo.relativePath('/' + appInstallDir,
'/' + libexecInstallDir) '/' + libexecInstallDir)
property string relativePluginsPath: FileInfo.relativePath('/' + appInstallDir, property string relativePluginsPath: FileInfo.relativePath('/' + appInstallDir,
'/' + pluginsInstallDir) '/' + qtc.ide_plugin_path)
property string relativeSearchPath: FileInfo.relativePath('/' + appInstallDir, property string relativeSearchPath: FileInfo.relativePath('/' + appInstallDir,
'/' + resourcesInstallDir) '/' + resourcesInstallDir)
} }

View File

@@ -458,10 +458,6 @@ class Dumper(DumperBase):
def report(self, stuff): def report(self, stuff):
sys.stdout.write(stuff + "\n") sys.stdout.write(stuff + "\n")
def loadDumpers(self, args):
msg = self.setupDumpers()
self.reportResult(msg, args)
def findValueByExpression(self, exp): def findValueByExpression(self, exp):
return cdbext.parseAndEvaluate(exp) return cdbext.parseAndEvaluate(exp)

View File

@@ -1024,7 +1024,20 @@ def qdump__std__basic_string(d, value):
def qdump__std____cxx11__basic_string(d, value): def qdump__std____cxx11__basic_string(d, value):
innerType = value.type[0] innerType = value.type[0]
try:
allocator = value.type[2].name
except:
allocator = ''
if allocator == 'std::allocator<%s>' % innerType.name:
(data, size) = value.split("pI") (data, size) = value.split("pI")
else:
try:
data = value["_M_dataplus"]["_M_p"]
size = int(value["_M_string_length"])
except:
d.putEmptyValue()
d.putPlainChildren(value)
return
d.check(0 <= size) #and size <= alloc and alloc <= 100*1000*1000) d.check(0 <= size) #and size <= alloc and alloc <= 100*1000*1000)
d.putCharArrayHelper(data, size, innerType, d.currentItemFormat()) d.putCharArrayHelper(data, size, innerType, d.currentItemFormat())

View File

@@ -267,13 +267,13 @@ static bool isList(const QQmlProperty &property)
static bool isQJSValue(const QQmlProperty &property) static bool isQJSValue(const QQmlProperty &property)
{ {
return !strcmp(property.propertyTypeName(), "QJSValue"); return property.isValid() && !strcmp(property.propertyTypeName(), "QJSValue");
} }
static bool isObject(const QQmlProperty &property) static bool isObject(const QQmlProperty &property)
{ {
/* QVariant and QJSValue can also store QObjects. Lets trust our model. */ /* QVariant and QJSValue can also store QObjects. Lets trust our model. */
return (property.propertyTypeCategory() == QQmlProperty::Object return property.isValid() && (property.propertyTypeCategory() == QQmlProperty::Object
|| !strcmp(property.propertyTypeName(), "QVariant") || !strcmp(property.propertyTypeName(), "QVariant")
|| isQJSValue(property)); || isQJSValue(property));
} }

View File

@@ -73,7 +73,8 @@ plugin_sources -= src/plugins/plugins.pro \
shared_sources = $$files($$IDE_SOURCE_TREE/src/shared/*) shared_sources = $$files($$IDE_SOURCE_TREE/src/shared/*)
shared_sources ~= s,^$$re_escape($$IDE_SOURCE_TREE/),,g$$i_flag shared_sources ~= s,^$$re_escape($$IDE_SOURCE_TREE/),,g$$i_flag
shared_sources -= \ shared_sources -= \
src/shared/qbs src/shared/qbs \
src/shared/shared.pro
sources = src/app src/libs $$plugin_sources $$shared_sources share/qtcreator/qmldesigner sources = src/app src/libs $$plugin_sources $$shared_sources share/qtcreator/qmldesigner
for(path, INCLUDEPATH): include_options *= -I$$shell_quote($$path) for(path, INCLUDEPATH): include_options *= -I$$shell_quote($$path)

View File

@@ -26,14 +26,25 @@
#include "baseserverproxy.h" #include "baseserverproxy.h"
#include "messageenvelop.h" #include "messageenvelop.h"
#include <QIODevice> #include <QLocalSocket>
namespace ClangBackEnd { namespace ClangBackEnd {
BaseServerProxy::BaseServerProxy(IpcClientInterface *client, QLocalSocket *localSocket)
: m_writeMessageBlock(localSocket)
, m_readMessageBlock(localSocket)
, m_client(client)
{
if (localSocket)
QObject::connect(localSocket, &QIODevice::readyRead, [this]() {
BaseServerProxy::readMessages();
});
}
BaseServerProxy::BaseServerProxy(IpcClientInterface *client, QIODevice *ioDevice) BaseServerProxy::BaseServerProxy(IpcClientInterface *client, QIODevice *ioDevice)
: m_writeMessageBlock(ioDevice), : m_writeMessageBlock(ioDevice)
m_readMessageBlock(ioDevice), , m_readMessageBlock(ioDevice)
m_client(client) , m_client(client)
{ {
if (ioDevice) if (ioDevice)
QObject::connect(ioDevice, &QIODevice::readyRead, [this] () { BaseServerProxy::readMessages(); }); QObject::connect(ioDevice, &QIODevice::readyRead, [this] () { BaseServerProxy::readMessages(); });
@@ -51,11 +62,13 @@ void BaseServerProxy::resetState()
m_readMessageBlock.resetState(); m_readMessageBlock.resetState();
} }
void BaseServerProxy::setIoDevice(QIODevice *ioDevice) void BaseServerProxy::setLocalSocket(QLocalSocket *localSocket)
{ {
QObject::connect(ioDevice, &QIODevice::readyRead, [this] () { BaseServerProxy::readMessages(); }); QObject::connect(localSocket, &QIODevice::readyRead, [this]() {
m_writeMessageBlock.setIoDevice(ioDevice); BaseServerProxy::readMessages();
m_readMessageBlock.setIoDevice(ioDevice); });
m_writeMessageBlock.setLocalSocket(localSocket);
m_readMessageBlock.setIoDevice(localSocket);
} }
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -37,13 +37,14 @@ class CLANGSUPPORT_EXPORT BaseServerProxy
BaseServerProxy &operator=(const BaseServerProxy&) = delete; BaseServerProxy &operator=(const BaseServerProxy&) = delete;
public: public:
BaseServerProxy(IpcClientInterface *client, QLocalSocket *localSocket);
BaseServerProxy(IpcClientInterface *client, QIODevice *ioDevice); BaseServerProxy(IpcClientInterface *client, QIODevice *ioDevice);
void readMessages(); void readMessages();
void resetState(); void resetState();
void setIoDevice(QIODevice *ioDevice); void setLocalSocket(QLocalSocket *localSocket);
protected: protected:
~BaseServerProxy() = default; ~BaseServerProxy() = default;

View File

@@ -31,19 +31,34 @@
#include "messageenvelop.h" #include "messageenvelop.h"
#include <QDebug> #include <QDebug>
#include <QIODevice> #include <QLocalSocket>
#include <QVariant> #include <QVariant>
#include <QVector> #include <QVector>
namespace ClangBackEnd { namespace ClangBackEnd {
ClangCodeModelClientProxy::ClangCodeModelClientProxy(ClangCodeModelServerInterface *server, QIODevice *ioDevice) ClangCodeModelClientProxy::ClangCodeModelClientProxy(ClangCodeModelServerInterface *server,
: m_writeMessageBlock(ioDevice), QLocalSocket *localSocket)
m_readMessageBlock(ioDevice), : m_writeMessageBlock(localSocket)
m_server(server), , m_readMessageBlock(localSocket)
m_ioDevice(ioDevice) , m_server(server)
, m_ioDevice(localSocket)
{ {
QObject::connect(m_ioDevice, &QIODevice::readyRead, [this] () {ClangCodeModelClientProxy::readMessages();}); QObject::connect(m_ioDevice, &QIODevice::readyRead, [this]() {
ClangCodeModelClientProxy::readMessages();
});
}
ClangCodeModelClientProxy::ClangCodeModelClientProxy(ClangCodeModelServerInterface *server,
QIODevice *ioDevice)
: m_writeMessageBlock(ioDevice)
, m_readMessageBlock(ioDevice)
, m_server(server)
, m_ioDevice(ioDevice)
{
QObject::connect(m_ioDevice, &QIODevice::readyRead, [this]() {
ClangCodeModelClientProxy::readMessages();
});
} }
ClangCodeModelClientProxy::ClangCodeModelClientProxy(ClangCodeModelClientProxy &&other) ClangCodeModelClientProxy::ClangCodeModelClientProxy(ClangCodeModelClientProxy &&other)
@@ -106,9 +121,9 @@ void ClangCodeModelClientProxy::readMessages()
m_server->dispatch(message); m_server->dispatch(message);
} }
bool ClangCodeModelClientProxy::isUsingThatIoDevice(QIODevice *m_ioDevice) const bool ClangCodeModelClientProxy::isUsingThatIoDevice(QIODevice *ioDevice) const
{ {
return this->m_ioDevice == m_ioDevice; return m_ioDevice == ioDevice;
} }
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -36,6 +36,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QLocalServer; class QLocalServer;
class QLocalSocket;
class QIODevice; class QIODevice;
QT_END_NAMESPACE QT_END_NAMESPACE
@@ -44,6 +45,8 @@ namespace ClangBackEnd {
class CLANGSUPPORT_EXPORT ClangCodeModelClientProxy : public ClangCodeModelClientInterface class CLANGSUPPORT_EXPORT ClangCodeModelClientProxy : public ClangCodeModelClientInterface
{ {
public: public:
explicit ClangCodeModelClientProxy(ClangCodeModelServerInterface *server,
QLocalSocket *localSocket);
explicit ClangCodeModelClientProxy(ClangCodeModelServerInterface *server, QIODevice *ioDevice); explicit ClangCodeModelClientProxy(ClangCodeModelServerInterface *server, QIODevice *ioDevice);
ClangCodeModelClientProxy(const ClangCodeModelClientProxy&) = delete; ClangCodeModelClientProxy(const ClangCodeModelClientProxy&) = delete;
const ClangCodeModelClientProxy &operator=(const ClangCodeModelClientProxy&) = delete; const ClangCodeModelClientProxy &operator=(const ClangCodeModelClientProxy&) = delete;

View File

@@ -41,12 +41,10 @@ QString currentProcessId()
} }
ClangCodeModelConnectionClient::ClangCodeModelConnectionClient( ClangCodeModelConnectionClient::ClangCodeModelConnectionClient(ClangCodeModelClientInterface *client)
ClangCodeModelClientInterface *client)
: ConnectionClient(Utils::TemporaryDirectory::masterDirectoryPath() : ConnectionClient(Utils::TemporaryDirectory::masterDirectoryPath()
+ QStringLiteral("/ClangBackEnd-") + QStringLiteral("/ClangBackEnd-") + currentProcessId())
+ currentProcessId()), , m_serverProxy(client)
m_serverProxy(client, nullptr)
{ {
m_processCreator.setTemporaryDirectoryPattern("clangbackend-XXXXXX"); m_processCreator.setTemporaryDirectoryPattern("clangbackend-XXXXXX");
m_processCreator.setArguments({connectionName()}); m_processCreator.setArguments({connectionName()});
@@ -85,9 +83,9 @@ QString ClangCodeModelConnectionClient::outputName() const
return QStringLiteral("ClangCodeModelConnectionClient"); return QStringLiteral("ClangCodeModelConnectionClient");
} }
void ClangCodeModelConnectionClient::newConnectedServer(QIODevice *ioDevice) void ClangCodeModelConnectionClient::newConnectedServer(QLocalSocket *localSocket)
{ {
m_serverProxy.setIoDevice(ioDevice); m_serverProxy.setLocalSocket(localSocket);
} }
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -41,7 +41,7 @@ protected:
void sendEndCommand() override; void sendEndCommand() override;
void resetState() override; void resetState() override;
QString outputName() const override; QString outputName() const override;
void newConnectedServer(QIODevice *ioDevice) override; void newConnectedServer(QLocalSocket *localSocket) override;
private: private:
ClangCodeModelServerProxy m_serverProxy; ClangCodeModelServerProxy m_serverProxy;

View File

@@ -31,6 +31,11 @@
namespace ClangBackEnd { namespace ClangBackEnd {
ClangCodeModelServerProxy::ClangCodeModelServerProxy(ClangCodeModelClientInterface *client,
QLocalSocket *localSocket)
: BaseServerProxy(client, localSocket)
{}
ClangCodeModelServerProxy::ClangCodeModelServerProxy(ClangCodeModelClientInterface *client, ClangCodeModelServerProxy::ClangCodeModelServerProxy(ClangCodeModelClientInterface *client,
QIODevice *ioDevice) QIODevice *ioDevice)
: BaseServerProxy(client, ioDevice) : BaseServerProxy(client, ioDevice)

View File

@@ -46,6 +46,7 @@ class CLANGSUPPORT_EXPORT ClangCodeModelServerProxy : public BaseServerProxy,
public ClangCodeModelServerInterface public ClangCodeModelServerInterface
{ {
public: public:
ClangCodeModelServerProxy(ClangCodeModelClientInterface *client, QLocalSocket *localSocket = {});
ClangCodeModelServerProxy(ClangCodeModelClientInterface *client, QIODevice *ioDevice); ClangCodeModelServerProxy(ClangCodeModelClientInterface *client, QIODevice *ioDevice);
void end() override; void end() override;

View File

@@ -235,11 +235,5 @@ enum class SymbolTag : uchar
using SymbolTags = Utils::SizedArray<SymbolTag, 7>; using SymbolTags = Utils::SizedArray<SymbolTag, 7>;
enum class ProgressType enum class ProgressType { Invalid, PrecompiledHeader, Indexing, DependencyCreation };
{ } // namespace ClangBackEnd
Invalid,
PrecompiledHeader,
Indexing
};
}

View File

@@ -100,7 +100,7 @@ protected:
QString connectionName() const; QString connectionName() const;
bool event(QEvent* event); bool event(QEvent* event);
virtual void newConnectedServer(QIODevice *ioDevice) = 0; virtual void newConnectedServer(QLocalSocket *localSocket) = 0;
private: private:
static bool isProcessRunning(QProcess *process); static bool isProcessRunning(QProcess *process);

View File

@@ -32,35 +32,29 @@
#include "progressmessage.h" #include "progressmessage.h"
#include <QDebug> #include <QDebug>
#include <QIODevice> #include <QLocalSocket>
namespace ClangBackEnd { namespace ClangBackEnd {
PchManagerClientProxy::PchManagerClientProxy(PchManagerServerInterface *server,
QLocalSocket *localSocket)
: writeMessageBlock(localSocket)
, readMessageBlock(localSocket)
, server(server)
{
QObject::connect(localSocket, &QIODevice::readyRead, [this]() {
PchManagerClientProxy::readMessages();
});
}
PchManagerClientProxy::PchManagerClientProxy(PchManagerServerInterface *server, QIODevice *ioDevice) PchManagerClientProxy::PchManagerClientProxy(PchManagerServerInterface *server, QIODevice *ioDevice)
: writeMessageBlock(ioDevice), : writeMessageBlock(ioDevice)
readMessageBlock(ioDevice), , readMessageBlock(ioDevice)
server(server), , server(server)
ioDevice(ioDevice)
{ {
QObject::connect(ioDevice, &QIODevice::readyRead, [this] () {PchManagerClientProxy::readMessages();}); QObject::connect(ioDevice, &QIODevice::readyRead, [this]() {
} PchManagerClientProxy::readMessages();
});
PchManagerClientProxy::PchManagerClientProxy(PchManagerClientProxy &&other)
: writeMessageBlock(std::move(other.writeMessageBlock)),
readMessageBlock(std::move(other.readMessageBlock)),
server(std::move(other.server)),
ioDevice(std::move(other.ioDevice))
{
}
PchManagerClientProxy &PchManagerClientProxy::operator=(PchManagerClientProxy &&other)
{
writeMessageBlock = std::move(other.writeMessageBlock);
readMessageBlock = std::move(other.readMessageBlock);
server = std::move(other.server);
ioDevice = std::move(other.ioDevice);
return *this;
} }
void PchManagerClientProxy::readMessages() void PchManagerClientProxy::readMessages()

View File

@@ -34,15 +34,16 @@ namespace ClangBackEnd {
class PchManagerServerInterface; class PchManagerServerInterface;
class CLANGSUPPORT_EXPORT PchManagerClientProxy : public PchManagerClientInterface class CLANGSUPPORT_EXPORT PchManagerClientProxy final : public PchManagerClientInterface
{ {
public: public:
explicit PchManagerClientProxy(PchManagerServerInterface *server, QLocalSocket *localSocket);
explicit PchManagerClientProxy(PchManagerServerInterface *server, QIODevice *ioDevice); explicit PchManagerClientProxy(PchManagerServerInterface *server, QIODevice *ioDevice);
PchManagerClientProxy(const PchManagerClientProxy&) = delete; PchManagerClientProxy(const PchManagerClientProxy&) = delete;
const PchManagerClientProxy &operator=(const PchManagerClientProxy&) = delete; const PchManagerClientProxy &operator=(const PchManagerClientProxy&) = delete;
PchManagerClientProxy(PchManagerClientProxy&&other); PchManagerClientProxy(PchManagerClientProxy &&other) = default;
PchManagerClientProxy &operator=(PchManagerClientProxy&&other); PchManagerClientProxy &operator=(PchManagerClientProxy &&other) = default;
void readMessages(); void readMessages();
@@ -54,7 +55,6 @@ private:
ClangBackEnd::WriteMessageBlock writeMessageBlock; ClangBackEnd::WriteMessageBlock writeMessageBlock;
ClangBackEnd::ReadMessageBlock readMessageBlock; ClangBackEnd::ReadMessageBlock readMessageBlock;
PchManagerServerInterface *server = nullptr; PchManagerServerInterface *server = nullptr;
QIODevice *ioDevice = nullptr;
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -38,6 +38,11 @@
namespace ClangBackEnd { namespace ClangBackEnd {
PchManagerServerProxy::PchManagerServerProxy(PchManagerClientInterface *client,
QLocalSocket *localSocket)
: BaseServerProxy(client, localSocket)
{}
PchManagerServerProxy::PchManagerServerProxy(PchManagerClientInterface *client, QIODevice *ioDevice) PchManagerServerProxy::PchManagerServerProxy(PchManagerClientInterface *client, QIODevice *ioDevice)
: BaseServerProxy(client, ioDevice) : BaseServerProxy(client, ioDevice)
{ {

View File

@@ -47,6 +47,7 @@ class CLANGSUPPORT_EXPORT PchManagerServerProxy final : public BaseServerProxy,
public PchManagerServerInterface public PchManagerServerInterface
{ {
public: public:
explicit PchManagerServerProxy(PchManagerClientInterface *client, QLocalSocket *localSocket);
explicit PchManagerServerProxy(PchManagerClientInterface *client, QIODevice *ioDevice); explicit PchManagerServerProxy(PchManagerClientInterface *client, QIODevice *ioDevice);
void end() override; void end() override;

View File

@@ -84,7 +84,7 @@ public:
{ {
Lock lock(m_mutex); Lock lock(m_mutex);
return m_total; return m_progress;
} }
private: private:

View File

@@ -36,23 +36,27 @@ class ProgressMessage
public: public:
ProgressMessage() = default; ProgressMessage() = default;
ProgressMessage(ProgressType progressType, int progress, int total) ProgressMessage(ProgressType progressType, int progress, int total)
: progressType(progressType), : progress(progress)
progress(progress), , total(total)
total(total) , progressType(progressType)
{} {}
friend QDataStream &operator<<(QDataStream &out, const ProgressMessage &message) friend QDataStream &operator<<(QDataStream &out, const ProgressMessage &message)
{ {
out << message.progress; out << message.progress;
out << message.total; out << message.total;
out << static_cast<int>(message.progressType);
return out; return out;
} }
friend QDataStream &operator>>(QDataStream &in, ProgressMessage &message) friend QDataStream &operator>>(QDataStream &in, ProgressMessage &message)
{ {
int progressTupe;
in >> message.progress; in >> message.progress;
in >> message.total; in >> message.total;
in >> progressTupe;
message.progressType = static_cast<ProgressType>(progressTupe);
return in; return in;
} }
@@ -69,9 +73,9 @@ public:
} }
public: public:
ProgressType progressType = ProgressType::Invalid;
int progress = 0; int progress = 0;
int total = 0; int total = 0;
ProgressType progressType = ProgressType::Invalid;
}; };
DECLARE_MESSAGE(ProgressMessage) DECLARE_MESSAGE(ProgressMessage)

View File

@@ -31,38 +31,30 @@
#include "clangrefactoringclientmessages.h" #include "clangrefactoringclientmessages.h"
#include <QDebug> #include <QDebug>
#include <QIODevice> #include <QLocalSocket>
namespace ClangBackEnd { namespace ClangBackEnd {
RefactoringClientProxy::RefactoringClientProxy(RefactoringServerInterface *server, QIODevice *ioDevice) RefactoringClientProxy::RefactoringClientProxy(RefactoringServerInterface *server,
: writeMessageBlock(ioDevice), QLocalSocket *localSocket)
readMessageBlock(ioDevice), : writeMessageBlock(localSocket)
server(server), , readMessageBlock(localSocket)
ioDevice(ioDevice) , server(server)
{
QObject::connect(localSocket, &QIODevice::readyRead, [this]() {
RefactoringClientProxy::readMessages();
});
}
RefactoringClientProxy::RefactoringClientProxy(RefactoringServerInterface *server,
QIODevice *ioDevice)
: writeMessageBlock(ioDevice)
, readMessageBlock(ioDevice)
, server(server)
{ {
QObject::connect(ioDevice, &QIODevice::readyRead, [this] () {RefactoringClientProxy::readMessages();}); QObject::connect(ioDevice, &QIODevice::readyRead, [this] () {RefactoringClientProxy::readMessages();});
} }
RefactoringClientProxy::RefactoringClientProxy(RefactoringClientProxy &&other)
: writeMessageBlock(std::move(other.writeMessageBlock)),
readMessageBlock(std::move(other.readMessageBlock)),
server(std::move(other.server)),
ioDevice(std::move(other.ioDevice))
{
}
RefactoringClientProxy &RefactoringClientProxy::operator=(RefactoringClientProxy &&other)
{
writeMessageBlock = std::move(other.writeMessageBlock);
readMessageBlock = std::move(other.readMessageBlock);
server = std::move(other.server);
ioDevice = std::move(other.ioDevice);
return *this;
}
void RefactoringClientProxy::readMessages() void RefactoringClientProxy::readMessages()
{ {
for (const MessageEnvelop &message : readMessageBlock.readAll()) for (const MessageEnvelop &message : readMessageBlock.readAll())

View File

@@ -39,12 +39,13 @@ class RefactoringServerInterface;
class CLANGSUPPORT_EXPORT RefactoringClientProxy : public RefactoringClientInterface class CLANGSUPPORT_EXPORT RefactoringClientProxy : public RefactoringClientInterface
{ {
public: public:
explicit RefactoringClientProxy(RefactoringServerInterface *server, QLocalSocket *localSocket);
explicit RefactoringClientProxy(RefactoringServerInterface *server, QIODevice *ioDevice); explicit RefactoringClientProxy(RefactoringServerInterface *server, QIODevice *ioDevice);
RefactoringClientProxy(const RefactoringClientProxy&) = delete; RefactoringClientProxy(const RefactoringClientProxy&) = delete;
const RefactoringClientProxy &operator=(const RefactoringClientProxy&) = delete; const RefactoringClientProxy &operator=(const RefactoringClientProxy&) = delete;
RefactoringClientProxy(RefactoringClientProxy&&other); RefactoringClientProxy(RefactoringClientProxy &&other) = default;
RefactoringClientProxy &operator=(RefactoringClientProxy&&other); RefactoringClientProxy &operator=(RefactoringClientProxy &&other) = default;
void readMessages(); void readMessages();
@@ -60,7 +61,6 @@ private:
ClangBackEnd::WriteMessageBlock writeMessageBlock; ClangBackEnd::WriteMessageBlock writeMessageBlock;
ClangBackEnd::ReadMessageBlock readMessageBlock; ClangBackEnd::ReadMessageBlock readMessageBlock;
RefactoringServerInterface *server = nullptr; RefactoringServerInterface *server = nullptr;
QIODevice *ioDevice = nullptr;
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -34,7 +34,13 @@
namespace ClangBackEnd { namespace ClangBackEnd {
RefactoringServerProxy::RefactoringServerProxy(RefactoringClientInterface *client, QIODevice *ioDevice) RefactoringServerProxy::RefactoringServerProxy(RefactoringClientInterface *client,
QLocalSocket *localSocket)
: BaseServerProxy(client, localSocket)
{}
RefactoringServerProxy::RefactoringServerProxy(RefactoringClientInterface *client,
QIODevice *ioDevice)
: BaseServerProxy(client, ioDevice) : BaseServerProxy(client, ioDevice)
{ {
} }

View File

@@ -47,6 +47,8 @@ class CLANGSUPPORT_EXPORT RefactoringServerProxy final : public BaseServerProxy,
public RefactoringServerInterface public RefactoringServerInterface
{ {
public: public:
explicit RefactoringServerProxy(RefactoringClientInterface *client,
QLocalSocket *localSocket = {});
explicit RefactoringServerProxy(RefactoringClientInterface *client, QIODevice *ioDevice); explicit RefactoringServerProxy(RefactoringClientInterface *client, QIODevice *ioDevice);
void end() override; void end() override;

View File

@@ -29,16 +29,19 @@
#include <QDataStream> #include <QDataStream>
#include <QDebug> #include <QDebug>
#include <QIODevice> #include <QLocalSocket>
#include <QVariant> #include <QVariant>
namespace ClangBackEnd { namespace ClangBackEnd {
WriteMessageBlock::WriteMessageBlock(QIODevice *ioDevice) WriteMessageBlock::WriteMessageBlock(QIODevice *ioDevice)
: m_messageCounter(0), : m_ioDevice(ioDevice)
m_ioDevice(ioDevice) {}
{
} WriteMessageBlock::WriteMessageBlock(QLocalSocket *localSocket)
: m_ioDevice(localSocket)
, m_localSocket(localSocket)
{}
void WriteMessageBlock::write(const MessageEnvelop &message) void WriteMessageBlock::write(const MessageEnvelop &message)
{ {
@@ -74,10 +77,19 @@ void WriteMessageBlock::resetState()
void WriteMessageBlock::setIoDevice(QIODevice *ioDevice) void WriteMessageBlock::setIoDevice(QIODevice *ioDevice)
{ {
m_ioDevice = ioDevice; m_ioDevice = ioDevice;
if (m_localSocket != ioDevice)
m_localSocket = nullptr;
flushBlock(); flushBlock();
} }
void WriteMessageBlock::setLocalSocket(QLocalSocket *localSocket)
{
m_localSocket = localSocket;
setIoDevice(localSocket);
}
void WriteMessageBlock::flushBlock() void WriteMessageBlock::flushBlock()
{ {
if (m_ioDevice) { if (m_ioDevice) {
@@ -85,6 +97,8 @@ void WriteMessageBlock::flushBlock()
m_block.clear(); m_block.clear();
if (bytesWritten == -1) if (bytesWritten == -1)
qWarning() << "Failed to write data:" << m_ioDevice->errorString(); qWarning() << "Failed to write data:" << m_ioDevice->errorString();
if (m_localSocket)
m_localSocket->flush();
} }
} }

View File

@@ -32,6 +32,7 @@ QT_BEGIN_NAMESPACE
class QVariant; class QVariant;
class QDataStream; class QDataStream;
class QIODevice; class QIODevice;
class QLocalSocket;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace ClangBackEnd { namespace ClangBackEnd {
@@ -42,6 +43,7 @@ class WriteMessageBlock
{ {
public: public:
WriteMessageBlock(QIODevice *ioDevice = nullptr); WriteMessageBlock(QIODevice *ioDevice = nullptr);
WriteMessageBlock(QLocalSocket *localSocket);
void write(const MessageEnvelop &message); void write(const MessageEnvelop &message);
@@ -50,13 +52,15 @@ public:
void resetState(); void resetState();
void setIoDevice(QIODevice *ioDevice); void setIoDevice(QIODevice *ioDevice);
void setLocalSocket(QLocalSocket *localSocket);
void flushBlock(); void flushBlock();
private: private:
QByteArray m_block; QByteArray m_block;
qint64 m_messageCounter; qint64 m_messageCounter = 0;
QIODevice *m_ioDevice; QIODevice *m_ioDevice = {};
QLocalSocket *m_localSocket = {};
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -764,7 +764,7 @@ QByteArray Preprocessor::run(const QString &fileName,
preprocessed.reserve(source.size() * 2); // multiply by 2 because we insert #gen lines. preprocessed.reserve(source.size() * 2); // multiply by 2 because we insert #gen lines.
preprocess(fileName, source, &preprocessed, &includeGuardMacroName, noLines, preprocess(fileName, source, &preprocessed, &includeGuardMacroName, noLines,
markGeneratedTokens, false); markGeneratedTokens, false);
if (!includeGuardMacroName.isEmpty()) if (m_client && !includeGuardMacroName.isEmpty())
m_client->markAsIncludeGuard(includeGuardMacroName); m_client->markAsIncludeGuard(includeGuardMacroName);
return preprocessed; return preprocessed;
} }
@@ -986,10 +986,12 @@ bool Preprocessor::handleIdentifier(PPToken *tk)
if (!expandFunctionlikeMacros() if (!expandFunctionlikeMacros()
// Still expand if this originally started with an object-like macro. // Still expand if this originally started with an object-like macro.
&& m_state.m_expansionStatus != Expanding) { && m_state.m_expansionStatus != Expanding) {
if (m_client) {
m_client->notifyMacroReference(m_state.m_bytesOffsetRef + idTk.byteOffset, m_client->notifyMacroReference(m_state.m_bytesOffsetRef + idTk.byteOffset,
m_state.m_utf16charsOffsetRef + idTk.utf16charOffset, m_state.m_utf16charsOffsetRef + idTk.utf16charOffset,
idTk.lineno, idTk.lineno,
*macro); *macro);
}
return false; return false;
} }
@@ -1793,7 +1795,7 @@ void Preprocessor::handleDefineDirective(PPToken *tk)
} }
} }
} else if (macroReference) { } else if (macroReference) {
if (tk->is(T_LPAREN)) { if (m_client && tk->is(T_LPAREN)) {
m_client->notifyMacroReference(previousBytesOffset, previousUtf16charsOffset, m_client->notifyMacroReference(previousBytesOffset, previousUtf16charsOffset,
previousLine, *macroReference); previousLine, *macroReference);
} }

View File

@@ -86,7 +86,7 @@ static void addFunctionOverloadAssistProposalItem(QList<AssistProposalItemInterf
const QString &name) const QString &name)
{ {
auto *item = static_cast<ClangAssistProposalItem *>(sameItem); auto *item = static_cast<ClangAssistProposalItem *>(sameItem);
item->setHasOverloadsWithParameters(true); item->setHasOverloadsWithParameters(codeCompletion.hasParameters);
if (codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind) { if (codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind) {
// It's the constructor, currently constructor definitions do not lead here. // It's the constructor, currently constructor definitions do not lead here.
// CLANG-UPGRADE-CHECK: Can we get here with constructor definition? // CLANG-UPGRADE-CHECK: Can we get here with constructor definition?

View File

@@ -49,7 +49,7 @@ private:
void filterFixits(); void filterFixits();
private: private:
const QString &m_filePath; const QString m_filePath;
QVector<ClangBackEnd::DiagnosticContainer> m_warningDiagnostics; QVector<ClangBackEnd::DiagnosticContainer> m_warningDiagnostics;
QVector<ClangBackEnd::DiagnosticContainer> m_errorDiagnostics; QVector<ClangBackEnd::DiagnosticContainer> m_errorDiagnostics;

View File

@@ -28,6 +28,7 @@
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <cpptools/cppmodelmanager.h> #include <cpptools/cppmodelmanager.h>
#include <cpptools/cppfollowsymbolundercursor.h>
#include <texteditor/texteditor.h> #include <texteditor/texteditor.h>
#include <clangsupport/tokeninfocontainer.h> #include <clangsupport/tokeninfocontainer.h>
@@ -183,12 +184,22 @@ void ClangFollowSymbol::findLink(const CppTools::CursorInEditor &data,
return processLinkCallback(Utils::Link()); return processLinkCallback(Utils::Link());
if (!resolveTarget) { if (!resolveTarget) {
processLinkCallback(linkAtCursor(cursor, Utils::Link link = linkAtCursor(cursor,
data.filePath().toString(), data.filePath().toString(),
static_cast<uint>(line), static_cast<uint>(line),
static_cast<uint>(column), static_cast<uint>(column),
processor)); processor);
return; if (link == Utils::Link()) {
CppTools::FollowSymbolUnderCursor followSymbol;
return followSymbol.findLink(data,
std::move(processLinkCallback),
false,
snapshot,
documentFromSemanticInfo,
symbolFinder,
inNextSplit);
}
return processLinkCallback(link);
} }
QFuture<CppTools::SymbolInfo> infoFuture QFuture<CppTools::SymbolInfo> infoFuture

View File

@@ -15,6 +15,7 @@ QtcPlugin {
Depends { name: "Qt.widgets" } Depends { name: "Qt.widgets" }
condition: libclang.present condition: libclang.present
&& libclang.llvmFormattingLibs.length
&& (!qbs.targetOS.contains("windows") || libclang.llvmBuildModeMatches) && (!qbs.targetOS.contains("windows") || libclang.llvmBuildModeMatches)
cpp.cxxFlags: { cpp.cxxFlags: {

View File

@@ -5,4 +5,4 @@ QTC_LIB_DEPENDS += \
QTC_PLUGIN_DEPENDS += \ QTC_PLUGIN_DEPENDS += \
cpptools \ cpptools \
projectexplorer \ projectexplorer \
texteditor cppeditor

View File

@@ -136,7 +136,7 @@ int forceIndentWithExtraText(QByteArray &buffer, const QTextBlock &block, bool s
int utf8Offset = Utils::Text::utf8NthLineOffset(block.document(), int utf8Offset = Utils::Text::utf8NthLineOffset(block.document(),
buffer, buffer,
block.blockNumber() + 1); block.blockNumber() + 1);
if (firstNonWhitespace > 0) if (firstNonWhitespace >= 0)
utf8Offset += firstNonWhitespace; utf8Offset += firstNonWhitespace;
else else
utf8Offset += blockText.length(); utf8Offset += blockText.length();
@@ -336,6 +336,7 @@ ClangFormatBaseIndenter::ClangFormatBaseIndenter(QTextDocument *doc)
TextEditor::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffer, TextEditor::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffer,
const QTextBlock &startBlock, const QTextBlock &startBlock,
const QTextBlock &endBlock, const QTextBlock &endBlock,
int cursorPositionInEditor,
ReplacementsToKeep replacementsToKeep, ReplacementsToKeep replacementsToKeep,
const QChar &typedChar, const QChar &typedChar,
bool secondTry) const bool secondTry) const
@@ -353,19 +354,26 @@ TextEditor::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffer
if (replacementsToKeep == ReplacementsToKeep::IndentAndBefore) if (replacementsToKeep == ReplacementsToKeep::IndentAndBefore)
rangeStart = formattingRangeStart(startBlock, buffer, lastSaveRevision()); rangeStart = formattingRangeStart(startBlock, buffer, lastSaveRevision());
adjustFormatStyleForLineBreak(style, replacementsToKeep);
if (typedChar == QChar::Null) {
if (replacementsToKeep == ReplacementsToKeep::IndentAndBefore) { if (replacementsToKeep == ReplacementsToKeep::IndentAndBefore) {
if (utf8Offset > 0) {
buffer.insert(utf8Offset - 1, " //"); buffer.insert(utf8Offset - 1, " //");
utf8Offset += 3; utf8Offset += 3;
} }
utf8Length += forceIndentWithExtraText(buffer,
adjustFormatStyleForLineBreak(style, replacementsToKeep); cursorPositionInEditor < 0
if (typedChar == QChar::Null) { ? endBlock
: m_doc->findBlock(cursorPositionInEditor),
secondTry);
} else {
for (int index = startBlock.blockNumber(); index <= endBlock.blockNumber(); ++index) { for (int index = startBlock.blockNumber(); index <= endBlock.blockNumber(); ++index) {
utf8Length += forceIndentWithExtraText(buffer, utf8Length += forceIndentWithExtraText(buffer,
m_doc->findBlockByNumber(index), m_doc->findBlockByNumber(index),
secondTry); secondTry);
} }
} }
}
if (replacementsToKeep != ReplacementsToKeep::IndentAndBefore || utf8Offset < rangeStart) if (replacementsToKeep != ReplacementsToKeep::IndentAndBefore || utf8Offset < rangeStart)
rangeStart = utf8Offset; rangeStart = utf8Offset;
@@ -394,6 +402,7 @@ TextEditor::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffer
return replacements(originalBuffer, return replacements(originalBuffer,
startBlock, startBlock,
endBlock, endBlock,
cursorPositionInEditor,
replacementsToKeep, replacementsToKeep,
typedChar, typedChar,
true); true);
@@ -468,6 +477,7 @@ TextEditor::Replacements ClangFormatBaseIndenter::indentsFor(QTextBlock startBlo
return replacements(buffer, return replacements(buffer,
startBlock, startBlock,
endBlock, endBlock,
cursorPositionInEditor,
replacementsToKeep, replacementsToKeep,
typedChar); typedChar);
} }

View File

@@ -87,6 +87,7 @@ private:
TextEditor::Replacements replacements(QByteArray buffer, TextEditor::Replacements replacements(QByteArray buffer,
const QTextBlock &startBlock, const QTextBlock &startBlock,
const QTextBlock &endBlock, const QTextBlock &endBlock,
int cursorPositionInEditor,
ReplacementsToKeep replacementsToKeep, ReplacementsToKeep replacementsToKeep,
const QChar &typedChar = QChar::Null, const QChar &typedChar = QChar::Null,
bool secondTry = false) const; bool secondTry = false) const;

View File

@@ -23,10 +23,10 @@
** **
****************************************************************************/ ****************************************************************************/
#include "clangformatconfigwidget.h" #include "clangformatconfigwidget.h"
#include "clangformatconstants.h" #include "clangformatconstants.h"
#include "clangformatindenter.h"
#include "clangformatsettings.h" #include "clangformatsettings.h"
#include "clangformatutils.h" #include "clangformatutils.h"
#include "ui_clangformatconfigwidget.h" #include "ui_clangformatconfigwidget.h"
@@ -34,10 +34,17 @@
#include <clang/Format/Format.h> #include <clang/Format/Format.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <cppeditor/cpphighlighter.h>
#include <cpptools/cppcodestylesnippets.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
#include <texteditor/displaysettings.h>
#include <texteditor/snippets/snippeteditor.h>
#include <texteditor/textdocument.h>
#include <texteditor/texteditorsettings.h>
#include <QFile> #include <QFile>
#include <QMessageBox>
#include <sstream> #include <sstream>
@@ -45,79 +52,7 @@ using namespace ProjectExplorer;
namespace ClangFormat { namespace ClangFormat {
static void readTable(QTableWidget *table, std::istringstream &stream) ClangFormatConfigWidget::ClangFormatConfigWidget(ProjectExplorer::Project *project, QWidget *parent)
{
table->horizontalHeader()->hide();
table->verticalHeader()->hide();
table->setColumnCount(2);
table->setRowCount(0);
std::string line;
while (std::getline(stream, line)) {
if (line == "---" || line == "...")
continue;
const size_t firstLetter = line.find_first_not_of(' ');
if (firstLetter == std::string::npos || line.at(firstLetter) == '#')
continue;
// Increase indent where it already exists.
if (firstLetter > 0 && firstLetter < 5)
line = " " + line;
table->insertRow(table->rowCount());
const size_t colonPos = line.find_first_of(':');
auto *keyItem = new QTableWidgetItem;
auto *valueItem = new QTableWidgetItem;
keyItem->setFlags(keyItem->flags() & ~Qt::ItemFlags(Qt::ItemIsEditable));
table->setItem(table->rowCount() - 1, 0, keyItem);
table->setItem(table->rowCount() - 1, 1, valueItem);
if (colonPos == std::string::npos) {
keyItem->setText(QString::fromStdString(line));
valueItem->setFlags(valueItem->flags() & ~Qt::ItemFlags(Qt::ItemIsEditable));
continue;
}
keyItem->setText(QString::fromStdString(line.substr(0, colonPos)));
const size_t optionValueStart = line.find_first_not_of(' ', colonPos + 1);
if (optionValueStart == std::string::npos)
valueItem->setFlags(valueItem->flags() & ~Qt::ItemFlags(Qt::ItemIsEditable));
else
valueItem->setText(QString::fromStdString(line.substr(optionValueStart)));
}
table->resizeColumnToContents(0);
table->resizeColumnToContents(1);
}
static QByteArray tableToYAML(QTableWidget *table)
{
QByteArray text;
text += "---\n";
for (int i = 0; i < table->rowCount(); ++i) {
auto *keyItem = table->item(i, 0);
auto *valueItem = table->item(i, 1);
QByteArray itemText = keyItem->text().toUtf8();
// Change the indent back to 2 spaces
itemText.replace(" ", " ");
if (!valueItem->text().isEmpty() || !itemText.trimmed().startsWith('-'))
itemText += ": ";
itemText += valueItem->text().toUtf8() + '\n';
text += itemText;
}
text += "...\n";
return text;
}
ClangFormatConfigWidget::ClangFormatConfigWidget(ProjectExplorer::Project *project,
QWidget *parent)
: CodeStyleEditorWidget(parent) : CodeStyleEditorWidget(parent)
, m_project(project) , m_project(project)
, m_ui(std::make_unique<Ui::ClangFormatConfigWidget>()) , m_ui(std::make_unique<Ui::ClangFormatConfigWidget>())
@@ -153,6 +88,17 @@ void ClangFormatConfigWidget::initialize()
m_ui->applyButton->show(); m_ui->applyButton->show();
hideGlobalCheckboxes(); hideGlobalCheckboxes();
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());
m_preview->textDocument()->setSyntaxHighlighter(new CppEditor::CppHighlighter);
TextEditor::DisplaySettings displaySettings = m_preview->displaySettings();
displaySettings.m_visualizeWhitespace = true;
m_preview->setDisplaySettings(displaySettings);
QLayoutItem *lastItem = m_ui->verticalLayout->itemAt(m_ui->verticalLayout->count() - 1); QLayoutItem *lastItem = m_ui->verticalLayout->itemAt(m_ui->verticalLayout->count() - 1);
if (lastItem->spacerItem()) if (lastItem->spacerItem())
m_ui->verticalLayout->removeItem(lastItem); m_ui->verticalLayout->removeItem(lastItem);
@@ -164,8 +110,7 @@ void ClangFormatConfigWidget::initialize()
m_ui->applyButton->hide(); m_ui->applyButton->hide();
m_ui->verticalLayout->addStretch(1); m_ui->verticalLayout->addStretch(1);
connect(m_ui->createFileButton, &QPushButton::clicked, connect(m_ui->createFileButton, &QPushButton::clicked, this, [this]() {
this, [this]() {
createStyleFileIfNeeded(false); createStyleFileIfNeeded(false);
initialize(); initialize();
}); });
@@ -174,9 +119,11 @@ void ClangFormatConfigWidget::initialize()
m_ui->createFileButton->hide(); m_ui->createFileButton->hide();
Utils::FileName fileName;
if (m_project) { if (m_project) {
m_ui->projectHasClangFormat->hide(); m_ui->projectHasClangFormat->hide();
connect(m_ui->applyButton, &QPushButton::clicked, this, &ClangFormatConfigWidget::apply); connect(m_ui->applyButton, &QPushButton::clicked, this, &ClangFormatConfigWidget::apply);
fileName = m_project->projectFilePath().appendPath("snippet.cpp");
} else { } else {
const Project *currentProject = SessionManager::startupProject(); const Project *currentProject = SessionManager::startupProject();
if (!currentProject if (!currentProject
@@ -192,9 +139,21 @@ void ClangFormatConfigWidget::initialize()
createStyleFileIfNeeded(true); createStyleFileIfNeeded(true);
showGlobalCheckboxes(); showGlobalCheckboxes();
m_ui->applyButton->hide(); m_ui->applyButton->hide();
fileName = Utils::FileName::fromString(Core::ICore::userResourcePath())
.appendPath("snippet.cpp");
} }
m_preview->textDocument()->indenter()->setFileName(fileName);
fillTable(); fillTable();
updatePreview();
}
void ClangFormatConfigWidget::updatePreview()
{
QTextCursor cursor(m_preview->document());
cursor.setPosition(0);
cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
m_preview->textDocument()->autoFormatOrIndent(cursor);
} }
void ClangFormatConfigWidget::fillTable() void ClangFormatConfigWidget::fillTable()
@@ -202,8 +161,7 @@ void ClangFormatConfigWidget::fillTable()
clang::format::FormatStyle style = m_project ? currentProjectStyle() : currentGlobalStyle(); clang::format::FormatStyle style = m_project ? currentProjectStyle() : currentGlobalStyle();
std::string configText = clang::format::configurationAsText(style); std::string configText = clang::format::configurationAsText(style);
std::istringstream stream(configText); m_ui->clangFormatOptionsTable->setPlainText(QString::fromStdString(configText));
readTable(m_ui->clangFormatOptionsTable, stream);
} }
ClangFormatConfigWidget::~ClangFormatConfigWidget() = default; ClangFormatConfigWidget::~ClangFormatConfigWidget() = default;
@@ -218,7 +176,19 @@ void ClangFormatConfigWidget::apply()
settings.write(); settings.write();
} }
const QByteArray text = tableToYAML(m_ui->clangFormatOptionsTable); const QString text = m_ui->clangFormatOptionsTable->toPlainText();
clang::format::FormatStyle style;
style.Language = clang::format::FormatStyle::LK_Cpp;
const std::error_code error = clang::format::parseConfiguration(text.toStdString(), &style);
if (error.value() != static_cast<int>(clang::format::ParseError::Success)) {
QMessageBox::warning(this,
tr("Error in ClangFormat configuration"),
QString::fromStdString(error.message()));
fillTable();
updatePreview();
return;
}
QString filePath; QString filePath;
if (m_project) if (m_project)
filePath = m_project->projectDirectory().appendPath(Constants::SETTINGS_FILE_NAME).toString(); filePath = m_project->projectDirectory().appendPath(Constants::SETTINGS_FILE_NAME).toString();
@@ -228,8 +198,10 @@ void ClangFormatConfigWidget::apply()
if (!file.open(QFile::WriteOnly)) if (!file.open(QFile::WriteOnly))
return; return;
file.write(text); file.write(text.toUtf8());
file.close(); file.close();
updatePreview();
} }
} // namespace ClangFormat } // namespace ClangFormat

View File

@@ -29,7 +29,12 @@
#include <memory> #include <memory>
namespace ProjectExplorer { class Project; } namespace ProjectExplorer {
class Project;
}
namespace TextEditor {
class SnippetEditorWidget;
}
namespace ClangFormat { namespace ClangFormat {
@@ -54,7 +59,10 @@ private:
void hideGlobalCheckboxes(); void hideGlobalCheckboxes();
void showGlobalCheckboxes(); void showGlobalCheckboxes();
void updatePreview();
ProjectExplorer::Project *m_project; ProjectExplorer::Project *m_project;
TextEditor::SnippetEditorWidget *m_preview;
std::unique_ptr<Ui::ClangFormatConfigWidget> m_ui; std::unique_ptr<Ui::ClangFormatConfigWidget> m_ui;
}; };

View File

@@ -55,7 +55,11 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QTableWidget" name="clangFormatOptionsTable"/> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPlainTextEdit" name="clangFormatOptionsTable"/>
</item>
</layout>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">

View File

@@ -84,7 +84,10 @@ Utils::optional<TabSettings> ClangFormatIndenter::tabSettings() const
int ClangFormatIndenter::lastSaveRevision() const int ClangFormatIndenter::lastSaveRevision() const
{ {
return qobject_cast<TextEditor::TextDocumentLayout *>(m_doc->documentLayout())->lastSaveRevision; auto *layout = qobject_cast<TextEditor::TextDocumentLayout *>(m_doc->documentLayout());
if (!layout)
return 0;
return layout->lastSaveRevision;
} }
bool ClangFormatIndenter::formatOnSave() const bool ClangFormatIndenter::formatOnSave() const

View File

@@ -106,19 +106,44 @@ static Utils::FileName globalPath()
return Utils::FileName::fromString(Core::ICore::userResourcePath()); return Utils::FileName::fromString(Core::ICore::userResourcePath());
} }
static bool configForFileExists(Utils::FileName fileName) static QString configForFile(Utils::FileName fileName)
{ {
Utils::FileName topProjectPath = projectPath();
if (topProjectPath.isEmpty())
return QString();
QDir projectDir(fileName.parentDir().toString()); QDir projectDir(fileName.parentDir().toString());
while (!projectDir.exists(Constants::SETTINGS_FILE_NAME) while (!projectDir.exists(Constants::SETTINGS_FILE_NAME)
&& !projectDir.exists(Constants::SETTINGS_FILE_ALT_NAME)) { && !projectDir.exists(Constants::SETTINGS_FILE_ALT_NAME)) {
if (!projectDir.cdUp()) if (projectDir.path() == topProjectPath.toString()
return false; || !Utils::FileName::fromString(projectDir.path()).isChildOf(topProjectPath)
|| !projectDir.cdUp()) {
return QString();
} }
return true; }
if (projectDir.exists(Constants::SETTINGS_FILE_NAME))
return projectDir.filePath(Constants::SETTINGS_FILE_NAME);
return projectDir.filePath(Constants::SETTINGS_FILE_ALT_NAME);
} }
static clang::format::FormatStyle constructStyle(bool isGlobal) static clang::format::FormatStyle constructStyle(bool isGlobal,
const QByteArray &baseStyle = QByteArray())
{ {
if (!baseStyle.isEmpty()) {
// Try to get the style for this base style.
Expected<FormatStyle> style = getStyle(baseStyle.toStdString(),
"dummy.cpp",
baseStyle.toStdString());
if (style)
return *style;
handleAllErrors(style.takeError(), [](const ErrorInfoBase &) {
// do nothing
});
// Fallthrough to the default style.
}
FormatStyle style = getLLVMStyle(); FormatStyle style = getLLVMStyle();
style.BreakBeforeBraces = FormatStyle::BS_Custom; style.BreakBeforeBraces = FormatStyle::BS_Custom;
@@ -151,18 +176,37 @@ void createStyleFileIfNeeded(bool isGlobal)
} }
} }
static QByteArray configBaseStyleName(const QString &configFile)
{
if (configFile.isEmpty())
return QByteArray();
QFile config(configFile);
if (!config.open(QIODevice::ReadOnly))
return QByteArray();
const QByteArray content = config.readAll();
const char basedOnStyle[] = "BasedOnStyle:";
int basedOnStyleIndex = content.indexOf(basedOnStyle);
if (basedOnStyleIndex < 0)
return QByteArray();
basedOnStyleIndex += sizeof(basedOnStyle) - 1;
const int endOfLineIndex = content.indexOf('\n', basedOnStyleIndex);
return content
.mid(basedOnStyleIndex, endOfLineIndex < 0 ? -1 : endOfLineIndex - basedOnStyleIndex)
.trimmed();
}
clang::format::FormatStyle styleForFile(Utils::FileName fileName) clang::format::FormatStyle styleForFile(Utils::FileName fileName)
{ {
bool isGlobal = false; bool isGlobal = false;
if (!configForFileExists(fileName)) { QString configFile = configForFile(fileName);
if (fileName.isChildOf(projectPath()) && CppCodeStyleSettings::currentProjectCodeStyle()) { if (configFile.isEmpty()) {
fileName = projectPath(); Utils::FileName path = fileName = globalPath();
} else {
fileName = globalPath();
isGlobal = true;
}
fileName.appendPath(Constants::SAMPLE_FILE_NAME); fileName.appendPath(Constants::SAMPLE_FILE_NAME);
createStyleFileIfNeeded(isGlobal); createStyleFileIfNeeded(true);
configFile = path.appendPath(Constants::SETTINGS_FILE_NAME).toString();
} }
Expected<FormatStyle> style = format::getStyle("file", Expected<FormatStyle> style = format::getStyle("file",
@@ -175,7 +219,7 @@ clang::format::FormatStyle styleForFile(Utils::FileName fileName)
// do nothing // do nothing
}); });
return constructStyle(isGlobal); return constructStyle(isGlobal, configBaseStyleName(configFile));
} }
clang::format::FormatStyle currentProjectStyle() clang::format::FormatStyle currentProjectStyle()

View File

@@ -65,12 +65,19 @@ public:
Sqlite::Database database{Utils::PathString{Core::ICore::userResourcePath() + "/symbol-experimental-v1.db"}, 1000ms}; Sqlite::Database database{Utils::PathString{Core::ICore::userResourcePath() + "/symbol-experimental-v1.db"}, 1000ms};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database}; ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
ClangBackEnd::FilePathCaching filePathCache{database}; ClangBackEnd::FilePathCaching filePathCache{database};
ClangPchManager::ProgressManager progressManager{ ClangPchManager::ProgressManager pchCreationProgressManager{[](QFutureInterface<void> &promise) {
[] (QFutureInterface<void> &promise) { auto title = QCoreApplication::translate("ClangPchProgressManager",
auto title = QCoreApplication::translate("ClangPchProgressManager", "Creating PCHs", "PCH stands for precompiled header"); "Creating PCHs",
"PCH stands for precompiled header");
Core::ProgressManager::addTask(promise.future(), title, "pch creation", nullptr); Core::ProgressManager::addTask(promise.future(), title, "pch creation", nullptr);
}}; }};
PchManagerClient pchManagerClient{progressManager}; ClangPchManager::ProgressManager dependencyCreationProgressManager{
[](QFutureInterface<void> &promise) {
auto title = QCoreApplication::translate("ClangPchProgressManager",
"Creating Dependencies");
Core::ProgressManager::addTask(promise.future(), title, "dependency creation", nullptr);
}};
PchManagerClient pchManagerClient{pchCreationProgressManager, dependencyCreationProgressManager};
PchManagerConnectionClient connectionClient{&pchManagerClient}; PchManagerConnectionClient connectionClient{&pchManagerClient};
QtCreatorProjectUpdater<PchManagerProjectUpdater> projectUpdate{connectionClient.serverProxy(), QtCreatorProjectUpdater<PchManagerProjectUpdater> projectUpdate{connectionClient.serverProxy(),
pchManagerClient, pchManagerClient,

View File

@@ -53,7 +53,16 @@ void PchManagerClient::precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeader
void PchManagerClient::progress(ClangBackEnd::ProgressMessage &&message) void PchManagerClient::progress(ClangBackEnd::ProgressMessage &&message)
{ {
m_progressManager.setProgress(message.progress, message.total); switch (message.progressType) {
case ClangBackEnd::ProgressType::PrecompiledHeader:
m_pchCreationProgressManager.setProgress(message.progress, message.total);
break;
case ClangBackEnd::ProgressType::DependencyCreation:
m_dependencyCreationProgressManager.setProgress(message.progress, message.total);
break;
default:
break;
}
} }
void PchManagerClient::precompiledHeaderRemoved(const QString &projectPartId) void PchManagerClient::precompiledHeaderRemoved(const QString &projectPartId)

View File

@@ -42,8 +42,10 @@ class CLANGPCHMANAGER_EXPORT PchManagerClient final : public ClangBackEnd::PchMa
{ {
friend class PchManagerNotifierInterface; friend class PchManagerNotifierInterface;
public: public:
PchManagerClient(ProgressManagerInterface &progressManager) PchManagerClient(ProgressManagerInterface &pchCreationProgressManager,
: m_progressManager(progressManager) ProgressManagerInterface &dependencyCreationProgressManager)
: m_pchCreationProgressManager(pchCreationProgressManager)
, m_dependencyCreationProgressManager(dependencyCreationProgressManager)
{} {}
void alive() override; void alive() override;
@@ -78,7 +80,8 @@ private:
ClangBackEnd::ProjectPartPchs m_projectPartPchs; ClangBackEnd::ProjectPartPchs m_projectPartPchs;
std::vector<PchManagerNotifierInterface*> m_notifiers; std::vector<PchManagerNotifierInterface*> m_notifiers;
PchManagerConnectionClient *m_connectionClient=nullptr; PchManagerConnectionClient *m_connectionClient=nullptr;
ProgressManagerInterface &m_progressManager; ProgressManagerInterface &m_pchCreationProgressManager;
ProgressManagerInterface &m_dependencyCreationProgressManager;
}; };
} // namespace ClangPchManager } // namespace ClangPchManager

View File

@@ -87,9 +87,9 @@ QString PchManagerConnectionClient::outputName() const
return QStringLiteral("PchManagerConnectionClient"); return QStringLiteral("PchManagerConnectionClient");
} }
void PchManagerConnectionClient::newConnectedServer(QIODevice *ioDevice) void PchManagerConnectionClient::newConnectedServer(QLocalSocket *localSocket)
{ {
m_serverProxy.setIoDevice(ioDevice); m_serverProxy.setLocalSocket(localSocket);
} }
} // namespace ClangPchManager } // namespace ClangPchManager

View File

@@ -42,7 +42,7 @@ protected:
void sendEndCommand() override; void sendEndCommand() override;
void resetState() override; void resetState() override;
QString outputName() const override; QString outputName() const override;
void newConnectedServer(QIODevice *ioDevice) override; void newConnectedServer(QLocalSocket *localSocket) override;
private: private:
ClangBackEnd::PchManagerServerProxy m_serverProxy; ClangBackEnd::PchManagerServerProxy m_serverProxy;

View File

@@ -52,7 +52,8 @@ public:
if (!m_promise) if (!m_promise)
initialize(); initialize();
m_promise->setExpectedResultCount(maximumProgress); if (m_promise->progressMaximum() != maximumProgress)
m_promise->setProgressRange(0, maximumProgress);
m_promise->setProgressValue(currentProgress); m_promise->setProgressValue(currentProgress);
if (currentProgress >= maximumProgress) if (currentProgress >= maximumProgress)

View File

@@ -44,9 +44,8 @@ QString currentProcessId()
RefactoringConnectionClient::RefactoringConnectionClient(RefactoringClientInterface *client) RefactoringConnectionClient::RefactoringConnectionClient(RefactoringClientInterface *client)
: ConnectionClient(Utils::TemporaryDirectory::masterDirectoryPath() : ConnectionClient(Utils::TemporaryDirectory::masterDirectoryPath()
+ QStringLiteral("/ClangRefactoringBackEnd-") + QStringLiteral("/ClangRefactoringBackEnd-") + currentProcessId())
+ currentProcessId()), , m_serverProxy(client)
m_serverProxy(client, nullptr)
{ {
m_processCreator.setTemporaryDirectoryPattern("clangrefactoringbackend-XXXXXX"); m_processCreator.setTemporaryDirectoryPattern("clangrefactoringbackend-XXXXXX");
m_processCreator.setArguments({connectionName(), m_processCreator.setArguments({connectionName(),
@@ -81,9 +80,9 @@ QString RefactoringConnectionClient::outputName() const
return QStringLiteral("RefactoringConnectionClient"); return QStringLiteral("RefactoringConnectionClient");
} }
void RefactoringConnectionClient::newConnectedServer(QIODevice *ioDevice) void RefactoringConnectionClient::newConnectedServer(QLocalSocket *localSocket)
{ {
m_serverProxy.setIoDevice(ioDevice); m_serverProxy.setLocalSocket(localSocket);
} }
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -44,7 +44,7 @@ protected:
void sendEndCommand() override; void sendEndCommand() override;
void resetState() override; void resetState() override;
QString outputName() const override; QString outputName() const override;
void newConnectedServer(QIODevice *ioDevice) override; void newConnectedServer(QLocalSocket *localSocket) override;
private: private:
RefactoringServerProxy m_serverProxy; RefactoringServerProxy m_serverProxy;

View File

@@ -85,9 +85,6 @@ bool FixitsRefactoringFile::apply()
ICodeStylePreferencesFactory *factory = TextEditorSettings::codeStyleFactory( ICodeStylePreferencesFactory *factory = TextEditorSettings::codeStyleFactory(
CppTools::Constants::CPP_SETTINGS_ID); CppTools::Constants::CPP_SETTINGS_ID);
const TextEditor::TabSettings tabSettings
= CppTools::CppCodeStyleSettings::currentProjectTabSettings();
// Apply changes // Apply changes
std::unique_ptr<TextEditor::Indenter> indenter; std::unique_ptr<TextEditor::Indenter> indenter;
QString lastFilename; QString lastFilename;

View File

@@ -35,7 +35,7 @@
#include <QTextDocument> #include <QTextDocument>
using namespace CppEditor::Internal; using namespace CppEditor;
using namespace TextEditor; using namespace TextEditor;
using namespace CPlusPlus; using namespace CPlusPlus;

View File

@@ -25,6 +25,8 @@
#pragma once #pragma once
#include "cppeditor_global.h"
#include <texteditor/syntaxhighlighter.h> #include <texteditor/syntaxhighlighter.h>
#include <cplusplus/Token.h> #include <cplusplus/Token.h>
@@ -33,10 +35,7 @@
namespace CppEditor { namespace CppEditor {
namespace Internal { class CPPEDITOR_EXPORT CppHighlighter : public TextEditor::SyntaxHighlighter
class CppHighlighter : public TextEditor::SyntaxHighlighter
{ {
Q_OBJECT Q_OBJECT
@@ -58,5 +57,4 @@ private:
CPlusPlus::LanguageFeatures m_languageFeatures = CPlusPlus::LanguageFeatures::defaultFeatures(); CPlusPlus::LanguageFeatures m_languageFeatures = CPlusPlus::LanguageFeatures::defaultFeatures();
}; };
} // namespace Internal
} // namespace CppEditor } // namespace CppEditor

View File

@@ -26,6 +26,7 @@
#include "cppcodestylesettingspage.h" #include "cppcodestylesettingspage.h"
#include "cppcodestylepreferences.h" #include "cppcodestylepreferences.h"
#include "cppcodestylesnippets.h"
#include "cpppointerdeclarationformatter.h" #include "cpppointerdeclarationformatter.h"
#include "cppqtstyleindenter.h" #include "cppqtstyleindenter.h"
#include "cpptoolsconstants.h" #include "cpptoolsconstants.h"
@@ -49,170 +50,6 @@
#include <QTextBlock> #include <QTextBlock>
#include <QTextStream> #include <QTextStream>
static const char *defaultCodeStyleSnippets[] = {
"#include <math.h>\n"
"\n"
"class Complex\n"
" {\n"
"public:\n"
" Complex(double re, double im)\n"
" : _re(re), _im(im)\n"
" {}\n"
" double modulus() const\n"
" {\n"
" return sqrt(_re * _re + _im * _im);\n"
" }\n"
"private:\n"
" double _re;\n"
" double _im;\n"
" };\n"
"\n"
"void bar(int i)\n"
" {\n"
" static int counter = 0;\n"
" counter += i;\n"
" }\n"
"\n"
"namespace Foo\n"
" {\n"
" namespace Bar\n"
" {\n"
" void foo(int a, int b)\n"
" {\n"
" for (int i = 0; i < a; i++)\n"
" {\n"
" if (i < b)\n"
" bar(i);\n"
" else\n"
" {\n"
" bar(i);\n"
" bar(b);\n"
" }\n"
" }\n"
" }\n"
" } // namespace Bar\n"
" } // namespace Foo\n"
,
"#include <math.h>\n"
"\n"
"class Complex\n"
" {\n"
"public:\n"
" Complex(double re, double im)\n"
" : _re(re), _im(im)\n"
" {}\n"
" double modulus() const\n"
" {\n"
" return sqrt(_re * _re + _im * _im);\n"
" }\n"
"private:\n"
" double _re;\n"
" double _im;\n"
" };\n"
"\n"
"void bar(int i)\n"
" {\n"
" static int counter = 0;\n"
" counter += i;\n"
" }\n"
"\n"
"namespace Foo\n"
" {\n"
" namespace Bar\n"
" {\n"
" void foo(int a, int b)\n"
" {\n"
" for (int i = 0; i < a; i++)\n"
" {\n"
" if (i < b)\n"
" bar(i);\n"
" else\n"
" {\n"
" bar(i);\n"
" bar(b);\n"
" }\n"
" }\n"
" }\n"
" } // namespace Bar\n"
" } // namespace Foo\n"
,
"namespace Foo\n"
"{\n"
"namespace Bar\n"
"{\n"
"class FooBar\n"
" {\n"
"public:\n"
" FooBar(int a)\n"
" : _a(a)\n"
" {}\n"
" int calculate() const\n"
" {\n"
" if (a > 10)\n"
" {\n"
" int b = 2 * a;\n"
" return a * b;\n"
" }\n"
" return -a;\n"
" }\n"
"private:\n"
" int _a;\n"
" };\n"
"}\n"
"}\n"
,
"#include \"bar.h\"\n"
"\n"
"int foo(int a)\n"
" {\n"
" switch (a)\n"
" {\n"
" case 1:\n"
" bar(1);\n"
" break;\n"
" case 2:\n"
" {\n"
" bar(2);\n"
" break;\n"
" }\n"
" case 3:\n"
" default:\n"
" bar(3);\n"
" break;\n"
" }\n"
" return 0;\n"
" }\n"
,
"void foo() {\n"
" if (a &&\n"
" b)\n"
" c;\n"
"\n"
" while (a ||\n"
" b)\n"
" break;\n"
" a = b +\n"
" c;\n"
" myInstance.longMemberName +=\n"
" foo;\n"
" myInstance.longMemberName += bar +\n"
" foo;\n"
"}\n"
,
"int *foo(const Bar &b1, Bar &&b2, int*, int *&rpi)\n"
"{\n"
" int*pi = 0;\n"
" int*const*const cpcpi = &pi;\n"
" int*const*pcpi = &pi;\n"
" int**const cppi = &pi;\n"
"\n"
" void (*foo)(char *s) = 0;\n"
" int (*bar)[] = 0;\n"
"\n"
" return pi;\n"
"}\n"
};
using namespace TextEditor; using namespace TextEditor;
namespace CppTools { namespace CppTools {
@@ -270,7 +107,7 @@ CppCodeStylePreferencesWidget::CppCodeStylePreferencesWidget(QWidget *parent)
<< m_ui->previewTextEditBraces << m_ui->previewTextEditSwitch << m_ui->previewTextEditBraces << m_ui->previewTextEditSwitch
<< m_ui->previewTextEditPadding << m_ui->previewTextEditPointerReferences; << m_ui->previewTextEditPadding << m_ui->previewTextEditPointerReferences;
for (int i = 0; i < m_previews.size(); ++i) for (int i = 0; i < m_previews.size(); ++i)
m_previews[i]->setPlainText(QLatin1String(defaultCodeStyleSnippets[i])); m_previews[i]->setPlainText(QLatin1String(Constants::DEFAULT_CODE_STYLE_SNIPPETS[i]));
decorateEditors(TextEditorSettings::fontSettings()); decorateEditors(TextEditorSettings::fontSettings());
connect(TextEditorSettings::instance(), &TextEditorSettings::fontSettingsChanged, connect(TextEditorSettings::instance(), &TextEditorSettings::fontSettingsChanged,

View File

@@ -0,0 +1,190 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
namespace CppTools {
namespace Constants {
static const char *DEFAULT_CODE_STYLE_SNIPPETS[]
= {"#include <math.h>\n"
"\n"
"class Complex\n"
" {\n"
"public:\n"
" Complex(double re, double im)\n"
" : _re(re), _im(im)\n"
" {}\n"
" double modulus() const\n"
" {\n"
" return sqrt(_re * _re + _im * _im);\n"
" }\n"
"private:\n"
" double _re;\n"
" double _im;\n"
" };\n"
"\n"
"void bar(int i)\n"
" {\n"
" static int counter = 0;\n"
" counter += i;\n"
" }\n"
"\n"
"namespace Foo\n"
" {\n"
" namespace Bar\n"
" {\n"
" void foo(int a, int b)\n"
" {\n"
" for (int i = 0; i < a; i++)\n"
" {\n"
" if (i < b)\n"
" bar(i);\n"
" else\n"
" {\n"
" bar(i);\n"
" bar(b);\n"
" }\n"
" }\n"
" }\n"
" } // namespace Bar\n"
" } // namespace Foo\n",
"#include <math.h>\n"
"\n"
"class Complex\n"
" {\n"
"public:\n"
" Complex(double re, double im)\n"
" : _re(re), _im(im)\n"
" {}\n"
" double modulus() const\n"
" {\n"
" return sqrt(_re * _re + _im * _im);\n"
" }\n"
"private:\n"
" double _re;\n"
" double _im;\n"
" };\n"
"\n"
"void bar(int i)\n"
" {\n"
" static int counter = 0;\n"
" counter += i;\n"
" }\n"
"\n"
"namespace Foo\n"
" {\n"
" namespace Bar\n"
" {\n"
" void foo(int a, int b)\n"
" {\n"
" for (int i = 0; i < a; i++)\n"
" {\n"
" if (i < b)\n"
" bar(i);\n"
" else\n"
" {\n"
" bar(i);\n"
" bar(b);\n"
" }\n"
" }\n"
" }\n"
" } // namespace Bar\n"
" } // namespace Foo\n",
"namespace Foo\n"
"{\n"
"namespace Bar\n"
"{\n"
"class FooBar\n"
" {\n"
"public:\n"
" FooBar(int a)\n"
" : _a(a)\n"
" {}\n"
" int calculate() const\n"
" {\n"
" if (a > 10)\n"
" {\n"
" int b = 2 * a;\n"
" return a * b;\n"
" }\n"
" return -a;\n"
" }\n"
"private:\n"
" int _a;\n"
" };\n"
"}\n"
"}\n",
"#include \"bar.h\"\n"
"\n"
"int foo(int a)\n"
" {\n"
" switch (a)\n"
" {\n"
" case 1:\n"
" bar(1);\n"
" break;\n"
" case 2:\n"
" {\n"
" bar(2);\n"
" break;\n"
" }\n"
" case 3:\n"
" default:\n"
" bar(3);\n"
" break;\n"
" }\n"
" return 0;\n"
" }\n",
"void foo() {\n"
" if (a &&\n"
" b)\n"
" c;\n"
"\n"
" while (a ||\n"
" b)\n"
" break;\n"
" a = b +\n"
" c;\n"
" myInstance.longMemberName +=\n"
" foo;\n"
" myInstance.longMemberName += bar +\n"
" foo;\n"
"}\n",
"int *foo(const Bar &b1, Bar &&b2, int*, int *&rpi)\n"
"{\n"
" int*pi = 0;\n"
" int*const*const cpcpi = &pi;\n"
" int*const*pcpi = &pi;\n"
" int**const cppi = &pi;\n"
"\n"
" void (*foo)(char *s) = 0;\n"
" int (*bar)[] = 0;\n"
"\n"
" return pi;\n"
"}\n"};
} // namespace Constants
} // namespace CppTools

View File

@@ -37,6 +37,7 @@
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/mimetypes/mimedatabase.h> #include <utils/mimetypes/mimedatabase.h>
#include <QSettings> #include <QSettings>
@@ -173,7 +174,8 @@ static bool keyWordReplacement(const QString &keyWord,
return true; return true;
} }
if (keyWord == QLatin1String("%USER%")) { if (keyWord == QLatin1String("%USER%")) {
*value = QLatin1String("%{Env:USER}"); *value = Utils::HostOsInfo::isWindowsHost() ? QLatin1String("%{Env:USERNAME}")
: QLatin1String("%{Env:USER}");
return true; return true;
} }
// Environment variables (for example '%$EMAIL%'). // Environment variables (for example '%$EMAIL%').

View File

@@ -26,6 +26,7 @@ HEADERS += \
cppcodestylepreferencesfactory.h \ cppcodestylepreferencesfactory.h \
cppcodestylesettings.h \ cppcodestylesettings.h \
cppcodestylesettingspage.h \ cppcodestylesettingspage.h \
cppcodestylesnippets.h \
cppcompletionassist.h \ cppcompletionassist.h \
cppcompletionassistprocessor.h \ cppcompletionassistprocessor.h \
cppcompletionassistprovider.h \ cppcompletionassistprovider.h \

View File

@@ -82,6 +82,7 @@ Project {
"cppcodestylesettingspage.cpp", "cppcodestylesettingspage.cpp",
"cppcodestylesettingspage.h", "cppcodestylesettingspage.h",
"cppcodestylesettingspage.ui", "cppcodestylesettingspage.ui",
"cppcodestylesnippets.h",
"cppcompletionassist.cpp", "cppcompletionassist.cpp",
"cppcompletionassist.h", "cppcompletionassist.h",
"cppcompletionassistprocessor.cpp", "cppcompletionassistprocessor.cpp",

View File

@@ -372,24 +372,16 @@ void DebuggerMainWindowPrivate::fixupLayoutIfNeeded()
{ {
// Evil workaround for QTCREATORBUG-21455: In some so far unknown situation // Evil workaround for QTCREATORBUG-21455: In some so far unknown situation
// the saveLayout/restoreLayout process leads to a situation where some docks // the saveLayout/restoreLayout process leads to a situation where some docks
// does not end up below the perspective toolbar even though they were there // do not end up below the perspective toolbar even though they were there
// initially, leading to an awkward dock layout. // initially, leading to an awkward dock layout.
// This here tries to detect the situation (no other dock directly below the // This here tries to detect the situation (sonmething else in the bottom
// toolbar) and "corrects" that by restoring the default layout. // area is at the right of the toolbar) "corrects" that by restoring the
const QRect toolbarRect = m_toolBarDock->geometry(); // default layout.
const int targetX = toolbarRect.left();
const int targetY = toolbarRect.bottom();
const QList<QDockWidget *> docks = q->dockWidgets();
for (QDockWidget *dock : docks) {
const QRect dockRect = dock->geometry();
// 10 for some decoration wiggle room. Found something below? Good.
if (targetX == dockRect.left() && qAbs(targetY - dockRect.top()) < 10)
return;
}
if (m_toolBarDock->width() != q->width()) {
qDebug() << "Scrambled dock layout found. Resetting it."; qDebug() << "Scrambled dock layout found. Resetting it.";
resetCurrentPerspective(); resetCurrentPerspective();
}
} }
void DebuggerMainWindowPrivate::selectPerspective(Perspective *perspective) void DebuggerMainWindowPrivate::selectPerspective(Perspective *perspective)

View File

@@ -1410,7 +1410,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
m_perspective.addWindow(m_engineManagerWindow, Perspective::SplitVertical, nullptr); m_perspective.addWindow(m_engineManagerWindow, Perspective::SplitVertical, nullptr);
m_perspective.addWindow(m_breakpointManagerWindow, Perspective::SplitHorizontal, m_engineManagerWindow); m_perspective.addWindow(m_breakpointManagerWindow, Perspective::SplitHorizontal, m_engineManagerWindow);
m_perspective.addWindow(m_globalLogWindow, Perspective::AddToTab, m_breakpointManagerWindow, false); m_perspective.addWindow(m_globalLogWindow, Perspective::AddToTab, nullptr, false, Qt::TopDockWidgetArea);
setInitialState(); setInitialState();

View File

@@ -291,6 +291,7 @@ GitDiffEditorController::GitDiffEditorController(IDocument *document, const QStr
{ {
connect(&m_decorator, &DescriptionWidgetDecorator::branchListRequested, connect(&m_decorator, &DescriptionWidgetDecorator::branchListRequested,
this, &GitDiffEditorController::updateBranchList); this, &GitDiffEditorController::updateBranchList);
setDisplayName("Git Diff");
} }
void GitDiffEditorController::updateBranchList() void GitDiffEditorController::updateBranchList()
@@ -514,7 +515,9 @@ public:
GitDiffEditorController(document, dir), GitDiffEditorController(document, dir),
m_id(id), m_id(id),
m_state(Idle) m_state(Idle)
{ } {
setDisplayName("Git Show");
}
void reload() override; void reload() override;
void processCommandOutput(const QString &output) override; void processCommandOutput(const QString &output) override;

View File

@@ -68,6 +68,7 @@ protected:
MercurialDiffEditorController::MercurialDiffEditorController(IDocument *document, const QString &workingDirectory): MercurialDiffEditorController::MercurialDiffEditorController(IDocument *document, const QString &workingDirectory):
VcsBaseDiffEditorController(document, MercurialPlugin::client(), workingDirectory) VcsBaseDiffEditorController(document, MercurialPlugin::client(), workingDirectory)
{ {
setDisplayName("Hg Diff");
} }
void MercurialDiffEditorController::runCommand(const QList<QStringList> &args, QTextCodec *codec) void MercurialDiffEditorController::runCommand(const QList<QStringList> &args, QTextCodec *codec)

View File

@@ -3,7 +3,6 @@
\"Version\" : \"$$QTCREATOR_VERSION\", \"Version\" : \"$$QTCREATOR_VERSION\",
\"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\", \"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
\"Revision\" : \"$$QTC_PLUGIN_REVISION\", \"Revision\" : \"$$QTC_PLUGIN_REVISION\",
\"DisabledByDefault\" : true,
\"Vendor\" : \"The Qt Company Ltd\", \"Vendor\" : \"The Qt Company Ltd\",
\"Copyright\" : \"(C) $$QTCREATOR_COPYRIGHT_YEAR The Qt Company Ltd\", \"Copyright\" : \"(C) $$QTCREATOR_COPYRIGHT_YEAR The Qt Company Ltd\",
\"License\" : [ \"Commercial Usage\", \"License\" : [ \"Commercial Usage\",

View File

@@ -140,10 +140,12 @@ AbiWidget::AbiWidget(QWidget *parent) : QWidget(parent),
d->m_wordWidthComboBox = new QComboBox(this); d->m_wordWidthComboBox = new QComboBox(this);
layout->addWidget(d->m_wordWidthComboBox); layout->addWidget(d->m_wordWidthComboBox);
d->m_wordWidthComboBox->addItem(Abi::toString(16), 16);
d->m_wordWidthComboBox->addItem(Abi::toString(32), 32); d->m_wordWidthComboBox->addItem(Abi::toString(32), 32);
d->m_wordWidthComboBox->addItem(Abi::toString(64), 64); d->m_wordWidthComboBox->addItem(Abi::toString(64), 64);
d->m_wordWidthComboBox->addItem(Abi::toString(0), 0); d->m_wordWidthComboBox->addItem(Abi::toString(0), 0);
d->m_wordWidthComboBox->setCurrentIndex(2); // Setup current word width of 0 by default.
d->m_wordWidthComboBox->setCurrentIndex(d->m_wordWidthComboBox->count() - 1);
connect(d->m_wordWidthComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), connect(d->m_wordWidthComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &AbiWidget::customComboBoxesChanged); this, &AbiWidget::customComboBoxesChanged);

View File

@@ -52,7 +52,6 @@
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QRegularExpression> #include <QRegularExpression>
#include <algorithm>
#include <memory> #include <memory>
namespace { namespace {
@@ -343,6 +342,11 @@ bool GccToolChain::isValid() const
return fi.isExecutable(); return fi.isExecutable();
} }
static bool isNetworkCompiler(const QString &dirPath)
{
return dirPath.contains("icecc") || dirPath.contains("distcc");
}
static Utils::FileName findLocalCompiler(const Utils::FileName &compilerPath, static Utils::FileName findLocalCompiler(const Utils::FileName &compilerPath,
const Environment &env) const Environment &env)
{ {
@@ -351,21 +355,13 @@ static Utils::FileName findLocalCompiler(const Utils::FileName &compilerPath,
// Get the path to the compiler, ignoring direct calls to icecc and distcc as we cannot // Get the path to the compiler, ignoring direct calls to icecc and distcc as we cannot
// do anything about those. // do anything about those.
const Utils::FileName compilerDir = compilerPath.parentDir(); if (!isNetworkCompiler(compilerPath.parentDir().toString()))
const QString compilerDirString = compilerDir.toString();
if (!compilerDirString.contains("icecc") && !compilerDirString.contains("distcc"))
return compilerPath; return compilerPath;
FileNameList pathComponents = env.path(); // Filter out network compilers
auto it = std::find_if(pathComponents.begin(), pathComponents.end(), const FileNameList pathComponents = Utils::filtered(env.path(), [] (const FileName &dirPath) {
[compilerDir](const FileName &p) { return !isNetworkCompiler(dirPath.toString());
return p == compilerDir;
}); });
if (it != pathComponents.end()) {
std::rotate(pathComponents.begin(), it, pathComponents.end());
pathComponents.removeFirst(); // remove directory of compilerPath
// No need to put it at the end again, it is in PATH anyway...
}
// This effectively searches the PATH twice, once via pathComponents and once via PATH itself: // This effectively searches the PATH twice, once via pathComponents and once via PATH itself:
// searchInPath filters duplicates, so that will not hurt. // searchInPath filters duplicates, so that will not hurt.
@@ -402,15 +398,7 @@ ToolChain::MacroInspectionRunner GccToolChain::createMacroInspectionRunner() con
|| a == "-gcc-toolchain" || a == "-target") { || a == "-gcc-toolchain" || a == "-target") {
if (++iArg < allFlags.length()) if (++iArg < allFlags.length())
arguments << a << allFlags.at(iArg); arguments << a << allFlags.at(iArg);
} else if (a == "-m128bit-long-double" || a == "-m32" || a == "-m3dnow" } else if (a.startsWith("-m") || a == "-Os" || a == "-O0" || a == "-O1" || a == "-O2"
|| a == "-m3dnowa" || a == "-m64" || a == "-m96bit-long-double"
|| a == "-mabm" || a == "-maes" || a.startsWith("-march=") || a == "-mavx"
|| a.startsWith("-masm=") || a.startsWith("-mfloat-abi") || a == "-mcx16"
|| a == "-mfma" || a == "-mfma4" || a == "-mlwp" || a == "-mpclmul"
|| a == "-mpopcnt" || a == "-msse" || a == "-msse2" || a == "-msse2avx"
|| a == "-msse3" || a == "-msse4" || a == "-msse4.1" || a == "-msse4.2"
|| a == "-msse4a" || a == "-mssse3" || a.startsWith("-mtune=")
|| a == "-mxop" || a == "-Os" || a == "-O0" || a == "-O1" || a == "-O2"
|| a == "-O3" || a == "-ffinite-math-only" || a == "-fshort-double" || a == "-O3" || a == "-ffinite-math-only" || a == "-fshort-double"
|| a == "-fshort-wchar" || a == "-fsignaling-nans" || a == "-fno-inline" || a == "-fshort-wchar" || a == "-fsignaling-nans" || a == "-fno-inline"
|| a == "-fno-exceptions" || a == "-fstack-protector" || a == "-fno-exceptions" || a == "-fstack-protector"

View File

@@ -79,6 +79,9 @@
<property name="minimum"> <property name="minimum">
<number>1</number> <number>1</number>
</property> </property>
<property name="maximum">
<number>999</number>
</property>
</widget> </widget>
</item> </item>
<item> <item>

View File

@@ -44,6 +44,7 @@
#include "projectexplorersettingspage.h" #include "projectexplorersettingspage.h"
#include "projectmanager.h" #include "projectmanager.h"
#include "removetaskhandler.h" #include "removetaskhandler.h"
#include "runconfigurationaspects.h"
#include "kitfeatureprovider.h" #include "kitfeatureprovider.h"
#include "kitmanager.h" #include "kitmanager.h"
#include "kitoptionspage.h" #include "kitoptionspage.h"
@@ -1595,8 +1596,14 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
tr("The currently active run configuration's executable (if applicable)."), tr("The currently active run configuration's executable (if applicable)."),
[]() -> QString { []() -> QString {
if (Target *target = activeTarget()) { if (Target *target = activeTarget()) {
if (RunConfiguration *rc = target->activeRunConfiguration()) if (RunConfiguration *rc = target->activeRunConfiguration()) {
return rc->runnable().executable; // TODO: This duplicates code and is not always correct, but see
// QTCREATORBUG-18317.
// Solution: Re-introduce RunConfiguration::executable()?
if (auto executableAspect = rc->aspect<ExecutableAspect>())
return executableAspect->executable().toString();
return QString();
}
} }
return QString(); return QString();
}); });
@@ -3459,15 +3466,12 @@ void ProjectExplorerPluginPrivate::removeProject()
Node *node = ProjectTree::findCurrentNode(); Node *node = ProjectTree::findCurrentNode();
if (!node) if (!node)
return; return;
ProjectNode *subProjectNode = node->managingProject(); ProjectNode *projectNode = node->managingProject();
if (!subProjectNode)
return;
ProjectNode *projectNode = subProjectNode->managingProject();
if (projectNode) { if (projectNode) {
Utils::RemoveFileDialog removeFileDialog(subProjectNode->filePath().toString(), ICore::mainWindow()); Utils::RemoveFileDialog removeFileDialog(node->filePath().toString(), ICore::mainWindow());
removeFileDialog.setDeleteFileVisible(false); removeFileDialog.setDeleteFileVisible(false);
if (removeFileDialog.exec() == QDialog::Accepted) if (removeFileDialog.exec() == QDialog::Accepted)
projectNode->removeSubProject(subProjectNode->filePath().toString()); projectNode->removeSubProject(node->filePath().toString());
} }
} }

View File

@@ -378,6 +378,8 @@ void FlatModel::saveExpandData()
void FlatModel::addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<Node *> *seen) void FlatModel::addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<Node *> *seen)
{ {
for (Node *node : folderNode->nodes()) { for (Node *node : folderNode->nodes()) {
if (m_filterGeneratedFiles && node->isGenerated())
continue;
if (FolderNode *subFolderNode = node->asFolderNode()) { if (FolderNode *subFolderNode = node->asFolderNode()) {
const bool isHidden = m_filterProjects && !subFolderNode->showInSimpleTree(); const bool isHidden = m_filterProjects && !subFolderNode->showInSimpleTree();
if (!isHidden && !seen->contains(subFolderNode)) { if (!isHidden && !seen->contains(subFolderNode)) {
@@ -390,8 +392,7 @@ void FlatModel::addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<
addFolderNode(parent, subFolderNode, seen); addFolderNode(parent, subFolderNode, seen);
} }
} else if (FileNode *fileNode = node->asFileNode()) { } else if (FileNode *fileNode = node->asFileNode()) {
const bool isHidden = m_filterGeneratedFiles && fileNode->isGenerated(); if (!seen->contains(fileNode)) {
if (!isHidden && !seen->contains(fileNode)) {
seen->insert(fileNode); seen->insert(fileNode);
parent->appendChild(new WrapperNode(fileNode)); parent->appendChild(new WrapperNode(fileNode));
} }

View File

@@ -132,7 +132,7 @@ bool QmakePriFileNode::supportsAction(ProjectAction action, const Node *node) co
break; break;
} }
case ProjectType::SubDirsTemplate: case ProjectType::SubDirsTemplate:
if (action == AddSubProject || action == RemoveSubProject || action == AddExistingProject) if (action == AddSubProject || action == AddExistingProject)
return true; return true;
break; break;
default: default:
@@ -344,6 +344,13 @@ bool QmakeProFileNode::includedInExactParse() const
return pro && pro->includedInExactParse(); return pro && pro->includedInExactParse();
} }
bool QmakeProFileNode::supportsAction(ProjectAction action, const Node *node) const
{
if (action == RemoveSubProject)
return parentProjectNode() && !parentProjectNode()->asContainerNode();
return QmakePriFileNode::supportsAction(action, node);
}
FolderNode::AddNewInformation QmakeProFileNode::addNewInformation(const QStringList &files, Node *context) const FolderNode::AddNewInformation QmakeProFileNode::addNewInformation(const QStringList &files, Node *context) const
{ {
Q_UNUSED(files) Q_UNUSED(files)

View File

@@ -90,6 +90,7 @@ public:
bool isQtcRunnable() const; bool isQtcRunnable() const;
bool includedInExactParse() const; bool includedInExactParse() const;
bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
bool showInSimpleTree() const override; bool showInSimpleTree() const override;
QString buildKey() const override; QString buildKey() const override;

View File

@@ -168,8 +168,12 @@ static void createTree(const QmakePriFile *pri, QmakePriFileNode *node, const Fi
int eid = vfs->idForFileName(file.toString(), QMakeVfs::VfsExact); int eid = vfs->idForFileName(file.toString(), QMakeVfs::VfsExact);
vfs->readFile(eid, &contents, &errorMessage); vfs->readFile(eid, &contents, &errorMessage);
} }
vfolder->addNode(std::make_unique<ResourceEditor::ResourceTopLevelNode> auto topLevel = std::make_unique<ResourceEditor::ResourceTopLevelNode>
(file, vfolder->filePath(), contents)); (file, vfolder->filePath(), contents);
const QString baseName = file.toFileInfo().completeBaseName();
topLevel->setIsGenerated(baseName.startsWith("qmake_")
|| baseName.endsWith("_qmlcache"));
vfolder->addNode(std::move(topLevel));
} }
} else { } else {
for (const FileName &fn : newFilePaths) { for (const FileName &fn : newFilePaths) {

View File

@@ -1246,6 +1246,7 @@ static bool evaluateOne(const QmakeEvalInput &input, ProFile *pro,
QStringList basecfgs = reader->values(build + QLatin1String(".CONFIG")); QStringList basecfgs = reader->values(build + QLatin1String(".CONFIG"));
basecfgs += build; basecfgs += build;
basecfgs += QLatin1String("build_pass"); basecfgs += QLatin1String("build_pass");
basecfgs += "qtc_run";
basevars[QLatin1String("BUILD_PASS")] = QStringList(build); basevars[QLatin1String("BUILD_PASS")] = QStringList(build);
QStringList buildname = reader->values(build + QLatin1String(".name")); QStringList buildname = reader->values(build + QLatin1String(".name"));
basevars[QLatin1String("BUILD_NAME")] = (buildname.isEmpty() ? QStringList(build) : buildname); basevars[QLatin1String("BUILD_NAME")] = (buildname.isEmpty() ? QStringList(build) : buildname);

View File

@@ -265,19 +265,30 @@ void QmakeProjectImporter::deleteDirectoryData(void *directoryData) const
delete static_cast<DirectoryData *>(directoryData); delete static_cast<DirectoryData *>(directoryData);
} }
static ToolChain *preferredToolChain(BaseQtVersion *qtVersion, const FileName &ms, static const QList<ToolChain *> preferredToolChains(BaseQtVersion *qtVersion, const FileName &ms,
const QMakeStepConfig::TargetArchConfig &archConfig) const QMakeStepConfig::TargetArchConfig &archConfig)
{ {
const FileName spec = ms.isEmpty() ? qtVersion->mkspec() : ms; const FileName spec = ms.isEmpty() ? qtVersion->mkspec() : ms;
const QList<ToolChain *> toolchains = ToolChainManager::toolChains(); const QList<ToolChain *> toolchains = ToolChainManager::toolChains();
QList<Abi> qtAbis = qtVersion->qtAbis(); QList<Abi> qtAbis = qtVersion->qtAbis();
return findOr(toolchains, toolchains.isEmpty() ? nullptr : toolchains.first(), const auto matcher = [&](const ToolChain *tc) {
[&](ToolChain *tc) {
return qtAbis.contains(tc->targetAbi()) return qtAbis.contains(tc->targetAbi())
&& tc->suggestedMkspecList().contains(spec) && tc->suggestedMkspecList().contains(spec)
&& QMakeStepConfig::targetArchFor(tc->targetAbi(), qtVersion) == archConfig; && QMakeStepConfig::targetArchFor(tc->targetAbi(), qtVersion) == archConfig;
};
ToolChain * const cxxToolchain = findOrDefault(toolchains, [matcher](const ToolChain *tc) {
return tc->language() == ProjectExplorer::Constants::CXX_LANGUAGE_ID && matcher(tc);
}); });
ToolChain * const cToolchain = findOrDefault(toolchains, [matcher](const ToolChain *tc) {
return tc->language() == ProjectExplorer::Constants::C_LANGUAGE_ID && matcher(tc);
});
QList<ToolChain *> chosenToolchains;
for (ToolChain * const tc : {cxxToolchain, cToolchain}) {
if (tc)
chosenToolchains << tc;
};
return chosenToolchains;
} }
Kit *QmakeProjectImporter::createTemporaryKit(const QtProjectImporter::QtVersionData &data, Kit *QmakeProjectImporter::createTemporaryKit(const QtProjectImporter::QtVersionData &data,
@@ -288,7 +299,8 @@ Kit *QmakeProjectImporter::createTemporaryKit(const QtProjectImporter::QtVersion
Q_UNUSED(osType); // TODO use this to select the right toolchain? Q_UNUSED(osType); // TODO use this to select the right toolchain?
return QtProjectImporter::createTemporaryKit(data, return QtProjectImporter::createTemporaryKit(data,
[&data, parsedSpec, archConfig](Kit *k) -> void { [&data, parsedSpec, archConfig](Kit *k) -> void {
ToolChainKitAspect::setToolChain(k, preferredToolChain(data.qt, parsedSpec, archConfig)); for (ToolChain * const tc : preferredToolChains(data.qt, parsedSpec, archConfig))
ToolChainKitAspect::setToolChain(k, tc);
if (parsedSpec != data.qt->mkspec()) if (parsedSpec != data.qt->mkspec())
QmakeKitAspect::setMkspec(k, parsedSpec); QmakeKitAspect::setMkspec(k, parsedSpec);
}); });

View File

@@ -32,6 +32,8 @@
#include <QTextStream> #include <QTextStream>
#include <QStringList> #include <QStringList>
#include <cstring>
namespace QmakeProjectManager { namespace QmakeProjectManager {
namespace Internal { namespace Internal {
@@ -150,7 +152,7 @@ void LibraryParameters::generateCode(QtProjectParameters:: Type t,
} }
QTC_ASSERT(nameIndex != -1, continue); QTC_ASSERT(nameIndex != -1, continue);
sourceStr << '\n' << namespaceIndent << signature.left(nameIndex); sourceStr << '\n' << namespaceIndent << signature.left(nameIndex);
if (signature.at(nameIndex - 1) != ' ') if (!std::strchr("&* ", signature.at(nameIndex - 1).toLatin1()))
sourceStr << ' '; sourceStr << ' ';
sourceStr << unqualifiedClassName << "::" << signature.mid(nameIndex) << '\n'; sourceStr << unqualifiedClassName << "::" << signature.mid(nameIndex) << '\n';
sourceStr << namespaceIndent << "{\n" << indent sourceStr << namespaceIndent << "{\n" << indent

View File

@@ -56,7 +56,7 @@ using QSL = QStringList;
static const PluginBaseClasses pluginBaseClasses[] = static const PluginBaseClasses pluginBaseClasses[] =
{ {
{"QAccessiblePlugin", "QtGui", {"QAccessiblePlugin", "QtGui",
QSL{"QAccessibleInterface * create(const QString &key, QObject *object)"}, QSL{"QAccessibleInterface *create(const QString &key, QObject *object)"},
"QtCore", "accessible", "QAccessibleFactoryInterface"}, "QtCore", "accessible", "QAccessibleFactoryInterface"},
{"QGenericPlugin", "QtGui", QSL{"QObject *create(const QString &name, const QString &spec)"}, {"QGenericPlugin", "QtGui", QSL{"QObject *create(const QString &name, const QString &spec)"},
"QtCore", "generic", "QGenericPluginFactoryInterface"}, "QtCore", "generic", "QGenericPluginFactoryInterface"},

View File

@@ -104,21 +104,19 @@ int GradientModel::addStop(qreal position, const QColor &color)
return -1; return -1;
if (m_itemNode.modelNode().hasNodeProperty(gradientPropertyName().toUtf8())) { if (m_itemNode.modelNode().hasNodeProperty(gradientPropertyName().toUtf8())) {
//QmlDesigner::RewriterTransaction transaction = m_itemNode.modelNode().view()->beginRewriterTransaction(); int properPos = 0;
//### TODO does not work try {
QmlDesigner::ModelNode gradientNode = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode(); QmlDesigner::ModelNode gradientNode = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode();
QmlDesigner::ModelNode gradientStopNode = QmlDesigner::ModelNode gradientStopNode = createGradientStopNode();
m_itemNode.modelNode().view()->createModelNode("QtQuick.GradientStop",
m_itemNode.modelNode().view()->majorQtQuickVersion(), 0);
gradientStopNode.variantProperty("position").setValue(position); gradientStopNode.variantProperty("position").setValue(position);
gradientStopNode.variantProperty("color").setValue(color); gradientStopNode.variantProperty("color").setValue(color);
gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode);
const QList<QmlDesigner::ModelNode> stopNodes = gradientNode.nodeListProperty("stops").toModelNodeList(); const QList<QmlDesigner::ModelNode> stopNodes = gradientNode.nodeListProperty("stops").toModelNodeList();
int properPos = 0;
for (int i = 0; i < stopNodes.count(); i++) { for (int i = 0; i < stopNodes.count(); i++) {
if (QmlDesigner::QmlObjectNode(stopNodes.at(i)).modelValue("position").toReal() < position) if (QmlDesigner::QmlObjectNode(stopNodes.at(i)).modelValue("position").toReal() < position)
properPos = i + 1; properPos = i + 1;
@@ -126,6 +124,9 @@ int GradientModel::addStop(qreal position, const QColor &color)
gradientNode.nodeListProperty("stops").slide(stopNodes.count() - 1, properPos); gradientNode.nodeListProperty("stops").slide(stopNodes.count() - 1, properPos);
setupModel(); setupModel();
} catch (const QmlDesigner::Exception &e) {
e.showException();
}
return properPos; return properPos;
} }
@@ -155,12 +156,12 @@ void GradientModel::addGradient()
m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).reparentHere(gradientNode); m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).reparentHere(gradientNode);
QmlDesigner::ModelNode gradientStopNode = view()->createModelNode("QtQuick.GradientStop", view()->majorQtQuickVersion(), 0); QmlDesigner::ModelNode gradientStopNode = createGradientStopNode();
gradientStopNode.variantProperty("position").setValue(0.0); gradientStopNode.variantProperty("position").setValue(0.0);
gradientStopNode.variantProperty("color").setValue(color); gradientStopNode.variantProperty("color").setValue(color);
gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode);
gradientStopNode = view()->createModelNode("QtQuick.GradientStop", view()->majorQtQuickVersion(), 0); gradientStopNode = createGradientStopNode();
gradientStopNode.variantProperty("position").setValue(1.0); gradientStopNode.variantProperty("position").setValue(1.0);
gradientStopNode.variantProperty("color").setValue(QColor(Qt::black)); gradientStopNode.variantProperty("color").setValue(QColor(Qt::black));
gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode);
@@ -459,6 +460,17 @@ QmlDesigner::ModelNode GradientModel::createGradientNode()
return gradientNode; return gradientNode;
} }
QmlDesigner::ModelNode GradientModel::createGradientStopNode()
{
QByteArray fullTypeName = "QtQuick.GradientStop";
auto metaInfo = model()->metaInfo(fullTypeName);
int minorVersion = metaInfo.minorVersion();
int majorVersion = metaInfo.majorVersion();
return view()->createModelNode(fullTypeName, majorVersion, minorVersion);
}
void GradientModel::setGradientProperty(const QString &propertyName, qreal value) void GradientModel::setGradientProperty(const QString &propertyName, qreal value)
{ {
QTC_ASSERT(m_itemNode.isValid(), return); QTC_ASSERT(m_itemNode.isValid(), return);

View File

@@ -86,6 +86,7 @@ private:
bool hasGradient() const; bool hasGradient() const;
bool locked() const; bool locked() const;
QmlDesigner::ModelNode createGradientNode(); QmlDesigner::ModelNode createGradientNode();
QmlDesigner::ModelNode createGradientStopNode();
private: private:
QmlDesigner::QmlItemNode m_itemNode; QmlDesigner::QmlItemNode m_itemNode;

View File

@@ -486,6 +486,8 @@ QString RewriterView::auxiliaryDataAsQML() const
QString str = "Designer {\n "; QString str = "Designer {\n ";
QTC_ASSERT(!m_canonicalIntModelNode.isEmpty(), return {});
int columnCount = 0; int columnCount = 0;
for (const auto &node : allModelNodes()) { for (const auto &node : allModelNodes()) {
QHash<PropertyName, QVariant> data = node.auxiliaryData(); QHash<PropertyName, QVariant> data = node.auxiliaryData();
@@ -727,8 +729,11 @@ void RewriterView::setupCanonicalHashes() const
using myPair = std::pair<ModelNode,int>; using myPair = std::pair<ModelNode,int>;
std::vector<myPair> data; std::vector<myPair> data;
for (const ModelNode &node : allModelNodes()) for (const ModelNode &node : allModelNodes()) {
data.emplace_back(std::make_pair(node, nodeOffset(node))); int offset = nodeOffset(node);
QTC_ASSERT(offset > 0, qDebug() << Q_FUNC_INFO << "no offset" << node; return);
data.emplace_back(std::make_pair(node, offset));
}
std::sort(data.begin(), data.end(), [](myPair a, myPair b) { std::sort(data.begin(), data.end(), [](myPair a, myPair b) {
return a.second < b.second; return a.second < b.second;
@@ -1066,6 +1071,8 @@ void RewriterView::restoreAuxiliaryData()
setupCanonicalHashes(); setupCanonicalHashes();
QTC_ASSERT(!m_canonicalIntModelNode.isEmpty(), return);
const QString text = m_textModifier->text(); const QString text = m_textModifier->text();
int startIndex = text.indexOf(annotationsStart()); int startIndex = text.indexOf(annotationsStart());

View File

@@ -65,6 +65,7 @@ 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 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 STANDALONE_MODE[] = "StandAloneMode";
const char ENABLE_TIMELINEVIEW[] = "EnableTimelineView"; const char ENABLE_TIMELINEVIEW[] = "EnableTimelineView";
const char ENABLE_TIMELINEVIEW_ENVVAR[] = "QTC_ENABLE_QTQUICKTIMELINE_EDITOR";
} }
class DesignerSettings : public QHash<QByteArray, QVariant> class DesignerSettings : public QHash<QByteArray, QVariant>

View File

@@ -194,7 +194,8 @@ bool QmlDesignerPlugin::delayedInitialize()
d->settings.fromSettings(Core::ICore::settings()); d->settings.fromSettings(Core::ICore::settings());
d->viewManager.registerViewTakingOwnership(new QmlDesigner::Internal::ConnectionView); d->viewManager.registerViewTakingOwnership(new QmlDesigner::Internal::ConnectionView);
if (DesignerSettings::getValue(DesignerSettingsKey::ENABLE_TIMELINEVIEW).toBool()) if (DesignerSettings::getValue(DesignerSettingsKey::ENABLE_TIMELINEVIEW).toBool()
|| qEnvironmentVariableIsSet(DesignerSettingsKey::ENABLE_TIMELINEVIEW_ENVVAR))
d->viewManager.registerViewTakingOwnership(new QmlDesigner::TimelineView); d->viewManager.registerViewTakingOwnership(new QmlDesigner::TimelineView);
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::SourceTool); d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::SourceTool);
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::ColorTool); d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::ColorTool);

View File

@@ -79,6 +79,7 @@ ProFileReader::ProFileReader(QMakeGlobals *option, QMakeVfs *vfs)
, ProFileEvaluator(option, this, vfs, this) , ProFileEvaluator(option, this, vfs, this)
, m_ignoreLevel(0) , m_ignoreLevel(0)
{ {
setExtraConfigs(QStringList("qtc_run"));
} }
ProFileReader::~ProFileReader() ProFileReader::~ProFileReader()

View File

@@ -228,7 +228,7 @@ void QtOutputFormatter::handleLink(const QString &href)
if (qmlLineMatch.hasMatch()) { if (qmlLineMatch.hasMatch()) {
const QUrl fileUrl = QUrl(qmlLineMatch.captured(1)); const QUrl fileUrl = QUrl(qmlLineMatch.captured(1));
const int line = qmlLineMatch.captured(2).toInt(); const int line = qmlLineMatch.captured(2).toInt();
openEditor(d->projectFinder.findFile(d->projectFinder.findFile(fileUrl)), line); openEditor(d->projectFinder.findFile(fileUrl), line);
return; return;
} }

View File

@@ -65,17 +65,16 @@ public:
InternalEngine() : m_widget(new QWidget) {} InternalEngine() : m_widget(new QWidget) {}
~InternalEngine() override { delete m_widget;} ~InternalEngine() override { delete m_widget;}
QString title() const override { return TextEditor::SearchEngine::tr("Internal"); } QString title() const override { return TextEditor::SearchEngine::tr("Internal"); }
QString toolTip() const override { return QString(); } QString toolTip() const override { return {}; }
QWidget *widget() const override { return m_widget; } QWidget *widget() const override { return m_widget; }
QVariant parameters() const override { return QVariant(); } QVariant parameters() const override { return {}; }
void readSettings(QSettings * /*settings*/) override {} void readSettings(QSettings * /*settings*/) override {}
void writeSettings(QSettings * /*settings*/) const override {} void writeSettings(QSettings * /*settings*/) const override {}
QFuture<Utils::FileSearchResultList> executeSearch( QFuture<Utils::FileSearchResultList> executeSearch(
const TextEditor::FileFindParameters &parameters, const TextEditor::FileFindParameters &parameters,
BaseFileFind *baseFileFind) override BaseFileFind *baseFileFind) override
{ {
auto func = parameters.flags & FindRegularExpression const auto func = parameters.flags & FindRegularExpression ? Utils::findInFilesRegExp
? Utils::findInFilesRegExp
: Utils::findInFiles; : Utils::findInFiles;
return func(parameters.text, return func(parameters.text,
@@ -112,7 +111,8 @@ public:
class BaseFileFindPrivate class BaseFileFindPrivate
{ {
public: public:
~BaseFileFindPrivate() { delete m_internalSearchEngine; } BaseFileFindPrivate() : m_internalSearchEngine(std::make_unique<InternalEngine>()) {}
QPointer<IFindSupport> m_currentFindSupport; QPointer<IFindSupport> m_currentFindSupport;
QLabel *m_resultLabel = nullptr; QLabel *m_resultLabel = nullptr;
@@ -125,7 +125,7 @@ public:
QPointer<QComboBox> m_filterCombo; QPointer<QComboBox> m_filterCombo;
QPointer<QComboBox> m_exclusionCombo; QPointer<QComboBox> m_exclusionCombo;
QVector<SearchEngine *> m_searchEngines; QVector<SearchEngine *> m_searchEngines;
SearchEngine *m_internalSearchEngine; std::unique_ptr<SearchEngine> m_internalSearchEngine;
int m_currentSearchEngineIndex = -1; int m_currentSearchEngineIndex = -1;
}; };
@@ -182,8 +182,7 @@ void SearchEngine::setEnabled(bool enabled)
BaseFileFind::BaseFileFind() : d(new BaseFileFindPrivate) BaseFileFind::BaseFileFind() : d(new BaseFileFindPrivate)
{ {
d->m_internalSearchEngine = new InternalEngine; addSearchEngine(d->m_internalSearchEngine.get());
addSearchEngine(d->m_internalSearchEngine);
} }
BaseFileFind::~BaseFileFind() BaseFileFind::~BaseFileFind()
@@ -200,14 +199,14 @@ QStringList BaseFileFind::fileNameFilters() const
{ {
if (d->m_filterCombo) if (d->m_filterCombo)
return splitFilterUiText(d->m_filterCombo->currentText()); return splitFilterUiText(d->m_filterCombo->currentText());
return QStringList(); return {};
} }
QStringList BaseFileFind::fileExclusionFilters() const QStringList BaseFileFind::fileExclusionFilters() const
{ {
if (d->m_exclusionCombo) if (d->m_exclusionCombo)
return splitFilterUiText(d->m_exclusionCombo->currentText()); return splitFilterUiText(d->m_exclusionCombo->currentText());
return QStringList(); return {};
} }
SearchEngine *BaseFileFind::currentSearchEngine() const SearchEngine *BaseFileFind::currentSearchEngine() const
@@ -233,11 +232,11 @@ void BaseFileFind::setCurrentSearchEngine(int index)
static void displayResult(QFutureWatcher<FileSearchResultList> *watcher, static void displayResult(QFutureWatcher<FileSearchResultList> *watcher,
SearchResult *search, int index) SearchResult *search, int index)
{ {
FileSearchResultList results = watcher->resultAt(index); const FileSearchResultList results = watcher->resultAt(index);
QList<SearchResultItem> items; QList<SearchResultItem> items;
foreach (const FileSearchResult &result, results) { for (const FileSearchResult &result : results) {
SearchResultItem item; SearchResultItem item;
item.path = QStringList() << QDir::toNativeSeparators(result.fileName); item.path = QStringList(QDir::toNativeSeparators(result.fileName));
item.mainRange.begin.line = result.lineNumber; item.mainRange.begin.line = result.lineNumber;
item.mainRange.begin.column = result.matchStart; item.mainRange.begin.column = result.matchStart;
item.mainRange.end = item.mainRange.begin; item.mainRange.end = item.mainRange.begin;
@@ -258,7 +257,7 @@ void BaseFileFind::runNewSearch(const QString &txt, FindFlags findFlags,
updateComboEntries(d->m_filterCombo, true); updateComboEntries(d->m_filterCombo, true);
if (d->m_exclusionCombo) if (d->m_exclusionCombo)
updateComboEntries(d->m_exclusionCombo, true); updateComboEntries(d->m_exclusionCombo, true);
QString tooltip = toolTip(); const QString tooltip = toolTip();
SearchResult *search = SearchResultWindow::instance()->startNewSearch( SearchResult *search = SearchResultWindow::instance()->startNewSearch(
label(), label(),
@@ -276,20 +275,26 @@ void BaseFileFind::runNewSearch(const QString &txt, FindFlags findFlags,
parameters.searchEngineParameters = currentSearchEngine()->parameters(); parameters.searchEngineParameters = currentSearchEngine()->parameters();
parameters.searchEngineIndex = d->m_currentSearchEngineIndex; parameters.searchEngineIndex = d->m_currentSearchEngineIndex;
search->setUserData(qVariantFromValue(parameters)); search->setUserData(qVariantFromValue(parameters));
connect(search, &SearchResult::activated, this, &BaseFileFind::openEditor); connect(search, &SearchResult::activated, this, [this, search](const SearchResultItem &item) {
openEditor(search, item);
});
if (searchMode == SearchResultWindow::SearchAndReplace) if (searchMode == SearchResultWindow::SearchAndReplace)
connect(search, &SearchResult::replaceButtonClicked, this, &BaseFileFind::doReplace); connect(search, &SearchResult::replaceButtonClicked, this, &BaseFileFind::doReplace);
connect(search, &SearchResult::visibilityChanged, this, &BaseFileFind::hideHighlightAll); connect(search, &SearchResult::visibilityChanged, this, &BaseFileFind::hideHighlightAll);
connect(search, &SearchResult::searchAgainRequested, this, &BaseFileFind::searchAgain); connect(search, &SearchResult::searchAgainRequested, this, [this, search] {
searchAgain(search);
});
connect(this, &BaseFileFind::enabledChanged, search, &SearchResult::requestEnabledCheck); connect(this, &BaseFileFind::enabledChanged, search, &SearchResult::requestEnabledCheck);
connect(search, &SearchResult::requestEnabledCheck, this, &BaseFileFind::recheckEnabled); connect(search, &SearchResult::requestEnabledCheck, this, [this, search] {
recheckEnabled(search);
});
runSearch(search); runSearch(search);
} }
void BaseFileFind::runSearch(SearchResult *search) void BaseFileFind::runSearch(SearchResult *search)
{ {
FileFindParameters parameters = search->userData().value<FileFindParameters>(); const FileFindParameters parameters = search->userData().value<FileFindParameters>();
auto label = new CountingLabel; auto label = new CountingLabel;
connect(search, &SearchResult::countChanged, label, &CountingLabel::updateCount); connect(search, &SearchResult::countChanged, label, &CountingLabel::updateCount);
auto statusLabel = new CountingLabel; auto statusLabel = new CountingLabel;
@@ -341,7 +346,7 @@ void BaseFileFind::doReplace(const QString &text,
const QList<SearchResultItem> &items, const QList<SearchResultItem> &items,
bool preserveCase) bool preserveCase)
{ {
QStringList files = replaceAll(text, items, preserveCase); const QStringList files = replaceAll(text, items, preserveCase);
if (!files.isEmpty()) { if (!files.isEmpty()) {
Utils::FadingIndicator::showText(ICore::mainWindow(), Utils::FadingIndicator::showText(ICore::mainWindow(),
tr("%n occurrences replaced.", nullptr, items.size()), tr("%n occurrences replaced.", nullptr, items.size()),
@@ -391,7 +396,7 @@ QList<QPair<QWidget *, QWidget *>> BaseFileFind::createPatternWidgets()
void BaseFileFind::writeCommonSettings(QSettings *settings) void BaseFileFind::writeCommonSettings(QSettings *settings)
{ {
std::function<QStringList(const QStringList &)> fromNativeSeparators = [](const QStringList &files) { const auto fromNativeSeparators = [](const QStringList &files) -> QStringList {
return Utils::transform(files, &QDir::fromNativeSeparators); return Utils::transform(files, &QDir::fromNativeSeparators);
}; };
@@ -404,7 +409,7 @@ void BaseFileFind::writeCommonSettings(QSettings *settings)
settings->setValue("currentExclusionFilter", settings->setValue("currentExclusionFilter",
QDir::fromNativeSeparators(d->m_exclusionCombo->currentText())); QDir::fromNativeSeparators(d->m_exclusionCombo->currentText()));
foreach (SearchEngine *searchEngine, d->m_searchEngines) for (const SearchEngine *searchEngine : qAsConst(d->m_searchEngines))
searchEngine->writeSettings(settings); searchEngine->writeSettings(settings);
settings->setValue("currentSearchEngineIndex", d->m_currentSearchEngineIndex); settings->setValue("currentSearchEngineIndex", d->m_currentSearchEngineIndex);
} }
@@ -412,13 +417,13 @@ void BaseFileFind::writeCommonSettings(QSettings *settings)
void BaseFileFind::readCommonSettings(QSettings *settings, const QString &defaultFilter, void BaseFileFind::readCommonSettings(QSettings *settings, const QString &defaultFilter,
const QString &defaultExclusionFilter) const QString &defaultExclusionFilter)
{ {
std::function<QStringList(const QStringList &)> toNativeSeparators = [](const QStringList &files) { const auto toNativeSeparators = [](const QStringList &files) -> QStringList {
return Utils::transform(files, &QDir::toNativeSeparators); return Utils::transform(files, &QDir::toNativeSeparators);
}; };
QStringList filters = settings->value("filters").toStringList(); const QStringList filterSetting = settings->value("filters").toStringList();
if (filters.isEmpty()) const QStringList filters = filterSetting.isEmpty() ? QStringList(defaultFilter)
filters << defaultFilter; : filterSetting;
const QVariant currentFilter = settings->value("currentFilter"); const QVariant currentFilter = settings->value("currentFilter");
d->m_filterSetting = currentFilter.isValid() ? currentFilter.toString() d->m_filterSetting = currentFilter.isValid() ? currentFilter.toString()
: filters.first(); : filters.first();
@@ -436,16 +441,15 @@ void BaseFileFind::readCommonSettings(QSettings *settings, const QString &defaul
if (d->m_exclusionCombo) if (d->m_exclusionCombo)
syncComboWithSettings(d->m_exclusionCombo, d->m_exclusionSetting); syncComboWithSettings(d->m_exclusionCombo, d->m_exclusionSetting);
foreach (SearchEngine* searchEngine, d->m_searchEngines) for (SearchEngine* searchEngine : qAsConst(d->m_searchEngines))
searchEngine->readSettings(settings); searchEngine->readSettings(settings);
const int currentSearchEngineIndex = settings->value("currentSearchEngineIndex", 0).toInt(); const int currentSearchEngineIndex = settings->value("currentSearchEngineIndex", 0).toInt();
syncSearchEngineCombo(currentSearchEngineIndex); syncSearchEngineCombo(currentSearchEngineIndex);
} }
void BaseFileFind::openEditor(const SearchResultItem &item) void BaseFileFind::openEditor(SearchResult *result, const SearchResultItem &item)
{ {
auto result = qobject_cast<SearchResult *>(sender()); const FileFindParameters parameters = result->userData().value<FileFindParameters>();
FileFindParameters parameters = result->userData().value<FileFindParameters>();
IEditor *openedEditor = IEditor *openedEditor =
d->m_searchEngines[parameters.searchEngineIndex]->openEditor(item, parameters); d->m_searchEngines[parameters.searchEngineIndex]->openEditor(item, parameters);
if (!openedEditor) if (!openedEditor)
@@ -468,16 +472,14 @@ void BaseFileFind::hideHighlightAll(bool visible)
d->m_currentFindSupport->clearHighlights(); d->m_currentFindSupport->clearHighlights();
} }
void BaseFileFind::searchAgain() void BaseFileFind::searchAgain(SearchResult *search)
{ {
auto search = qobject_cast<SearchResult *>(sender());
search->restart(); search->restart();
runSearch(search); runSearch(search);
} }
void BaseFileFind::recheckEnabled() void BaseFileFind::recheckEnabled(SearchResult *search)
{ {
auto search = qobject_cast<SearchResult *>(sender());
if (!search) if (!search)
return; return;
search->setSearchAgainEnabled(isEnabled()); search->setSearchAgainEnabled(isEnabled());
@@ -493,7 +495,7 @@ QStringList BaseFileFind::replaceAll(const QString &text,
RefactoringChanges refactoring; RefactoringChanges refactoring;
QHash<QString, QList<SearchResultItem> > changes; QHash<QString, QList<SearchResultItem> > changes;
foreach (const SearchResultItem &item, items) for (const SearchResultItem &item : items)
changes[QDir::fromNativeSeparators(item.path.first())].append(item); changes[QDir::fromNativeSeparators(item.path.first())].append(item);
// Checking for files without write permissions // Checking for files without write permissions
@@ -523,7 +525,7 @@ QStringList BaseFileFind::replaceAll(const QString &text,
ChangeSet changeSet; ChangeSet changeSet;
RefactoringFilePtr file = refactoring.file(fileName); RefactoringFilePtr file = refactoring.file(fileName);
QSet<QPair<int, int> > processed; QSet<QPair<int, int> > processed;
foreach (const SearchResultItem &item, changeItems) { for (const SearchResultItem &item : changeItems) {
const QPair<int, int> &p = qMakePair(item.mainRange.begin.line, const QPair<int, int> &p = qMakePair(item.mainRange.begin.line,
item.mainRange.begin.column); item.mainRange.begin.column);
if (processed.contains(p)) if (processed.contains(p))

View File

@@ -67,6 +67,7 @@ class TEXTEDITOR_EXPORT SearchEngine : public QObject
public: public:
SearchEngine(QObject *parent = nullptr); SearchEngine(QObject *parent = nullptr);
~SearchEngine() override; ~SearchEngine() override;
virtual QString title() const = 0; virtual QString title() const = 0;
virtual QString toolTip() const = 0; // add %1 placeholder where the find flags should be put virtual QString toolTip() const = 0; // add %1 placeholder where the find flags should be put
virtual QWidget *widget() const = 0; virtual QWidget *widget() const = 0;
@@ -132,13 +133,13 @@ signals:
void currentSearchEngineChanged(); void currentSearchEngineChanged();
private: private:
void openEditor(const Core::SearchResultItem &item); void openEditor(Core::SearchResult *result, const Core::SearchResultItem &item);
void doReplace(const QString &txt, void doReplace(const QString &txt,
const QList<Core::SearchResultItem> &items, const QList<Core::SearchResultItem> &items,
bool preserveCase); bool preserveCase);
void hideHighlightAll(bool visible); void hideHighlightAll(bool visible);
void searchAgain(); void searchAgain(Core::SearchResult *search);
void recheckEnabled(); void recheckEnabled(Core::SearchResult *search);
void runNewSearch(const QString &txt, Core::FindFlags findFlags, void runNewSearch(const QString &txt, Core::FindFlags findFlags,
Core::SearchResultWindow::SearchMode searchMode); Core::SearchResultWindow::SearchMode searchMode);

View File

@@ -43,6 +43,10 @@
using namespace TextEditor; using namespace TextEditor;
static const char kDefinitionForMimeType[] = "definitionForMimeType";
static const char kDefinitionForExtension[] = "definitionForExtension";
static const char kDefinitionForFilePath[] = "definitionForFilePath";
KSyntaxHighlighting::Repository *highlightRepository() KSyntaxHighlighting::Repository *highlightRepository()
{ {
static KSyntaxHighlighting::Repository *repository = nullptr; static KSyntaxHighlighting::Repository *repository = nullptr;
@@ -107,18 +111,24 @@ Highlighter::Definition Highlighter::definitionForDocument(const TextDocument *d
if (mimeType.isValid()) if (mimeType.isValid())
definition = Highlighter::definitionForMimeType(mimeType.name()); definition = Highlighter::definitionForMimeType(mimeType.name());
if (!definition.isValid()) if (!definition.isValid())
definition = Highlighter::definitionForFileName(document->filePath().fileName()); definition = Highlighter::definitionForFilePath(document->filePath());
return definition; return definition;
} }
Highlighter::Definition Highlighter::definitionForMimeType(const QString &mimeType) Highlighter::Definition Highlighter::definitionForMimeType(const QString &mimeType)
{ {
const Definitions definitions = definitionsForMimeType(mimeType);
if (definitions.size() == 1)
return definitions.first();
return highlightRepository()->definitionForMimeType(mimeType); return highlightRepository()->definitionForMimeType(mimeType);
} }
Highlighter::Definition Highlighter::definitionForFileName(const QString &fileName) Highlighter::Definition Highlighter::definitionForFilePath(const Utils::FileName &fileName)
{ {
return highlightRepository()->definitionForFileName(fileName); const Definitions definitions = definitionsForFileName(fileName);
if (definitions.size() == 1)
return definitions.first();
return highlightRepository()->definitionForFileName(fileName.fileName());
} }
Highlighter::Definition Highlighter::definitionForName(const QString &name) Highlighter::Definition Highlighter::definitionForName(const QString &name)
@@ -133,18 +143,88 @@ Highlighter::Definitions Highlighter::definitionsForDocument(const TextDocument
if (mimeType.isValid()) if (mimeType.isValid())
definitions = Highlighter::definitionsForMimeType(mimeType.name()); definitions = Highlighter::definitionsForMimeType(mimeType.name());
if (definitions.isEmpty()) if (definitions.isEmpty())
definitions = Highlighter::definitionsForFileName(document->filePath().fileName()); definitions = Highlighter::definitionsForFileName(document->filePath());
return definitions; return definitions;
} }
static Highlighter::Definition definitionForSetting(const QString &settingsKey,
const QString &mapKey)
{
QSettings *settings = Core::ICore::settings();
settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY);
const QString &definitionName = settings->value(settingsKey).toMap().value(mapKey).toString();
settings->endGroup();
return Highlighter::definitionForName(definitionName);
}
Highlighter::Definitions Highlighter::definitionsForMimeType(const QString &mimeType) Highlighter::Definitions Highlighter::definitionsForMimeType(const QString &mimeType)
{ {
return highlightRepository()->definitionsForMimeType(mimeType).toList(); Definitions definitions = highlightRepository()->definitionsForMimeType(mimeType).toList();
if (definitions.size() > 1) {
const Definition &rememberedDefinition = definitionForSetting(kDefinitionForMimeType,
mimeType);
if (rememberedDefinition.isValid() && definitions.contains(rememberedDefinition))
definitions = {rememberedDefinition};
}
return definitions;
} }
Highlighter::Definitions Highlighter::definitionsForFileName(const QString &fileName) Highlighter::Definitions Highlighter::definitionsForFileName(const Utils::FileName &fileName)
{ {
return highlightRepository()->definitionsForFileName(fileName).toList(); Definitions definitions
= highlightRepository()->definitionsForFileName(fileName.fileName()).toList();
if (definitions.size() > 1) {
const QString &fileExtension = fileName.toFileInfo().completeSuffix();
const Definition &rememberedDefinition
= fileExtension.isEmpty()
? definitionForSetting(kDefinitionForFilePath,
fileName.toFileInfo().canonicalFilePath())
: definitionForSetting(kDefinitionForExtension, fileExtension);
if (rememberedDefinition.isValid() && definitions.contains(rememberedDefinition))
definitions = {rememberedDefinition};
}
return definitions;
}
void Highlighter::rememberDefintionForDocument(const Highlighter::Definition &definition,
const TextDocument *document)
{
if (!definition.isValid())
return;
const QString &mimeType = document->mimeType();
const QString &fileExtension = document->filePath().toFileInfo().completeSuffix();
const QString &path = document->filePath().toFileInfo().canonicalFilePath();
QSettings *settings = Core::ICore::settings();
settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY);
if (!mimeType.isEmpty()) {
const QString id(kDefinitionForMimeType);
QMap<QString, QVariant> map = settings->value(id).toMap();
map.insert(mimeType, definition.name());
settings->setValue(id, map);
} else if (!fileExtension.isEmpty()) {
const QString id(kDefinitionForExtension);
QMap<QString, QVariant> map = settings->value(id).toMap();
map.insert(fileExtension, definition.name());
settings->setValue(id, map);
} else if (!path.isEmpty()) {
const QString id(kDefinitionForFilePath);
QMap<QString, QVariant> map = settings->value(id).toMap();
map.insert(document->filePath().toFileInfo().absoluteFilePath(), definition.name());
settings->setValue(id, map);
}
settings->endGroup();
}
void Highlighter::clearDefintionForDocumentCache()
{
QSettings *settings = Core::ICore::settings();
settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY);
settings->remove(kDefinitionForMimeType);
settings->remove(kDefinitionForExtension);
settings->remove(kDefinitionForFilePath);
settings->endGroup();
} }
void Highlighter::addCustomHighlighterPath(const Utils::FileName &path) void Highlighter::addCustomHighlighterPath(const Utils::FileName &path)

View File

@@ -38,6 +38,8 @@ class TextDocument;
class Highlighter : public SyntaxHighlighter, public KSyntaxHighlighting::AbstractHighlighter class Highlighter : public SyntaxHighlighter, public KSyntaxHighlighting::AbstractHighlighter
{ {
Q_OBJECT
Q_INTERFACES(KSyntaxHighlighting::AbstractHighlighter)
public: public:
using Definition = KSyntaxHighlighting::Definition; using Definition = KSyntaxHighlighting::Definition;
using Definitions = QList<Definition>; using Definitions = QList<Definition>;
@@ -45,12 +47,16 @@ public:
static Definition definitionForDocument(const TextDocument *document); static Definition definitionForDocument(const TextDocument *document);
static Definition definitionForMimeType(const QString &mimeType); static Definition definitionForMimeType(const QString &mimeType);
static Definition definitionForFileName(const QString &fileName); static Definition definitionForFilePath(const Utils::FileName &fileName);
static Definition definitionForName(const QString &name); static Definition definitionForName(const QString &name);
static Definitions definitionsForDocument(const TextDocument *document); static Definitions definitionsForDocument(const TextDocument *document);
static Definitions definitionsForMimeType(const QString &mimeType); static Definitions definitionsForMimeType(const QString &mimeType);
static Definitions definitionsForFileName(const QString &fileName); static Definitions definitionsForFileName(const Utils::FileName &fileName);
static void rememberDefintionForDocument(const Definition &definition,
const TextDocument *document);
static void clearDefintionForDocumentCache();
static void addCustomHighlighterPath(const Utils::FileName &path); static void addCustomHighlighterPath(const Utils::FileName &path);
static void updateDefinitions(std::function<void()> callback = nullptr); static void updateDefinitions(std::function<void()> callback = nullptr);

View File

@@ -25,6 +25,8 @@
#include "highlightersettings.h" #include "highlightersettings.h"
#include "texteditorconstants.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/synchronousprocess.h> #include <utils/synchronousprocess.h>
@@ -97,7 +99,6 @@ namespace {
static const QLatin1String kDefinitionFilesPath("UserDefinitionFilesPath"); static const QLatin1String kDefinitionFilesPath("UserDefinitionFilesPath");
static const QLatin1String kIgnoredFilesPatterns("IgnoredFilesPatterns"); static const QLatin1String kIgnoredFilesPatterns("IgnoredFilesPatterns");
static const QLatin1String kGroupPostfix("HighlighterSettings");
QString groupSpecifier(const QString &postFix, const QString &category) QString groupSpecifier(const QString &postFix, const QString &category)
{ {
@@ -113,7 +114,7 @@ using namespace Internal;
void HighlighterSettings::toSettings(const QString &category, QSettings *s) const void HighlighterSettings::toSettings(const QString &category, QSettings *s) const
{ {
const QString &group = groupSpecifier(kGroupPostfix, category); const QString &group = groupSpecifier(Constants::HIGHLIGHTER_SETTINGS_CATEGORY, category);
s->beginGroup(group); s->beginGroup(group);
s->setValue(kDefinitionFilesPath, m_definitionFilesPath); s->setValue(kDefinitionFilesPath, m_definitionFilesPath);
s->setValue(kIgnoredFilesPatterns, ignoredFilesPatterns()); s->setValue(kIgnoredFilesPatterns, ignoredFilesPatterns());
@@ -122,7 +123,7 @@ void HighlighterSettings::toSettings(const QString &category, QSettings *s) cons
void HighlighterSettings::fromSettings(const QString &category, QSettings *s) void HighlighterSettings::fromSettings(const QString &category, QSettings *s)
{ {
const QString &group = groupSpecifier(kGroupPostfix, category); const QString &group = groupSpecifier(Constants::HIGHLIGHTER_SETTINGS_CATEGORY, category);
s->beginGroup(group); s->beginGroup(group);
m_definitionFilesPath = s->value(kDefinitionFilesPath, QString()).toString(); m_definitionFilesPath = s->value(kDefinitionFilesPath, QString()).toString();
if (!s->contains(kDefinitionFilesPath)) if (!s->contains(kDefinitionFilesPath))

View File

@@ -112,6 +112,9 @@ QWidget *HighlighterSettingsPage::widget()
label->setText(tr("Update finished")); label->setText(tr("Update finished"));
}); });
}); });
connect(m_d->m_page->resetCache, &QPushButton::clicked, []() {
Highlighter::clearDefintionForDocumentCache();
});
settingsToUI(); settingsToUI();
} }

View File

@@ -110,6 +110,30 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="resetCache">
<property name="text">
<string>Reset Remembered Definitions</string>
</property>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@@ -613,6 +613,7 @@ public:
void reconfigure(); void reconfigure();
void updateSyntaxInfoBar(const Highlighter::Definitions &definitions, const QString &fileName); void updateSyntaxInfoBar(const Highlighter::Definitions &definitions, const QString &fileName);
void configureGenericHighlighter(const KSyntaxHighlighting::Definition &definition); void configureGenericHighlighter(const KSyntaxHighlighting::Definition &definition);
void rememberCurrentSyntaxDefinition();
public: public:
TextEditorWidget *q; TextEditorWidget *q;
@@ -3306,6 +3307,11 @@ void TextEditorWidgetPrivate::updateSyntaxInfoBar(const Highlighter::Definitions
this->configureGenericHighlighter(Highlighter::definitionForName(definition)); this->configureGenericHighlighter(Highlighter::definitionForName(definition));
}); });
info.setCustomButtonInfo(BaseTextEditor::tr("Remember My Choice"), [multiple, this]() {
m_document->infoBar()->removeInfo(multiple);
rememberCurrentSyntaxDefinition();
});
infoBar->removeInfo(missing); infoBar->removeInfo(missing);
infoBar->addInfo(info); infoBar->addInfo(info);
} else { } else {
@@ -3333,6 +3339,16 @@ void TextEditorWidgetPrivate::configureGenericHighlighter(
m_document->setFontSettings(TextEditorSettings::fontSettings()); m_document->setFontSettings(TextEditorSettings::fontSettings());
} }
void TextEditorWidgetPrivate::rememberCurrentSyntaxDefinition()
{
auto highlighter = qobject_cast<Highlighter *>(m_document->syntaxHighlighter());
if (!highlighter)
return;
const Highlighter::Definition &definition = highlighter->definition();
if (definition.isValid())
Highlighter::rememberDefintionForDocument(definition, m_document.data());
}
bool TextEditorWidget::codeFoldingVisible() const bool TextEditorWidget::codeFoldingVisible() const
{ {
return d->m_codeFoldingVisible; return d->m_codeFoldingVisible;
@@ -8539,7 +8555,7 @@ QString TextEditorWidget::textAt(int from, int to) const
void TextEditorWidget::configureGenericHighlighter() void TextEditorWidget::configureGenericHighlighter()
{ {
const Highlighter::Definitions definitions = Highlighter::definitionsForDocument(textDocument()); Highlighter::Definitions definitions = Highlighter::definitionsForDocument(textDocument());
d->configureGenericHighlighter(definitions.isEmpty() ? Highlighter::Definition() d->configureGenericHighlighter(definitions.isEmpty() ? Highlighter::Definition()
: definitions.first()); : definitions.first());
d->updateSyntaxInfoBar(definitions, textDocument()->filePath().fileName()); d->updateSyntaxInfoBar(definitions, textDocument()->filePath().fileName());

View File

@@ -214,6 +214,8 @@ const char TEXT_EDITOR_DISPLAY_SETTINGS[] = "D.DisplaySettings";
const char TEXT_EDITOR_HIGHLIGHTER_SETTINGS[] = "E.HighlighterSettings"; const char TEXT_EDITOR_HIGHLIGHTER_SETTINGS[] = "E.HighlighterSettings";
const char TEXT_EDITOR_SNIPPETS_SETTINGS[] = "F.SnippetsSettings"; const char TEXT_EDITOR_SNIPPETS_SETTINGS[] = "F.SnippetsSettings";
const char HIGHLIGHTER_SETTINGS_CATEGORY[] = "HighlighterSettings";
const char SNIPPET_EDITOR_ID[] = "TextEditor.SnippetEditor"; const char SNIPPET_EDITOR_ID[] = "TextEditor.SnippetEditor";
const char TEXT_SNIPPET_GROUP_ID[] = "Text"; const char TEXT_SNIPPET_GROUP_ID[] = "Text";

View File

@@ -98,6 +98,7 @@ public:
const QString m_directory; const QString m_directory;
QString m_startupFile; QString m_startupFile;
QString m_output; QString m_output;
QString m_displayName;
QPointer<VcsCommand> m_command; QPointer<VcsCommand> m_command;
QPointer<VcsCommandResultProxy> m_commandResultProxy; QPointer<VcsCommandResultProxy> m_commandResultProxy;
QFutureWatcher<QList<FileData>> *m_processWatcher = nullptr; QFutureWatcher<QList<FileData>> *m_processWatcher = nullptr;
@@ -251,6 +252,7 @@ void VcsBaseDiffEditorController::runCommand(const QList<QStringList> &args, uns
d->cancelReload(); d->cancelReload();
d->m_command = new VcsCommand(workingDirectory(), d->m_client->processEnvironment()); d->m_command = new VcsCommand(workingDirectory(), d->m_client->processEnvironment());
d->m_command->setDisplayName(d->m_displayName);
d->m_command->setCodec(codec ? codec : EditorManager::defaultTextCodec()); d->m_command->setCodec(codec ? codec : EditorManager::defaultTextCodec());
d->m_commandResultProxy = new VcsCommandResultProxy(d->m_command.data(), d); d->m_commandResultProxy = new VcsCommandResultProxy(d->m_command.data(), d);
d->m_command->addFlags(flags); d->m_command->addFlags(flags);
@@ -289,6 +291,11 @@ QString VcsBaseDiffEditorController::startupFile() const
return d->m_startupFile; return d->m_startupFile;
} }
void VcsBaseDiffEditorController::setDisplayName(const QString &displayName)
{
d->m_displayName = displayName;
}
} // namespace VcsBase } // namespace VcsBase
#include "vcsbasediffeditorcontroller.moc" #include "vcsbasediffeditorcontroller.moc"

View File

@@ -53,6 +53,7 @@ protected:
QString workingDirectory() const; QString workingDirectory() const;
void setStartupFile(const QString &startupFile); void setStartupFile(const QString &startupFile);
QString startupFile() const; QString startupFile() const;
void setDisplayName(const QString &displayName);
private: private:
friend class VcsBaseDiffEditorControllerPrivate; friend class VcsBaseDiffEditorControllerPrivate;

View File

@@ -150,25 +150,6 @@ isEmpty(LLVM_INSTALL_DIR) {
output = $$system($$llvm_config --version, lines) output = $$system($$llvm_config --version, lines)
LLVM_VERSION = $$extractVersion($$output) LLVM_VERSION = $$extractVersion($$output)
!isEmpty(LLVM_VERSION) {
versionIsAtLeast($$LLVM_VERSION, 7, 0, 0): {
CLANGFORMAT_LIBS=-lclangFormat -lclangToolingInclusions -lclangToolingCore -lclangRewrite -lclangLex -lclangBasic
ALL_CLANG_LIBS=-lclangFormat -lclangToolingInclusions -lclangTooling -lclangToolingCore \
-lclangRewrite -lclangIndex -lclangFrontend -lclangParse -lclangSerialization \
-lclangSema -lclangEdit -lclangAnalysis -lclangDriver -lclangDynamicASTMatchers \
-lclangASTMatchers -lclangAST -lclangLex -lclangBasic
} else:versionIsAtLeast($$LLVM_VERSION, 6, 0, 0): {
CLANGFORMAT_LIBS=-lclangFormat -lclangToolingCore -lclangRewrite -lclangLex -lclangBasic
ALL_CLANG_LIBS=-lclangFormat -lclangTooling -lclangToolingCore \
-lclangRewrite -lclangIndex -lclangFrontend -lclangParse -lclangSerialization \
-lclangSema -lclangEdit -lclangAnalysis -lclangDriver -lclangDynamicASTMatchers \
-lclangASTMatchers -lclangAST -lclangLex -lclangBasic
}
win32:CLANGFORMAT_LIBS += -lversion
win32:ALL_CLANG_LIBS += -lversion
}
isEmpty(LLVM_VERSION) { isEmpty(LLVM_VERSION) {
$$llvmWarningOrError(\ $$llvmWarningOrError(\
"Cannot determine clang version. Set LLVM_INSTALL_DIR to build the Clang Code Model",\ "Cannot determine clang version. Set LLVM_INSTALL_DIR to build the Clang Code Model",\
@@ -204,6 +185,25 @@ isEmpty(LLVM_VERSION) {
LLVM_STATIC_LIBS = $$split(LLVM_STATIC_LIBS_STRING, " ") LLVM_STATIC_LIBS = $$split(LLVM_STATIC_LIBS_STRING, " ")
CLANGFORMAT_MAIN_HEADER = $$LLVM_INCLUDEPATH/clang/Format/Format.h
exists($$CLANGFORMAT_MAIN_HEADER) {
versionIsAtLeast($$LLVM_VERSION, 7, 0, 0): {
CLANGFORMAT_LIBS=-lclangFormat -lclangToolingInclusions -lclangToolingCore -lclangRewrite -lclangLex -lclangBasic
ALL_CLANG_LIBS=-lclangFormat -lclangToolingInclusions -lclangTooling -lclangToolingCore \
-lclangRewrite -lclangIndex -lclangFrontend -lclangParse -lclangSerialization \
-lclangSema -lclangEdit -lclangAnalysis -lclangDriver -lclangDynamicASTMatchers \
-lclangASTMatchers -lclangAST -lclangLex -lclangBasic
} else:versionIsAtLeast($$LLVM_VERSION, 6, 0, 0): {
CLANGFORMAT_LIBS=-lclangFormat -lclangToolingCore -lclangRewrite -lclangLex -lclangBasic
ALL_CLANG_LIBS=-lclangFormat -lclangTooling -lclangToolingCore \
-lclangRewrite -lclangIndex -lclangFrontend -lclangParse -lclangSerialization \
-lclangSema -lclangEdit -lclangAnalysis -lclangDriver -lclangDynamicASTMatchers \
-lclangASTMatchers -lclangAST -lclangLex -lclangBasic
}
win32:CLANGFORMAT_LIBS += -lversion
}
win32:ALL_CLANG_LIBS += -lversion
LIBCLANG_MAIN_HEADER = $$LLVM_INCLUDEPATH/clang-c/Index.h LIBCLANG_MAIN_HEADER = $$LLVM_INCLUDEPATH/clang-c/Index.h
!exists($$LIBCLANG_MAIN_HEADER) { !exists($$LIBCLANG_MAIN_HEADER) {
$$llvmWarningOrError(\ $$llvmWarningOrError(\
@@ -231,7 +231,9 @@ isEmpty(LLVM_VERSION) {
warning("Clang LibTooling is disabled. Set QTC_ENABLE_CLANG_LIBTOOLING to enable it.") warning("Clang LibTooling is disabled. Set QTC_ENABLE_CLANG_LIBTOOLING to enable it.")
} }
!isEmpty(CLANGFORMAT_LIBS) {
CLANGFORMAT_LIBS = -L$${LLVM_LIBDIR} $$CLANGFORMAT_LIBS $$LLVM_STATIC_LIBS CLANGFORMAT_LIBS = -L$${LLVM_LIBDIR} $$CLANGFORMAT_LIBS $$LLVM_STATIC_LIBS
}
ALL_CLANG_LIBS = -L$${LLVM_LIBDIR} $$ALL_CLANG_LIBS $$CLANG_LIB $$LLVM_STATIC_LIBS ALL_CLANG_LIBS = -L$${LLVM_LIBDIR} $$ALL_CLANG_LIBS $$CLANG_LIB $$LLVM_STATIC_LIBS
contains(QMAKE_DEFAULT_INCDIRS, $$LLVM_INCLUDEPATH): LLVM_INCLUDEPATH = contains(QMAKE_DEFAULT_INCDIRS, $$LLVM_INCLUDEPATH): LLVM_INCLUDEPATH =

View File

@@ -106,8 +106,8 @@ QString IoUtils::resolvePath(const QString &baseDir, const QString &fileName)
return QDir::cleanPath(fileName); return QDir::cleanPath(fileName);
#ifdef Q_OS_WIN // Add drive to otherwise-absolute path: #ifdef Q_OS_WIN // Add drive to otherwise-absolute path:
if (fileName.at(0).unicode() == '/' || fileName.at(0).unicode() == '\\') { if (fileName.at(0).unicode() == '/' || fileName.at(0).unicode() == '\\') {
Q_ASSERT(isAbsolutePath(baseDir)); return isAbsolutePath(baseDir) ? QDir::cleanPath(baseDir.left(2) + fileName)
return QDir::cleanPath(baseDir.left(2) + fileName); : QDir::cleanPath(fileName);
} }
#endif // Q_OS_WIN #endif // Q_OS_WIN
return QDir::cleanPath(baseDir + QLatin1Char('/') + fileName); return QDir::cleanPath(baseDir + QLatin1Char('/') + fileName);

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