forked from qt-creator/qt-creator
C++: Implement context-aware expand / shrink selection actions.
Implement selection expanding / shrinking, that is aware of C++ semantics, thus giving smart selection changing. Change-Id: I1386a20597fa6bb85c3aa0d8ddfb87cdb3fd7c38 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
committed by
Nikolai Kosjar
parent
8bfdc82c5a
commit
bed88818ce
@@ -48,6 +48,7 @@
|
||||
#include <cpptools/cppcompletionassistprovider.h>
|
||||
#include <cpptools/cppeditoroutline.h>
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
#include <cpptools/cppselectionchanger.h>
|
||||
#include <cpptools/cppsemanticinfo.h>
|
||||
#include <cpptools/cpptoolsconstants.h>
|
||||
#include <cpptools/cpptoolsplugin.h>
|
||||
@@ -55,6 +56,7 @@
|
||||
#include <cpptools/cppworkingcopy.h>
|
||||
#include <cpptools/symbolfinder.h>
|
||||
|
||||
#include <texteditor/behaviorsettings.h>
|
||||
#include <texteditor/completionsettings.h>
|
||||
#include <texteditor/convenience.h>
|
||||
#include <texteditor/textdocument.h>
|
||||
@@ -119,6 +121,8 @@ public:
|
||||
|
||||
QScopedPointer<FollowSymbolUnderCursor> m_followSymbolUnderCursor;
|
||||
QToolButton *m_preprocessorButton;
|
||||
|
||||
CppSelectionChanger m_cppSelectionChanger;
|
||||
};
|
||||
|
||||
CppEditorWidgetPrivate::CppEditorWidgetPrivate(CppEditorWidget *q)
|
||||
@@ -130,6 +134,7 @@ CppEditorWidgetPrivate::CppEditorWidgetPrivate(CppEditorWidget *q)
|
||||
, m_declDefLinkFinder(new FunctionDeclDefLinkFinder(q))
|
||||
, m_followSymbolUnderCursor(new FollowSymbolUnderCursor(q))
|
||||
, m_preprocessorButton(0)
|
||||
, m_cppSelectionChanger()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -201,6 +206,9 @@ void CppEditorWidget::finalizeInitialization()
|
||||
connect(this, &CppEditorWidget::cursorPositionChanged, [this]() {
|
||||
if (!d->m_localRenaming.isActive())
|
||||
d->m_useSelectionsUpdater.scheduleUpdate();
|
||||
|
||||
// Notify selection expander about the changed cursor.
|
||||
d->m_cppSelectionChanger.onCursorPositionChanged(textCursor());
|
||||
});
|
||||
|
||||
// Tool bar creation
|
||||
@@ -328,6 +336,44 @@ void CppEditorWidget::renameUsages(const QString &replacement)
|
||||
}
|
||||
}
|
||||
|
||||
bool CppEditorWidget::selectBlockUp()
|
||||
{
|
||||
if (!behaviorSettings().m_smartSelectionChanging)
|
||||
return TextEditorWidget::selectBlockUp();
|
||||
|
||||
QTextCursor cursor = textCursor();
|
||||
d->m_cppSelectionChanger.startChangeSelection();
|
||||
const bool changed =
|
||||
d->m_cppSelectionChanger.changeSelection(
|
||||
CppSelectionChanger::ExpandSelection,
|
||||
cursor,
|
||||
d->m_lastSemanticInfo.doc);
|
||||
if (changed)
|
||||
setTextCursor(cursor);
|
||||
d->m_cppSelectionChanger.stopChangeSelection();
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool CppEditorWidget::selectBlockDown()
|
||||
{
|
||||
if (!behaviorSettings().m_smartSelectionChanging)
|
||||
return TextEditorWidget::selectBlockDown();
|
||||
|
||||
QTextCursor cursor = textCursor();
|
||||
d->m_cppSelectionChanger.startChangeSelection();
|
||||
const bool changed =
|
||||
d->m_cppSelectionChanger.changeSelection(
|
||||
CppSelectionChanger::ShrinkSelection,
|
||||
cursor,
|
||||
d->m_lastSemanticInfo.doc);
|
||||
if (changed)
|
||||
setTextCursor(cursor);
|
||||
d->m_cppSelectionChanger.stopChangeSelection();
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
void CppEditorWidget::renameSymbolUnderCursor()
|
||||
{
|
||||
d->m_useSelectionsUpdater.abortSchedule();
|
||||
|
||||
@@ -92,6 +92,9 @@ public slots:
|
||||
void renameSymbolUnderCursor();
|
||||
void renameUsages(const QString &replacement = QString());
|
||||
|
||||
bool selectBlockUp() override;
|
||||
bool selectBlockDown() override;
|
||||
|
||||
protected:
|
||||
bool event(QEvent *e) override;
|
||||
void contextMenuEvent(QContextMenuEvent *) override;
|
||||
|
||||
1113
src/plugins/cpptools/cppselectionchanger.cpp
Normal file
1113
src/plugins/cpptools/cppselectionchanger.cpp
Normal file
File diff suppressed because it is too large
Load Diff
128
src/plugins/cpptools/cppselectionchanger.h
Normal file
128
src/plugins/cpptools/cppselectionchanger.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 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.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CPPSELECTIONCHANGER_H
|
||||
#define CPPSELECTIONCHANGER_H
|
||||
|
||||
#include "cpptools_global.h"
|
||||
|
||||
#include <cplusplus/ASTPath.h>
|
||||
#include <cplusplus/CppDocument.h>
|
||||
#include <cplusplus/TranslationUnit.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QTextCursor>
|
||||
|
||||
namespace CppTools {
|
||||
|
||||
class ASTNodePositions {
|
||||
public:
|
||||
ASTNodePositions() {}
|
||||
ASTNodePositions(CPlusPlus::AST *_ast) : ast(_ast) {}
|
||||
operator bool() const { return ast; }
|
||||
|
||||
CPlusPlus::AST *ast = 0;
|
||||
unsigned firstTokenIndex = 0;
|
||||
unsigned lastTokenIndex = 0;
|
||||
unsigned secondToLastTokenIndex = 0;
|
||||
int astPosStart = -1;
|
||||
int astPosEnd = -1;
|
||||
};
|
||||
|
||||
class CPPTOOLS_EXPORT CppSelectionChanger : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CppSelectionChanger(QObject *parent = 0);
|
||||
|
||||
enum Direction {
|
||||
ExpandSelection,
|
||||
ShrinkSelection
|
||||
};
|
||||
|
||||
enum NodeIndexAndStepState {
|
||||
NodeIndexAndStepNotSet,
|
||||
NodeIndexAndStepWholeDocument,
|
||||
};
|
||||
|
||||
bool changeSelection(Direction direction,
|
||||
QTextCursor &cursorToModify,
|
||||
const CPlusPlus::Document::Ptr doc);
|
||||
void startChangeSelection();
|
||||
void stopChangeSelection();
|
||||
|
||||
public slots:
|
||||
void onCursorPositionChanged(const QTextCursor &newCursor);
|
||||
|
||||
protected slots:
|
||||
void fineTuneForStatementPositions(unsigned firstParensTokenIndex,
|
||||
unsigned lastParensTokenIndex,
|
||||
ASTNodePositions &positions) const;
|
||||
|
||||
private:
|
||||
bool performSelectionChange(QTextCursor &cursorToModify);
|
||||
ASTNodePositions getASTPositions(CPlusPlus::AST *ast, const QTextCursor &cursor) const;
|
||||
void updateCursorSelection(QTextCursor &cursorToModify, ASTNodePositions positions);
|
||||
|
||||
int possibleASTStepCount(CPlusPlus::AST *ast) const;
|
||||
int currentASTStep() const;
|
||||
ASTNodePositions findNextASTStepPositions(const QTextCursor &cursor);
|
||||
|
||||
void fineTuneASTNodePositions(ASTNodePositions &positions) const;
|
||||
ASTNodePositions getFineTunedASTPositions(CPlusPlus::AST *ast, const QTextCursor &cursor) const;
|
||||
int getFirstCurrentStepForASTNode(CPlusPlus::AST *ast) const;
|
||||
bool isLastPossibleStepForASTNode(CPlusPlus::AST *ast) const;
|
||||
ASTNodePositions findRelevantASTPositionsFromCursor(const QList<CPlusPlus::AST *> &astPath,
|
||||
const QTextCursor &cursor,
|
||||
int startingFromNodeIndex = -1);
|
||||
ASTNodePositions findRelevantASTPositionsFromCursorWhenNodeIndexNotSet(
|
||||
const QList<CPlusPlus::AST *> astPath,
|
||||
const QTextCursor &cursor);
|
||||
ASTNodePositions findRelevantASTPositionsFromCursorWhenWholeDocumentSelected(
|
||||
const QList<CPlusPlus::AST *> astPath,
|
||||
const QTextCursor &cursor);
|
||||
ASTNodePositions findRelevantASTPositionsFromCursorFromPreviousNodeIndex(
|
||||
const QList<CPlusPlus::AST *> astPath,
|
||||
const QTextCursor &cursor);
|
||||
bool shouldSkipASTNodeBasedOnPosition(const ASTNodePositions &positions,
|
||||
const QTextCursor &cursor) const;
|
||||
void setNodeIndexAndStep(NodeIndexAndStepState state);
|
||||
int getTokenStartCursorPosition(unsigned tokenIndex, const QTextCursor &cursor) const;
|
||||
int getTokenEndCursorPosition(unsigned tokenIndex, const QTextCursor &cursor) const;
|
||||
void printTokenDebugInfo(unsigned tokenIndex, const QTextCursor &cursor, QString prefix) const;
|
||||
|
||||
QTextCursor m_initialChangeSelectionCursor;
|
||||
QTextCursor m_workingCursor;
|
||||
CPlusPlus::Document::Ptr m_doc;
|
||||
CPlusPlus::TranslationUnit *m_unit;
|
||||
Direction m_direction;
|
||||
int m_changeSelectionNodeIndex;
|
||||
int m_nodeCurrentStep;
|
||||
bool m_inChangeSelection;
|
||||
};
|
||||
|
||||
} // namespace CppTools
|
||||
|
||||
#endif // CPPSELECTIONCHANGER_H
|
||||
@@ -43,6 +43,7 @@ HEADERS += \
|
||||
cppprojectfile.h \
|
||||
cppqtstyleindenter.h \
|
||||
cpprefactoringchanges.h \
|
||||
cppselectionchanger.h \
|
||||
cppsemanticinfo.h \
|
||||
cppsemanticinfoupdater.h \
|
||||
cppsourceprocessor.h \
|
||||
@@ -117,6 +118,7 @@ SOURCES += \
|
||||
cppprojectfile.cpp \
|
||||
cppqtstyleindenter.cpp \
|
||||
cpprefactoringchanges.cpp \
|
||||
cppselectionchanger.cpp \
|
||||
cppsemanticinfo.cpp \
|
||||
cppsemanticinfoupdater.cpp \
|
||||
cppsourceprocessor.cpp \
|
||||
|
||||
@@ -66,6 +66,7 @@ QtcPlugin {
|
||||
"cppprojectfile.cpp", "cppprojectfile.h",
|
||||
"cppqtstyleindenter.cpp", "cppqtstyleindenter.h",
|
||||
"cpprefactoringchanges.cpp", "cpprefactoringchanges.h",
|
||||
"cppselectionchanger.cpp", "cppselectionchanger.h",
|
||||
"cppsemanticinfo.cpp", "cppsemanticinfo.h",
|
||||
"cppsemanticinfoupdater.cpp", "cppsemanticinfoupdater.h",
|
||||
"cppsourceprocessor.cpp", "cppsourceprocessor.h",
|
||||
|
||||
@@ -37,6 +37,7 @@ static const char constrainTooltips[] = "ConstrainTooltips";
|
||||
static const char camelCaseNavigationKey[] = "CamelCaseNavigation";
|
||||
static const char keyboardTooltips[] = "KeyboardTooltips";
|
||||
static const char groupPostfix[] = "BehaviorSettings";
|
||||
static const char smartSelectionChanging[] = "SmartSelectionChanging";
|
||||
|
||||
namespace TextEditor {
|
||||
|
||||
@@ -46,7 +47,8 @@ BehaviorSettings::BehaviorSettings() :
|
||||
m_scrollWheelZooming(true),
|
||||
m_constrainHoverTooltips(false),
|
||||
m_camelCaseNavigation(true),
|
||||
m_keyboardTooltips(false)
|
||||
m_keyboardTooltips(false),
|
||||
m_smartSelectionChanging(true)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -69,6 +71,7 @@ void BehaviorSettings::toMap(const QString &prefix, QVariantMap *map) const
|
||||
map->insert(prefix + QLatin1String(constrainTooltips), m_constrainHoverTooltips);
|
||||
map->insert(prefix + QLatin1String(camelCaseNavigationKey), m_camelCaseNavigation);
|
||||
map->insert(prefix + QLatin1String(keyboardTooltips), m_keyboardTooltips);
|
||||
map->insert(prefix + QLatin1String(smartSelectionChanging), m_smartSelectionChanging);
|
||||
}
|
||||
|
||||
void BehaviorSettings::fromMap(const QString &prefix, const QVariantMap &map)
|
||||
@@ -85,6 +88,9 @@ void BehaviorSettings::fromMap(const QString &prefix, const QVariantMap &map)
|
||||
map.value(prefix + QLatin1String(camelCaseNavigationKey), m_camelCaseNavigation).toBool();
|
||||
m_keyboardTooltips =
|
||||
map.value(prefix + QLatin1String(keyboardTooltips), m_keyboardTooltips).toBool();
|
||||
m_smartSelectionChanging =
|
||||
map.value(prefix + QLatin1String(smartSelectionChanging), m_smartSelectionChanging)
|
||||
.toBool();
|
||||
}
|
||||
|
||||
bool BehaviorSettings::equals(const BehaviorSettings &ds) const
|
||||
@@ -95,6 +101,7 @@ bool BehaviorSettings::equals(const BehaviorSettings &ds) const
|
||||
&& m_constrainHoverTooltips == ds.m_constrainHoverTooltips
|
||||
&& m_camelCaseNavigation == ds.m_camelCaseNavigation
|
||||
&& m_keyboardTooltips == ds.m_keyboardTooltips
|
||||
&& m_smartSelectionChanging == ds.m_smartSelectionChanging
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ public:
|
||||
bool m_constrainHoverTooltips;
|
||||
bool m_camelCaseNavigation;
|
||||
bool m_keyboardTooltips;
|
||||
bool m_smartSelectionChanging;
|
||||
};
|
||||
|
||||
inline bool operator==(const BehaviorSettings &t1, const BehaviorSettings &t2) { return t1.equals(t2); }
|
||||
|
||||
@@ -111,6 +111,8 @@ BehaviorSettingsWidget::BehaviorSettingsWidget(QWidget *parent)
|
||||
this, &BehaviorSettingsWidget::slotBehaviorSettingsChanged);
|
||||
connect(d->m_ui.keyboardTooltips, &QAbstractButton::clicked,
|
||||
this, &BehaviorSettingsWidget::slotBehaviorSettingsChanged);
|
||||
connect(d->m_ui.smartSelectionChanging, &QAbstractButton::clicked,
|
||||
this, &BehaviorSettingsWidget::slotBehaviorSettingsChanged);
|
||||
}
|
||||
|
||||
BehaviorSettingsWidget::~BehaviorSettingsWidget()
|
||||
@@ -198,6 +200,7 @@ void BehaviorSettingsWidget::setAssignedBehaviorSettings(const BehaviorSettings
|
||||
d->m_ui.constrainTooltipsBox->setCurrentIndex(behaviorSettings.m_constrainHoverTooltips ? 1 : 0);
|
||||
d->m_ui.camelCaseNavigation->setChecked(behaviorSettings.m_camelCaseNavigation);
|
||||
d->m_ui.keyboardTooltips->setChecked(behaviorSettings.m_keyboardTooltips);
|
||||
d->m_ui.smartSelectionChanging->setChecked(behaviorSettings.m_smartSelectionChanging);
|
||||
updateConstrainTooltipsBoxTooltip();
|
||||
}
|
||||
|
||||
@@ -209,6 +212,7 @@ void BehaviorSettingsWidget::assignedBehaviorSettings(BehaviorSettings *behavior
|
||||
behaviorSettings->m_constrainHoverTooltips = (d->m_ui.constrainTooltipsBox->currentIndex() == 1);
|
||||
behaviorSettings->m_camelCaseNavigation = d->m_ui.camelCaseNavigation->isChecked();
|
||||
behaviorSettings->m_keyboardTooltips = d->m_ui.keyboardTooltips->isChecked();
|
||||
behaviorSettings->m_smartSelectionChanging = d->m_ui.smartSelectionChanging->isChecked();
|
||||
}
|
||||
|
||||
void BehaviorSettingsWidget::setAssignedExtraEncodingSettings(
|
||||
|
||||
@@ -357,6 +357,16 @@ Specifies how backspace interacts with indentation.
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="smartSelectionChanging">
|
||||
<property name="toolTip">
|
||||
<string>Using Select Block Up / Down actions will now provide smarter selections.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable smart selection changing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="keyboardTooltips">
|
||||
<property name="toolTip">
|
||||
|
||||
@@ -61,5 +61,13 @@ QString textAt(QTextCursor tc, int pos, int length)
|
||||
return tc.selectedText().replace(QChar::ParagraphSeparator, QLatin1Char('\n'));
|
||||
}
|
||||
|
||||
QTextCursor flippedCursor(const QTextCursor &cursor)
|
||||
{
|
||||
QTextCursor flipped = cursor;
|
||||
flipped.clearSelection();
|
||||
flipped.setPosition(cursor.anchor(), QTextCursor::KeepAnchor);
|
||||
return flipped;
|
||||
}
|
||||
|
||||
} // Util
|
||||
} // TextEditor
|
||||
|
||||
@@ -44,6 +44,8 @@ TEXTEDITOR_EXPORT bool convertPosition(const QTextDocument *document,
|
||||
|
||||
TEXTEDITOR_EXPORT QString textAt(QTextCursor tc, int pos, int length);
|
||||
|
||||
TEXTEDITOR_EXPORT QTextCursor flippedCursor(const QTextCursor &cursor);
|
||||
|
||||
} // Util
|
||||
} // TextEditor
|
||||
|
||||
|
||||
@@ -1300,14 +1300,6 @@ void TextEditorWidget::gotoNextWordCamelCaseWithSelection()
|
||||
setTextCursor(c);
|
||||
}
|
||||
|
||||
static QTextCursor flippedCursor(const QTextCursor &cursor)
|
||||
{
|
||||
QTextCursor flipped = cursor;
|
||||
flipped.clearSelection();
|
||||
flipped.setPosition(cursor.anchor(), QTextCursor::KeepAnchor);
|
||||
return flipped;
|
||||
}
|
||||
|
||||
bool TextEditorWidget::selectBlockUp()
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
@@ -1321,7 +1313,7 @@ bool TextEditorWidget::selectBlockUp()
|
||||
if (!TextBlockUserData::findNextClosingParenthesis(&cursor, true))
|
||||
return false;
|
||||
|
||||
setTextCursor(flippedCursor(cursor));
|
||||
setTextCursor(Convenience::flippedCursor(cursor));
|
||||
d->_q_matchParentheses();
|
||||
return true;
|
||||
}
|
||||
@@ -1346,7 +1338,7 @@ bool TextEditorWidget::selectBlockDown()
|
||||
if ( cursor != d->m_selectBlockAnchor)
|
||||
TextBlockUserData::findNextClosingParenthesis(&cursor, true);
|
||||
|
||||
setTextCursor(flippedCursor(cursor));
|
||||
setTextCursor(Convenience::flippedCursor(cursor));
|
||||
d->_q_matchParentheses();
|
||||
return true;
|
||||
}
|
||||
@@ -5346,6 +5338,11 @@ const MarginSettings &TextEditorWidget::marginSettings() const
|
||||
return d->m_marginSettings;
|
||||
}
|
||||
|
||||
const BehaviorSettings &TextEditorWidget::behaviorSettings() const
|
||||
{
|
||||
return d->m_behaviorSettings;
|
||||
}
|
||||
|
||||
void TextEditorWidgetPrivate::handleHomeKey(bool anchor)
|
||||
{
|
||||
QTextCursor cursor = q->textCursor();
|
||||
|
||||
@@ -294,6 +294,7 @@ public:
|
||||
|
||||
const DisplaySettings &displaySettings() const;
|
||||
const MarginSettings &marginSettings() const;
|
||||
const BehaviorSettings &behaviorSettings() const;
|
||||
|
||||
void ensureCursorVisible();
|
||||
|
||||
@@ -389,8 +390,8 @@ public:
|
||||
void gotoNextWordCamelCase();
|
||||
void gotoNextWordCamelCaseWithSelection();
|
||||
|
||||
bool selectBlockUp();
|
||||
bool selectBlockDown();
|
||||
virtual bool selectBlockUp();
|
||||
virtual bool selectBlockDown();
|
||||
|
||||
void moveLineUp();
|
||||
void moveLineDown();
|
||||
@@ -498,6 +499,7 @@ protected:
|
||||
void showDefaultContextMenu(QContextMenuEvent *e, Core::Id menuContextId);
|
||||
virtual void finalizeInitialization() {}
|
||||
virtual void finalizeInitializationAfterDuplication(TextEditorWidget *) {}
|
||||
static QTextCursor flippedCursor(const QTextCursor &cursor);
|
||||
|
||||
public:
|
||||
struct Link
|
||||
|
||||
@@ -449,7 +449,7 @@ void TextEditorActionHandlerPrivate::createActions()
|
||||
G_EDIT_BLOCKS, advancedEditMenu);
|
||||
m_selectBlockDownAction = registerAction(SELECT_BLOCK_DOWN,
|
||||
[this] (TextEditorWidget *w) { w->selectBlockDown(); }, true, tr("Select Block Down"),
|
||||
QKeySequence(),
|
||||
QKeySequence(tr("Ctrl+Shift+Alt+U")),
|
||||
G_EDIT_BLOCKS, advancedEditMenu);
|
||||
|
||||
// register GOTO Actions
|
||||
|
||||
@@ -11,6 +11,7 @@ SUBDIRS = \
|
||||
typeprettyprinter \
|
||||
misc \
|
||||
c99 \
|
||||
cppselectionchanger\
|
||||
cxx11 \
|
||||
checksymbols \
|
||||
lexer \
|
||||
|
||||
@@ -7,6 +7,7 @@ Project {
|
||||
"c99/c99.qbs",
|
||||
"checksymbols/checksymbols.qbs",
|
||||
"codeformatter/codeformatter.qbs",
|
||||
"cppselectionchanger/cppselectionchanger.qbs",
|
||||
"cxx11/cxx11.qbs",
|
||||
"fileiterationorder/fileiterationorder.qbs",
|
||||
"findusages/findusages.qbs",
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
include(../shared/shared.pri)
|
||||
|
||||
# Inject the source dir for referencing test data from shadow builds.
|
||||
DEFINES += SRCDIR=\\\"$$PWD\\\"
|
||||
|
||||
SOURCES += tst_cppselectionchangertest.cpp
|
||||
|
||||
DISTFILES += testCppFile.cpp \
|
||||
cppselectionchanger.qbs
|
||||
@@ -0,0 +1,21 @@
|
||||
import qbs
|
||||
import "../cplusplusautotest.qbs" as CPlusPlusAutotest
|
||||
|
||||
CPlusPlusAutotest {
|
||||
name: "CPlusPlus selection changer autotest"
|
||||
|
||||
Group {
|
||||
name: "Source Files"
|
||||
files: "tst_cppselectionchangertest.cpp"
|
||||
}
|
||||
|
||||
Group {
|
||||
name: "Data Files"
|
||||
fileTags: ["data"]
|
||||
files: [
|
||||
"testCppFile.cpp",
|
||||
]
|
||||
}
|
||||
|
||||
cpp.defines: base.concat(['SRCDIR="' + path + '"'])
|
||||
}
|
||||
124
tests/auto/cplusplus/cppselectionchanger/testCppFile.cpp
Normal file
124
tests/auto/cplusplus/cppselectionchanger/testCppFile.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 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.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
struct TestClass {
|
||||
int a;
|
||||
char b;
|
||||
char x;
|
||||
char y;
|
||||
char z;
|
||||
std::string c;
|
||||
double d;
|
||||
std::map<int, int> e;
|
||||
};
|
||||
|
||||
int add(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int subtract(T a, T b) {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
namespace CustomNamespace {
|
||||
extern int insideNamespace;
|
||||
int foo() {
|
||||
insideNamespace = 2;
|
||||
return insideNamespace;
|
||||
}
|
||||
}
|
||||
|
||||
class CustomClass {
|
||||
bool customClassMethod(const int ¶meter) const volatile;
|
||||
};
|
||||
|
||||
class SecondCustomClass {
|
||||
public:
|
||||
SecondCustomClass(int argc, char *argv[]);
|
||||
void secondCustomClassFunction();
|
||||
};
|
||||
|
||||
bool CustomClass::customClassMethod(const int ¶meter) const volatile {
|
||||
int secondParameter = parameter;
|
||||
++secondParameter;
|
||||
return secondParameter;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
std::map<int,TestClass> a;
|
||||
|
||||
SecondCustomClass secondCustomClass(argc, argv);
|
||||
secondCustomClass.secondCustomClassFunction();
|
||||
|
||||
TestClass bla;
|
||||
bla.a = 1;
|
||||
bla.b = 65;
|
||||
bla.c = "Hello";
|
||||
bla.d = 3.14f;
|
||||
bla.e[3] = 3;
|
||||
|
||||
a[3] = bla;
|
||||
|
||||
std::vector<int> v;
|
||||
v.push_back(1);
|
||||
v.push_back(2);
|
||||
|
||||
if (5 == 5) {
|
||||
std::cout << "Hello" << 'c' << 54545 << u8"utf8string" << U"unicodeString";
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
std::cout << i;
|
||||
}
|
||||
|
||||
for (auto val :v) {
|
||||
std::cout << val;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "\n After exec";
|
||||
std::cout << argc << argv;
|
||||
|
||||
std::cout << add(1, add(2, add(10, 20)));
|
||||
|
||||
auto res = std::find(v.begin(), v.end(), 1);
|
||||
if (res != v.end())
|
||||
std::cout << *res;
|
||||
std::cout << static_cast<int>(3);
|
||||
|
||||
auto aLambda = [=, &a](int lambdaArgument) -> int {
|
||||
return lambdaArgument + 1;
|
||||
};
|
||||
aLambda(1);
|
||||
|
||||
std::cout << R"(
|
||||
Raw literal
|
||||
)";
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user