Merge remote-tracking branch 'origin/4.9'

Change-Id: Ieed07c7fd0f422f8e1a96877c07916c7c1c1816e
This commit is contained in:
Eike Ziller
2019-02-11 14:50:08 +01:00
20 changed files with 139 additions and 44 deletions

View File

@@ -221,7 +221,7 @@ CppTools::CursorInfo::Range toCursorInfoRange(const SourceRangeContainer &source
const SourceLocationContainer &end = sourceRange.end;
const unsigned length = end.column - start.column;
return CppTools::CursorInfo::Range(start.line, start.column, length);
return {start.line, start.column, length};
}
static

View File

@@ -39,6 +39,7 @@ class ClangCompletionAssistInterface;
class ClangCompletionContextAnalyzer
{
public:
ClangCompletionContextAnalyzer() = delete;
ClangCompletionContextAnalyzer(const ClangCompletionAssistInterface *assistInterface,
CPlusPlus::LanguageFeatures languageFeatures);
void analyze();
@@ -61,8 +62,6 @@ public:
bool addSnippets() const { return m_addSnippets; }
private:
ClangCompletionContextAnalyzer();
int startOfFunctionCall(int endOfExpression) const;
void setActionAndClangPosition(CompletionAction action,

View File

@@ -91,7 +91,7 @@ QChar selectionEndChar(const QChar startSymbol)
return QLatin1Char('"');
if (startSymbol == '<')
return QLatin1Char('>');
return QChar();
return {};
}
void selectToLocationEnd(QTextCursor &cursor)

View File

@@ -386,10 +386,14 @@ private:
static int widthLimit()
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
auto screen = QGuiApplication::screenAt(QCursor::pos());
if (!screen)
screen = QGuiApplication::primaryScreen();
return screen->availableGeometry().width() / 2;
#else
return QApplication::desktop()->availableGeometry(QCursor::pos()).width() / 2;
#endif
}
private:

View File

@@ -209,12 +209,12 @@ TextEditor::BlockRange
toTextEditorBlock(QTextDocument *textDocument,
const ClangBackEnd::SourceRangeContainer &sourceRangeContainer)
{
return TextEditor::BlockRange(::Utils::Text::positionInText(textDocument,
sourceRangeContainer.start.line,
sourceRangeContainer.start.column),
::Utils::Text::positionInText(textDocument,
sourceRangeContainer.end.line,
sourceRangeContainer.end.column));
return {::Utils::Text::positionInText(textDocument,
sourceRangeContainer.start.line,
sourceRangeContainer.start.column),
::Utils::Text::positionInText(textDocument,
sourceRangeContainer.end.line,
sourceRangeContainer.end.column)};
}
QList<TextEditor::BlockRange>

View File

@@ -35,6 +35,8 @@
#include <utils/textutils.h>
#include <utils/algorithm.h>
#include <memory>
namespace ClangCodeModel {
namespace Internal {
@@ -199,7 +201,7 @@ void ClangFollowSymbol::findLink(const CppTools::CursorInEditor &data,
if (m_watcher)
m_watcher->cancel();
m_watcher.reset(new FutureSymbolWatcher());
m_watcher = std::make_unique<FutureSymbolWatcher>();
QObject::connect(m_watcher.get(), &FutureSymbolWatcher::finished, [=, filePath=data.filePath(),
callback=std::move(processLinkCallback)]() mutable {

View File

@@ -138,10 +138,7 @@ TextEditor::HighlightingResult toHighlightingResult(
{
const auto textStyles = toTextStyles(tokenInfo.types);
return TextEditor::HighlightingResult(tokenInfo.line,
tokenInfo.column,
tokenInfo.length,
textStyles);
return {tokenInfo.line, tokenInfo.column, tokenInfo.length, textStyles};
}
} // anonymous

View File

@@ -233,8 +233,8 @@ bool OverviewModel::isGenerated(const QModelIndex &) const
auto item = static_cast<TokenTreeItem *>(itemForIndex(sourceIndex));
if (!item)
return {};
return ::Utils::LineColumn(static_cast<int>(item->token.line),
static_cast<int>(item->token.column));
return {static_cast<int>(item->token.line),
static_cast<int>(item->token.column)};
}
OverviewModel::Range OverviewModel::rangeFromIndex(const QModelIndex &sourceIndex) const

View File

@@ -408,6 +408,36 @@ int ClangFormatBaseIndenter::indentBeforeCursor(const QTextBlock &block,
return cursorPositionInEditor;
}
static bool doNotIndentInContext(QTextDocument *doc, int pos)
{
const QChar character = doc->characterAt(pos);
const QTextBlock currentBlock = doc->findBlock(pos);
const QString text = currentBlock.text().left(pos - currentBlock.position());
switch (character.toLatin1()) {
default:
break;
case ':':
// Do not indent when it's the first ':' and it's not the 'case' line.
if (text.contains(QLatin1String("case")) || text.contains(QLatin1String("default"))
|| text.contains(QLatin1String("public")) || text.contains(QLatin1String("private"))
|| text.contains(QLatin1String("protected")) || text.contains(QLatin1String("signals"))
|| text.contains(QLatin1String("Q_SIGNALS"))) {
return false;
}
if (pos > 0 && doc->characterAt(pos - 1) != ':')
return true;
break;
case '<':
case '>':
// "<<" and ">>" could be problematic
if (pos > 0 && doc->characterAt(pos - 1) == character)
return true;
break;
}
return false;
}
void ClangFormatBaseIndenter::indentBlock(const QTextBlock &block,
const QChar &typedChar,
int cursorPositionInEditor)
@@ -416,12 +446,21 @@ void ClangFormatBaseIndenter::indentBlock(const QTextBlock &block,
const int blockPosition = currentBlock.position();
trimFirstNonEmptyBlock(currentBlock);
if (typedChar != QChar::Null && cursorPositionInEditor > 0
&& m_doc->characterAt(cursorPositionInEditor - 1) == typedChar
&& doNotIndentInContext(m_doc, cursorPositionInEditor - 1)) {
return;
}
if (formatWhileTyping()
&& (cursorPositionInEditor == -1 || cursorPositionInEditor >= blockPosition)) {
&& (cursorPositionInEditor == -1 || cursorPositionInEditor >= blockPosition)
&& (typedChar == QChar::Null || typedChar == ';' || typedChar == '}')) {
// Format before current position only in case the cursor is inside the indented block.
// So if cursor position is less then the block position then the current line is before
// the indented block - don't trigger extra formatting in this case.
// cursorPositionInEditor == -1 means the consition matches automatically.
// Format only before newline or complete statement not to break code.
if (cursorPositionInEditor >= 0)
cursorPositionInEditor += currentBlock.position() - blockPosition;
else

View File

@@ -462,6 +462,8 @@ static int formatRange(QTextDocument *doc,
bool CppEditorDocument::save(QString *errorString, const QString &fileName, bool autoSave)
{
if (indenter()->formatOnSave()) {
QTextCursor cursor(document());
cursor.joinPreviousEditBlock();
auto *layout = qobject_cast<TextEditor::TextDocumentLayout *>(document()->documentLayout());
const int documentRevision = layout->lastSaveRevision;
@@ -483,6 +485,7 @@ bool CppEditorDocument::save(QString *errorString, const QString &fileName, bool
}
if (editedRange.first != -1)
formatRange(document(), indenter(), editedRange, tabSettings());
cursor.endEditBlock();
}
return TextEditor::TextDocument::save(errorString, fileName, autoSave);

View File

@@ -624,11 +624,15 @@ void DebuggerToolTipWidget::computeSize()
// Add a bit of space to account for tooltip border, and not
// touch the border of the screen.
QPoint pos(x(), y());
QTC_ASSERT(QApplication::desktop(), return);
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
auto screen = QGuiApplication::screenAt(pos);
if (!screen)
screen = QGuiApplication::primaryScreen();
QRect desktopRect = screen->availableGeometry();
#else
QTC_ASSERT(QApplication::desktop(), return);
QRect desktopRect = QApplication::desktop()->availableGeometry();
#endif
const int maxWidth = desktopRect.right() - pos.x() - 5 - 5;
const int maxHeight = desktopRect.bottom() - pos.y() - 5 - 5;

View File

@@ -164,7 +164,9 @@ PerfProfilerTool::PerfProfilerTool(QObject *parent) :
m_filterMenu = new QMenu(m_filterButton);
m_aggregateButton = new QToolButton;
m_recordedLabel = new QLabel;
m_recordedLabel->setProperty("panelwidget", true);
m_delayLabel = new QLabel;
m_delayLabel->setProperty("panelwidget", true);
m_perspective.setAboutToActivateCallback([this]() { createViews(); });
}

View File

@@ -82,10 +82,6 @@ QVariantList PerfTimelineModel::labels() const
sample.insert(QLatin1String("id"), PerfEvent::LastSpecialTypeId);
result << sample;
QVariantMap kernel;
kernel.insert(QLatin1String("description"), tr("[kernel]"));
result << kernel;
const PerfProfilerTraceManager *manager = traceManager();
const bool aggregated = manager->aggregateAddresses();
for (int i = 0; i < m_locationOrder.length(); ++i) {

View File

@@ -185,7 +185,11 @@ bool BuildStepList::removeStep(int position)
void BuildStepList::moveStepUp(int position)
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
m_steps.swapItemsAt(position - 1, position);
#else
m_steps.swap(position - 1, position);
#endif
emit stepMoved(position, position - 1);
}

View File

@@ -171,7 +171,28 @@ bool QmakePriFileNode::removeSubProject(const QString &proFilePath)
bool QmakePriFileNode::addFiles(const QStringList &filePaths, QStringList *notAdded)
{
QmakePriFile *pri = priFile();
return pri ? pri->addFiles(filePaths, notAdded) : false;
if (!pri)
return false;
QList<Node *> matchingNodes = findNodes([filePaths](const Node *n) {
return n->nodeType() == NodeType::File && filePaths.contains(n->filePath().toString());
});
matchingNodes = filtered(matchingNodes, [](const Node *n) {
for (const Node *parent = n->parentFolderNode(); parent;
parent = parent->parentFolderNode()) {
if (dynamic_cast<const ResourceEditor::ResourceTopLevelNode *>(parent))
return false;
}
return true;
});
QStringList alreadyPresentFiles = transform<QStringList>(matchingNodes,
[](const Node *n) { return n->filePath().toString(); });
alreadyPresentFiles.removeDuplicates();
QStringList actualFilePaths = filePaths;
for (const QString &e : alreadyPresentFiles)
actualFilePaths.removeOne(e);
if (notAdded)
*notAdded = alreadyPresentFiles;
return pri->addFiles(actualFilePaths, notAdded);
}
bool QmakePriFileNode::removeFiles(const QStringList &filePaths, QStringList *notRemoved)

View File

@@ -213,9 +213,7 @@ QmlProfilerTool::QmlProfilerTool()
this, &QmlProfilerTool::toggleVisibleFeature);
d->m_timeLabel = new QLabel();
QPalette palette;
palette.setColor(QPalette::WindowText, Qt::white);
d->m_timeLabel->setPalette(palette);
d->m_timeLabel->setProperty("panelwidget", true);
d->m_timeLabel->setIndent(10);
updateTimeDisplay();
connect(d->m_timeLabel, &QObject::destroyed, &d->m_recordingTimer, &QTimer::stop);

View File

@@ -121,6 +121,11 @@ Highlighter::Definition Highlighter::definitionForFileName(const QString &fileNa
return highlightRepository()->definitionForFileName(fileName);
}
Highlighter::Definition Highlighter::definitionForName(const QString &name)
{
return highlightRepository()->definitionForName(name);
}
Highlighter::Definitions Highlighter::definitionsForDocument(const TextDocument *document)
{
const Utils::MimeType mimeType = Utils::mimeTypeForName(document->mimeType());

View File

@@ -46,6 +46,7 @@ public:
static Definition definitionForDocument(const TextDocument *document);
static Definition definitionForMimeType(const QString &mimeType);
static Definition definitionForFileName(const QString &fileName);
static Definition definitionForName(const QString &name);
static Definitions definitionsForDocument(const TextDocument *document);
static Definitions definitionsForMimeType(const QString &mimeType);

View File

@@ -611,7 +611,7 @@ public:
void updateCodeFoldingVisible();
void reconfigure();
void updateSyntaxInfoBar(bool showInfo);
void updateSyntaxInfoBar(const Highlighter::Definitions &definitions, const QString &fileName);
void configureGenericHighlighter(const KSyntaxHighlighting::Definition &definition);
public:
@@ -3274,27 +3274,43 @@ void TextEditorWidgetPrivate::reconfigure()
q->configureGenericHighlighter();
}
void TextEditorWidgetPrivate::updateSyntaxInfoBar(bool showInfo)
void TextEditorWidgetPrivate::updateSyntaxInfoBar(const Highlighter::Definitions &definitions,
const QString &fileName)
{
Id id(Constants::INFO_SYNTAX_DEFINITION);
Id missing(Constants::INFO_MISSING_SYNTAX_DEFINITION);
Id multiple(Constants::INFO_MULTIPLE_SYNTAX_DEFINITIONS);
InfoBar *infoBar = m_document->infoBar();
if (showInfo) {
InfoBarEntry info(id,
BaseTextEditor::tr(
"A highlight definition was not found for this file. "
"Would you like to update highlight definition files?"),
if (definitions.isEmpty() && infoBar->canInfoBeAdded(missing)
&& !TextEditorSettings::highlighterSettings().isIgnoredFilePattern(fileName)) {
InfoBarEntry info(missing,
BaseTextEditor::tr("A highlight definition was not found for this file. "
"Would you like to update highlight definition files?"),
InfoBarEntry::GlobalSuppressionEnabled);
info.setCustomButtonInfo(BaseTextEditor::tr("Update Definitions"), [&]() {
m_document->infoBar()->removeInfo(id);
info.setCustomButtonInfo(BaseTextEditor::tr("Update Definitions"), [missing, this]() {
m_document->infoBar()->removeInfo(missing);
Highlighter::updateDefinitions([widget = QPointer<TextEditorWidget>(q)]() {
if (widget)
widget->configureGenericHighlighter();
});
});
infoBar->removeInfo(multiple);
infoBar->addInfo(info);
} else if (definitions.size() > 1) {
InfoBarEntry info(multiple,
BaseTextEditor::tr("More than one highlight definition was found for this file. "
"Which one should be used to highlight this file?"));
info.setComboInfo(Utils::transform(definitions, &Highlighter::Definition::name),
[this](const QString &definition) {
this->configureGenericHighlighter(Highlighter::definitionForName(definition));
});
infoBar->removeInfo(missing);
infoBar->addInfo(info);
} else {
infoBar->removeInfo(id);
infoBar->removeInfo(multiple);
infoBar->removeInfo(missing);
}
}
@@ -8236,7 +8252,11 @@ void TextEditorWidgetPrivate::updateTabStops()
// to be set as an int. A work around is to access directly the QTextOption.
qreal charWidth = QFontMetricsF(q->font()).width(QLatin1Char(' '));
QTextOption option = q->document()->defaultTextOption();
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
option.setTabStopDistance(charWidth * m_document->tabSettings().m_tabSize);
#else
option.setTabStop(charWidth * m_document->tabSettings().m_tabSize);
#endif
q->document()->setDefaultTextOption(option);
}
@@ -8514,11 +8534,10 @@ QString TextEditorWidget::textAt(int from, int to) const
void TextEditorWidget::configureGenericHighlighter()
{
const Highlighter::Definition definition = Highlighter::definitionForDocument(textDocument());
d->configureGenericHighlighter(definition);
d->updateSyntaxInfoBar(!definition.isValid()
&& !TextEditorSettings::highlighterSettings().isIgnoredFilePattern(
textDocument()->filePath().fileName()));
const Highlighter::Definitions definitions = Highlighter::definitionsForDocument(textDocument());
d->configureGenericHighlighter(definitions.isEmpty() ? Highlighter::Definition()
: definitions.first());
d->updateSyntaxInfoBar(definitions, textDocument()->filePath().fileName());
}
int TextEditorWidget::blockNumberForVisibleRow(int row) const

View File

@@ -188,7 +188,8 @@ const char GOTO_NEXT_WORD_WITH_SELECTION[] = "TextEditor.GotoNextWordWithSelecti
const char GOTO_PREVIOUS_WORD_CAMEL_CASE_WITH_SELECTION[] = "TextEditor.GotoPreviousWordCamelCaseWithSelection";
const char GOTO_NEXT_WORD_CAMEL_CASE_WITH_SELECTION[] = "TextEditor.GotoNextWordCamelCaseWithSelection";
const char C_TEXTEDITOR_MIMETYPE_TEXT[] = "text/plain";
const char INFO_SYNTAX_DEFINITION[] = "TextEditor.InfoSyntaxDefinition";
const char INFO_MISSING_SYNTAX_DEFINITION[] = "TextEditor.InfoSyntaxDefinition";
const char INFO_MULTIPLE_SYNTAX_DEFINITIONS[] = "TextEditor.InfoMultipleSyntaxDefinitions";
const char TASK_OPEN_FILE[] = "TextEditor.Task.OpenFile";
const char CIRCULAR_PASTE[] = "TextEditor.CircularPaste";
const char SWITCH_UTF8BOM[] = "TextEditor.SwitchUtf8bom";