Merge remote-tracking branch 'origin/master' into 4.5

Change-Id: I20eb743180b51dbedabced277a8f12ebe9620807
This commit is contained in:
Eike Ziller
2017-09-25 11:03:45 +02:00
311 changed files with 4011 additions and 3115 deletions

View File

@@ -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.

View File

@@ -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.

View File

@@ -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*'))

View File

@@ -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()

View File

@@ -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" ]

View File

@@ -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,

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)

View 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

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)
@@ -262,16 +273,16 @@ void DatabaseBackend::checkDatabaseCouldBeOpened(int resultCode)
}
void DatabaseBackend::checkPragmaValue(Utils::SmallStringView databaseValue,
Utils::SmallStringView expectedValue)
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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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_OK)
unlockNotification.wait();
else
throwException("SqliteStatement::waitForUnlockNotify: database is in a dead lock!");
if (resultCode == SQLITE_LOCKED)
throw DeadLock("SqliteStatement::waitForUnlockNotify: database is in a dead lock!");
unlockNotification.wait();
}
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;
}
@@ -159,30 +166,30 @@ 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!");
int resultCode = sqlite3_bind_int(m_compiledStatement.get(), index, value);
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!");
int resultCode = sqlite3_bind_int64(m_compiledStatement.get(), index, value);
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);

View File

@@ -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,164 +92,86 @@ 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)
template <typename ResultType,
int ResultTypeCount = 1>
std::vector<ResultType> values(std::size_t reserveSize)
{
using Container = std::vector<std::tuple<ResultTypes...>>;
Container resultValues;
std::vector<ResultType> resultValues;
resultValues.reserve(reserveSize);
while (next())
emplaceTupleValues<Container, ResultTypes...>(resultValues);
emplaceBackValues<ResultTypeCount>(resultValues);
reset();
return resultValues;
}
template <typename... ResultTypes,
template <typename ResultType,
int ResultTypeCount = 1,
typename... QueryTypes>
std::vector<std::tuple<ResultTypes...>> tupleValues(std::size_t reserveSize, const QueryTypes&... queryValues)
std::vector<ResultType> values(std::size_t reserveSize, const QueryTypes&... queryValues)
{
using Container = std::vector<std::tuple<ResultTypes...>>;
Container resultValues;
std::vector<ResultType> resultValues;
resultValues.reserve(reserveSize);
bindValues(queryValues...);
while (next())
emplaceTupleValues<Container, ResultTypes...>(resultValues);
emplaceBackValues<ResultTypeCount>(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,
template <typename ResultType,
int ResultTypeCount = 1,
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,
std::vector<ResultType> values(std::size_t reserveSize,
const std::vector<QueryElementType> &queryValues)
{
using Container = std::vector<ResultType>;
Container resultValues;
std::vector<ResultType> resultValues;
resultValues.reserve(reserveSize);
for (const QueryElementType &queryValue : queryValues) {
bindValues(queryValue);
while (next())
pushBackStructValues<Container, ResultEntryTypes...>(resultValues);
emplaceBackValues<ResultTypeCount>(resultValues);
reset();
}
@@ -250,9 +180,9 @@ protected:
}
template <typename ResultType,
typename... ResultEntryTypes,
int ResultTypeCount = 1,
typename... QueryElementTypes>
std::vector<ResultType> structValues(std::size_t reserveSize,
std::vector<ResultType> values(std::size_t reserveSize,
const std::vector<std::tuple<QueryElementTypes...>> &queryTuples)
{
using Container = std::vector<ResultType>;
@@ -263,62 +193,7 @@ protected:
bindTupleValues(queryTuple);
while (next())
pushBackStructValues<Container, ResultEntryTypes...>(resultValues);
reset();
}
return resultValues;
}
template <typename ResultType,
typename... ElementTypes>
std::vector<ResultType> values(std::size_t reserveSize)
{
std::vector<ResultType> resultValues;
resultValues.reserve(reserveSize);
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<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));
emplaceBackValues<ResultTypeCount>(resultValues);
reset();
}
@@ -327,20 +202,20 @@ protected:
}
template <typename ResultType,
int ResultTypeCount = 1,
typename... QueryTypes>
std::vector<ResultType> values(std::size_t reserveSize, const QueryTypes&... queryValues)
Utils::optional<ResultType> value( const QueryTypes&... queryValues)
{
std::vector<ResultType> resultValues;
resultValues.reserve(reserveSize);
Utils::optional<ResultType> resultValue;
bindValues(queryValues...);
while (next())
resultValues.push_back(value<ResultType>(0));
if (next())
resultValue = assignValue<Utils::optional<ResultType>, ResultTypeCount>();
reset();
return resultValues;
return resultValue;
}
template <typename Type>
@@ -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

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)) {

View File

@@ -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

View File

@@ -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,
int pos,
int *line, int *column);
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

View File

@@ -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 \

View File

@@ -232,6 +232,8 @@ Project {
"textfieldcombobox.h",
"textfileformat.cpp",
"textfileformat.h",
"textutils.cpp",
"textutils.h",
"treemodel.cpp",
"treemodel.h",
"treeviewcombobox.cpp",

View File

@@ -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());
}

View File

@@ -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();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 B

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 B

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 B

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 280 B

View File

@@ -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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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";

View File

@@ -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)

View File

@@ -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>

View File

@@ -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"};

View 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;

View File

@@ -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());

View File

@@ -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,

View File

@@ -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};

View File

@@ -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();

View File

@@ -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,10 +320,10 @@ static QFuture<CppTools::CursorInfo> defaultCursorInfoFuture()
static bool convertPosition(const QTextCursor &textCursor, int *line, int *column)
{
const bool converted = TextEditor::Convenience::convertPosition(textCursor.document(),
textCursor.position(),
line,
column);
const bool converted = ::Utils::Text::convertPosition(textCursor.document(),
textCursor.position(),
line,
column);
QTC_CHECK(converted);
return converted;
}
@@ -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

View File

@@ -86,14 +86,14 @@ public:
void setParserConfig(const CppTools::BaseEditorDocumentParser::Configuration config) override;
QFuture<CppTools::CursorInfo> cursorInfo(const CppTools::CursorInfoParams &params) 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;
};

View File

@@ -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,
&positionInBlock);
const unsigned line = lineNumber;
const unsigned column = positionInBlock + 1;
QTextCursor cursor = Utils::Text::wordStartCursor(data.cursor());
Utils::Text::convertPosition(cursor.document(), cursor.position(), &lineNumber,
&positionInBlock);
const uint line = lineNumber;
const uint column = positionInBlock + 1;
if (!resolveTarget)
return link;
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);
}

View File

@@ -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;

View File

@@ -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(

View File

@@ -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

View File

@@ -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)

View File

@@ -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(

View File

@@ -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

View File

@@ -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);

View File

@@ -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();

View File

@@ -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);

View File

@@ -39,24 +39,25 @@ class SourceLocations
public:
struct Location
{
qint64 sourceId;
qint64 line;
qint64 column;
Location(qint64 sourceId, qint64 line, qint64 column)
: sourceId(sourceId), line(line), column(column)
{}
qint64 sourceId;
qint64 line;
qint64 column;
};
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;
};

View File

@@ -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);

View File

@@ -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),

View File

@@ -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 &macroName, 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
{
// 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 addExtraOptions() final {}
void addLanguageOption(ProjectFile::Kind fileKind) override
void addWrappedQtHeadersIncludePath() final
{
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();

View File

@@ -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");

View File

@@ -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)

View File

@@ -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);

View File

@@ -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());
}

View File

@@ -378,6 +378,33 @@ void CMakeBuildSettingsWidget::updateSelection(const QModelIndex &current, 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();

View File

@@ -65,6 +65,7 @@ private:
void updateFromKit();
void updateSelection(const QModelIndex &current, const QModelIndex &previous);
QAction *createForceAction(int type, const QModelIndex &idx);
bool eventFilter(QObject *target, QEvent *event);

View File

@@ -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();

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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();

View File

@@ -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?

View File

@@ -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);

View File

@@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 B

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 B

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 B

After

Width:  |  Height:  |  Size: 117 B

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