Merge remote-tracking branch 'origin/master' into 4.5
Change-Id: I20eb743180b51dbedabced277a8f12ebe9620807
3
dist/clangformat/README.md
vendored
@@ -57,7 +57,8 @@ For Windows:
|
||||
3. Set shortcuts for convenience:
|
||||
In Menu: Tools > Options > Environment > Keyboard
|
||||
* ClangFormat / FormatFile - e.g. Alt+C, F
|
||||
* ClangFormat / FormatSelectedText - e.g. Alt+C, S
|
||||
* ClangFormat / FormatAtCursor - e.g. Alt+C, C
|
||||
* ClangFormat / DisableFormattingSelectedText - e.g. Alt+C, D
|
||||
|
||||
Due to several issues outlined below the FormatFile action might be of limited
|
||||
use.
|
||||
|
@@ -174,7 +174,13 @@
|
||||
\endlist
|
||||
|
||||
In addition to the \uicontrol {Format Current File} command, ClangFormat
|
||||
and Uncrustify provide the \uicontrol {Format Selected Text} command. If you
|
||||
and Uncrustify provide additional commands.
|
||||
ClangFormat provides the \uicontrol {Format at Cursor} command. If you
|
||||
select it when no text is selected, the syntactic entity under the cursor
|
||||
is formatted. The \uicontrol {Disable Formatting for Selected Text} command
|
||||
wraps selected lines within \c {// clang-format off} and
|
||||
\c {// clang-format on}.
|
||||
Uncrustify provides the \uicontrol {Format Selected Text} command. If you
|
||||
select it when no text is selected, the whole file is formatted by default.
|
||||
To disable this behavior, deselect the
|
||||
\uicontrol {Format entire file if no text was selected} check box.
|
||||
|
@@ -223,8 +223,6 @@ def deploy_libclang(install_dir, llvm_install_dir, chrpath_bin):
|
||||
os.path.join(install_dir, 'bin')))
|
||||
deployinfo.append((os.path.join(llvm_install_dir, 'bin', 'clang.exe'),
|
||||
clangbindirtarget))
|
||||
deployinfo.append((os.path.join(llvm_install_dir, 'bin', 'clang-cl.exe'),
|
||||
clangbindirtarget))
|
||||
resourcetarget = os.path.join(clanglibdirtarget, 'clang')
|
||||
else:
|
||||
libsources = glob(os.path.join(llvm_install_dir, 'lib', 'libclang.so*'))
|
||||
|
@@ -1258,9 +1258,7 @@ class Dumper(DumperBase):
|
||||
if not skipEventReporting:
|
||||
self.eventState = state
|
||||
if state == lldb.eStateExited:
|
||||
if self.isShuttingDown_:
|
||||
self.reportState("inferiorshutdownok")
|
||||
else:
|
||||
if not self.isShuttingDown_:
|
||||
self.reportState("inferiorexited")
|
||||
self.report('exited={status="%s",desc="%s"}'
|
||||
% (self.process.GetExitStatus(), self.process.GetExitDescription()))
|
||||
@@ -1290,7 +1288,7 @@ class Dumper(DumperBase):
|
||||
return
|
||||
if self.isInterrupting_:
|
||||
self.isInterrupting_ = False
|
||||
self.reportState("stopped")
|
||||
self.reportState("inferiorstopok")
|
||||
elif self.ignoreStops > 0:
|
||||
self.ignoreStops -= 1
|
||||
self.process.Continue()
|
||||
|
@@ -20,7 +20,7 @@ Module {
|
||||
prototype: "QQuickItem"
|
||||
Property { name: "condition"; type: "bool" }
|
||||
Property { name: "limitToSubProject"; type: "bool" }
|
||||
Property { name: "multiplexConfigurationId"; type: "string" }
|
||||
Property { name: "multiplexConfigurationIds"; type: "string"; isList: true }
|
||||
Property { name: "name"; type: "string" }
|
||||
Property { name: "productTypes"; type: "string"; isList: true }
|
||||
Property { name: "profiles"; type: "string"; isList: true }
|
||||
@@ -49,6 +49,7 @@ Module {
|
||||
Property { name: "condition"; type: "bool" }
|
||||
Property { name: "fileTags"; type: "string"; isList: true }
|
||||
Property { name: "patterns"; type: "string"; isList: true }
|
||||
Property { name: "priority"; type: "int" }
|
||||
}
|
||||
Component {
|
||||
name: "Group"
|
||||
@@ -118,6 +119,14 @@ Module {
|
||||
Property { name: "type"; type: "string"; isList: true }
|
||||
Property { name: "version"; type: "string" }
|
||||
}
|
||||
Component {
|
||||
name: "Profile"
|
||||
exports: [ "qbs/Profile 1.0" ]
|
||||
prototype: "QQuickItem"
|
||||
Property { name: "baseProfile"; type: "string" }
|
||||
Property { name: "condition"; type: "bool" }
|
||||
Property { name: "name"; type: "string" }
|
||||
}
|
||||
Component {
|
||||
name: "Project"
|
||||
exports: [ "qbs/Project 1.0" ]
|
||||
|
@@ -157,7 +157,7 @@ void sortFilterImports(const QStringList &imports, QStringList *workingImports,
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
static NodeInstanceServer *nodeInstanceServerInstance = 0;
|
||||
static NodeInstanceServer *nodeInstanceServerInstance = nullptr;
|
||||
|
||||
static void notifyPropertyChangeCallBackFunction(QObject *object, const PropertyName &propertyName)
|
||||
{
|
||||
@@ -170,11 +170,7 @@ static void (*notifyPropertyChangeCallBackPointer)(QObject *, const PropertyName
|
||||
NodeInstanceServer::NodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) :
|
||||
NodeInstanceServerInterface(),
|
||||
m_childrenChangeEventFilter(new Internal::ChildrenChangeEventFilter(this)),
|
||||
m_nodeInstanceClient(nodeInstanceClient),
|
||||
m_timer(0),
|
||||
m_renderTimerInterval(16),
|
||||
m_slowRenderTimer(false),
|
||||
m_slowRenderTimerInterval(200)
|
||||
m_nodeInstanceClient(nodeInstanceClient)
|
||||
{
|
||||
qmlRegisterType<DummyContextObject>("QmlDesigner", 1, 0, "DummyContextObject");
|
||||
|
||||
@@ -184,10 +180,6 @@ NodeInstanceServer::NodeInstanceServer(NodeInstanceClientInterface *nodeInstance
|
||||
Internal::QmlPrivateGate::registerFixResourcePathsForObjectCallBack();
|
||||
}
|
||||
|
||||
NodeInstanceServer::~NodeInstanceServer()
|
||||
{
|
||||
}
|
||||
|
||||
QList<ServerNodeInstance> NodeInstanceServer::createInstances(const QVector<InstanceContainer> &containerVector)
|
||||
{
|
||||
Q_ASSERT(declarativeView() || quickView());
|
||||
@@ -247,7 +239,7 @@ ServerNodeInstance NodeInstanceServer::instanceForObject(QObject *object) const
|
||||
|
||||
bool NodeInstanceServer::hasInstanceForObject(QObject *object) const
|
||||
{
|
||||
if (object == 0)
|
||||
if (object == nullptr)
|
||||
return false;
|
||||
|
||||
return m_objectInstanceHash.contains(object) && m_objectInstanceHash.value(object).isValid();
|
||||
@@ -671,7 +663,7 @@ QQmlContext *NodeInstanceServer::context() const
|
||||
if (engine())
|
||||
return rootContext();
|
||||
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QQmlContext *NodeInstanceServer::rootContext() const
|
||||
@@ -979,7 +971,7 @@ void NodeInstanceServer::setInstanceAuxiliaryData(const PropertyValueContainer &
|
||||
}
|
||||
}
|
||||
if (auxiliaryContainer.name().endsWith("@NodeInstance")) {
|
||||
PropertyName propertyName = auxiliaryContainer.name().left(auxiliaryContainer.name().count() - 12);
|
||||
PropertyName propertyName = auxiliaryContainer.name().left(auxiliaryContainer.name().count() - 13);
|
||||
if (!auxiliaryContainer.value().isNull()) {
|
||||
setInstancePropertyVariant(PropertyValueContainer(auxiliaryContainer.instanceId(),
|
||||
propertyName,
|
||||
|
@@ -71,7 +71,6 @@ public:
|
||||
typedef QPair<QString, QPointer<QObject> > DummyPair;
|
||||
|
||||
explicit NodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient);
|
||||
~NodeInstanceServer();
|
||||
|
||||
void createInstances(const CreateInstancesCommand &command);
|
||||
void changeFileUrl(const ChangeFileUrlCommand &command);
|
||||
@@ -214,10 +213,10 @@ private:
|
||||
QPointer<Internal::ChildrenChangeEventFilter> m_childrenChangeEventFilter;
|
||||
QUrl m_fileUrl;
|
||||
NodeInstanceClientInterface *m_nodeInstanceClient;
|
||||
int m_timer;
|
||||
int m_renderTimerInterval;
|
||||
bool m_slowRenderTimer;
|
||||
int m_slowRenderTimerInterval;
|
||||
int m_timer = 0;
|
||||
int m_renderTimerInterval = 16;
|
||||
bool m_slowRenderTimer = false;
|
||||
int m_slowRenderTimerInterval = 200;
|
||||
QVector<InstancePropertyPair> m_changedPropertyList;
|
||||
QByteArray m_importCode;
|
||||
QPointer<QObject> m_dummyContextObject;
|
||||
|
16
src/libs/3rdparty/cplusplus/Lexer.cpp
vendored
@@ -211,7 +211,7 @@ void Lexer::scan_helper(Token *tok)
|
||||
_state = 0;
|
||||
scanCppComment(originalKind);
|
||||
return;
|
||||
} else if (isRawStringLiteral(s._tokenKind)) {
|
||||
} else if (!control() && isRawStringLiteral(s._tokenKind)) {
|
||||
tok->f.kind = s._tokenKind;
|
||||
if (scanUntilRawStringLiteralEndSimple())
|
||||
_state = 0;
|
||||
@@ -755,13 +755,17 @@ void Lexer::scanRawStringLiteral(Token *tok, unsigned char hint)
|
||||
yyinp();
|
||||
} else if (_yychar == ')') {
|
||||
yyinp();
|
||||
if (delimLength == -1)
|
||||
break;
|
||||
if (delimLength == -1) {
|
||||
tok->f.kind = T_ERROR;
|
||||
return;
|
||||
}
|
||||
closingDelimCandidate = _currentChar;
|
||||
} else {
|
||||
if (delimLength == -1) {
|
||||
if (_yychar == '\\' || std::isspace(_yychar))
|
||||
break;
|
||||
if (_yychar == '\\' || std::isspace(_yychar)) {
|
||||
tok->f.kind = T_ERROR;
|
||||
return;
|
||||
}
|
||||
yyinp();
|
||||
} else {
|
||||
if (!closingDelimCandidate) {
|
||||
@@ -804,7 +808,7 @@ void Lexer::scanRawStringLiteral(Token *tok, unsigned char hint)
|
||||
else
|
||||
tok->f.kind = T_RAW_STRING_LITERAL;
|
||||
|
||||
if (!closed)
|
||||
if (!control() && !closed)
|
||||
s._tokenKind = tok->f.kind;
|
||||
}
|
||||
|
||||
|
@@ -175,6 +175,7 @@ HEADERS += \
|
||||
$$PWD/requestsourcerangesforquerymessage.h \
|
||||
$$PWD/stringcachefwd.h \
|
||||
$$PWD/stringcachealgorithms.h \
|
||||
$$PWD/projectmanagementserverinterface.h
|
||||
$$PWD/projectmanagementserverinterface.h \
|
||||
$$PWD/refactoringdatabaseinitializer.h
|
||||
|
||||
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
|
||||
|
@@ -36,8 +36,7 @@ QDebug operator<<(QDebug debug, const FollowSymbolMessage &message)
|
||||
debug.nospace() << "FollowSymbolMessage("
|
||||
<< message.m_fileContainer
|
||||
<< ", " << message.m_ticketNumber
|
||||
<< ", " << message.m_sourceRange
|
||||
<< ", " << message.m_failedToFollow;
|
||||
<< ", " << message.m_sourceRange;
|
||||
|
||||
debug.nospace() << ")";
|
||||
|
||||
@@ -50,7 +49,6 @@ std::ostream &operator<<(std::ostream &os, const FollowSymbolMessage &message)
|
||||
<< message.m_fileContainer << ", "
|
||||
<< message.m_ticketNumber << ", "
|
||||
<< message.m_sourceRange << ", "
|
||||
<< message.m_failedToFollow << ", "
|
||||
<< ")";
|
||||
|
||||
return os;
|
||||
|
@@ -39,12 +39,10 @@ public:
|
||||
FollowSymbolMessage() = default;
|
||||
FollowSymbolMessage(const FileContainer &fileContainer,
|
||||
const SourceRangeContainer &range,
|
||||
bool failedToFollow,
|
||||
quint64 ticketNumber)
|
||||
: m_fileContainer(fileContainer)
|
||||
, m_sourceRange(range)
|
||||
, m_ticketNumber(ticketNumber)
|
||||
, m_failedToFollow(failedToFollow)
|
||||
{
|
||||
}
|
||||
const FileContainer &fileContainer() const
|
||||
@@ -57,11 +55,6 @@ public:
|
||||
return m_sourceRange;
|
||||
}
|
||||
|
||||
bool failedToFollow() const
|
||||
{
|
||||
return m_failedToFollow;
|
||||
}
|
||||
|
||||
quint64 ticketNumber() const
|
||||
{
|
||||
return m_ticketNumber;
|
||||
@@ -72,7 +65,6 @@ public:
|
||||
out << message.m_fileContainer;
|
||||
out << message.m_sourceRange;
|
||||
out << message.m_ticketNumber;
|
||||
out << message.m_failedToFollow;
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -81,7 +73,6 @@ public:
|
||||
in >> message.m_fileContainer;
|
||||
in >> message.m_sourceRange;
|
||||
in >> message.m_ticketNumber;
|
||||
in >> message.m_failedToFollow;
|
||||
return in;
|
||||
}
|
||||
|
||||
@@ -89,8 +80,7 @@ public:
|
||||
{
|
||||
return first.m_ticketNumber == second.m_ticketNumber
|
||||
&& first.m_fileContainer == second.m_fileContainer
|
||||
&& first.m_sourceRange == second.m_sourceRange
|
||||
&& first.m_failedToFollow == second.m_failedToFollow;
|
||||
&& first.m_sourceRange == second.m_sourceRange;
|
||||
}
|
||||
|
||||
friend CMBIPC_EXPORT QDebug operator<<(QDebug debug, const FollowSymbolMessage &message);
|
||||
@@ -99,7 +89,6 @@ private:
|
||||
FileContainer m_fileContainer;
|
||||
SourceRangeContainer m_sourceRange;
|
||||
quint64 m_ticketNumber = 0;
|
||||
bool m_failedToFollow = false;
|
||||
};
|
||||
|
||||
DECLARE_MESSAGE(FollowSymbolMessage);
|
||||
|
@@ -65,6 +65,8 @@ QDebug operator<<(QDebug debug, const HighlightingMarkContainer &container)
|
||||
<< container.column() << ", "
|
||||
<< container.length() << ", "
|
||||
<< highlightingTypeToCStringLiteral(container.types().mainHighlightingType) << ", "
|
||||
<< container.isIdentifier() << ", "
|
||||
<< container.isIncludeDirectivePath()
|
||||
<< ")";
|
||||
|
||||
return debug;
|
||||
@@ -94,7 +96,9 @@ std::ostream &operator<<(std::ostream &os, const HighlightingMarkContainer &cont
|
||||
<< container.line() << ", "
|
||||
<< container.column() << ", "
|
||||
<< container.length() << ", "
|
||||
<< container.types()
|
||||
<< container.types() << ", "
|
||||
<< container.isIdentifier() << ", "
|
||||
<< container.isIncludeDirectivePath()
|
||||
<< ")";
|
||||
|
||||
return os;
|
||||
|
@@ -44,11 +44,14 @@ class HighlightingMarkContainer
|
||||
{
|
||||
public:
|
||||
HighlightingMarkContainer() = default;
|
||||
HighlightingMarkContainer(uint line, uint column, uint length, HighlightingTypes types)
|
||||
HighlightingMarkContainer(uint line, uint column, uint length, HighlightingTypes types,
|
||||
bool isIdentifier = false, bool isIncludeDirectivePath = false)
|
||||
: line_(line),
|
||||
column_(column),
|
||||
length_(length),
|
||||
types_(types)
|
||||
types_(types),
|
||||
isIdentifier_(isIdentifier),
|
||||
isIncludeDirectivePath_(isIncludeDirectivePath)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -80,12 +83,29 @@ public:
|
||||
return types_;
|
||||
}
|
||||
|
||||
bool isInvalid() const
|
||||
{
|
||||
return line_ == 0 && column_ == 0 && length_ == 0;
|
||||
}
|
||||
|
||||
bool isIdentifier() const
|
||||
{
|
||||
return isIdentifier_;
|
||||
}
|
||||
|
||||
bool isIncludeDirectivePath() const
|
||||
{
|
||||
return isIncludeDirectivePath_;
|
||||
}
|
||||
|
||||
friend QDataStream &operator<<(QDataStream &out, const HighlightingMarkContainer &container)
|
||||
{
|
||||
out << container.line_;
|
||||
out << container.column_;
|
||||
out << container.length_;
|
||||
out << container.types_;
|
||||
out << container.isIdentifier_;
|
||||
out << container.isIncludeDirectivePath_;
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -96,6 +116,8 @@ public:
|
||||
in >> container.column_;
|
||||
in >> container.length_;
|
||||
in >> container.types_;
|
||||
in >> container.isIdentifier_;
|
||||
in >> container.isIncludeDirectivePath_;
|
||||
|
||||
return in;
|
||||
}
|
||||
@@ -105,7 +127,9 @@ public:
|
||||
return first.line_ == second.line_
|
||||
&& first.column_ == second.column_
|
||||
&& first.length_ == second.length_
|
||||
&& first.types_ == second.types_;
|
||||
&& first.types_ == second.types_
|
||||
&& first.isIdentifier_ == second.isIdentifier_
|
||||
&& first.isIncludeDirectivePath_ == second.isIncludeDirectivePath_;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -113,6 +137,8 @@ private:
|
||||
uint column_ = 0;
|
||||
uint length_ = 0;
|
||||
HighlightingTypes types_;
|
||||
bool isIdentifier_ = false;
|
||||
bool isIncludeDirectivePath_ = false;
|
||||
};
|
||||
|
||||
inline QDataStream &operator<<(QDataStream &out, HighlightingType highlightingType)
|
||||
|
93
src/libs/clangsupport/refactoringdatabaseinitializer.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <createtablesqlstatementbuilder.h>
|
||||
|
||||
#include <sqlitetransaction.h>
|
||||
#include <sqlitetable.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
template<typename DatabaseType>
|
||||
class RefactoringDatabaseInitializer
|
||||
{
|
||||
public:
|
||||
RefactoringDatabaseInitializer(DatabaseType &database)
|
||||
: database(database)
|
||||
{
|
||||
Sqlite::ImmediateTransaction<DatabaseType> transaction{database};
|
||||
|
||||
createSymbolsTable();
|
||||
createLocationsTable();
|
||||
createSourcesTable();
|
||||
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
void createSymbolsTable()
|
||||
{
|
||||
Sqlite::Table table;
|
||||
table.setUseIfNotExists(true);
|
||||
table.setName("symbols");
|
||||
table.addColumn("symbolId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
|
||||
const Sqlite::Column &usrColumn = table.addColumn("usr", Sqlite::ColumnType::Text);
|
||||
table.addColumn("symbolName", Sqlite::ColumnType::Text);
|
||||
table.addIndex({usrColumn});
|
||||
|
||||
table.initialize(database);
|
||||
}
|
||||
|
||||
void createLocationsTable()
|
||||
{
|
||||
Sqlite::Table table;
|
||||
table.setUseIfNotExists(true);
|
||||
table.setName("locations");
|
||||
table.addColumn("symbolId", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("line", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("column", Sqlite::ColumnType::Integer);
|
||||
const Sqlite::Column &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
|
||||
table.addIndex({sourceIdColumn});
|
||||
|
||||
table.initialize(database);
|
||||
}
|
||||
|
||||
void createSourcesTable()
|
||||
{
|
||||
Sqlite::Table table;
|
||||
table.setUseIfNotExists(true);
|
||||
table.setName("sources");
|
||||
table.addColumn("sourceId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
|
||||
table.addColumn("sourcePath", Sqlite::ColumnType::Text);
|
||||
|
||||
table.initialize(database);
|
||||
}
|
||||
|
||||
public:
|
||||
DatabaseType &database;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
@@ -42,7 +42,6 @@ QDebug operator<<(QDebug debug, const RequestFollowSymbolMessage &message)
|
||||
debug.nospace() << message.m_ticketNumber << ", ";
|
||||
debug.nospace() << message.m_line << ", ";
|
||||
debug.nospace() << message.m_column << ", ";
|
||||
debug.nospace() << message.m_resolveTarget << ", ";
|
||||
|
||||
debug.nospace() << ")";
|
||||
|
||||
@@ -57,7 +56,6 @@ std::ostream &operator<<(std::ostream &os, const RequestFollowSymbolMessage &mes
|
||||
<< message.m_ticketNumber << ", "
|
||||
<< message.m_line << ", "
|
||||
<< message.m_column << ", "
|
||||
<< message.m_resolveTarget << ", "
|
||||
<< ")";
|
||||
|
||||
return os;
|
||||
|
@@ -40,14 +40,12 @@ public:
|
||||
RequestFollowSymbolMessage(const FileContainer &fileContainer,
|
||||
const QVector<Utf8String> &dependentFiles,
|
||||
quint32 line,
|
||||
quint32 column,
|
||||
bool resolveTarget = true)
|
||||
quint32 column)
|
||||
: m_fileContainer(fileContainer)
|
||||
, m_ticketNumber(++ticketCounter)
|
||||
, m_line(line)
|
||||
, m_column(column)
|
||||
, m_dependentFiles(dependentFiles)
|
||||
, m_resolveTarget(resolveTarget)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -71,11 +69,6 @@ public:
|
||||
return m_column;
|
||||
}
|
||||
|
||||
bool resolveTarget() const
|
||||
{
|
||||
return m_resolveTarget;
|
||||
}
|
||||
|
||||
quint64 ticketNumber() const
|
||||
{
|
||||
return m_ticketNumber;
|
||||
@@ -88,7 +81,6 @@ public:
|
||||
out << message.m_ticketNumber;
|
||||
out << message.m_line;
|
||||
out << message.m_column;
|
||||
out << message.m_resolveTarget;
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -100,7 +92,6 @@ public:
|
||||
in >> message.m_ticketNumber;
|
||||
in >> message.m_line;
|
||||
in >> message.m_column;
|
||||
in >> message.m_resolveTarget;
|
||||
|
||||
return in;
|
||||
}
|
||||
@@ -112,7 +103,6 @@ public:
|
||||
&& first.m_line == second.m_line
|
||||
&& first.m_column == second.m_column
|
||||
&& first.m_fileContainer == second.m_fileContainer
|
||||
&& first.m_resolveTarget == second.m_resolveTarget
|
||||
&& first.m_dependentFiles == second.m_dependentFiles;
|
||||
}
|
||||
|
||||
@@ -124,7 +114,6 @@ private:
|
||||
quint32 m_line = 0;
|
||||
quint32 m_column = 0;
|
||||
QVector<Utf8String> m_dependentFiles;
|
||||
bool m_resolveTarget = true;
|
||||
static CMBIPC_EXPORT quint64 ticketCounter;
|
||||
};
|
||||
|
||||
|
@@ -108,16 +108,6 @@ OpenMode Database::openMode() const
|
||||
return m_openMode;
|
||||
}
|
||||
|
||||
int Database::changesCount()
|
||||
{
|
||||
return m_databaseBackend.changesCount();
|
||||
}
|
||||
|
||||
int Database::totalChangesCount()
|
||||
{
|
||||
return m_databaseBackend.totalChangesCount();
|
||||
}
|
||||
|
||||
void Database::execute(Utils::SmallStringView sqlStatement)
|
||||
{
|
||||
m_databaseBackend.execute(sqlStatement);
|
||||
|
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <utils/smallstring.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace Sqlite {
|
||||
@@ -38,11 +39,13 @@ namespace Sqlite {
|
||||
class SQLITE_EXPORT Database
|
||||
{
|
||||
template <typename Database>
|
||||
friend class SqliteAbstractTransaction;
|
||||
friend class SqliteStatement;
|
||||
friend class SqliteBackend;
|
||||
friend class AbstractTransaction;
|
||||
friend class Statement;
|
||||
friend class Backend;
|
||||
|
||||
public:
|
||||
using MutexType = std::mutex;
|
||||
|
||||
Database();
|
||||
Database(Utils::PathString &&databaseFilePath);
|
||||
|
||||
@@ -70,21 +73,34 @@ public:
|
||||
void setOpenMode(OpenMode openMode);
|
||||
OpenMode openMode() const;
|
||||
|
||||
int changesCount();
|
||||
int totalChangesCount();
|
||||
|
||||
void execute(Utils::SmallStringView sqlStatement);
|
||||
|
||||
DatabaseBackend &backend();
|
||||
|
||||
int64_t lastInsertedRowId() const
|
||||
{
|
||||
return m_databaseBackend.lastInsertedRowId();
|
||||
}
|
||||
|
||||
int changesCount()
|
||||
{
|
||||
return m_databaseBackend.changesCount();
|
||||
}
|
||||
|
||||
int totalChangesCount()
|
||||
{
|
||||
return m_databaseBackend.totalChangesCount();
|
||||
}
|
||||
|
||||
private:
|
||||
void initializeTables();
|
||||
|
||||
std::mutex &databaseMutex() { return m_databaseMutex; }
|
||||
|
||||
private:
|
||||
Utils::PathString m_databaseFilePath;
|
||||
DatabaseBackend m_databaseBackend;
|
||||
std::vector<Table> m_sqliteTables;
|
||||
Utils::PathString m_databaseFilePath;
|
||||
std::mutex m_databaseMutex;
|
||||
JournalMode m_journalMode = JournalMode::Wal;
|
||||
OpenMode m_openMode = OpenMode::ReadWrite;
|
||||
bool m_isOpen = false;
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "sqlitestatement.h"
|
||||
#include "sqlitewritestatement.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
|
||||
@@ -109,7 +110,7 @@ void DatabaseBackend::open(Utils::SmallStringView databaseFilePath, OpenMode mod
|
||||
cacheTextEncoding();
|
||||
}
|
||||
|
||||
sqlite3 *DatabaseBackend::sqliteDatabaseHandle()
|
||||
sqlite3 *DatabaseBackend::sqliteDatabaseHandle() const
|
||||
{
|
||||
checkDatabaseHandleIsNotNull();
|
||||
return m_databaseHandle;
|
||||
@@ -156,16 +157,21 @@ Utils::SmallStringVector DatabaseBackend::columnNames(Utils::SmallStringView tab
|
||||
return statement.columnNames();
|
||||
}
|
||||
|
||||
int DatabaseBackend::changesCount()
|
||||
int DatabaseBackend::changesCount() const
|
||||
{
|
||||
return sqlite3_changes(sqliteDatabaseHandle());
|
||||
}
|
||||
|
||||
int DatabaseBackend::totalChangesCount()
|
||||
int DatabaseBackend::totalChangesCount() const
|
||||
{
|
||||
return sqlite3_total_changes(sqliteDatabaseHandle());
|
||||
}
|
||||
|
||||
int64_t DatabaseBackend::lastInsertedRowId() const
|
||||
{
|
||||
return sqlite3_last_insert_rowid(sqliteDatabaseHandle());
|
||||
}
|
||||
|
||||
void DatabaseBackend::execute(Utils::SmallStringView sqlStatement)
|
||||
{
|
||||
ReadWriteStatement statement(sqlStatement, m_database);
|
||||
@@ -230,24 +236,29 @@ void DatabaseBackend::cacheTextEncoding()
|
||||
void DatabaseBackend::checkForOpenDatabaseWhichCanBeClosed()
|
||||
{
|
||||
if (m_databaseHandle == nullptr)
|
||||
throwException("SqliteDatabaseBackend::close: database is not open so it can not be closed.");
|
||||
throw DatabaseIsAlreadyClosed("SqliteDatabaseBackend::close: database is not open so it can not be closed.");
|
||||
}
|
||||
|
||||
void DatabaseBackend::checkDatabaseClosing(int resultCode)
|
||||
{
|
||||
switch (resultCode) {
|
||||
case SQLITE_OK: return;
|
||||
default: throwException("SqliteDatabaseBackend::close: unknown error happens at closing!");
|
||||
case SQLITE_BUSY: throw DatabaseIsBusy("SqliteDatabaseBackend::close: database is busy because of e.g. unfinalized statements and will stay open!");
|
||||
default: throwUnknowError("SqliteDatabaseBackend::close: unknown error happens at closing!");
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseBackend::checkCanOpenDatabase(Utils::SmallStringView databaseFilePath)
|
||||
{
|
||||
if (databaseFilePath.isEmpty())
|
||||
throw Exception("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened:", "database file path is empty!");
|
||||
throw DatabaseFilePathIsEmpty("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened because the file path is empty!");
|
||||
|
||||
if (!QFileInfo::exists(QFileInfo(QString(databaseFilePath)).path()))
|
||||
throw WrongFilePath("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened because of wrong file path!",
|
||||
Utils::SmallString(databaseFilePath));
|
||||
|
||||
if (databaseIsOpen())
|
||||
throw Exception("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened:", "database is already open!");
|
||||
throw DatabaseIsAlreadyOpen("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened because it is already open!");
|
||||
}
|
||||
|
||||
void DatabaseBackend::checkDatabaseCouldBeOpened(int resultCode)
|
||||
@@ -265,13 +276,13 @@ void DatabaseBackend::checkPragmaValue(Utils::SmallStringView databaseValue,
|
||||
Utils::SmallStringView expectedValue)
|
||||
{
|
||||
if (databaseValue != expectedValue)
|
||||
throwException("SqliteDatabaseBackend::setPragmaValue: pragma value is not set!");
|
||||
throw PragmaValueNotSet("SqliteDatabaseBackend::setPragmaValue: pragma value is not set!");
|
||||
}
|
||||
|
||||
void DatabaseBackend::checkDatabaseHandleIsNotNull()
|
||||
void DatabaseBackend::checkDatabaseHandleIsNotNull() const
|
||||
{
|
||||
if (m_databaseHandle == nullptr)
|
||||
throwException("SqliteDatabaseBackend: database is not open!");
|
||||
throwDatabaseIsNotOpen("SqliteDatabaseBackend: database is not open!");
|
||||
}
|
||||
|
||||
void DatabaseBackend::checkIfMultithreadingIsActivated(int resultCode)
|
||||
@@ -392,6 +403,16 @@ void DatabaseBackend::throwException(const char *whatHasHappens) const
|
||||
throw Exception(whatHasHappens);
|
||||
}
|
||||
|
||||
void DatabaseBackend::throwUnknowError(const char *whatHasHappens) const
|
||||
{
|
||||
throw UnknowError(whatHasHappens);
|
||||
}
|
||||
|
||||
void DatabaseBackend::throwDatabaseIsNotOpen(const char *whatHasHappens) const
|
||||
{
|
||||
throw DatabaseIsNotOpen(whatHasHappens);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
Type DatabaseBackend::toValue(Utils::SmallStringView sqlStatement)
|
||||
{
|
||||
@@ -399,7 +420,7 @@ Type DatabaseBackend::toValue(Utils::SmallStringView sqlStatement)
|
||||
|
||||
statement.next();
|
||||
|
||||
return statement.value<Type>(0);
|
||||
return statement.fetchValue<Type>(0);
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -58,7 +58,7 @@ public:
|
||||
void close();
|
||||
void closeWithoutException();
|
||||
|
||||
sqlite3* sqliteDatabaseHandle();
|
||||
sqlite3* sqliteDatabaseHandle() const;
|
||||
|
||||
void setJournalMode(JournalMode journalMode);
|
||||
JournalMode journalMode();
|
||||
@@ -68,8 +68,10 @@ public:
|
||||
|
||||
Utils::SmallStringVector columnNames(Utils::SmallStringView tableName);
|
||||
|
||||
int changesCount();
|
||||
int totalChangesCount();
|
||||
int changesCount() const;
|
||||
int totalChangesCount() const;
|
||||
|
||||
int64_t lastInsertedRowId() const;
|
||||
|
||||
void execute(Utils::SmallStringView sqlStatement);
|
||||
|
||||
@@ -95,7 +97,7 @@ protected:
|
||||
void checkCanOpenDatabase(Utils::SmallStringView databaseFilePath);
|
||||
void checkDatabaseCouldBeOpened(int resultCode);
|
||||
void checkPragmaValue(Utils::SmallStringView databaseValue, Utils::SmallStringView expectedValue);
|
||||
void checkDatabaseHandleIsNotNull();
|
||||
void checkDatabaseHandleIsNotNull() const;
|
||||
void checkIfMultithreadingIsActivated(int resultCode);
|
||||
void checkIfLoogingIsActivated(int resultCode);
|
||||
void checkMmapSizeIsSet(int resultCode);
|
||||
@@ -110,8 +112,9 @@ protected:
|
||||
|
||||
|
||||
Q_NORETURN static void throwExceptionStatic(const char *whatHasHappens);
|
||||
Q_NORETURN void throwException(const char *whatHasHappens) const;
|
||||
|
||||
[[noreturn]] void throwException(const char *whatHasHappens) const;
|
||||
[[noreturn]] void throwUnknowError(const char *whatHasHappens) const;
|
||||
[[noreturn]] void throwDatabaseIsNotOpen(const char *whatHasHappens) const;
|
||||
|
||||
private:
|
||||
Database &m_database;
|
||||
|
@@ -48,4 +48,211 @@ private:
|
||||
Utils::SmallString m_sqliteErrorMessage;
|
||||
};
|
||||
|
||||
class StatementIsBusy : public Exception
|
||||
{
|
||||
public:
|
||||
StatementIsBusy(const char *whatErrorHasHappen,
|
||||
Utils::SmallString &&sqliteErrorMessage = Utils::SmallString())
|
||||
: Exception(whatErrorHasHappen, std::move(sqliteErrorMessage))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class DatabaseIsBusy : public Exception
|
||||
{
|
||||
public:
|
||||
DatabaseIsBusy(const char *whatErrorHasHappen)
|
||||
: Exception(whatErrorHasHappen)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class StatementHasError : public Exception
|
||||
{
|
||||
public:
|
||||
StatementHasError(const char *whatErrorHasHappen,
|
||||
Utils::SmallString &&sqliteErrorMessage = Utils::SmallString())
|
||||
: Exception(whatErrorHasHappen, std::move(sqliteErrorMessage))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class StatementIsMisused : public Exception
|
||||
{
|
||||
public:
|
||||
StatementIsMisused(const char *whatErrorHasHappen,
|
||||
Utils::SmallString &&sqliteErrorMessage = Utils::SmallString())
|
||||
: Exception(whatErrorHasHappen, std::move(sqliteErrorMessage))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class ContraintPreventsModification : public Exception
|
||||
{
|
||||
public:
|
||||
ContraintPreventsModification(const char *whatErrorHasHappen,
|
||||
Utils::SmallString &&sqliteErrorMessage = Utils::SmallString())
|
||||
: Exception(whatErrorHasHappen, std::move(sqliteErrorMessage))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class NoValuesToFetch : public Exception
|
||||
{
|
||||
public:
|
||||
NoValuesToFetch(const char *whatErrorHasHappen)
|
||||
: Exception(whatErrorHasHappen)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class InvalidColumnFetched : public Exception
|
||||
{
|
||||
public:
|
||||
InvalidColumnFetched(const char *whatErrorHasHappen)
|
||||
: Exception(whatErrorHasHappen)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class BindingIndexIsOutOfRange : public Exception
|
||||
{
|
||||
public:
|
||||
BindingIndexIsOutOfRange(const char *whatErrorHasHappen,
|
||||
Utils::SmallString &&sqliteErrorMessage = Utils::SmallString())
|
||||
: Exception(whatErrorHasHappen, std::move(sqliteErrorMessage))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class WrongBingingName : public Exception
|
||||
{
|
||||
public:
|
||||
WrongBingingName(const char *whatErrorHasHappen)
|
||||
: Exception(whatErrorHasHappen)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class DatabaseIsNotOpen : public Exception
|
||||
{
|
||||
public:
|
||||
DatabaseIsNotOpen(const char *whatErrorHasHappen)
|
||||
: Exception(whatErrorHasHappen)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class DatabaseCannotBeOpened : public Exception
|
||||
{
|
||||
public:
|
||||
DatabaseCannotBeOpened(const char *whatErrorHasHappen,
|
||||
Utils::SmallString &&errorMessage = Utils::SmallString())
|
||||
: Exception(whatErrorHasHappen, std::move(errorMessage))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class DatabaseFilePathIsEmpty : public DatabaseCannotBeOpened
|
||||
{
|
||||
public:
|
||||
DatabaseFilePathIsEmpty(const char *whatErrorHasHappen)
|
||||
: DatabaseCannotBeOpened(whatErrorHasHappen)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class DatabaseIsAlreadyOpen : public DatabaseCannotBeOpened
|
||||
{
|
||||
public:
|
||||
DatabaseIsAlreadyOpen(const char *whatErrorHasHappen)
|
||||
: DatabaseCannotBeOpened(whatErrorHasHappen)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class DatabaseCannotBeClosed : public Exception
|
||||
{
|
||||
public:
|
||||
DatabaseCannotBeClosed(const char *whatErrorHasHappen)
|
||||
: Exception(whatErrorHasHappen)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class DatabaseIsAlreadyClosed : public DatabaseCannotBeClosed
|
||||
{
|
||||
public:
|
||||
DatabaseIsAlreadyClosed(const char *whatErrorHasHappen)
|
||||
: DatabaseCannotBeClosed(whatErrorHasHappen)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class WrongFilePath : public DatabaseCannotBeOpened
|
||||
{
|
||||
public:
|
||||
WrongFilePath(const char *whatErrorHasHappen,
|
||||
Utils::SmallString &&errorMessage = Utils::SmallString())
|
||||
: DatabaseCannotBeOpened(whatErrorHasHappen, std::move(errorMessage))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class PragmaValueNotSet : public Exception
|
||||
{
|
||||
public:
|
||||
PragmaValueNotSet(const char *whatErrorHasHappen)
|
||||
: Exception(whatErrorHasHappen)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class NotReadOnlySqlStatement : public Exception
|
||||
{
|
||||
public:
|
||||
NotReadOnlySqlStatement(const char *whatErrorHasHappen)
|
||||
: Exception(whatErrorHasHappen)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class NotWriteSqlStatement : public Exception
|
||||
{
|
||||
public:
|
||||
NotWriteSqlStatement(const char *whatErrorHasHappen)
|
||||
: Exception(whatErrorHasHappen)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class DeadLock : public Exception
|
||||
{
|
||||
public:
|
||||
DeadLock(const char *whatErrorHasHappen)
|
||||
: Exception(whatErrorHasHappen)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class UnknowError : public Exception
|
||||
{
|
||||
public:
|
||||
UnknowError(const char *whatErrorHasHappen,
|
||||
Utils::SmallString &&errorMessage = Utils::SmallString())
|
||||
: Exception(whatErrorHasHappen, std::move(errorMessage))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class BindingTooBig : public Exception
|
||||
{
|
||||
public:
|
||||
BindingTooBig(const char *whatErrorHasHappen,
|
||||
Utils::SmallString &&errorMessage = Utils::SmallString())
|
||||
: Exception(whatErrorHasHappen, std::move(errorMessage))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -39,7 +39,7 @@ ReadStatement::ReadStatement(Utils::SmallStringView sqlStatement,
|
||||
void ReadStatement::checkIsReadOnlyStatement()
|
||||
{
|
||||
if (!isReadOnlyStatement())
|
||||
throwException("SqliteStatement::SqliteReadStatement: is not read only statement!");
|
||||
throw NotReadOnlySqlStatement("SqliteStatement::SqliteReadStatement: is not read only statement!");
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -34,21 +34,8 @@ class SQLITE_EXPORT ReadStatement final : private Statement
|
||||
public:
|
||||
explicit ReadStatement(Utils::SmallStringView sqlStatement, Database &database);
|
||||
|
||||
using Statement::next;
|
||||
using Statement::reset;
|
||||
using Statement::value;
|
||||
using Statement::structValues;
|
||||
using Statement::tupleValues;
|
||||
using Statement::text;
|
||||
using Statement::values;
|
||||
using Statement::columnCount;
|
||||
using Statement::columnNames;
|
||||
using Statement::bind;
|
||||
using Statement::bindValues;
|
||||
using Statement::bindNameValues;
|
||||
using Statement::bindingIndexForName;
|
||||
using Statement::setBindingColumnNames;
|
||||
using Statement::bindingColumnNames;
|
||||
using Statement::toValue;
|
||||
using Statement::database;
|
||||
|
||||
|
@@ -36,22 +36,9 @@ class SQLITE_EXPORT ReadWriteStatement final : private Statement
|
||||
public:
|
||||
ReadWriteStatement(Utils::SmallStringView sqlStatement, Database &database);
|
||||
|
||||
using Statement::next;
|
||||
using Statement::execute;
|
||||
using Statement::reset;
|
||||
using Statement::bind;
|
||||
using Statement::bindValues;
|
||||
using Statement::bindNameValues;
|
||||
using Statement::bindingIndexForName;
|
||||
using Statement::setBindingColumnNames;
|
||||
using Statement::bindingColumnNames;
|
||||
using Statement::value;
|
||||
using Statement::text;
|
||||
using Statement::values;
|
||||
using Statement::structValues;
|
||||
using Statement::tupleValues;
|
||||
using Statement::columnCount;
|
||||
using Statement::columnNames;
|
||||
using Statement::toValue;
|
||||
using Statement::database;
|
||||
using Statement::write;
|
||||
|
@@ -95,19 +95,26 @@ private:
|
||||
void Statement::waitForUnlockNotify() const
|
||||
{
|
||||
UnlockNotification unlockNotification;
|
||||
int resultCode = sqlite3_unlock_notify(sqliteDatabaseHandle(), UnlockNotification::unlockNotifyCallBack, &unlockNotification);
|
||||
int resultCode = sqlite3_unlock_notify(sqliteDatabaseHandle(),
|
||||
UnlockNotification::unlockNotifyCallBack,
|
||||
&unlockNotification);
|
||||
|
||||
if (resultCode == SQLITE_LOCKED)
|
||||
throw DeadLock("SqliteStatement::waitForUnlockNotify: database is in a dead lock!");
|
||||
|
||||
if (resultCode == SQLITE_OK)
|
||||
unlockNotification.wait();
|
||||
else
|
||||
throwException("SqliteStatement::waitForUnlockNotify: database is in a dead lock!");
|
||||
}
|
||||
|
||||
void Statement::reset() const
|
||||
{
|
||||
int resultCode = sqlite3_reset(m_compiledStatement.get());
|
||||
if (resultCode != SQLITE_OK)
|
||||
throwException("SqliteStatement::reset: can't reset statement!");
|
||||
switch (resultCode) {
|
||||
case SQLITE_OK: return;
|
||||
case SQLITE_BUSY: throwStatementIsBusy("SqliteStatement::stepStatement: database engine was unable to acquire the database locks!");
|
||||
case SQLITE_ERROR : throwStatementHasError("SqliteStatement::stepStatement: run-time error (such as a constraint violation) has occurred!");
|
||||
case SQLITE_MISUSE: throwStatementIsMisused("SqliteStatement::stepStatement: was called inappropriately!");
|
||||
case SQLITE_CONSTRAINT: throwConstraintPreventsModification("SqliteStatement::stepStatement: contraint prevent insert or update!");
|
||||
}
|
||||
|
||||
m_isReadyToFetchValues = false;
|
||||
}
|
||||
@@ -160,29 +167,29 @@ Utils::SmallStringVector Statement::columnNames() const
|
||||
void Statement::bind(int index, int value)
|
||||
{
|
||||
int resultCode = sqlite3_bind_int(m_compiledStatement.get(), index, value);
|
||||
if (resultCode != SQLITE_OK)
|
||||
throwException("SqliteStatement::bind: cant' bind 32 bit integer!");
|
||||
checkForBindingError(resultCode);
|
||||
}
|
||||
|
||||
void Statement::bind(int index, long long value)
|
||||
{
|
||||
int resultCode = sqlite3_bind_int64(m_compiledStatement.get(), index, value);
|
||||
if (resultCode != SQLITE_OK)
|
||||
throwException("SqliteStatement::bind: cant' bind 64 bit integer!");
|
||||
checkForBindingError(resultCode);
|
||||
}
|
||||
|
||||
void Statement::bind(int index, double value)
|
||||
{
|
||||
int resultCode = sqlite3_bind_double(m_compiledStatement.get(), index, value);
|
||||
if (resultCode != SQLITE_OK)
|
||||
throwException("SqliteStatement::bind: cant' bind double!");
|
||||
checkForBindingError(resultCode);
|
||||
}
|
||||
|
||||
void Statement::bind(int index, Utils::SmallStringView text)
|
||||
{
|
||||
int resultCode = sqlite3_bind_text(m_compiledStatement.get(), index, text.data(), int(text.size()), SQLITE_TRANSIENT);
|
||||
if (resultCode != SQLITE_OK)
|
||||
throwException("SqliteStatement::bind: cant' bind double!");
|
||||
int resultCode = sqlite3_bind_text(m_compiledStatement.get(),
|
||||
index,
|
||||
text.data(),
|
||||
int(text.size()),
|
||||
SQLITE_STATIC);
|
||||
checkForBindingError(resultCode);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
@@ -250,13 +257,13 @@ bool Statement::checkForStepError(int resultCode) const
|
||||
switch (resultCode) {
|
||||
case SQLITE_ROW: return true;
|
||||
case SQLITE_DONE: return false;
|
||||
case SQLITE_BUSY: throwException("SqliteStatement::stepStatement: database engine was unable to acquire the database locks!");
|
||||
case SQLITE_ERROR : throwException("SqliteStatement::stepStatement: run-time error (such as a constraint violation) has occurred!");
|
||||
case SQLITE_MISUSE: throwException("SqliteStatement::stepStatement: was called inappropriately!");
|
||||
case SQLITE_CONSTRAINT: throwException("SqliteStatement::stepStatement: contraint prevent insert or update!");
|
||||
case SQLITE_BUSY: throwStatementIsBusy("SqliteStatement::stepStatement: database engine was unable to acquire the database locks!");
|
||||
case SQLITE_ERROR : throwStatementHasError("SqliteStatement::stepStatement: run-time error (such as a constraint violation) has occurred!");
|
||||
case SQLITE_MISUSE: throwStatementIsMisused("SqliteStatement::stepStatement: was called inappropriately!");
|
||||
case SQLITE_CONSTRAINT: throwConstraintPreventsModification("SqliteStatement::stepStatement: contraint prevent insert or update!");
|
||||
}
|
||||
|
||||
throwException("SqliteStatement::stepStatement: unknown error has happened");
|
||||
throwUnknowError("SqliteStatement::stepStatement: unknown error has happened");
|
||||
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
@@ -265,12 +272,24 @@ void Statement::checkForPrepareError(int resultCode) const
|
||||
{
|
||||
switch (resultCode) {
|
||||
case SQLITE_OK: return;
|
||||
case SQLITE_BUSY: throwException("SqliteStatement::prepareStatement: database engine was unable to acquire the database locks!");
|
||||
case SQLITE_ERROR : throwException("SqliteStatement::prepareStatement: run-time error (such as a constraint violation) has occurred!");
|
||||
case SQLITE_MISUSE: throwException("SqliteStatement::prepareStatement: was called inappropriately!");
|
||||
case SQLITE_BUSY: throwStatementIsBusy("SqliteStatement::prepareStatement: database engine was unable to acquire the database locks!");
|
||||
case SQLITE_ERROR : throwStatementHasError("SqliteStatement::prepareStatement: run-time error (such as a constraint violation) has occurred!");
|
||||
case SQLITE_MISUSE: throwStatementIsMisused("SqliteStatement::prepareStatement: was called inappropriately!");
|
||||
}
|
||||
|
||||
throwException("SqliteStatement::prepareStatement: unknown error has happened");
|
||||
throwUnknowError("SqliteStatement::prepareStatement: unknown error has happened");
|
||||
}
|
||||
|
||||
void Statement::checkForBindingError(int resultCode) const
|
||||
{
|
||||
switch (resultCode) {
|
||||
case SQLITE_OK: return;
|
||||
case SQLITE_TOOBIG: throwBingingTooBig("SqliteStatement::bind: string or blob are over size limits(SQLITE_LIMIT_LENGTH)!");
|
||||
case SQLITE_RANGE : throwBindingIndexIsOutOfRange("SqliteStatement::bind: binding index is out of range!");
|
||||
case SQLITE_NOMEM: throw std::bad_alloc();
|
||||
}
|
||||
|
||||
throwUnknowError("SqliteStatement::bind: unknown error has happened");
|
||||
}
|
||||
|
||||
void Statement::setIfIsReadyToFetchValues(int resultCode) const
|
||||
@@ -285,33 +304,27 @@ void Statement::setIfIsReadyToFetchValues(int resultCode) const
|
||||
void Statement::checkIfIsReadyToFetchValues() const
|
||||
{
|
||||
if (!m_isReadyToFetchValues)
|
||||
throwException("SqliteStatement::value: there are no values to fetch!");
|
||||
throwNoValuesToFetch("SqliteStatement::value: there are no values to fetch!");
|
||||
}
|
||||
|
||||
void Statement::checkColumnsAreValid(const std::vector<int> &columns) const
|
||||
{
|
||||
for (int column : columns) {
|
||||
if (column < 0 || column >= m_columnCount)
|
||||
throwException("SqliteStatement::values: column index out of bound!");
|
||||
throwInvalidColumnFetched("SqliteStatement::values: column index out of bound!");
|
||||
}
|
||||
}
|
||||
|
||||
void Statement::checkColumnIsValid(int column) const
|
||||
{
|
||||
if (column < 0 || column >= m_columnCount)
|
||||
throwException("SqliteStatement::values: column index out of bound!");
|
||||
}
|
||||
|
||||
void Statement::checkBindingIndex(int index) const
|
||||
{
|
||||
if (index <= 0 || index > m_bindingParameterCount)
|
||||
throwException("SqliteStatement::bind: binding index is out of bound!");
|
||||
throwInvalidColumnFetched("SqliteStatement::values: column index out of bound!");
|
||||
}
|
||||
|
||||
void Statement::checkBindingName(int index) const
|
||||
{
|
||||
if (index <= 0 || index > m_bindingParameterCount)
|
||||
throwException("SqliteStatement::bind: binding name are not exists in this statement!");
|
||||
throwWrongBingingName("SqliteStatement::bind: binding name are not exists in this statement!");
|
||||
}
|
||||
|
||||
void Statement::setBindingParameterCount()
|
||||
@@ -345,9 +358,57 @@ bool Statement::isReadOnlyStatement() const
|
||||
return sqlite3_stmt_readonly(m_compiledStatement.get());
|
||||
}
|
||||
|
||||
void Statement::throwException(const char *whatHasHappened) const
|
||||
void Statement::throwStatementIsBusy(const char *whatHasHappened) const
|
||||
{
|
||||
throw Exception(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
|
||||
throw StatementIsBusy(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
|
||||
}
|
||||
|
||||
void Statement::throwStatementHasError(const char *whatHasHappened) const
|
||||
{
|
||||
throw StatementHasError(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
|
||||
}
|
||||
|
||||
void Statement::throwStatementIsMisused(const char *whatHasHappened) const
|
||||
{
|
||||
throw StatementIsMisused(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
|
||||
}
|
||||
|
||||
void Statement::throwConstraintPreventsModification(const char *whatHasHappened) const
|
||||
{
|
||||
throw ContraintPreventsModification(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
|
||||
}
|
||||
|
||||
void Statement::throwNoValuesToFetch(const char *whatHasHappened) const
|
||||
{
|
||||
throw NoValuesToFetch(whatHasHappened);
|
||||
}
|
||||
|
||||
void Statement::throwInvalidColumnFetched(const char *whatHasHappened) const
|
||||
{
|
||||
throw InvalidColumnFetched(whatHasHappened);
|
||||
}
|
||||
|
||||
void Statement::throwBindingIndexIsOutOfRange(const char *whatHasHappened) const
|
||||
{
|
||||
throw BindingIndexIsOutOfRange(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
|
||||
}
|
||||
|
||||
void Statement::throwWrongBingingName(const char *whatHasHappened) const
|
||||
{
|
||||
throw WrongBingingName(whatHasHappened);
|
||||
}
|
||||
|
||||
void Statement::throwUnknowError(const char *whatHasHappened) const
|
||||
{
|
||||
if (sqliteDatabaseHandle())
|
||||
throw UnknowError(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
|
||||
else
|
||||
throw UnknowError(whatHasHappened);
|
||||
}
|
||||
|
||||
void Statement::throwBingingTooBig(const char *whatHasHappened) const
|
||||
{
|
||||
throw BindingTooBig(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
|
||||
}
|
||||
|
||||
QString Statement::columnName(int column) const
|
||||
@@ -384,8 +445,7 @@ static StringType convertToTextForColumn(sqlite3_stmt *sqlStatment, int column)
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
template<>
|
||||
int Statement::value<int>(int column) const
|
||||
int Statement::fetchIntValue(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
@@ -393,13 +453,23 @@ int Statement::value<int>(int column) const
|
||||
}
|
||||
|
||||
template<>
|
||||
long Statement::value<long>(int column) const
|
||||
int Statement::fetchValue<int>(int column) const
|
||||
{
|
||||
return long(value<long long>(column));
|
||||
return fetchIntValue(column);
|
||||
}
|
||||
|
||||
long Statement::fetchLongValue(int column) const
|
||||
{
|
||||
return long(fetchValue<long long>(column));
|
||||
}
|
||||
|
||||
template<>
|
||||
long long Statement::value<long long>(int column) const
|
||||
long Statement::fetchValue<long>(int column) const
|
||||
{
|
||||
return fetchLongValue(column);
|
||||
}
|
||||
|
||||
long long Statement::fetchLongLongValue(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
@@ -407,27 +477,48 @@ long long Statement::value<long long>(int column) const
|
||||
}
|
||||
|
||||
template<>
|
||||
double Statement::value<double>(int column) const
|
||||
long long Statement::fetchValue<long long>(int column) const
|
||||
{
|
||||
return fetchLongLongValue(column);
|
||||
}
|
||||
|
||||
double Statement::fetchDoubleValue(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
return sqlite3_column_double(m_compiledStatement.get(), column);
|
||||
}
|
||||
|
||||
template<>
|
||||
double Statement::fetchValue<double>(int column) const
|
||||
{
|
||||
return fetchDoubleValue(column);
|
||||
}
|
||||
|
||||
template<typename StringType>
|
||||
StringType Statement::value(int column) const
|
||||
StringType Statement::fetchValue(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
return convertToTextForColumn<StringType>(m_compiledStatement.get(), column);
|
||||
}
|
||||
|
||||
template SQLITE_EXPORT Utils::SmallString Statement::value<Utils::SmallString>(int column) const;
|
||||
template SQLITE_EXPORT Utils::PathString Statement::value<Utils::PathString>(int column) const;
|
||||
Utils::SmallString Statement::fetchSmallStringValue(int column) const
|
||||
{
|
||||
return fetchValue<Utils::SmallString>(column);
|
||||
}
|
||||
|
||||
Utils::PathString Statement::fetchPathStringValue(int column) const
|
||||
{
|
||||
return fetchValue<Utils::PathString>(column);
|
||||
}
|
||||
|
||||
template SQLITE_EXPORT Utils::SmallString Statement::fetchValue<Utils::SmallString>(int column) const;
|
||||
template SQLITE_EXPORT Utils::PathString Statement::fetchValue<Utils::PathString>(int column) const;
|
||||
|
||||
Utils::SmallString Statement::text(int column) const
|
||||
{
|
||||
return value<Utils::SmallString>(column);
|
||||
return fetchValue<Utils::SmallString>(column);
|
||||
}
|
||||
|
||||
template <typename ContainerType>
|
||||
@@ -437,7 +528,7 @@ ContainerType Statement::columnValues(const std::vector<int> &columnIndices) con
|
||||
ContainerType valueContainer;
|
||||
valueContainer.reserve(columnIndices.size());
|
||||
for (int columnIndex : columnIndices)
|
||||
valueContainer.push_back(value<ElementType>(columnIndex));
|
||||
valueContainer.push_back(fetchValue<ElementType>(columnIndex));
|
||||
|
||||
return valueContainer;
|
||||
}
|
||||
@@ -449,7 +540,7 @@ Type Statement::toValue(Utils::SmallStringView sqlStatement, Database &database)
|
||||
|
||||
statement.next();
|
||||
|
||||
return statement.value<Type>(0);
|
||||
return statement.fetchValue<Type>(0);
|
||||
}
|
||||
|
||||
template SQLITE_EXPORT int Statement::toValue<int>(Utils::SmallStringView sqlStatement, Database &database);
|
||||
|
@@ -31,6 +31,8 @@
|
||||
|
||||
#include <utils/smallstringvector.h>
|
||||
|
||||
#include <utils/optional.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
@@ -58,16 +60,22 @@ protected:
|
||||
void execute() const;
|
||||
void reset() const;
|
||||
|
||||
int fetchIntValue(int column) const;
|
||||
long fetchLongValue(int column) const;
|
||||
long long fetchLongLongValue(int column) const;
|
||||
double fetchDoubleValue(int column) const;
|
||||
Utils::SmallString fetchSmallStringValue(int column) const;
|
||||
Utils::PathString fetchPathStringValue(int column) const;
|
||||
template<typename Type>
|
||||
Type value(int column) const;
|
||||
Type fetchValue(int column) const;
|
||||
Utils::SmallString text(int column) const;
|
||||
int columnCount() const;
|
||||
Utils::SmallStringVector columnNames() const;
|
||||
|
||||
void bind(int index, int value);
|
||||
void bind(int index, long long value);
|
||||
void bind(int index, double value);
|
||||
void bind(int index, Utils::SmallStringView value);
|
||||
void bind(int index, int fetchValue);
|
||||
void bind(int index, long long fetchValue);
|
||||
void bind(int index, double fetchValue);
|
||||
void bind(int index, Utils::SmallStringView fetchValue);
|
||||
|
||||
void bind(int index, uint value)
|
||||
{
|
||||
@@ -84,202 +92,48 @@ protected:
|
||||
}
|
||||
|
||||
template<typename... ValueType>
|
||||
void bindValues(ValueType... values)
|
||||
void bindValues(const ValueType&... values)
|
||||
{
|
||||
bindValuesByIndex(1, values...);
|
||||
}
|
||||
|
||||
template<typename... ValueType>
|
||||
void write(ValueType... values)
|
||||
void write(const ValueType&... values)
|
||||
{
|
||||
bindValuesByIndex(1, values...);
|
||||
execute();
|
||||
}
|
||||
|
||||
template<typename... ValueType>
|
||||
void bindNameValues(ValueType... values)
|
||||
void bindNameValues(const ValueType&... values)
|
||||
{
|
||||
bindValuesByName(values...);
|
||||
}
|
||||
|
||||
template<typename... ValueType>
|
||||
void writeNamed(ValueType... values)
|
||||
void writeNamed(const ValueType&... values)
|
||||
{
|
||||
bindValuesByName(values...);
|
||||
execute();
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void bind(Utils::SmallStringView name, Type value);
|
||||
void bind(Utils::SmallStringView name, Type fetchValue);
|
||||
|
||||
int bindingIndexForName(Utils::SmallStringView name) const;
|
||||
|
||||
void setBindingColumnNames(const Utils::SmallStringVector &bindingColumnNames);
|
||||
const Utils::SmallStringVector &bindingColumnNames() const;
|
||||
|
||||
template <typename... ResultTypes>
|
||||
std::vector<std::tuple<ResultTypes...>> tupleValues(std::size_t reserveSize)
|
||||
{
|
||||
using Container = std::vector<std::tuple<ResultTypes...>>;
|
||||
Container resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
while (next())
|
||||
emplaceTupleValues<Container, ResultTypes...>(resultValues);
|
||||
|
||||
reset();
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename... ResultTypes,
|
||||
typename... QueryTypes>
|
||||
std::vector<std::tuple<ResultTypes...>> tupleValues(std::size_t reserveSize, const QueryTypes&... queryValues)
|
||||
{
|
||||
using Container = std::vector<std::tuple<ResultTypes...>>;
|
||||
Container resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
bindValues(queryValues...);
|
||||
|
||||
while (next())
|
||||
emplaceTupleValues<Container, ResultTypes...>(resultValues);
|
||||
|
||||
reset();
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename... ResultTypes,
|
||||
typename... QueryElementTypes>
|
||||
std::vector<std::tuple<ResultTypes...>> tupleValues(std::size_t reserveSize,
|
||||
const std::vector<std::tuple<QueryElementTypes...>> &queryTuples)
|
||||
{
|
||||
using Container = std::vector<std::tuple<ResultTypes...>>;
|
||||
Container resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
for (const auto &queryTuple : queryTuples) {
|
||||
bindTupleValues(queryTuple);
|
||||
|
||||
while (next())
|
||||
emplaceTupleValues<Container, ResultTypes...>(resultValues);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename... ResultTypes,
|
||||
typename QueryElementType>
|
||||
std::vector<std::tuple<ResultTypes...>> tupleValues(std::size_t reserveSize,
|
||||
const std::vector<QueryElementType> &queryValues)
|
||||
{
|
||||
using Container = std::vector<std::tuple<ResultTypes...>>;
|
||||
Container resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
for (const QueryElementType &queryValue : queryValues) {
|
||||
bindValues(queryValue);
|
||||
|
||||
while (next())
|
||||
emplaceTupleValues<Container, ResultTypes...>(resultValues);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
typename... ResultEntryTypes>
|
||||
std::vector<ResultType> structValues(std::size_t reserveSize)
|
||||
{
|
||||
using Container = std::vector<ResultType>;
|
||||
Container resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
while (next())
|
||||
pushBackStructValues<Container, ResultEntryTypes...>(resultValues);
|
||||
|
||||
reset();
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
typename... ResultEntryTypes,
|
||||
typename... QueryTypes>
|
||||
std::vector<ResultType> structValues(std::size_t reserveSize, const QueryTypes&... queryValues)
|
||||
{
|
||||
using Container = std::vector<ResultType>;
|
||||
Container resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
bindValues(queryValues...);
|
||||
|
||||
while (next())
|
||||
pushBackStructValues<Container, ResultEntryTypes...>(resultValues);
|
||||
|
||||
reset();
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
typename... ResultEntryTypes,
|
||||
typename QueryElementType>
|
||||
std::vector<ResultType> structValues(std::size_t reserveSize,
|
||||
const std::vector<QueryElementType> &queryValues)
|
||||
{
|
||||
using Container = std::vector<ResultType>;
|
||||
Container resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
for (const QueryElementType &queryValue : queryValues) {
|
||||
bindValues(queryValue);
|
||||
|
||||
while (next())
|
||||
pushBackStructValues<Container, ResultEntryTypes...>(resultValues);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
typename... ResultEntryTypes,
|
||||
typename... QueryElementTypes>
|
||||
std::vector<ResultType> structValues(std::size_t reserveSize,
|
||||
const std::vector<std::tuple<QueryElementTypes...>> &queryTuples)
|
||||
{
|
||||
using Container = std::vector<ResultType>;
|
||||
Container resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
for (const auto &queryTuple : queryTuples) {
|
||||
bindTupleValues(queryTuple);
|
||||
|
||||
while (next())
|
||||
pushBackStructValues<Container, ResultEntryTypes...>(resultValues);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
typename... ElementTypes>
|
||||
int ResultTypeCount = 1>
|
||||
std::vector<ResultType> values(std::size_t reserveSize)
|
||||
{
|
||||
std::vector<ResultType> resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
while (next())
|
||||
resultValues.push_back(value<ResultType>(0));
|
||||
emplaceBackValues<ResultTypeCount>(resultValues);
|
||||
|
||||
reset();
|
||||
|
||||
@@ -287,46 +141,7 @@ protected:
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
typename... ElementType>
|
||||
std::vector<ResultType> values(std::size_t reserveSize,
|
||||
const std::vector<std::tuple<ElementType...>> &queryTuples)
|
||||
{
|
||||
std::vector<ResultType> resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
for (const auto &queryTuple : queryTuples) {
|
||||
bindTupleValues(queryTuple);
|
||||
|
||||
while (next())
|
||||
resultValues.push_back(value<ResultType>(0));
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
typename ElementType>
|
||||
std::vector<ResultType> values(std::size_t reserveSize,
|
||||
const std::vector<ElementType> &queryValues)
|
||||
{
|
||||
std::vector<ResultType> resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
for (const ElementType &queryValue : queryValues) {
|
||||
bindValues(queryValue);
|
||||
|
||||
while (next())
|
||||
resultValues.push_back(value<ResultType>(0));
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
int ResultTypeCount = 1,
|
||||
typename... QueryTypes>
|
||||
std::vector<ResultType> values(std::size_t reserveSize, const QueryTypes&... queryValues)
|
||||
{
|
||||
@@ -336,13 +151,73 @@ protected:
|
||||
bindValues(queryValues...);
|
||||
|
||||
while (next())
|
||||
resultValues.push_back(value<ResultType>(0));
|
||||
emplaceBackValues<ResultTypeCount>(resultValues);
|
||||
|
||||
reset();
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
int ResultTypeCount = 1,
|
||||
typename QueryElementType>
|
||||
std::vector<ResultType> values(std::size_t reserveSize,
|
||||
const std::vector<QueryElementType> &queryValues)
|
||||
{
|
||||
std::vector<ResultType> resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
for (const QueryElementType &queryValue : queryValues) {
|
||||
bindValues(queryValue);
|
||||
|
||||
while (next())
|
||||
emplaceBackValues<ResultTypeCount>(resultValues);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
int ResultTypeCount = 1,
|
||||
typename... QueryElementTypes>
|
||||
std::vector<ResultType> values(std::size_t reserveSize,
|
||||
const std::vector<std::tuple<QueryElementTypes...>> &queryTuples)
|
||||
{
|
||||
using Container = std::vector<ResultType>;
|
||||
Container resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
for (const auto &queryTuple : queryTuples) {
|
||||
bindTupleValues(queryTuple);
|
||||
|
||||
while (next())
|
||||
emplaceBackValues<ResultTypeCount>(resultValues);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
int ResultTypeCount = 1,
|
||||
typename... QueryTypes>
|
||||
Utils::optional<ResultType> value( const QueryTypes&... queryValues)
|
||||
{
|
||||
Utils::optional<ResultType> resultValue;
|
||||
|
||||
bindValues(queryValues...);
|
||||
|
||||
if (next())
|
||||
resultValue = assignValue<Utils::optional<ResultType>, ResultTypeCount>();
|
||||
|
||||
reset();
|
||||
|
||||
return resultValue;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
static Type toValue(Utils::SmallStringView sqlStatement, Database &database);
|
||||
|
||||
@@ -352,20 +227,28 @@ protected:
|
||||
sqlite3 *sqliteDatabaseHandle() const;
|
||||
TextEncoding databaseTextEncoding();
|
||||
|
||||
|
||||
bool checkForStepError(int resultCode) const;
|
||||
void checkForPrepareError(int resultCode) const;
|
||||
void checkForBindingError(int resultCode) const;
|
||||
void setIfIsReadyToFetchValues(int resultCode) const;
|
||||
void checkIfIsReadyToFetchValues() const;
|
||||
void checkColumnsAreValid(const std::vector<int> &columns) const;
|
||||
void checkColumnIsValid(int column) const;
|
||||
void checkBindingIndex(int index) const;
|
||||
void checkBindingName(int index) const;
|
||||
void setBindingParameterCount();
|
||||
void setBindingColumnNamesFromStatement();
|
||||
void setColumnCount();
|
||||
bool isReadOnlyStatement() const;
|
||||
Q_NORETURN void throwException(const char *whatHasHappened) const;
|
||||
[[noreturn]] void throwStatementIsBusy(const char *whatHasHappened) const;
|
||||
[[noreturn]] void throwStatementHasError(const char *whatHasHappened) const;
|
||||
[[noreturn]] void throwStatementIsMisused(const char *whatHasHappened) const;
|
||||
[[noreturn]] void throwConstraintPreventsModification(const char *whatHasHappened) const;
|
||||
[[noreturn]] void throwNoValuesToFetch(const char *whatHasHappened) const;
|
||||
[[noreturn]] void throwInvalidColumnFetched(const char *whatHasHappened) const;
|
||||
[[noreturn]] void throwBindingIndexIsOutOfRange(const char *whatHasHappened) const;
|
||||
[[noreturn]] void throwWrongBingingName(const char *whatHasHappened) const;
|
||||
[[noreturn]] void throwUnknowError(const char *whatHasHappened) const;
|
||||
[[noreturn]] void throwBingingTooBig(const char *whatHasHappened) const;
|
||||
|
||||
template <typename ContainerType>
|
||||
ContainerType columnValues(const std::vector<int> &columnIndices) const;
|
||||
@@ -379,58 +262,97 @@ protected:
|
||||
DatabaseBackend &databaseBackend);
|
||||
|
||||
private:
|
||||
class ValueGetter
|
||||
{
|
||||
public:
|
||||
ValueGetter(Statement &statement, int column)
|
||||
: statement(statement),
|
||||
column(column)
|
||||
{}
|
||||
|
||||
operator int()
|
||||
{
|
||||
return statement.fetchIntValue(column);
|
||||
}
|
||||
|
||||
operator long()
|
||||
{
|
||||
return statement.fetchLongValue(column);
|
||||
}
|
||||
|
||||
operator long long()
|
||||
{
|
||||
return statement.fetchLongLongValue(column);
|
||||
}
|
||||
|
||||
operator double()
|
||||
{
|
||||
return statement.fetchDoubleValue(column);
|
||||
}
|
||||
|
||||
operator Utils::SmallString()
|
||||
{
|
||||
return statement.fetchSmallStringValue(column);
|
||||
}
|
||||
|
||||
operator Utils::PathString()
|
||||
{
|
||||
return statement.fetchPathStringValue(column);
|
||||
}
|
||||
|
||||
Statement &statement;
|
||||
int column;
|
||||
};
|
||||
|
||||
template <typename ContainerType,
|
||||
typename... ResultTypes,
|
||||
int... ColumnIndices>
|
||||
void emplaceTupleValues(ContainerType &container, std::integer_sequence<int, ColumnIndices...>)
|
||||
void emplaceBackValues(ContainerType &container, std::integer_sequence<int, ColumnIndices...>)
|
||||
{
|
||||
container.emplace_back(value<ResultTypes>(ColumnIndices)...);
|
||||
container.emplace_back(ValueGetter(*this, ColumnIndices)...);
|
||||
}
|
||||
|
||||
template <typename ContainerType,
|
||||
typename... ResultTypes>
|
||||
void emplaceTupleValues(ContainerType &container)
|
||||
template <int ResultTypeCount,
|
||||
typename ContainerType>
|
||||
void emplaceBackValues(ContainerType &container)
|
||||
{
|
||||
emplaceTupleValues<ContainerType, ResultTypes...>(container, std::make_integer_sequence<int, sizeof...(ResultTypes)>{});
|
||||
emplaceBackValues(container, std::make_integer_sequence<int, ResultTypeCount>{});
|
||||
}
|
||||
|
||||
template <typename ContainerType,
|
||||
typename... ResultEntryTypes,
|
||||
template <typename ResultOptionalType,
|
||||
int... ColumnIndices>
|
||||
void pushBackStructValues(ContainerType &container, std::integer_sequence<int, ColumnIndices...>)
|
||||
ResultOptionalType assignValue(std::integer_sequence<int, ColumnIndices...>)
|
||||
{
|
||||
using ResultType = typename ContainerType::value_type;
|
||||
container.push_back(ResultType{value<ResultEntryTypes>(ColumnIndices)...});
|
||||
return ResultOptionalType(Utils::in_place, ValueGetter(*this, ColumnIndices)...);
|
||||
}
|
||||
|
||||
template <typename ContainerType,
|
||||
typename... ResultEntryTypes>
|
||||
void pushBackStructValues(ContainerType &container)
|
||||
template <typename ResultOptionalType,
|
||||
int ResultTypeCount>
|
||||
ResultOptionalType assignValue()
|
||||
{
|
||||
pushBackStructValues<ContainerType, ResultEntryTypes...>(container, std::make_integer_sequence<int, sizeof...(ResultEntryTypes)>{});
|
||||
return assignValue<ResultOptionalType>(std::make_integer_sequence<int, ResultTypeCount>{});
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
void bindValuesByIndex(int index, ValueType value)
|
||||
void bindValuesByIndex(int index, const ValueType &value)
|
||||
{
|
||||
bind(index, value);
|
||||
}
|
||||
|
||||
template<typename ValueType, typename... ValueTypes>
|
||||
void bindValuesByIndex(int index, ValueType value, ValueTypes... values)
|
||||
void bindValuesByIndex(int index, const ValueType &value, const ValueTypes&... values)
|
||||
{
|
||||
bind(index, value);
|
||||
bindValuesByIndex(index + 1, values...);
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
void bindValuesByName(Utils::SmallStringView name, ValueType value)
|
||||
void bindValuesByName(Utils::SmallStringView name, const ValueType &value)
|
||||
{
|
||||
bind(bindingIndexForName(name), value);
|
||||
}
|
||||
|
||||
template<typename ValueType, typename... ValueTypes>
|
||||
void bindValuesByName(Utils::SmallStringView name, ValueType value, ValueTypes... values)
|
||||
void bindValuesByName(Utils::SmallStringView name, const ValueType &value, const ValueTypes&... values)
|
||||
{
|
||||
bind(bindingIndexForName(name), value);
|
||||
bindValuesByName(values...);
|
||||
@@ -469,10 +391,10 @@ extern template SQLITE_EXPORT long long Statement::toValue<long long>(Utils::Sma
|
||||
extern template SQLITE_EXPORT double Statement::toValue<double>(Utils::SmallStringView sqlStatement, Database &database);
|
||||
extern template SQLITE_EXPORT Utils::SmallString Statement::toValue<Utils::SmallString>(Utils::SmallStringView sqlStatement, Database &database);
|
||||
|
||||
template <> SQLITE_EXPORT int Statement::value<int>(int column) const;
|
||||
template <> SQLITE_EXPORT long Statement::value<long>(int column) const;
|
||||
template <> SQLITE_EXPORT long long Statement::value<long long>(int column) const;
|
||||
template <> SQLITE_EXPORT double Statement::value<double>(int column) const;
|
||||
extern template SQLITE_EXPORT Utils::SmallString Statement::value<Utils::SmallString>(int column) const;
|
||||
extern template SQLITE_EXPORT Utils::PathString Statement::value<Utils::PathString>(int column) const;
|
||||
template <> SQLITE_EXPORT int Statement::fetchValue<int>(int column) const;
|
||||
template <> SQLITE_EXPORT long Statement::fetchValue<long>(int column) const;
|
||||
template <> SQLITE_EXPORT long long Statement::fetchValue<long long>(int column) const;
|
||||
template <> SQLITE_EXPORT double Statement::fetchValue<double>(int column) const;
|
||||
extern template SQLITE_EXPORT Utils::SmallString Statement::fetchValue<Utils::SmallString>(int column) const;
|
||||
extern template SQLITE_EXPORT Utils::PathString Statement::fetchValue<Utils::PathString>(int column) const;
|
||||
} // namespace Sqlite
|
||||
|
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "sqliteglobal.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
class DatabaseBackend;
|
||||
@@ -50,11 +52,13 @@ public:
|
||||
|
||||
protected:
|
||||
AbstractTransaction(Database &database)
|
||||
: m_database(database)
|
||||
: m_databaseLock(database.databaseMutex()),
|
||||
m_database(database)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
std::lock_guard<typename Database::MutexType> m_databaseLock;
|
||||
Database &m_database;
|
||||
bool m_isAlreadyCommited = false;
|
||||
};
|
||||
|
@@ -37,7 +37,7 @@ WriteStatement::WriteStatement(Utils::SmallStringView sqlStatement,
|
||||
void WriteStatement::checkIsWritableStatement()
|
||||
{
|
||||
if (isReadOnlyStatement())
|
||||
throwException("SqliteStatement::SqliteWriteStatement: is not a writable statement!");
|
||||
throw NotWriteSqlStatement("SqliteStatement::SqliteWriteStatement: is not a writable statement!");
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -35,13 +35,6 @@ public:
|
||||
explicit WriteStatement(Utils::SmallStringView sqlStatement, Database &database);
|
||||
|
||||
using Statement::execute;
|
||||
using Statement::reset;
|
||||
using Statement::bind;
|
||||
using Statement::bindValues;
|
||||
using Statement::bindNameValues;
|
||||
using Statement::bindingIndexForName;
|
||||
using Statement::setBindingColumnNames;
|
||||
using Statement::bindingColumnNames;
|
||||
using Statement::database;
|
||||
using Statement::write;
|
||||
using Statement::writeNamed;
|
||||
|
@@ -72,6 +72,7 @@ QRegularExpression CamelHumpMatcher::createCamelHumpRegExp(
|
||||
const QLatin1String lowercaseWordFirst("(?<=\\b|[A-Z0-9_])");
|
||||
const QLatin1String uppercaseWordContinuation("[a-z0-9_]*");
|
||||
const QLatin1String lowercaseWordContinuation("(?:[a-zA-Z0-9]*_)?");
|
||||
const QLatin1String upperSnakeWordContinuation("[A-Z0-9]*_");
|
||||
for (const QChar &c : pattern) {
|
||||
if (!c.isLetter()) {
|
||||
if (c == question)
|
||||
@@ -90,7 +91,9 @@ QRegularExpression CamelHumpMatcher::createCamelHumpRegExp(
|
||||
keyRegExp += '|' + lowercaseWordFirst + QRegularExpression::escape(c.toLower()) + ')';
|
||||
} else {
|
||||
keyRegExp += ")|" + lowercaseWordContinuation;
|
||||
keyRegExp += '(' + QRegularExpression::escape(c.toLower()) + ')';
|
||||
keyRegExp += '(' + QRegularExpression::escape(c.toLower()) + ")|";
|
||||
keyRegExp += upperSnakeWordContinuation;
|
||||
keyRegExp += '(' + QRegularExpression::escape(c.toUpper()) + ')';
|
||||
}
|
||||
keyRegExp += ')';
|
||||
} else {
|
||||
|
@@ -41,6 +41,8 @@ namespace Utils {
|
||||
using std::experimental::optional;
|
||||
// --> Utils::nullopt
|
||||
using std::experimental::nullopt;
|
||||
// --> Utils::in_place
|
||||
using std::experimental::in_place;
|
||||
|
||||
// TODO: make_optional is a copy, since there is no sensible way to import functions in C++
|
||||
template <class T>
|
||||
|
@@ -322,22 +322,22 @@ public:
|
||||
|
||||
reverse_iterator rbegin() noexcept
|
||||
{
|
||||
return reverse_iterator(end() - static_cast<std::size_t>(1));
|
||||
return reverse_iterator(end());
|
||||
}
|
||||
|
||||
reverse_iterator rend() noexcept
|
||||
{
|
||||
return reverse_iterator(begin() - static_cast<std::size_t>(1));
|
||||
return reverse_iterator(begin());
|
||||
}
|
||||
|
||||
const_reverse_iterator rbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(end() - static_cast<std::size_t>(1));
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
|
||||
const_reverse_iterator rend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(begin() - static_cast<std::size_t>(1));
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
const_iterator begin() const noexcept
|
||||
|
@@ -80,12 +80,12 @@ public:
|
||||
|
||||
const_reverse_iterator rbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(end() - static_cast<std::size_t>(1));
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
|
||||
const_reverse_iterator rend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(begin() - static_cast<std::size_t>(1));
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
constexpr static
|
||||
|
@@ -97,6 +97,12 @@ public:
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
constexpr
|
||||
size_type empty() const noexcept
|
||||
{
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
constexpr
|
||||
const_iterator begin() const noexcept
|
||||
{
|
||||
@@ -111,12 +117,12 @@ public:
|
||||
|
||||
const_reverse_iterator rbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(end() - static_cast<std::size_t>(1));
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
|
||||
const_reverse_iterator rend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(begin() - static_cast<std::size_t>(1));
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
operator std::string() const
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include <QFileInfo>
|
||||
#include <QCommonStyle>
|
||||
#include <QStyleOption>
|
||||
#include <QWindow>
|
||||
#include <qmath.h>
|
||||
|
||||
// Clamps float color values within (0, 255)
|
||||
@@ -397,7 +398,9 @@ void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect,
|
||||
QPainter *p, QIcon::Mode iconMode, int dipRadius, const QColor &color, const QPoint &dipOffset)
|
||||
{
|
||||
QPixmap cache;
|
||||
QString pixmapName = QString::fromLatin1("icon %0 %1 %2").arg(icon.cacheKey()).arg(iconMode).arg(rect.height());
|
||||
const int devicePixelRatio = p->device()->devicePixelRatio();
|
||||
QString pixmapName = QString::fromLatin1("icon %0 %1 %2 %3")
|
||||
.arg(icon.cacheKey()).arg(iconMode).arg(rect.height()).arg(devicePixelRatio);
|
||||
|
||||
if (!QPixmapCache::find(pixmapName, cache)) {
|
||||
// High-dpi support: The in parameters (rect, radius, offset) are in
|
||||
@@ -405,9 +408,8 @@ void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect,
|
||||
// return a high-dpi pixmap, which will in that case have a devicePixelRatio
|
||||
// different than 1. The shadow drawing caluculations are done in device
|
||||
// pixels.
|
||||
QWindow *window = QApplication::allWidgets().first()->windowHandle();
|
||||
QWindow *window = dynamic_cast<QWidget*>(p->device())->window()->windowHandle();
|
||||
QPixmap px = icon.pixmap(window, rect.size(), iconMode);
|
||||
int devicePixelRatio = qCeil(px.devicePixelRatio());
|
||||
int radius = dipRadius * devicePixelRatio;
|
||||
QPoint offset = dipOffset * devicePixelRatio;
|
||||
cache = QPixmap(px.size() + QSize(radius * 2, radius * 2));
|
||||
@@ -415,7 +417,8 @@ void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect,
|
||||
|
||||
QPainter cachePainter(&cache);
|
||||
if (iconMode == QIcon::Disabled) {
|
||||
const bool hasDisabledState = icon.availableSizes(QIcon::Disabled).contains(px.size());
|
||||
const bool hasDisabledState =
|
||||
icon.availableSizes().count() == icon.availableSizes(QIcon::Disabled).count();
|
||||
if (!hasDisabledState)
|
||||
px = disabledSideBarIcon(icon.pixmap(window, rect.size()));
|
||||
} else if (creatorTheme()->flag(Theme::ToolBarIconShadow)) {
|
||||
|
@@ -23,14 +23,14 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "convenience.h"
|
||||
#include "textutils.h"
|
||||
|
||||
#include <QTextDocument>
|
||||
#include <QTextBlock>
|
||||
#include <QTextCursor>
|
||||
|
||||
namespace TextEditor {
|
||||
namespace Convenience {
|
||||
namespace Utils {
|
||||
namespace Text {
|
||||
|
||||
bool convertPosition(const QTextDocument *document, int pos, int *line, int *column)
|
||||
{
|
||||
@@ -121,5 +121,5 @@ QTextCursor wordStartCursor(const QTextCursor &textCursor)
|
||||
return cursor;
|
||||
}
|
||||
|
||||
} // Util
|
||||
} // TextEditor
|
||||
} // Text
|
||||
} // Utils
|
@@ -25,30 +25,28 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "texteditor_global.h"
|
||||
#include "utils_global.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QTextDocument;
|
||||
class QTextCursor;
|
||||
QT_END_NAMESPACE
|
||||
QT_FORWARD_DECLARE_CLASS(QTextDocument)
|
||||
QT_FORWARD_DECLARE_CLASS(QTextCursor)
|
||||
|
||||
namespace TextEditor {
|
||||
namespace Convenience {
|
||||
namespace Utils {
|
||||
namespace Text {
|
||||
|
||||
// line is 1-based, column is 0-based
|
||||
TEXTEDITOR_EXPORT bool convertPosition(const QTextDocument *document,
|
||||
QTCREATOR_UTILS_EXPORT bool convertPosition(const QTextDocument *document,
|
||||
int pos,
|
||||
int *line, int *column);
|
||||
|
||||
TEXTEDITOR_EXPORT QString textAt(QTextCursor tc, int pos, int length);
|
||||
QTCREATOR_UTILS_EXPORT QString textAt(QTextCursor tc, int pos, int length);
|
||||
|
||||
TEXTEDITOR_EXPORT QTextCursor selectAt(QTextCursor textCursor, uint line, uint column, uint length);
|
||||
QTCREATOR_UTILS_EXPORT QTextCursor selectAt(QTextCursor textCursor, uint line, uint column, uint length);
|
||||
|
||||
TEXTEDITOR_EXPORT QTextCursor flippedCursor(const QTextCursor &cursor);
|
||||
QTCREATOR_UTILS_EXPORT QTextCursor flippedCursor(const QTextCursor &cursor);
|
||||
|
||||
TEXTEDITOR_EXPORT QTextCursor wordStartCursor(const QTextCursor &cursor);
|
||||
QTCREATOR_UTILS_EXPORT QTextCursor wordStartCursor(const QTextCursor &cursor);
|
||||
|
||||
} // Util
|
||||
} // TextEditor
|
||||
} // Text
|
||||
} // Utils
|
@@ -115,7 +115,8 @@ SOURCES += $$PWD/environment.cpp \
|
||||
$$PWD/utilsicons.cpp \
|
||||
$$PWD/guard.cpp \
|
||||
$$PWD/highlightingitemdelegate.cpp \
|
||||
$$PWD/camelhumpmatcher.cpp
|
||||
$$PWD/camelhumpmatcher.cpp \
|
||||
$$PWD/textutils.cpp
|
||||
|
||||
win32:SOURCES += $$PWD/consoleprocess_win.cpp
|
||||
else:SOURCES += $$PWD/consoleprocess_unix.cpp
|
||||
@@ -244,7 +245,8 @@ HEADERS += \
|
||||
$$PWD/../3rdparty/optional/optional.hpp \
|
||||
$$PWD/qtcfallthrough.h \
|
||||
$$PWD/highlightingitemdelegate.h \
|
||||
$$PWD/camelhumpmatcher.h
|
||||
$$PWD/camelhumpmatcher.h \
|
||||
$$PWD/textutils.h
|
||||
|
||||
FORMS += $$PWD/filewizardpage.ui \
|
||||
$$PWD/projectintropage.ui \
|
||||
|
@@ -232,6 +232,8 @@ Project {
|
||||
"textfieldcombobox.h",
|
||||
"textfileformat.cpp",
|
||||
"textfileformat.h",
|
||||
"textutils.cpp",
|
||||
"textutils.h",
|
||||
"treemodel.cpp",
|
||||
"treemodel.h",
|
||||
"treeviewcombobox.cpp",
|
||||
|
@@ -293,6 +293,7 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunControl *runControl, const AndroidRu
|
||||
QTC_ASSERT(server.listen(QHostAddress::LocalHost)
|
||||
|| server.listen(QHostAddress::LocalHostIPv6),
|
||||
qDebug() << tr("No free ports available on host for QML debugging."));
|
||||
m_qmlServer.setScheme(urlTcpScheme());
|
||||
m_qmlServer.setHost(server.serverAddress().toString());
|
||||
m_qmlServer.setPort(server.serverPort());
|
||||
}
|
||||
|
@@ -213,7 +213,7 @@ QString AndroidToolChain::makeCommand(const Environment &env) const
|
||||
if (HostOsInfo::isWindowsHost()) {
|
||||
FileName tmp = env.searchInPath(QLatin1String("ma-make.exe"), extraDirectories);
|
||||
if (!tmp.isEmpty())
|
||||
return QString();
|
||||
return tmp.toString();
|
||||
tmp = env.searchInPath(QLatin1String("mingw32-make"), extraDirectories);
|
||||
return tmp.isEmpty() ? QLatin1String("mingw32-make") : tmp.toString();
|
||||
}
|
||||
|
Before Width: | Height: | Size: 211 B After Width: | Height: | Size: 216 B |
Before Width: | Height: | Size: 255 B After Width: | Height: | Size: 259 B |
Before Width: | Height: | Size: 184 B After Width: | Height: | Size: 185 B |
Before Width: | Height: | Size: 277 B After Width: | Height: | Size: 280 B |
@@ -45,12 +45,12 @@
|
||||
#include <diffeditor/differ.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/projecttree.h>
|
||||
#include <texteditor/convenience.h>
|
||||
#include <texteditor/textdocument.h>
|
||||
#include <texteditor/textdocumentlayout.h>
|
||||
#include <texteditor/texteditor.h>
|
||||
#include <texteditor/texteditorconstants.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/textutils.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/mimetypes/mimedatabase.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -169,7 +169,7 @@ QString sourceData(TextEditorWidget *editor, int startPos, int endPos)
|
||||
{
|
||||
return (startPos < 0)
|
||||
? editor->toPlainText()
|
||||
: Convenience::textAt(editor->textCursor(), startPos, (endPos - startPos));
|
||||
: Utils::Text::textAt(editor->textCursor(), startPos, (endPos - startPos));
|
||||
}
|
||||
|
||||
bool isAutoFormatApplicable(const Core::IDocument *document,
|
||||
@@ -496,6 +496,18 @@ QString BeautifierPlugin::msgFormatSelectedText()
|
||||
return tr("Format &Selected Text");
|
||||
}
|
||||
|
||||
QString BeautifierPlugin::msgFormatAtCursor()
|
||||
{
|
||||
//: Menu entry
|
||||
return tr("&Format at Cursor");
|
||||
}
|
||||
|
||||
QString BeautifierPlugin::msgDisableFormattingSelectedText()
|
||||
{
|
||||
//: Menu entry
|
||||
return tr("&Disable Formatting for Selected Text");
|
||||
}
|
||||
|
||||
QString BeautifierPlugin::msgCommandPromptDialogTitle(const QString &command)
|
||||
{
|
||||
//: File dialog title for path chooser when choosing binary
|
||||
|
@@ -80,6 +80,8 @@ public:
|
||||
static QString msgCannotGetConfigurationFile(const QString &command);
|
||||
static QString msgFormatCurrentFile();
|
||||
static QString msgFormatSelectedText();
|
||||
static QString msgFormatAtCursor();
|
||||
static QString msgDisableFormattingSelectedText();
|
||||
static QString msgCommandPromptDialogTitle(const QString &command);
|
||||
static void showError(const QString &error);
|
||||
|
||||
|
@@ -48,6 +48,7 @@
|
||||
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
#include <QTextBlock>
|
||||
|
||||
namespace Beautifier {
|
||||
namespace Internal {
|
||||
@@ -82,11 +83,19 @@ bool ClangFormat::initialize()
|
||||
menu->addAction(cmd);
|
||||
connect(m_formatFile, &QAction::triggered, this, &ClangFormat::formatFile);
|
||||
|
||||
m_formatRange = new QAction(BeautifierPlugin::msgFormatSelectedText(), this);
|
||||
m_formatRange = new QAction(BeautifierPlugin::msgFormatAtCursor(), this);
|
||||
cmd = Core::ActionManager::registerAction(m_formatRange,
|
||||
Constants::ClangFormat::ACTION_FORMATSELECTED);
|
||||
Constants::ClangFormat::ACTION_FORMATATCURSOR);
|
||||
menu->addAction(cmd);
|
||||
connect(m_formatRange, &QAction::triggered, this, &ClangFormat::formatSelectedText);
|
||||
connect(m_formatRange, &QAction::triggered, this, &ClangFormat::formatAtCursor);
|
||||
|
||||
m_disableFormattingSelectedText
|
||||
= new QAction(BeautifierPlugin::msgDisableFormattingSelectedText(), this);
|
||||
cmd = Core::ActionManager::registerAction(
|
||||
m_disableFormattingSelectedText, Constants::ClangFormat::ACTION_DISABLEFORMATTINGSELECTED);
|
||||
menu->addAction(cmd);
|
||||
connect(m_disableFormattingSelectedText, &QAction::triggered,
|
||||
this, &ClangFormat::disableFormattingSelectedText);
|
||||
|
||||
Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu);
|
||||
|
||||
@@ -113,7 +122,7 @@ void ClangFormat::formatFile()
|
||||
m_beautifierPlugin->formatCurrentFile(command());
|
||||
}
|
||||
|
||||
void ClangFormat::formatSelectedText()
|
||||
void ClangFormat::formatAtCursor()
|
||||
{
|
||||
const TextEditor::TextEditorWidget *widget
|
||||
= TextEditor::TextEditorWidget::currentTextEditorWidget();
|
||||
@@ -125,11 +134,53 @@ void ClangFormat::formatSelectedText()
|
||||
const int offset = tc.selectionStart();
|
||||
const int length = tc.selectionEnd() - offset;
|
||||
m_beautifierPlugin->formatCurrentFile(command(offset, length));
|
||||
} else if (m_settings->formatEntireFileFallback()) {
|
||||
formatFile();
|
||||
} else {
|
||||
// Pretend that the current line was selected.
|
||||
// Note that clang-format will extend the range to the next bigger
|
||||
// syntactic construct if needed.
|
||||
const QTextBlock block = tc.block();
|
||||
const int offset = block.position();
|
||||
const int length = block.length();
|
||||
m_beautifierPlugin->formatCurrentFile(command(offset, length));
|
||||
}
|
||||
}
|
||||
|
||||
void ClangFormat::disableFormattingSelectedText()
|
||||
{
|
||||
TextEditor::TextEditorWidget *widget = TextEditor::TextEditorWidget::currentTextEditorWidget();
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
const QTextCursor tc = widget->textCursor();
|
||||
if (!tc.hasSelection())
|
||||
return;
|
||||
|
||||
// Insert start marker
|
||||
const QTextBlock selectionStartBlock = tc.document()->findBlock(tc.selectionStart());
|
||||
QTextCursor insertCursor(tc.document());
|
||||
insertCursor.beginEditBlock();
|
||||
insertCursor.setPosition(selectionStartBlock.position());
|
||||
insertCursor.insertText("// clang-format off\n");
|
||||
const int positionToRestore = tc.position();
|
||||
|
||||
// Insert end marker
|
||||
QTextBlock selectionEndBlock = tc.document()->findBlock(tc.selectionEnd());
|
||||
insertCursor.setPosition(selectionEndBlock.position() + selectionEndBlock.length() - 1);
|
||||
insertCursor.insertText("\n// clang-format on");
|
||||
insertCursor.endEditBlock();
|
||||
|
||||
// Reset the cursor position in order to clear the selection.
|
||||
QTextCursor restoreCursor(tc.document());
|
||||
restoreCursor.setPosition(positionToRestore);
|
||||
widget->setTextCursor(restoreCursor);
|
||||
|
||||
// The indentation of these markers might be undesired, so reformat.
|
||||
// This is not optimal because two undo steps will be needed to remove the markers.
|
||||
const int reformatTextLength = insertCursor.position() - selectionStartBlock.position();
|
||||
m_beautifierPlugin->formatCurrentFile(command(selectionStartBlock.position(),
|
||||
reformatTextLength));
|
||||
}
|
||||
|
||||
Command ClangFormat::command() const
|
||||
{
|
||||
Command command;
|
||||
|
@@ -54,10 +54,12 @@ public:
|
||||
|
||||
private:
|
||||
void formatFile();
|
||||
void formatSelectedText();
|
||||
void formatAtCursor();
|
||||
void disableFormattingSelectedText();
|
||||
BeautifierPlugin *m_beautifierPlugin;
|
||||
QAction *m_formatFile = nullptr;
|
||||
QAction *m_formatRange = nullptr;
|
||||
QAction *m_disableFormattingSelectedText = nullptr;
|
||||
ClangFormatSettings *m_settings;
|
||||
Command command(int offset, int length) const;
|
||||
};
|
||||
|
@@ -33,7 +33,8 @@ namespace ClangFormat {
|
||||
|
||||
const char DISPLAY_NAME[] = QT_TRANSLATE_NOOP("Beautifier::Internal::ClangFormat::ClangFormat", "ClangFormat");
|
||||
const char ACTION_FORMATFILE[] = "ClangFormat.FormatFile";
|
||||
const char ACTION_FORMATSELECTED[] = "ClangFormat.FormatSelectedText";
|
||||
const char ACTION_FORMATATCURSOR[] = "ClangFormat.FormatAtCursor";
|
||||
const char ACTION_DISABLEFORMATTINGSELECTED[] = "ClangFormat.DisableFormattingSelectedText";
|
||||
const char MENU_ID[] = "ClangFormat.Menu";
|
||||
const char OPTION_ID[] = "ClangFormat";
|
||||
const char SETTINGS_NAME[] = "clangformat";
|
||||
|
@@ -78,7 +78,6 @@ void ClangFormatOptionsPageWidget::restore()
|
||||
const int fallbackStyleIndex = ui->fallbackStyle->findText(m_settings->fallbackStyle());
|
||||
if (fallbackStyleIndex != -1)
|
||||
ui->fallbackStyle->setCurrentIndex(fallbackStyleIndex);
|
||||
ui->formatEntireFileFallback->setChecked(m_settings->formatEntireFileFallback());
|
||||
ui->configurations->setSettings(m_settings);
|
||||
ui->configurations->setCurrentConfiguration(m_settings->customStyle());
|
||||
|
||||
@@ -96,7 +95,6 @@ void ClangFormatOptionsPageWidget::apply()
|
||||
m_settings->setPredefinedStyle(ui->predefinedStyle->currentText());
|
||||
m_settings->setFallbackStyle(ui->fallbackStyle->currentText());
|
||||
m_settings->setCustomStyle(ui->configurations->currentConfiguration());
|
||||
m_settings->setFormatEntireFileFallback(ui->formatEntireFileFallback->isChecked());
|
||||
m_settings->save();
|
||||
|
||||
// update since not all MIME types are accepted (invalids or duplicates)
|
||||
|
@@ -20,6 +20,19 @@
|
||||
<string>Options</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="0">
|
||||
<widget class="QRadioButton" name="useCustomizedStyle">
|
||||
<property name="text">
|
||||
<string>Use customized style:</string>
|
||||
</property>
|
||||
<property name="autoExclusive">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="Beautifier::Internal::ConfigurationPanel" name="configurations" native="true"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="usePredefinedStyle">
|
||||
<property name="sizePolicy">
|
||||
@@ -62,29 +75,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QRadioButton" name="useCustomizedStyle">
|
||||
<property name="text">
|
||||
<string>Use customized style:</string>
|
||||
</property>
|
||||
<property name="autoExclusive">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="Beautifier::Internal::ConfigurationPanel" name="configurations" native="true"/>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="formatEntireFileFallback">
|
||||
<property name="toolTip">
|
||||
<string>For action Format Selected Text.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Format entire file if no text was selected</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@@ -43,7 +43,6 @@ const char USE_PREDEFINED_STYLE[] = "usePredefinedStyle";
|
||||
const char PREDEFINED_STYLE[] = "predefinedStyle";
|
||||
const char FALLBACK_STYLE[] = "fallbackStyle";
|
||||
const char CUSTOM_STYLE[] = "customStyle";
|
||||
const char FORMAT_ENTIRE_FILE_FALLBACK[] = "formatEntireFileFallback";
|
||||
}
|
||||
|
||||
ClangFormatSettings::ClangFormatSettings() :
|
||||
@@ -54,7 +53,6 @@ ClangFormatSettings::ClangFormatSettings() :
|
||||
m_settings.insert(PREDEFINED_STYLE, "LLVM");
|
||||
m_settings.insert(FALLBACK_STYLE, "Default");
|
||||
m_settings.insert(CUSTOM_STYLE, QVariant());
|
||||
m_settings.insert(FORMAT_ENTIRE_FILE_FALLBACK, QVariant(true));
|
||||
read();
|
||||
}
|
||||
|
||||
@@ -215,16 +213,6 @@ void ClangFormatSettings::setCustomStyle(const QString &customStyle)
|
||||
m_settings.insert(CUSTOM_STYLE, QVariant(customStyle));
|
||||
}
|
||||
|
||||
bool ClangFormatSettings::formatEntireFileFallback() const
|
||||
{
|
||||
return m_settings.value(FORMAT_ENTIRE_FILE_FALLBACK).toBool();
|
||||
}
|
||||
|
||||
void ClangFormatSettings::setFormatEntireFileFallback(bool formatEntireFileFallback)
|
||||
{
|
||||
m_settings.insert(FORMAT_ENTIRE_FILE_FALLBACK, QVariant(formatEntireFileFallback));
|
||||
}
|
||||
|
||||
QStringList ClangFormatSettings::predefinedStyles() const
|
||||
{
|
||||
return {"LLVM", "Google", "Chromium", "Mozilla", "WebKit", "File"};
|
||||
|
@@ -54,9 +54,6 @@ public:
|
||||
QString customStyle() const;
|
||||
void setCustomStyle(const QString &customStyle);
|
||||
|
||||
bool formatEntireFileFallback() const;
|
||||
void setFormatEntireFileFallback(bool formatEntireFileFallback);
|
||||
|
||||
QStringList predefinedStyles() const;
|
||||
QStringList fallbackStyles() const;
|
||||
|
||||
|
@@ -275,7 +275,6 @@ CppTools::SymbolInfo toSymbolInfo(const FollowSymbolMessage &message)
|
||||
result.endLine = static_cast<int>(end.line());
|
||||
result.endColumn = static_cast<int>(end.column());
|
||||
result.fileName = start.filePath();
|
||||
result.failedToFollow = message.failedToFollow();
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -748,14 +747,12 @@ QFuture<CppTools::SymbolInfo> IpcCommunicator::requestFollowSymbol(
|
||||
const FileContainer &curFileContainer,
|
||||
const QVector<Utf8String> &dependentFiles,
|
||||
quint32 line,
|
||||
quint32 column,
|
||||
bool resolveTarget)
|
||||
quint32 column)
|
||||
{
|
||||
const RequestFollowSymbolMessage message(curFileContainer,
|
||||
dependentFiles,
|
||||
line,
|
||||
column,
|
||||
resolveTarget);
|
||||
column);
|
||||
m_ipcSender->requestFollowSymbol(message);
|
||||
|
||||
return m_ipcReceiver.addExpectedRequestFollowSymbolMessage(message.ticketNumber());
|
||||
|
@@ -169,8 +169,7 @@ public:
|
||||
QFuture<CppTools::SymbolInfo> requestFollowSymbol(const FileContainer &curFileContainer,
|
||||
const QVector<Utf8String> &dependentFiles,
|
||||
quint32 line,
|
||||
quint32 column,
|
||||
bool resolveTarget);
|
||||
quint32 column);
|
||||
void completeCode(ClangCompletionAssistProcessor *assistProcessor, const QString &filePath,
|
||||
quint32 line,
|
||||
quint32 column,
|
||||
|
@@ -42,7 +42,6 @@
|
||||
#include <texteditor/codeassist/assistproposalitem.h>
|
||||
#include <texteditor/codeassist/functionhintproposal.h>
|
||||
#include <texteditor/codeassist/ifunctionhintproposalmodel.h>
|
||||
#include <texteditor/convenience.h>
|
||||
|
||||
#include <cplusplus/BackwardsScanner.h>
|
||||
#include <cplusplus/ExpressionUnderCursor.h>
|
||||
@@ -52,6 +51,7 @@
|
||||
#include <clangsupport/filecontainer.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/textutils.h>
|
||||
#include <utils/mimetypes/mimedatabase.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
@@ -556,10 +556,7 @@ ClangCompletionAssistProcessor::extractLineColumn(int position)
|
||||
return {-1, -1};
|
||||
|
||||
int line = -1, column = -1;
|
||||
TextEditor::Convenience::convertPosition(m_interface->textDocument(),
|
||||
position,
|
||||
&line,
|
||||
&column);
|
||||
::Utils::Text::convertPosition(m_interface->textDocument(), position, &line, &column);
|
||||
const QTextBlock block = m_interface->textDocument()->findBlock(position);
|
||||
column += ClangCodeModel::Utils::extraUtf8CharsShift(block.text(), column) + 1;
|
||||
return {line, column};
|
||||
|
@@ -33,11 +33,11 @@
|
||||
|
||||
#include <cpptools/cpptoolsconstants.h>
|
||||
|
||||
#include <texteditor/convenience.h>
|
||||
#include <texteditor/fontsettings.h>
|
||||
#include <texteditor/textdocument.h>
|
||||
#include <texteditor/texteditorsettings.h>
|
||||
|
||||
#include <utils/textutils.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/proxyaction.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -176,7 +176,7 @@ void addErrorSelections(const QVector<ClangBackEnd::DiagnosticContainer> &diagno
|
||||
ClangBackEnd::SourceLocationContainer toSourceLocation(QTextDocument *textDocument, int position)
|
||||
{
|
||||
int line, column;
|
||||
if (TextEditor::Convenience::convertPosition(textDocument, position, &line, &column))
|
||||
if (Utils::Text::convertPosition(textDocument, position, &line, &column))
|
||||
return ClangBackEnd::SourceLocationContainer(Utf8String(), line, column);
|
||||
|
||||
return ClangBackEnd::SourceLocationContainer();
|
||||
|
@@ -47,7 +47,6 @@
|
||||
#include <cpptools/cppworkingcopy.h>
|
||||
#include <cpptools/editordocumenthandle.h>
|
||||
|
||||
#include <texteditor/convenience.h>
|
||||
#include <texteditor/displaysettings.h>
|
||||
#include <texteditor/fontsettings.h>
|
||||
#include <texteditor/texteditor.h>
|
||||
@@ -56,6 +55,7 @@
|
||||
|
||||
#include <cplusplus/CppDocument.h>
|
||||
|
||||
#include <utils/textutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/runextensions.h>
|
||||
|
||||
@@ -225,6 +225,12 @@ toTextEditorBlocks(QTextDocument *textDocument,
|
||||
}
|
||||
}
|
||||
|
||||
const QVector<ClangBackEnd::HighlightingMarkContainer>
|
||||
&ClangEditorDocumentProcessor::highlightingMarks() const
|
||||
{
|
||||
return m_highlightingMarks;
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::updateHighlighting(
|
||||
const QVector<ClangBackEnd::HighlightingMarkContainer> &highlightingMarks,
|
||||
const QVector<ClangBackEnd::SourceRangeContainer> &skippedPreprocessorRanges,
|
||||
@@ -234,6 +240,7 @@ void ClangEditorDocumentProcessor::updateHighlighting(
|
||||
const auto skippedPreprocessorBlocks = toTextEditorBlocks(textDocument(), skippedPreprocessorRanges);
|
||||
emit ifdefedOutBlocksUpdated(documentRevision, skippedPreprocessorBlocks);
|
||||
|
||||
m_highlightingMarks = highlightingMarks;
|
||||
m_semanticHighlighter.setHighlightingRunner(
|
||||
[highlightingMarks]() {
|
||||
auto *reporter = new HighlightingMarksReporter(highlightingMarks);
|
||||
@@ -246,10 +253,8 @@ void ClangEditorDocumentProcessor::updateHighlighting(
|
||||
static int currentLine(const TextEditor::AssistInterface &assistInterface)
|
||||
{
|
||||
int line, column;
|
||||
TextEditor::Convenience::convertPosition(assistInterface.textDocument(),
|
||||
assistInterface.position(),
|
||||
&line,
|
||||
&column);
|
||||
::Utils::Text::convertPosition(assistInterface.textDocument(), assistInterface.position(),
|
||||
&line, &column);
|
||||
return line;
|
||||
}
|
||||
|
||||
@@ -315,7 +320,7 @@ static QFuture<CppTools::CursorInfo> defaultCursorInfoFuture()
|
||||
|
||||
static bool convertPosition(const QTextCursor &textCursor, int *line, int *column)
|
||||
{
|
||||
const bool converted = TextEditor::Convenience::convertPosition(textCursor.document(),
|
||||
const bool converted = ::Utils::Text::convertPosition(textCursor.document(),
|
||||
textCursor.position(),
|
||||
line,
|
||||
column);
|
||||
@@ -376,7 +381,7 @@ static QVector<Utf8String> prioritizeByBaseName(const QString &curPath,
|
||||
}
|
||||
|
||||
QFuture<CppTools::SymbolInfo>
|
||||
ClangEditorDocumentProcessor::requestFollowSymbol(int line, int column, bool resolveTarget)
|
||||
ClangEditorDocumentProcessor::requestFollowSymbol(int line, int column)
|
||||
{
|
||||
QVector<Utf8String> dependentFiles;
|
||||
CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
|
||||
@@ -390,8 +395,7 @@ ClangEditorDocumentProcessor::requestFollowSymbol(int line, int column, bool res
|
||||
return m_ipcCommunicator.requestFollowSymbol(simpleFileContainer(),
|
||||
dependentFiles,
|
||||
static_cast<quint32>(line),
|
||||
static_cast<quint32>(column),
|
||||
resolveTarget);
|
||||
static_cast<quint32>(column));
|
||||
}
|
||||
|
||||
ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithArguments() const
|
||||
|
@@ -86,14 +86,14 @@ public:
|
||||
void setParserConfig(const CppTools::BaseEditorDocumentParser::Configuration config) override;
|
||||
|
||||
QFuture<CppTools::CursorInfo> cursorInfo(const CppTools::CursorInfoParams ¶ms) override;
|
||||
QFuture<CppTools::SymbolInfo> requestFollowSymbol(int line,
|
||||
int column,
|
||||
bool resolveTarget) override;
|
||||
QFuture<CppTools::SymbolInfo> requestFollowSymbol(int line, int column) override;
|
||||
|
||||
ClangBackEnd::FileContainer fileContainerWithArguments() const;
|
||||
|
||||
void clearDiagnosticsWithFixIts();
|
||||
|
||||
const QVector<ClangBackEnd::HighlightingMarkContainer> &highlightingMarks() const;
|
||||
|
||||
public:
|
||||
static ClangEditorDocumentProcessor *get(const QString &filePath);
|
||||
|
||||
@@ -122,6 +122,7 @@ private:
|
||||
QTimer m_updateTranslationUnitTimer;
|
||||
unsigned m_parserRevision;
|
||||
|
||||
QVector<ClangBackEnd::HighlightingMarkContainer> m_highlightingMarks;
|
||||
CppTools::SemanticHighlighter m_semanticHighlighter;
|
||||
CppTools::BuiltinEditorDocumentProcessor m_builtinProcessor;
|
||||
};
|
||||
|
@@ -23,14 +23,78 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "clangfollowsymbol.h"
|
||||
#include "clangeditordocumentprocessor.h"
|
||||
#include "texteditor/texteditor.h"
|
||||
#include "texteditor/convenience.h"
|
||||
#include "clangfollowsymbol.h"
|
||||
|
||||
#include <texteditor/texteditor.h>
|
||||
|
||||
#include <clangsupport/highlightingmarkcontainer.h>
|
||||
|
||||
#include <utils/textutils.h>
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
// Returns invalid Mark if it is not found at (line, column)
|
||||
static bool findMark(const QVector<ClangBackEnd::HighlightingMarkContainer> &marks,
|
||||
uint line,
|
||||
uint column,
|
||||
ClangBackEnd::HighlightingMarkContainer &mark)
|
||||
{
|
||||
mark = Utils::findOrDefault(marks,
|
||||
[line, column](const ClangBackEnd::HighlightingMarkContainer &curMark) {
|
||||
if (curMark.line() != line)
|
||||
return false;
|
||||
if (curMark.column() == column)
|
||||
return true;
|
||||
if (curMark.column() < column && curMark.column() + curMark.length() >= column)
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
if (mark.isInvalid())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int getMarkPos(QTextCursor cursor, const ClangBackEnd::HighlightingMarkContainer &mark)
|
||||
{
|
||||
cursor.setPosition(0);
|
||||
cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, mark.line() - 1);
|
||||
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, mark.column() - 1);
|
||||
return cursor.position();
|
||||
}
|
||||
|
||||
static TextEditor::TextEditorWidget::Link linkAtCursor(QTextCursor cursor,
|
||||
const QString &filePath,
|
||||
uint line,
|
||||
uint column,
|
||||
ClangEditorDocumentProcessor *processor)
|
||||
{
|
||||
using Link = TextEditor::TextEditorWidget::Link;
|
||||
|
||||
const QVector<ClangBackEnd::HighlightingMarkContainer> &marks
|
||||
= processor->highlightingMarks();
|
||||
ClangBackEnd::HighlightingMarkContainer mark;
|
||||
if (!findMark(marks, line, column, mark))
|
||||
return Link();
|
||||
|
||||
cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
|
||||
const QString tokenStr = cursor.selectedText();
|
||||
|
||||
Link token(filePath, mark.line(), mark.column());
|
||||
token.linkTextStart = getMarkPos(cursor, mark);
|
||||
token.linkTextEnd = token.linkTextStart + mark.length();
|
||||
if (mark.isIncludeDirectivePath()) {
|
||||
if (tokenStr != "include" && tokenStr != "#" && tokenStr != "<")
|
||||
return token;
|
||||
return Link();
|
||||
}
|
||||
if (mark.isIdentifier() || tokenStr == "operator")
|
||||
return token;
|
||||
return Link();
|
||||
}
|
||||
|
||||
TextEditor::TextEditorWidget::Link ClangFollowSymbol::findLink(
|
||||
const CppTools::CursorInEditor &data,
|
||||
bool resolveTarget,
|
||||
@@ -39,42 +103,39 @@ TextEditor::TextEditorWidget::Link ClangFollowSymbol::findLink(
|
||||
CppTools::SymbolFinder *,
|
||||
bool)
|
||||
{
|
||||
Link link;
|
||||
|
||||
int lineNumber = 0, positionInBlock = 0;
|
||||
QTextCursor cursor = TextEditor::Convenience::wordStartCursor(data.cursor());
|
||||
TextEditor::Convenience::convertPosition(cursor.document(), cursor.position(), &lineNumber,
|
||||
QTextCursor cursor = Utils::Text::wordStartCursor(data.cursor());
|
||||
Utils::Text::convertPosition(cursor.document(), cursor.position(), &lineNumber,
|
||||
&positionInBlock);
|
||||
const unsigned line = lineNumber;
|
||||
const unsigned column = positionInBlock + 1;
|
||||
|
||||
if (!resolveTarget)
|
||||
return link;
|
||||
const uint line = lineNumber;
|
||||
const uint column = positionInBlock + 1;
|
||||
|
||||
ClangEditorDocumentProcessor *processor = ClangEditorDocumentProcessor::get(
|
||||
data.filePath().toString());
|
||||
if (!processor)
|
||||
return link;
|
||||
return Link();
|
||||
|
||||
if (!resolveTarget)
|
||||
return linkAtCursor(cursor, data.filePath().toString(), line, column, processor);
|
||||
|
||||
QFuture<CppTools::SymbolInfo> info
|
||||
= processor->requestFollowSymbol(static_cast<int>(line),
|
||||
static_cast<int>(column),
|
||||
resolveTarget);
|
||||
static_cast<int>(column));
|
||||
|
||||
if (info.isCanceled())
|
||||
return link;
|
||||
return Link();
|
||||
|
||||
while (!info.isFinished()) {
|
||||
if (info.isCanceled())
|
||||
return link;
|
||||
return Link();
|
||||
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
}
|
||||
CppTools::SymbolInfo result = info.result();
|
||||
|
||||
if (result.failedToFollow)
|
||||
return link;
|
||||
|
||||
// We did not fail but the result is empty
|
||||
if (result.fileName.isEmpty())
|
||||
return link;
|
||||
return Link();
|
||||
|
||||
return Link(result.fileName, result.startLine, result.startColumn - 1);
|
||||
}
|
||||
|
@@ -158,8 +158,15 @@ void HighlightingMarksReporter::run_internal()
|
||||
if (isCanceled())
|
||||
return;
|
||||
|
||||
for (const auto &highlightingMark : m_highlightingMarks)
|
||||
using ClangBackEnd::HighlightingType;
|
||||
|
||||
for (const auto &highlightingMark : m_highlightingMarks) {
|
||||
const HighlightingType mainType = highlightingMark.types().mainHighlightingType;
|
||||
if (mainType == HighlightingType::StringLiteral)
|
||||
continue;
|
||||
|
||||
reportChunkWise(toHighlightingResult(highlightingMark));
|
||||
}
|
||||
|
||||
if (isCanceled())
|
||||
return;
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "clangfollowsymbol.h"
|
||||
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <cpptools/cppfollowsymbolundercursor.h>
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
#include <cpptools/editordocumenthandle.h>
|
||||
#include <cpptools/projectinfo.h>
|
||||
@@ -72,6 +73,8 @@ ModelManagerSupportClang::ModelManagerSupportClang()
|
||||
|
||||
if (useClangFollowSymbol())
|
||||
m_followSymbol.reset(new ClangFollowSymbol);
|
||||
else
|
||||
m_followSymbol.reset(new CppTools::FollowSymbolUnderCursor);
|
||||
|
||||
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
||||
connect(editorManager, &Core::EditorManager::editorOpened,
|
||||
@@ -106,9 +109,9 @@ CppTools::CppCompletionAssistProvider *ModelManagerSupportClang::completionAssis
|
||||
return &m_completionAssistProvider;
|
||||
}
|
||||
|
||||
CppTools::FollowSymbolInterface *ModelManagerSupportClang::followSymbolInterface()
|
||||
CppTools::FollowSymbolInterface &ModelManagerSupportClang::followSymbolInterface()
|
||||
{
|
||||
return m_followSymbol.get();
|
||||
return *m_followSymbol;
|
||||
}
|
||||
|
||||
CppTools::BaseEditorDocumentProcessor *ModelManagerSupportClang::editorDocumentProcessor(
|
||||
|
@@ -42,12 +42,11 @@ QT_END_NAMESPACE
|
||||
|
||||
namespace Core { class IDocument; }
|
||||
namespace TextEditor { class TextEditorWidget; }
|
||||
namespace CppTools { class FollowSymbolInterface; }
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
class ClangFollowSymbol;
|
||||
|
||||
class ModelManagerSupportClang:
|
||||
public QObject,
|
||||
public CppTools::ModelManagerSupport
|
||||
@@ -61,7 +60,7 @@ public:
|
||||
CppTools::CppCompletionAssistProvider *completionAssistProvider() override;
|
||||
CppTools::BaseEditorDocumentProcessor *editorDocumentProcessor(
|
||||
TextEditor::TextDocument *baseTextDocument) override;
|
||||
CppTools::FollowSymbolInterface *followSymbolInterface() override;
|
||||
CppTools::FollowSymbolInterface &followSymbolInterface() override;
|
||||
|
||||
IpcCommunicator &ipcCommunicator();
|
||||
QString dummyUiHeaderOnDiskDirPath() const;
|
||||
@@ -105,7 +104,7 @@ private:
|
||||
UiHeaderOnDiskManager m_uiHeaderOnDiskManager;
|
||||
IpcCommunicator m_ipcCommunicator;
|
||||
ClangCompletionAssistProvider m_completionAssistProvider;
|
||||
std::unique_ptr<ClangFollowSymbol> m_followSymbol;
|
||||
std::unique_ptr<CppTools::FollowSymbolInterface> m_followSymbol;
|
||||
};
|
||||
|
||||
class ModelManagerSupportProviderClang : public CppTools::ModelManagerSupportProvider
|
||||
|
@@ -70,46 +70,21 @@ QStringList createClangOptions(const ProjectPart::Ptr &pPart, const QString &fil
|
||||
return createClangOptions(pPart, fileKind);
|
||||
}
|
||||
|
||||
class LibClangOptionsBuilder : public ClangCompilerOptionsBuilder
|
||||
class LibClangOptionsBuilder final : public ClangCompilerOptionsBuilder
|
||||
{
|
||||
public:
|
||||
static QStringList build(const ProjectPart::Ptr &projectPart, ProjectFile::Kind fileKind)
|
||||
{
|
||||
if (projectPart.isNull())
|
||||
return QStringList();
|
||||
|
||||
LibClangOptionsBuilder optionsBuilder(*projectPart.data());
|
||||
|
||||
optionsBuilder.addWordWidth();
|
||||
optionsBuilder.addTargetTriple();
|
||||
optionsBuilder.addLanguageOption(fileKind);
|
||||
optionsBuilder.addOptionsForLanguage(/*checkForBorlandExtensions*/ true);
|
||||
optionsBuilder.enableExceptions();
|
||||
|
||||
optionsBuilder.addDefineToAvoidIncludingGccOrMinGwIntrinsics();
|
||||
optionsBuilder.addDefineFloat128ForMingw();
|
||||
optionsBuilder.addToolchainAndProjectDefines();
|
||||
optionsBuilder.undefineCppLanguageFeatureMacrosForMsvc2015();
|
||||
|
||||
optionsBuilder.addPredefinedMacrosAndHeaderPathsOptions();
|
||||
optionsBuilder.addWrappedQtHeadersIncludePath();
|
||||
optionsBuilder.addHeaderPathOptions();
|
||||
optionsBuilder.addDummyUiHeaderOnDiskIncludePath();
|
||||
optionsBuilder.addProjectConfigFileInclude();
|
||||
|
||||
optionsBuilder.addMsvcCompatibilityVersion();
|
||||
|
||||
optionsBuilder.addExtraOptions();
|
||||
|
||||
return optionsBuilder.options();
|
||||
}
|
||||
|
||||
private:
|
||||
LibClangOptionsBuilder(const CppTools::ProjectPart &projectPart)
|
||||
LibClangOptionsBuilder(const ProjectPart &projectPart)
|
||||
: ClangCompilerOptionsBuilder(projectPart, CLANG_VERSION, CLANG_RESOURCE_DIR)
|
||||
{
|
||||
}
|
||||
|
||||
void addExtraOptions() final
|
||||
{
|
||||
addDummyUiHeaderOnDiskIncludePath();
|
||||
ClangCompilerOptionsBuilder::addExtraOptions();
|
||||
}
|
||||
|
||||
private:
|
||||
void addDummyUiHeaderOnDiskIncludePath()
|
||||
{
|
||||
const QString path = ModelManagerSupportClang::instance()->dummyUiHeaderOnDiskDirPath();
|
||||
@@ -125,7 +100,9 @@ private:
|
||||
*/
|
||||
QStringList createClangOptions(const ProjectPart::Ptr &pPart, ProjectFile::Kind fileKind)
|
||||
{
|
||||
return LibClangOptionsBuilder::build(pPart, fileKind);
|
||||
if (!pPart)
|
||||
return QStringList();
|
||||
return LibClangOptionsBuilder(*pPart).build(fileKind, CompilerOptionsBuilder::PchUsage::None);
|
||||
}
|
||||
|
||||
ProjectPart::Ptr projectPartForFile(const QString &filePath)
|
||||
|
@@ -108,35 +108,9 @@ HeaderAndSources ProjectUpdater::headerAndSourcesFromProjectPart(
|
||||
|
||||
QStringList ProjectUpdater::compilerArguments(CppTools::ProjectPart *projectPart)
|
||||
{
|
||||
using CppTools::ClangCompilerOptionsBuilder;
|
||||
|
||||
ClangCompilerOptionsBuilder builder(*projectPart, CLANG_VERSION, CLANG_RESOURCE_DIR);
|
||||
|
||||
builder.addWordWidth();
|
||||
builder.addTargetTriple();
|
||||
builder.addLanguageOption(CppTools::ProjectFile::CXXHeader);
|
||||
builder.addOptionsForLanguage(/*checkForBorlandExtensions*/ true);
|
||||
builder.enableExceptions();
|
||||
|
||||
builder.addDefineToAvoidIncludingGccOrMinGwIntrinsics();
|
||||
builder.addDefineFloat128ForMingw();
|
||||
builder.addToolchainAndProjectDefines();
|
||||
builder.undefineCppLanguageFeatureMacrosForMsvc2015();
|
||||
|
||||
builder.addPredefinedMacrosAndHeaderPathsOptions();
|
||||
builder.addWrappedQtHeadersIncludePath();
|
||||
builder.addPrecompiledHeaderOptions(ClangCompilerOptionsBuilder::PchUsage::None);
|
||||
builder.addHeaderPathOptions();
|
||||
builder.addProjectConfigFileInclude();
|
||||
|
||||
builder.addMsvcCompatibilityVersion();
|
||||
|
||||
builder.add("-fmessage-length=0");
|
||||
builder.add("-fmacro-backtrace-limit=0");
|
||||
builder.add("-w");
|
||||
builder.add("-ferror-limit=100000");
|
||||
|
||||
return builder.options();
|
||||
using ClangCOBuilder = CppTools::ClangCompilerOptionsBuilder;
|
||||
ClangCOBuilder builder(*projectPart, CLANG_VERSION, CLANG_RESOURCE_DIR);
|
||||
return builder.build(CppTools::ProjectFile::CXXHeader, ClangCOBuilder::PchUsage::None);
|
||||
}
|
||||
|
||||
ClangBackEnd::V2::ProjectPartContainer ProjectUpdater::toProjectPartContainer(
|
||||
|
@@ -155,31 +155,8 @@ Utils::SmallStringVector ClangQueryProjectsFindFilter::compilerArguments(CppTool
|
||||
|
||||
ClangCompilerOptionsBuilder builder(*projectPart, CLANG_VERSION, CLANG_RESOURCE_DIR);
|
||||
|
||||
builder.addWordWidth();
|
||||
builder.addTargetTriple();
|
||||
builder.addLanguageOption(fileKind);
|
||||
builder.addOptionsForLanguage(/*checkForBorlandExtensions*/ true);
|
||||
builder.enableExceptions();
|
||||
|
||||
builder.addDefineToAvoidIncludingGccOrMinGwIntrinsics();
|
||||
builder.addDefineFloat128ForMingw();
|
||||
builder.addToolchainAndProjectDefines();
|
||||
builder.undefineCppLanguageFeatureMacrosForMsvc2015();
|
||||
|
||||
builder.addPredefinedMacrosAndHeaderPathsOptions();
|
||||
builder.addWrappedQtHeadersIncludePath();
|
||||
builder.addPrecompiledHeaderOptions(ClangCompilerOptionsBuilder::PchUsage::None);
|
||||
builder.addHeaderPathOptions();
|
||||
builder.addProjectConfigFileInclude();
|
||||
|
||||
builder.addMsvcCompatibilityVersion();
|
||||
|
||||
builder.add("-fmessage-length=0");
|
||||
builder.add("-fmacro-backtrace-limit=0");
|
||||
builder.add("-w");
|
||||
builder.add("-ferror-limit=1000000");
|
||||
|
||||
return Utils::SmallStringVector(builder.options());
|
||||
return Utils::SmallStringVector(builder.build(fileKind,
|
||||
ClangCompilerOptionsBuilder::PchUsage::None));
|
||||
}
|
||||
|
||||
QWidget *ClangQueryProjectsFindFilter::widget() const
|
||||
|
@@ -96,6 +96,7 @@ void ClangRefactoringPlugin::extensionsInitialized()
|
||||
ExtensionSystem::IPlugin::ShutdownFlag ClangRefactoringPlugin::aboutToShutdown()
|
||||
{
|
||||
ExtensionSystem::PluginManager::removeObject(&d->qtCreatorfindFilter);
|
||||
CppTools::CppModelManager::setRefactoringEngine(nullptr);
|
||||
d->refactoringClient.setRefactoringConnectionClient(nullptr);
|
||||
d->refactoringClient.setRefactoringEngine(nullptr);
|
||||
|
||||
|
@@ -64,12 +64,10 @@ void RefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data,
|
||||
|
||||
QString filePath = data.filePath().toString();
|
||||
QTextCursor textCursor = data.cursor();
|
||||
Utils::SmallStringVector commandLine{ClangCompilerOptionsBuilder::build(
|
||||
projectPart,
|
||||
ClangCompilerOptionsBuilder clangCOBuilder{*projectPart, CLANG_VERSION, CLANG_RESOURCE_DIR};
|
||||
Utils::SmallStringVector commandLine{clangCOBuilder.build(
|
||||
fileKindInProjectPart(projectPart, filePath),
|
||||
CppTools::getPchUsage(),
|
||||
CLANG_VERSION,
|
||||
CLANG_RESOURCE_DIR)};
|
||||
CppTools::getPchUsage())};
|
||||
|
||||
commandLine.push_back(filePath);
|
||||
|
||||
@@ -84,6 +82,11 @@ void RefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data,
|
||||
server.requestSourceLocationsForRenamingMessage(std::move(message));
|
||||
}
|
||||
|
||||
void RefactoringEngine::startGlobalRenaming(const CppTools::CursorInEditor &)
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
bool RefactoringEngine::isUsable() const
|
||||
{
|
||||
return server.isUsable();
|
||||
|
@@ -42,6 +42,7 @@ public:
|
||||
void startLocalRenaming(const CppTools::CursorInEditor &data,
|
||||
CppTools::ProjectPart *projectPart,
|
||||
RenameCallback &&renameSymbolsCallback) override;
|
||||
void startGlobalRenaming(const CppTools::CursorInEditor &data) override;
|
||||
|
||||
bool isUsable() const override;
|
||||
void setUsable(bool isUsable);
|
||||
|
@@ -39,6 +39,10 @@ class SourceLocations
|
||||
public:
|
||||
struct Location
|
||||
{
|
||||
Location(qint64 sourceId, qint64 line, qint64 column)
|
||||
: sourceId(sourceId), line(line), column(column)
|
||||
{}
|
||||
|
||||
qint64 sourceId;
|
||||
qint64 line;
|
||||
qint64 column;
|
||||
@@ -46,17 +50,14 @@ public:
|
||||
|
||||
struct Source
|
||||
{
|
||||
Source(qint64 sourceId, Utils::PathString &&sourcePath)
|
||||
: sourceId(sourceId), sourcePath(std::move(sourcePath))
|
||||
{}
|
||||
|
||||
qint64 sourceId;
|
||||
Utils::PathString sourcePath;
|
||||
};
|
||||
|
||||
enum LocationGetter
|
||||
{
|
||||
SourceId = 0,
|
||||
Line,
|
||||
Column
|
||||
};
|
||||
|
||||
std::vector<Location> locations;
|
||||
std::unordered_map<qint64, Utils::PathString> sources;
|
||||
};
|
||||
|
@@ -52,7 +52,7 @@ public:
|
||||
|
||||
const std::size_t reserveSize = 128;
|
||||
|
||||
auto locations = locationsStatement.template structValues<Location, qint64, qint64, qint64>(
|
||||
auto locations = locationsStatement.template values<Location, 3>(
|
||||
reserveSize,
|
||||
filePath,
|
||||
line,
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
|
||||
ReadStatement &sourcesStatement = m_statementFactory.selectSourcePathForId;
|
||||
|
||||
auto sources = sourcesStatement.template structValues<Source, qint64, Utils::PathString>(
|
||||
auto sources = sourcesStatement.template values<Source, 2>(
|
||||
reserveSize,
|
||||
sourceIds);
|
||||
|
||||
|
@@ -167,7 +167,7 @@ static QList<Target *> validTargets(Project *project)
|
||||
const ToolChain * const toolchain = ToolChainKitInformation::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID);
|
||||
QTC_ASSERT(toolchain, return false);
|
||||
bool hasClangExecutable;
|
||||
clangExecutableFromSettings(toolchain->typeId(), &hasClangExecutable);
|
||||
clangExecutableFromSettings(&hasClangExecutable);
|
||||
if (!hasClangExecutable) {
|
||||
qWarning("Project \"%s\": Skipping target \"%s\" since no suitable clang was found for the toolchain.",
|
||||
qPrintable(projectFileName),
|
||||
|
@@ -38,7 +38,7 @@
|
||||
#include <coreplugin/progressmanager/futureprogress.h>
|
||||
#include <coreplugin/progressmanager/progressmanager.h>
|
||||
|
||||
#include <cpptools/compileroptionsbuilder.h>
|
||||
#include <cpptools/clangcompileroptionsbuilder.h>
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
#include <cpptools/cppprojectfile.h>
|
||||
#include <cpptools/cpptoolsreuse.h>
|
||||
@@ -161,8 +161,7 @@ static void prependTargetTripleIfNotIncludedAndNotEmpty(QStringList *arguments,
|
||||
}
|
||||
|
||||
// Removes (1) inputFile (2) -o <somePath>.
|
||||
QStringList inputAndOutputArgumentsRemoved(const QString &inputFile, const QStringList &arguments,
|
||||
bool isMsvc)
|
||||
QStringList inputAndOutputArgumentsRemoved(const QString &inputFile, const QStringList &arguments)
|
||||
{
|
||||
QStringList newArguments;
|
||||
|
||||
@@ -174,9 +173,6 @@ QStringList inputAndOutputArgumentsRemoved(const QString &inputFile, const QStri
|
||||
} else if (argument == QLatin1String("-o")) {
|
||||
skip = true;
|
||||
continue;
|
||||
} else if (isMsvc && argument == QLatin1String("-target")) {
|
||||
skip = true;
|
||||
continue;
|
||||
} else if (QDir::fromNativeSeparators(argument) == inputFile) {
|
||||
continue; // TODO: Let it in?
|
||||
}
|
||||
@@ -188,55 +184,11 @@ QStringList inputAndOutputArgumentsRemoved(const QString &inputFile, const QStri
|
||||
return newArguments;
|
||||
}
|
||||
|
||||
static QString createLanguageOptionMsvc(ProjectFile::Kind fileKind)
|
||||
{
|
||||
switch (fileKind) {
|
||||
case ProjectFile::CHeader:
|
||||
case ProjectFile::CSource:
|
||||
return QLatin1String("/TC");
|
||||
break;
|
||||
case ProjectFile::CXXHeader:
|
||||
case ProjectFile::CXXSource:
|
||||
return QLatin1String("/TP");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
class ClangStaticAnalyzerOptionsBuilder : public CompilerOptionsBuilder
|
||||
class ClangStaticAnalyzerOptionsBuilder final : public ClangCompilerOptionsBuilder
|
||||
{
|
||||
public:
|
||||
static QStringList build(const CppTools::ProjectPart &projectPart,
|
||||
CppTools::ProjectFile::Kind fileKind,
|
||||
PchUsage pchUsage)
|
||||
{
|
||||
ClangStaticAnalyzerOptionsBuilder optionsBuilder(projectPart);
|
||||
|
||||
optionsBuilder.addWordWidth();
|
||||
optionsBuilder.addTargetTriple();
|
||||
optionsBuilder.addLanguageOption(fileKind);
|
||||
optionsBuilder.addOptionsForLanguage(false);
|
||||
optionsBuilder.enableExceptions();
|
||||
|
||||
optionsBuilder.addDefineFloat128ForMingw();
|
||||
optionsBuilder.addDefineToAvoidIncludingGccOrMinGwIntrinsics();
|
||||
const Core::Id type = projectPart.toolchainType;
|
||||
if (type != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID)
|
||||
optionsBuilder.addMacros(projectPart.toolChainMacros);
|
||||
optionsBuilder.addMacros(projectPart.projectMacros);
|
||||
optionsBuilder.undefineClangVersionMacrosForMsvc();
|
||||
optionsBuilder.undefineCppLanguageFeatureMacrosForMsvc2015();
|
||||
optionsBuilder.addHeaderPathOptions();
|
||||
optionsBuilder.addPrecompiledHeaderOptions(pchUsage);
|
||||
optionsBuilder.addMsvcCompatibilityVersion();
|
||||
|
||||
return optionsBuilder.options();
|
||||
}
|
||||
|
||||
ClangStaticAnalyzerOptionsBuilder(const CppTools::ProjectPart &projectPart)
|
||||
: CompilerOptionsBuilder(projectPart)
|
||||
: ClangCompilerOptionsBuilder(projectPart)
|
||||
, m_isMsvcToolchain(m_projectPart.toolchainType
|
||||
== ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID)
|
||||
, m_isMinGWToolchain(m_projectPart.toolchainType
|
||||
@@ -244,91 +196,28 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
bool excludeHeaderPath(const QString &headerPath) const override
|
||||
bool excludeHeaderPath(const QString &headerPath) const final
|
||||
{
|
||||
if (CompilerOptionsBuilder::excludeHeaderPath(headerPath))
|
||||
return true;
|
||||
if (m_isMinGWToolchain && headerPath.contains(m_projectPart.toolChainTargetTriple))
|
||||
return true;
|
||||
return false;
|
||||
return ClangCompilerOptionsBuilder::excludeHeaderPath(headerPath);
|
||||
}
|
||||
|
||||
void undefineClangVersionMacrosForMsvc()
|
||||
void addPredefinedHeaderPathsOptions() final
|
||||
{
|
||||
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
|
||||
static QStringList macroNames {
|
||||
"__clang__",
|
||||
"__clang_major__",
|
||||
"__clang_minor__",
|
||||
"__clang_patchlevel__",
|
||||
"__clang_version__"
|
||||
};
|
||||
|
||||
foreach (const QString ¯oName, macroNames)
|
||||
add(QLatin1String("/U") + macroName);
|
||||
add("-undef");
|
||||
if (m_isMsvcToolchain) {
|
||||
// exclude default clang path to use msvc includes
|
||||
add("-nostdinc");
|
||||
add("-nostdlibinc");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void addTargetTriple() override
|
||||
void addExtraOptions() final {}
|
||||
|
||||
void addWrappedQtHeadersIncludePath() final
|
||||
{
|
||||
// For MSVC toolchains we use clang-cl.exe, so there is nothing to do here since
|
||||
// 1) clang-cl.exe does not understand the "-triple" option
|
||||
// 2) clang-cl.exe already hardcodes the right triple value (even if built with mingw)
|
||||
if (!m_isMsvcToolchain)
|
||||
CompilerOptionsBuilder::addTargetTriple();
|
||||
}
|
||||
|
||||
void addLanguageOption(ProjectFile::Kind fileKind) override
|
||||
{
|
||||
if (m_isMsvcToolchain)
|
||||
add(createLanguageOptionMsvc(fileKind));
|
||||
else
|
||||
CompilerOptionsBuilder::addLanguageOption(fileKind);
|
||||
}
|
||||
|
||||
void addOptionsForLanguage(bool checkForBorlandExtensions) override
|
||||
{
|
||||
if (m_isMsvcToolchain)
|
||||
return;
|
||||
CompilerOptionsBuilder::addOptionsForLanguage(checkForBorlandExtensions);
|
||||
}
|
||||
|
||||
QString includeOption() const override
|
||||
{
|
||||
if (m_isMsvcToolchain)
|
||||
return QLatin1String("/FI");
|
||||
return CompilerOptionsBuilder::includeOption();
|
||||
}
|
||||
|
||||
QString includeDirOption() const override
|
||||
{
|
||||
if (m_isMsvcToolchain)
|
||||
return QLatin1String("/I");
|
||||
return CompilerOptionsBuilder::includeDirOption();
|
||||
}
|
||||
|
||||
QString defineOption() const override
|
||||
{
|
||||
if (m_isMsvcToolchain)
|
||||
return QLatin1String("/D");
|
||||
return CompilerOptionsBuilder::defineOption();
|
||||
}
|
||||
|
||||
QString undefineOption() const override
|
||||
{
|
||||
if (m_isMsvcToolchain)
|
||||
return QLatin1String("/U");
|
||||
return CompilerOptionsBuilder::undefineOption();
|
||||
}
|
||||
|
||||
void enableExceptions() override
|
||||
{
|
||||
if (m_isMsvcToolchain)
|
||||
add(QLatin1String("/EHsc"));
|
||||
else
|
||||
CompilerOptionsBuilder::enableExceptions();
|
||||
// Empty, analyzer doesn't need them
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -383,7 +272,7 @@ static QStringList tweakedArguments(const ProjectPart &projectPart,
|
||||
{
|
||||
const bool isMsvc = projectPart.toolchainType
|
||||
== ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID;
|
||||
QStringList newArguments = inputAndOutputArgumentsRemoved(filePath, arguments, isMsvc);
|
||||
QStringList newArguments = inputAndOutputArgumentsRemoved(filePath, arguments);
|
||||
prependWordWidthArgumentIfNotIncluded(&newArguments, projectPart.toolChainWordWidth);
|
||||
if (!isMsvc)
|
||||
prependTargetTripleIfNotIncludedAndNotEmpty(&newArguments, targetTriple);
|
||||
@@ -434,7 +323,7 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector<ProjectPart::Pt
|
||||
AnalyzeUnits unitsToAnalyze;
|
||||
|
||||
foreach (const ProjectPart::Ptr &projectPart, projectParts) {
|
||||
if (!projectPart->selectedForBuilding)
|
||||
if (!projectPart->selectedForBuilding || !projectPart.data())
|
||||
continue;
|
||||
|
||||
foreach (const ProjectFile &file, projectPart->files) {
|
||||
@@ -445,7 +334,7 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector<ProjectPart::Pt
|
||||
if (ProjectFile::isSource(file.kind)) {
|
||||
const CompilerOptionsBuilder::PchUsage pchUsage = CppTools::getPchUsage();
|
||||
const QStringList arguments
|
||||
= ClangStaticAnalyzerOptionsBuilder::build(*projectPart.data(), file.kind, pchUsage);
|
||||
= ClangStaticAnalyzerOptionsBuilder(*projectPart).build(file.kind, pchUsage);
|
||||
unitsToAnalyze << AnalyzeUnit(file.path, arguments);
|
||||
}
|
||||
}
|
||||
@@ -501,21 +390,6 @@ static QDebug operator<<(QDebug debug, const AnalyzeUnits &analyzeUnits)
|
||||
return debug;
|
||||
}
|
||||
|
||||
static QString executableForVersionCheck(Core::Id toolchainType, const QString &executable)
|
||||
{
|
||||
if (toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
|
||||
const QString suffix = QLatin1String("-cl.exe");
|
||||
if (executable.endsWith(suffix, Utils::HostOsInfo::fileNameCaseSensitivity())) {
|
||||
QString modified = executable;
|
||||
modified.chop(suffix.length());
|
||||
modified.append(QLatin1String(".exe"));
|
||||
return modified;
|
||||
}
|
||||
}
|
||||
|
||||
return executable;
|
||||
}
|
||||
|
||||
void ClangStaticAnalyzerToolRunner::start()
|
||||
{
|
||||
m_success = false;
|
||||
@@ -532,8 +406,7 @@ void ClangStaticAnalyzerToolRunner::start()
|
||||
|
||||
// Check clang executable
|
||||
bool isValidClangExecutable;
|
||||
const QString executable = clangExecutableFromSettings(m_toolChainType,
|
||||
&isValidClangExecutable);
|
||||
const QString executable = clangExecutableFromSettings(&isValidClangExecutable);
|
||||
if (!isValidClangExecutable) {
|
||||
const QString errorMessage = tr("Clang Static Analyzer: Invalid executable \"%1\", stop.")
|
||||
.arg(executable);
|
||||
@@ -545,13 +418,12 @@ void ClangStaticAnalyzerToolRunner::start()
|
||||
}
|
||||
|
||||
// Check clang version
|
||||
const QString versionCheckExecutable = executableForVersionCheck(m_toolChainType, executable);
|
||||
const ClangExecutableVersion version = clangExecutableVersion(versionCheckExecutable);
|
||||
const ClangExecutableVersion version = clangExecutableVersion(executable);
|
||||
if (!version.isValid()) {
|
||||
const QString warningMessage
|
||||
= tr("Clang Static Analyzer: Running with possibly unsupported version, "
|
||||
"could not determine version from executable \"%1\".")
|
||||
.arg(versionCheckExecutable);
|
||||
.arg(executable);
|
||||
appendMessage(warningMessage, Utils::StdErrFormat);
|
||||
TaskHub::addTask(Task::Warning, warningMessage, Debugger::Constants::ANALYZERTASK_ID);
|
||||
TaskHub::requestPopup();
|
||||
|
@@ -58,7 +58,7 @@ void ClangStaticAnalyzerUnitTests::initTestCase()
|
||||
if (!toolchain)
|
||||
QSKIP("This test requires that there is a kit with a toolchain.");
|
||||
bool hasClangExecutable;
|
||||
clangExecutableFromSettings(toolchain->typeId(), &hasClangExecutable);
|
||||
clangExecutableFromSettings(&hasClangExecutable);
|
||||
if (!hasClangExecutable)
|
||||
QSKIP("No clang suitable for analyzing found");
|
||||
|
||||
|
@@ -50,7 +50,7 @@ static bool isFileExecutable(const QString &executablePath)
|
||||
namespace ClangStaticAnalyzer {
|
||||
namespace Internal {
|
||||
|
||||
QString clangExecutableFromSettings(Core::Id toolchainType, bool *isValid)
|
||||
QString clangExecutableFromSettings(bool *isValid)
|
||||
{
|
||||
QString executable = ClangStaticAnalyzerSettings::instance()->clangExecutable();
|
||||
if (executable.isEmpty()) {
|
||||
@@ -62,14 +62,6 @@ QString clangExecutableFromSettings(Core::Id toolchainType, bool *isValid)
|
||||
const Qt::CaseSensitivity caseSensitivity = Utils::HostOsInfo::fileNameCaseSensitivity();
|
||||
const bool hasSuffix = executable.endsWith(hostExeSuffix, caseSensitivity);
|
||||
|
||||
if (toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
|
||||
if (hasSuffix)
|
||||
executable.chop(hostExeSuffix.length());
|
||||
executable.append(QLatin1String("-cl"));
|
||||
if (hasSuffix)
|
||||
executable.append(hostExeSuffix);
|
||||
}
|
||||
|
||||
const QFileInfo fileInfo = QFileInfo(executable);
|
||||
if (fileInfo.isAbsolute()) {
|
||||
if (!hasSuffix)
|
||||
|
@@ -41,7 +41,7 @@ namespace Internal {
|
||||
|
||||
bool isClangExecutableUsable(const QString &filePath, QString *errorMessage = 0);
|
||||
|
||||
QString clangExecutableFromSettings(Core::Id toolchainType, bool *isValid);
|
||||
QString clangExecutableFromSettings(bool *isValid);
|
||||
|
||||
QString createFullLocationString(const Debugger::DiagnosticLocation &location);
|
||||
|
||||
|
@@ -44,6 +44,7 @@
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QSet>
|
||||
@@ -72,12 +73,22 @@ BuildDirManager::~BuildDirManager() = default;
|
||||
const Utils::FileName BuildDirManager::workDirectory() const
|
||||
{
|
||||
const Utils::FileName bdir = m_buildConfiguration->buildDirectory();
|
||||
if (bdir.exists())
|
||||
const CMakeTool *cmake = CMakeKitInformation::cmakeTool(m_buildConfiguration->target()->kit());
|
||||
if (bdir.exists()) {
|
||||
return bdir;
|
||||
} else {
|
||||
if (cmake && cmake->autoCreateBuildDirectory()) {
|
||||
if (!QDir().mkpath(bdir.toString()))
|
||||
emitErrorOccured(tr("Failed to create build directory \"%1\".").arg(bdir.toUserOutput()));
|
||||
return bdir;
|
||||
}
|
||||
}
|
||||
if (!m_tempDir) {
|
||||
m_tempDir.reset(new Utils::TemporaryDirectory("qtc-cmake-XXXXXXXX"));
|
||||
if (!m_tempDir->isValid())
|
||||
emitErrorOccured(tr("Failed to create temporary directory \"%1\".").arg(m_tempDir->path()));
|
||||
if (!m_tempDir->isValid()) {
|
||||
emitErrorOccured(tr("Failed to create temporary directory \"%1\".")
|
||||
.arg(QDir::toNativeSeparators(m_tempDir->path())));
|
||||
}
|
||||
}
|
||||
return Utils::FileName::fromString(m_tempDir->path());
|
||||
}
|
||||
|
@@ -378,6 +378,33 @@ void CMakeBuildSettingsWidget::updateSelection(const QModelIndex ¤t, const
|
||||
m_editButton->setEnabled(currentModelIndex.flags().testFlag(Qt::ItemIsEditable));
|
||||
}
|
||||
|
||||
QAction *CMakeBuildSettingsWidget::createForceAction(int type, const QModelIndex &idx)
|
||||
{
|
||||
ConfigModel::DataItem::Type t = static_cast<ConfigModel::DataItem::Type>(type);
|
||||
QString typeString;
|
||||
switch (type) {
|
||||
case ConfigModel::DataItem::BOOLEAN:
|
||||
typeString = tr("bool", "display string for cmake type BOOLEAN");
|
||||
break;
|
||||
case ConfigModel::DataItem::FILE:
|
||||
typeString = tr("file", "display string for cmake type FILE");
|
||||
break;
|
||||
case ConfigModel::DataItem::DIRECTORY:
|
||||
typeString = tr("directory", "display string for cmake type DIRECTORY");
|
||||
break;
|
||||
case ConfigModel::DataItem::STRING:
|
||||
typeString = tr("string", "display string for cmake type STRING");
|
||||
break;
|
||||
case ConfigModel::DataItem::UNKNOWN:
|
||||
return nullptr;
|
||||
}
|
||||
QAction *forceAction = new QAction(tr("Force to %1").arg(typeString), nullptr);
|
||||
forceAction->setEnabled(m_configModel->canForceTo(idx, t));
|
||||
connect(forceAction, &QAction::triggered,
|
||||
this, [this, idx, t]() { m_configModel->forceTo(idx, t); });
|
||||
return forceAction;
|
||||
}
|
||||
|
||||
bool CMakeBuildSettingsWidget::eventFilter(QObject *target, QEvent *event)
|
||||
{
|
||||
// handle context menu events:
|
||||
@@ -392,10 +419,15 @@ bool CMakeBuildSettingsWidget::eventFilter(QObject *target, QEvent *event)
|
||||
QMenu *menu = new QMenu(this);
|
||||
connect(menu, &QMenu::triggered, menu, &QMenu::deleteLater);
|
||||
|
||||
QAction *forceToStringAction = new QAction(tr("Force to String"), nullptr);
|
||||
forceToStringAction->setEnabled(m_configModel->canForceToString(idx));
|
||||
menu->addAction(forceToStringAction);
|
||||
connect(forceToStringAction, &QAction::triggered, this, [this, idx]() { m_configModel->forceToString(idx); });
|
||||
QAction *action = nullptr;
|
||||
if ((action = createForceAction(ConfigModel::DataItem::BOOLEAN, idx)))
|
||||
menu->addAction(action);
|
||||
if ((action = createForceAction(ConfigModel::DataItem::FILE, idx)))
|
||||
menu->addAction(action);
|
||||
if ((action = createForceAction(ConfigModel::DataItem::DIRECTORY, idx)))
|
||||
menu->addAction(action);
|
||||
if ((action = createForceAction(ConfigModel::DataItem::STRING, idx)))
|
||||
menu->addAction(action);
|
||||
|
||||
menu->move(e->globalPos());
|
||||
menu->show();
|
||||
|
@@ -65,6 +65,7 @@ private:
|
||||
void updateFromKit();
|
||||
|
||||
void updateSelection(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
QAction *createForceAction(int type, const QModelIndex &idx);
|
||||
|
||||
bool eventFilter(QObject *target, QEvent *event);
|
||||
|
||||
|
@@ -152,7 +152,7 @@ void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc)
|
||||
}
|
||||
|
||||
updateApplicationAndDeploymentTargets();
|
||||
t->updateDefaultRunConfigurations();
|
||||
updateTargetRunConfigurations(t);
|
||||
|
||||
createGeneratedCodeModelSupport();
|
||||
|
||||
@@ -448,6 +448,34 @@ QStringList CMakeProject::filesGeneratedFrom(const QString &sourceFile) const
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeProject::updateTargetRunConfigurations(Target *t)
|
||||
{
|
||||
// *Update* existing runconfigurations (no need to update new ones!):
|
||||
QHash<QString, const CMakeBuildTarget *> buildTargetHash;
|
||||
const QList<CMakeBuildTarget> buildTargetList = buildTargets();
|
||||
foreach (const CMakeBuildTarget &bt, buildTargetList) {
|
||||
if (bt.targetType != ExecutableType || bt.executable.isEmpty())
|
||||
continue;
|
||||
|
||||
buildTargetHash.insert(bt.title, &bt);
|
||||
}
|
||||
|
||||
foreach (RunConfiguration *rc, t->runConfigurations()) {
|
||||
auto cmakeRc = qobject_cast<CMakeRunConfiguration *>(rc);
|
||||
if (!cmakeRc)
|
||||
continue;
|
||||
|
||||
auto btIt = buildTargetHash.constFind(cmakeRc->title());
|
||||
if (btIt != buildTargetHash.constEnd()) {
|
||||
cmakeRc->setExecutable(btIt.value()->executable.toString());
|
||||
cmakeRc->setBaseWorkingDirectory(btIt.value()->workingDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
// create new and remove obsolete RCs using the factories
|
||||
t->updateDefaultRunConfigurations();
|
||||
}
|
||||
|
||||
void CMakeProject::updateApplicationAndDeploymentTargets()
|
||||
{
|
||||
Target *t = activeTarget();
|
||||
|
@@ -123,6 +123,7 @@ private:
|
||||
|
||||
void createGeneratedCodeModelSupport();
|
||||
QStringList filesGeneratedFrom(const QString &sourceFile) const final;
|
||||
void updateTargetRunConfigurations(ProjectExplorer::Target *t);
|
||||
void updateApplicationAndDeploymentTargets();
|
||||
|
||||
ProjectExplorer::Target *m_connectedTarget = nullptr;
|
||||
|
@@ -66,13 +66,13 @@ public:
|
||||
|
||||
CMakeToolTreeItem *cmakeToolItem(const Core::Id &id) const;
|
||||
CMakeToolTreeItem *cmakeToolItem(const QModelIndex &index) const;
|
||||
QModelIndex addCMakeTool(const QString &name, const FileName &executable, const bool autoRun, const bool isAutoDetected);
|
||||
QModelIndex addCMakeTool(const QString &name, const FileName &executable, const bool autoRun, const bool autoCreate, const bool isAutoDetected);
|
||||
void addCMakeTool(const CMakeTool *item, bool changed);
|
||||
TreeItem *autoGroupItem() const;
|
||||
TreeItem *manualGroupItem() const;
|
||||
void reevaluateChangedFlag(CMakeToolTreeItem *item) const;
|
||||
void updateCMakeTool(const Core::Id &id, const QString &displayName, const FileName &executable,
|
||||
bool autoRun);
|
||||
bool autoRun, bool autoCreate);
|
||||
void removeCMakeTool(const Core::Id &id);
|
||||
void apply();
|
||||
|
||||
@@ -95,16 +95,18 @@ public:
|
||||
m_name(item->displayName()),
|
||||
m_executable(item->cmakeExecutable()),
|
||||
m_isAutoRun(item->isAutoRun()),
|
||||
m_autoCreateBuildDirectory(item->autoCreateBuildDirectory()),
|
||||
m_autodetected(item->isAutoDetected()),
|
||||
m_changed(changed)
|
||||
{}
|
||||
|
||||
CMakeToolTreeItem(const QString &name, const Utils::FileName &executable,
|
||||
bool autoRun, bool autodetected) :
|
||||
bool autoRun, bool autoCreate, bool autodetected) :
|
||||
m_id(Core::Id::fromString(QUuid::createUuid().toString())),
|
||||
m_name(name),
|
||||
m_executable(executable),
|
||||
m_isAutoRun(autoRun),
|
||||
m_autoCreateBuildDirectory(autoCreate),
|
||||
m_autodetected(autodetected),
|
||||
m_changed(true)
|
||||
{}
|
||||
@@ -143,6 +145,7 @@ public:
|
||||
QString m_name;
|
||||
FileName m_executable;
|
||||
bool m_isAutoRun = true;
|
||||
bool m_autoCreateBuildDirectory = false;
|
||||
bool m_autodetected = false;
|
||||
bool m_changed = true;
|
||||
};
|
||||
@@ -166,9 +169,10 @@ CMakeToolItemModel::CMakeToolItemModel()
|
||||
}
|
||||
|
||||
QModelIndex CMakeToolItemModel::addCMakeTool(const QString &name, const FileName &executable,
|
||||
const bool autoRun, const bool isAutoDetected)
|
||||
const bool autoRun, const bool autoCreate,
|
||||
const bool isAutoDetected)
|
||||
{
|
||||
CMakeToolTreeItem *item = new CMakeToolTreeItem(name, executable, autoRun, isAutoDetected);
|
||||
CMakeToolTreeItem *item = new CMakeToolTreeItem(name, executable, autoRun, autoCreate, isAutoDetected);
|
||||
if (isAutoDetected)
|
||||
autoGroupItem()->appendChild(item);
|
||||
else
|
||||
@@ -219,7 +223,8 @@ void CMakeToolItemModel::reevaluateChangedFlag(CMakeToolTreeItem *item) const
|
||||
}
|
||||
|
||||
void CMakeToolItemModel::updateCMakeTool(const Core::Id &id, const QString &displayName,
|
||||
const FileName &executable, bool autoRun)
|
||||
const FileName &executable, bool autoRun,
|
||||
bool autoCreate)
|
||||
{
|
||||
CMakeToolTreeItem *treeItem = cmakeToolItem(id);
|
||||
QTC_ASSERT(treeItem, return);
|
||||
@@ -227,6 +232,7 @@ void CMakeToolItemModel::updateCMakeTool(const Core::Id &id, const QString &disp
|
||||
treeItem->m_name = displayName;
|
||||
treeItem->m_executable = executable;
|
||||
treeItem->m_isAutoRun = autoRun;
|
||||
treeItem->m_autoCreateBuildDirectory = autoCreate;
|
||||
|
||||
reevaluateChangedFlag(treeItem);
|
||||
}
|
||||
@@ -262,6 +268,7 @@ void CMakeToolItemModel::apply()
|
||||
cmake->setDisplayName(item->m_name);
|
||||
cmake->setCMakeExecutable(item->m_executable);
|
||||
cmake->setAutorun(item->m_isAutoRun);
|
||||
cmake->setAutoCreateBuildDirectory(item->m_autoCreateBuildDirectory);
|
||||
} else {
|
||||
toRegister.append(item);
|
||||
}
|
||||
@@ -329,6 +336,7 @@ private:
|
||||
CMakeToolItemModel *m_model;
|
||||
QLineEdit *m_displayNameLineEdit;
|
||||
QCheckBox *m_autoRunCheckBox;
|
||||
QCheckBox *m_autoCreateBuildDirectoryCheckBox;
|
||||
PathChooser *m_binaryChooser;
|
||||
Core::Id m_id;
|
||||
bool m_loadingItem;
|
||||
@@ -349,11 +357,16 @@ CMakeToolItemConfigWidget::CMakeToolItemConfigWidget(CMakeToolItemModel *model)
|
||||
m_autoRunCheckBox->setText(tr("Autorun CMake"));
|
||||
m_autoRunCheckBox->setToolTip(tr("Automatically run CMake after changes to CMake project files."));
|
||||
|
||||
m_autoCreateBuildDirectoryCheckBox = new QCheckBox;
|
||||
m_autoCreateBuildDirectoryCheckBox->setText(tr("Auto-create build directories"));
|
||||
m_autoCreateBuildDirectoryCheckBox->setToolTip(tr("Automatically create build directories for CMake projects."));
|
||||
|
||||
QFormLayout *formLayout = new QFormLayout(this);
|
||||
formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
|
||||
formLayout->addRow(new QLabel(tr("Name:")), m_displayNameLineEdit);
|
||||
formLayout->addRow(new QLabel(tr("Path:")), m_binaryChooser);
|
||||
formLayout->addRow(m_autoRunCheckBox);
|
||||
formLayout->addRow(m_autoCreateBuildDirectoryCheckBox);
|
||||
|
||||
connect(m_binaryChooser, &PathChooser::rawPathChanged,
|
||||
this, &CMakeToolItemConfigWidget::store);
|
||||
@@ -361,13 +374,16 @@ CMakeToolItemConfigWidget::CMakeToolItemConfigWidget(CMakeToolItemModel *model)
|
||||
this, &CMakeToolItemConfigWidget::store);
|
||||
connect(m_autoRunCheckBox, &QCheckBox::toggled,
|
||||
this, &CMakeToolItemConfigWidget::store);
|
||||
connect(m_autoCreateBuildDirectoryCheckBox, &QCheckBox::toggled,
|
||||
this, &CMakeToolItemConfigWidget::store);
|
||||
}
|
||||
|
||||
void CMakeToolItemConfigWidget::store() const
|
||||
{
|
||||
if (!m_loadingItem && m_id.isValid())
|
||||
m_model->updateCMakeTool(m_id, m_displayNameLineEdit->text(), m_binaryChooser->fileName(),
|
||||
m_autoRunCheckBox->checkState() == Qt::Checked);
|
||||
m_autoRunCheckBox->checkState() == Qt::Checked,
|
||||
m_autoCreateBuildDirectoryCheckBox->checkState() == Qt::Checked);
|
||||
}
|
||||
|
||||
void CMakeToolItemConfigWidget::load(const CMakeToolTreeItem *item)
|
||||
@@ -387,6 +403,7 @@ void CMakeToolItemConfigWidget::load(const CMakeToolTreeItem *item)
|
||||
m_binaryChooser->setFileName(item->m_executable);
|
||||
|
||||
m_autoRunCheckBox->setChecked(item->m_isAutoRun);
|
||||
m_autoCreateBuildDirectoryCheckBox->setChecked(item->m_autoCreateBuildDirectory);
|
||||
|
||||
m_id = item->m_id;
|
||||
m_loadingItem = false;
|
||||
@@ -492,7 +509,8 @@ void CMakeToolConfigWidget::cloneCMakeTool()
|
||||
|
||||
QModelIndex newItem = m_model.addCMakeTool(tr("Clone of %1").arg(m_currentItem->m_name),
|
||||
m_currentItem->m_executable,
|
||||
m_currentItem->m_isAutoRun, false);
|
||||
m_currentItem->m_isAutoRun,
|
||||
m_currentItem->m_autoCreateBuildDirectory, false);
|
||||
|
||||
m_cmakeToolsView->setCurrentIndex(newItem);
|
||||
}
|
||||
@@ -500,7 +518,7 @@ void CMakeToolConfigWidget::cloneCMakeTool()
|
||||
void CMakeToolConfigWidget::addCMakeTool()
|
||||
{
|
||||
QModelIndex newItem = m_model.addCMakeTool(m_model.uniqueDisplayName(tr("New CMake")),
|
||||
FileName(), true, false);
|
||||
FileName(), true, false, false);
|
||||
|
||||
m_cmakeToolsView->setCurrentIndex(newItem);
|
||||
}
|
||||
|
@@ -46,6 +46,7 @@ const char CMAKE_INFORMATION_ID[] = "Id";
|
||||
const char CMAKE_INFORMATION_COMMAND[] = "Binary";
|
||||
const char CMAKE_INFORMATION_DISPLAYNAME[] = "DisplayName";
|
||||
const char CMAKE_INFORMATION_AUTORUN[] = "AutoRun";
|
||||
const char CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY[] = "AutoCreateBuildDirectory";
|
||||
const char CMAKE_INFORMATION_AUTODETECTED[] = "AutoDetected";
|
||||
|
||||
|
||||
@@ -68,6 +69,7 @@ CMakeTool::CMakeTool(const QVariantMap &map, bool fromSdk) : m_isAutoDetected(fr
|
||||
m_id = Core::Id::fromSetting(map.value(CMAKE_INFORMATION_ID));
|
||||
m_displayName = map.value(CMAKE_INFORMATION_DISPLAYNAME).toString();
|
||||
m_isAutoRun = map.value(CMAKE_INFORMATION_AUTORUN, true).toBool();
|
||||
m_autoCreateBuildDirectory = map.value(CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY, false).toBool();
|
||||
|
||||
//loading a CMakeTool from SDK is always autodetection
|
||||
if (!fromSdk)
|
||||
@@ -102,6 +104,15 @@ void CMakeTool::setAutorun(bool autoRun)
|
||||
CMakeToolManager::notifyAboutUpdate(this);
|
||||
}
|
||||
|
||||
void CMakeTool::setAutoCreateBuildDirectory(bool autoBuildDir)
|
||||
{
|
||||
if (m_autoCreateBuildDirectory == autoBuildDir)
|
||||
return;
|
||||
|
||||
m_autoCreateBuildDirectory = autoBuildDir;
|
||||
CMakeToolManager::notifyAboutUpdate(this);
|
||||
}
|
||||
|
||||
bool CMakeTool::isValid() const
|
||||
{
|
||||
if (!m_id.isValid())
|
||||
@@ -142,6 +153,7 @@ QVariantMap CMakeTool::toMap() const
|
||||
data.insert(CMAKE_INFORMATION_ID, m_id.toSetting());
|
||||
data.insert(CMAKE_INFORMATION_COMMAND, m_executable.toString());
|
||||
data.insert(CMAKE_INFORMATION_AUTORUN, m_isAutoRun);
|
||||
data.insert(CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY, m_autoCreateBuildDirectory);
|
||||
data.insert(CMAKE_INFORMATION_AUTODETECTED, m_isAutoDetected);
|
||||
return data;
|
||||
}
|
||||
@@ -162,6 +174,11 @@ bool CMakeTool::isAutoRun() const
|
||||
return m_isAutoRun;
|
||||
}
|
||||
|
||||
bool CMakeTool::autoCreateBuildDirectory() const
|
||||
{
|
||||
return m_autoCreateBuildDirectory;
|
||||
}
|
||||
|
||||
QList<CMakeTool::Generator> CMakeTool::supportedGenerators() const
|
||||
{
|
||||
readInformation(QueryType::GENERATORS);
|
||||
|
@@ -90,9 +90,11 @@ public:
|
||||
|
||||
void setCMakeExecutable(const Utils::FileName &executable);
|
||||
void setAutorun(bool autoRun);
|
||||
void setAutoCreateBuildDirectory(bool autoBuildDir);
|
||||
|
||||
Utils::FileName cmakeExecutable() const;
|
||||
bool isAutoRun() const;
|
||||
bool autoCreateBuildDirectory() const;
|
||||
QList<Generator> supportedGenerators() const;
|
||||
TextEditor::Keywords keywords();
|
||||
bool hasServerMode() const;
|
||||
@@ -127,6 +129,7 @@ private:
|
||||
|
||||
bool m_isAutoRun = true;
|
||||
bool m_isAutoDetected = false;
|
||||
bool m_autoCreateBuildDirectory = false;
|
||||
|
||||
mutable bool m_didAttemptToRun = false;
|
||||
mutable bool m_didRun = false;
|
||||
|
@@ -135,23 +135,23 @@ bool ConfigModel::hasCMakeChanges() const
|
||||
return Utils::contains(m_configuration, [](const InternalDataItem &i) { return i.isCMakeChanged; });
|
||||
}
|
||||
|
||||
bool ConfigModel::canForceToString(const QModelIndex &idx) const
|
||||
bool ConfigModel::canForceTo(const QModelIndex &idx, const ConfigModel::DataItem::Type type) const
|
||||
{
|
||||
if (idx.model() != const_cast<ConfigModel *>(this) || idx.column() != 1)
|
||||
return false;
|
||||
Utils::TreeItem *item = itemForIndex(idx);
|
||||
auto cmti = dynamic_cast<Internal::ConfigModelTreeItem *>(item);
|
||||
return cmti && (cmti->dataItem->type != DataItem::STRING);
|
||||
return cmti && (cmti->dataItem->type != type);
|
||||
}
|
||||
|
||||
void ConfigModel::forceToString(const QModelIndex &idx)
|
||||
void ConfigModel::forceTo(const QModelIndex &idx, const ConfigModel::DataItem::Type type)
|
||||
{
|
||||
QTC_ASSERT(canForceToString(idx), return);
|
||||
QTC_ASSERT(canForceTo(idx, type), return);
|
||||
Utils::TreeItem *item = itemForIndex(idx);
|
||||
auto cmti = dynamic_cast<Internal::ConfigModelTreeItem *>(item);
|
||||
|
||||
cmti->dataItem->type = DataItem::STRING;
|
||||
const QModelIndex valueIdx = idx.sibling(1, idx.column());
|
||||
cmti->dataItem->type = type;
|
||||
const QModelIndex valueIdx = idx.sibling(idx.row(), 1);
|
||||
emit dataChanged(valueIdx, valueIdx);
|
||||
}
|
||||
|
||||
|
@@ -73,8 +73,8 @@ public:
|
||||
bool hasChanges() const;
|
||||
bool hasCMakeChanges() const;
|
||||
|
||||
bool canForceToString(const QModelIndex &idx) const;
|
||||
void forceToString(const QModelIndex &idx);
|
||||
bool canForceTo(const QModelIndex &idx, const DataItem::Type type) const;
|
||||
void forceTo(const QModelIndex &idx, const DataItem::Type type);
|
||||
|
||||
static DataItem dataItemFromIndex(const QModelIndex &idx);
|
||||
|
||||
|
@@ -207,7 +207,7 @@ const char TR_CLEAR_MENU[] = QT_TRANSLATE_NOOP("Core", "Clear Menu");
|
||||
|
||||
const char DEFAULT_BUILD_DIRECTORY[] = "../%{JS: Util.asciify(\"build-%{CurrentProject:Name}-%{CurrentKit:FileSystemName}-%{CurrentBuild:Name}\")}";
|
||||
|
||||
const int TARGET_ICON_SIZE = 32;
|
||||
const int MODEBAR_ICON_SIZE = 34;
|
||||
const int DEFAULT_MAX_LINE_COUNT = 100000;
|
||||
|
||||
} // namespace Constants
|
||||
|
@@ -178,7 +178,7 @@ void FancyToolButton::paintEvent(QPaintEvent *event)
|
||||
|
||||
const QIcon::Mode iconMode = isEnabled() ? ((isDown() || isChecked()) ? QIcon::Active : QIcon::Normal)
|
||||
: QIcon::Disabled;
|
||||
QRect iconRect(0, 0, Constants::TARGET_ICON_SIZE, Constants::TARGET_ICON_SIZE);
|
||||
QRect iconRect(0, 0, Constants::MODEBAR_ICON_SIZE, Constants::MODEBAR_ICON_SIZE);
|
||||
// draw popup texts
|
||||
if (isTitledAction) {
|
||||
|
||||
@@ -203,7 +203,7 @@ void FancyToolButton::paintEvent(QPaintEvent *event)
|
||||
painter.setFont(normalFont);
|
||||
|
||||
QPoint textOffset = centerRect.center() - QPoint(iconRect.width()/2, iconRect.height()/2);
|
||||
textOffset = textOffset - QPoint(0, lineHeight + 4);
|
||||
textOffset = textOffset - QPoint(0, lineHeight + 3);
|
||||
QRectF r(0, textOffset.y(), rect().width(), lineHeight);
|
||||
painter.setPen(creatorTheme()->color(isEnabled()
|
||||
? Theme::PanelTextColorLight
|
||||
@@ -218,8 +218,8 @@ void FancyToolButton::paintEvent(QPaintEvent *event)
|
||||
// draw build configuration name
|
||||
textOffset = iconRect.center() + QPoint(iconRect.width()/2, iconRect.height()/2);
|
||||
QRectF buildConfigRect[2];
|
||||
buildConfigRect[0] = QRectF(0, textOffset.y() + 5, rect().width(), lineHeight);
|
||||
buildConfigRect[1] = QRectF(0, textOffset.y() + 5 + lineHeight, rect().width(), lineHeight);
|
||||
buildConfigRect[0] = QRectF(0, textOffset.y() + 4, rect().width(), lineHeight);
|
||||
buildConfigRect[1] = QRectF(0, textOffset.y() + 4 + lineHeight, rect().width(), lineHeight);
|
||||
painter.setFont(boldFont);
|
||||
QVector<QString> splitBuildConfiguration(2);
|
||||
const QString buildConfiguration = defaultAction()->property("subtitle").toString();
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "fancytabwidget.h"
|
||||
#include "fancyactionbar.h"
|
||||
#include "coreconstants.h"
|
||||
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/stylehelper.h>
|
||||
@@ -324,7 +325,10 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const
|
||||
tabIconRect.adjust(0, 4, 0, -textHeight);
|
||||
const QIcon::Mode iconMode = enabled ? (selected ? QIcon::Active : QIcon::Normal)
|
||||
: QIcon::Disabled;
|
||||
StyleHelper::drawIconWithShadow(tab->icon, tabIconRect, painter, iconMode);
|
||||
QRect iconRect(0, 0, Core::Constants::MODEBAR_ICON_SIZE, Core::Constants::MODEBAR_ICON_SIZE);
|
||||
iconRect.moveCenter(tabIconRect.center());
|
||||
iconRect = iconRect.intersected(tabIconRect);
|
||||
StyleHelper::drawIconWithShadow(tab->icon, iconRect, painter, iconMode);
|
||||
}
|
||||
|
||||
painter->setOpacity(1.0); //FIXME: was 0.7 before?
|
||||
|
@@ -210,8 +210,6 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) :
|
||||
this, &SearchResultWidget::handleReplaceButton);
|
||||
connect(m_replaceButton, &QAbstractButton::clicked,
|
||||
this, &SearchResultWidget::handleReplaceButton);
|
||||
connect(m_replaceTextEdit, &QLineEdit::textChanged,
|
||||
this, &SearchResultWidget::handleReplaceEditTextChanged);
|
||||
}
|
||||
|
||||
SearchResultWidget::~SearchResultWidget()
|
||||
@@ -306,7 +304,6 @@ void SearchResultWidget::setSupportsReplace(bool replaceSupported, const QString
|
||||
|
||||
void SearchResultWidget::setTextToReplace(const QString &textToReplace)
|
||||
{
|
||||
m_replaceText = textToReplace;
|
||||
m_replaceTextEdit->setText(textToReplace);
|
||||
}
|
||||
|
||||
@@ -409,6 +406,7 @@ void SearchResultWidget::goToPrevious()
|
||||
void SearchResultWidget::restart()
|
||||
{
|
||||
m_replaceTextEdit->setEnabled(false);
|
||||
m_replaceButton->setEnabled(false);
|
||||
m_searchResultTreeView->clear();
|
||||
m_count = 0;
|
||||
Id sizeWarningId(SIZE_WARNING_ID);
|
||||
@@ -418,7 +416,6 @@ void SearchResultWidget::restart()
|
||||
m_searchAgainButton->setVisible(false);
|
||||
m_messageWidget->setVisible(false);
|
||||
updateMatchesFoundLabel();
|
||||
handleReplaceEditTextChanged();
|
||||
emit restarted();
|
||||
}
|
||||
|
||||
@@ -439,6 +436,7 @@ void SearchResultWidget::finishSearch(bool canceled)
|
||||
m_infoBar.removeInfo(sizeWarningId);
|
||||
m_infoBar.enableInfo(sizeWarningId);
|
||||
m_replaceTextEdit->setEnabled(m_count > 0);
|
||||
m_replaceButton->setEnabled(m_count > 0);
|
||||
m_preserveCaseCheck->setEnabled(m_count > 0);
|
||||
m_cancelButton->setVisible(false);
|
||||
m_messageWidget->setVisible(canceled);
|
||||
@@ -463,15 +461,6 @@ void SearchResultWidget::cancelAfterSizeWarning()
|
||||
emit paused(false);
|
||||
}
|
||||
|
||||
void SearchResultWidget::handleReplaceEditTextChanged()
|
||||
{
|
||||
const bool enabled = m_replaceTextEdit->text() != m_replaceText;
|
||||
m_replaceButton->setEnabled(enabled);
|
||||
m_replaceButton->setToolTip(enabled
|
||||
? QString()
|
||||
: tr("Cannot replace because replacement text is unchanged."));
|
||||
}
|
||||
|
||||
void SearchResultWidget::handleJumpToSearchResult(const SearchResultItem &item)
|
||||
{
|
||||
emit activated(item);
|
||||
|
@@ -115,7 +115,6 @@ private:
|
||||
void setShowReplaceUI(bool visible);
|
||||
void continueAfterSizeWarning();
|
||||
void cancelAfterSizeWarning();
|
||||
void handleReplaceEditTextChanged();
|
||||
|
||||
QList<SearchResultItem> checkedItems() const;
|
||||
void updateMatchesFoundLabel();
|
||||
@@ -142,7 +141,6 @@ private:
|
||||
bool m_isShowingReplaceUI = false;
|
||||
bool m_searchAgainSupported = false;
|
||||
bool m_replaceSupported = false;
|
||||
QString m_replaceText;
|
||||
};
|
||||
|
||||
} // Internal
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 426 B After Width: | Height: | Size: 389 B |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 223 B After Width: | Height: | Size: 218 B |
Before Width: | Height: | Size: 369 B After Width: | Height: | Size: 362 B |
Before Width: | Height: | Size: 109 B After Width: | Height: | Size: 110 B |
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 117 B |