forked from qt-creator/qt-creator
Snippets: Synchronize editing of equivalent variables inside snippets.
When editing one variable from a code snippet, all other variables with the same name are updated accordingly.
This commit is contained in:
@@ -30,20 +30,22 @@
|
||||
#include "texteditoroverlay.h"
|
||||
#include "basetexteditor.h"
|
||||
|
||||
#include <QtCore/QMap>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QTextBlock>
|
||||
|
||||
using namespace TextEditor;
|
||||
using namespace TextEditor::Internal;
|
||||
|
||||
TextEditorOverlay::TextEditorOverlay(BaseTextEditor *editor)
|
||||
:QObject(editor) {
|
||||
m_visible = false;
|
||||
m_borderWidth = 1;
|
||||
m_dropShadowWidth = 2;
|
||||
m_editor = editor;
|
||||
m_alpha = true;
|
||||
m_viewport = editor->viewport();
|
||||
TextEditorOverlay::TextEditorOverlay(BaseTextEditor *editor) :
|
||||
QObject(editor),
|
||||
m_visible(false),
|
||||
m_borderWidth(1),
|
||||
m_dropShadowWidth(2),
|
||||
m_alpha(true),
|
||||
m_editor(editor),
|
||||
m_viewport(editor->viewport())
|
||||
{
|
||||
}
|
||||
|
||||
void TextEditorOverlay::update()
|
||||
@@ -447,12 +449,79 @@ void TextEditorOverlay::fill(QPainter *painter, const QColor &color, const QRect
|
||||
start or end of a selection is counted as contained.
|
||||
*/
|
||||
bool TextEditorOverlay::hasCursorInSelection(const QTextCursor &cursor) const
|
||||
{
|
||||
if (selectionIndexForCursor(cursor) != -1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int TextEditorOverlay::selectionIndexForCursor(const QTextCursor &cursor) const
|
||||
{
|
||||
for (int i = 0; i < m_selections.size(); ++i) {
|
||||
const OverlaySelection &selection = m_selections.at(i);
|
||||
if (cursor.position() >= selection.m_cursor_begin.position()
|
||||
&& cursor.position() <= selection.m_cursor_end.position())
|
||||
return true;
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
QString TextEditorOverlay::selectionText(int selectionIndex) const
|
||||
{
|
||||
return assembleCursorForSelection(selectionIndex).selectedText();
|
||||
}
|
||||
|
||||
QTextCursor TextEditorOverlay::assembleCursorForSelection(int selectionIndex) const
|
||||
{
|
||||
const OverlaySelection &selection = m_selections.at(selectionIndex);
|
||||
QTextCursor cursor(m_editor->document());
|
||||
cursor.setPosition(selection.m_cursor_begin.position());
|
||||
cursor.setPosition(selection.m_cursor_end.position(), QTextCursor::KeepAnchor);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
void TextEditorOverlay::mapEquivalentSelections()
|
||||
{
|
||||
m_equivalentSelections.clear();
|
||||
m_equivalentSelections.resize(m_selections.size());
|
||||
|
||||
QMap<QString, int> all;
|
||||
for (int i = 0; i < m_selections.size(); ++i)
|
||||
all.insertMulti(selectionText(i), i);
|
||||
|
||||
const QList<QString> &uniqueKeys = all.uniqueKeys();
|
||||
foreach (const QString &key, uniqueKeys) {
|
||||
QList<int> indexes;
|
||||
QMap<QString, int>::const_iterator lbit = all.lowerBound(key);
|
||||
QMap<QString, int>::const_iterator ubit = all.upperBound(key);
|
||||
while (lbit != ubit) {
|
||||
indexes.append(lbit.value());
|
||||
++lbit;
|
||||
}
|
||||
|
||||
foreach (int index, indexes)
|
||||
m_equivalentSelections[index] = indexes;
|
||||
}
|
||||
}
|
||||
|
||||
void TextEditorOverlay::updateEquivalentSelections(const QTextCursor &cursor)
|
||||
{
|
||||
int selectionIndex = selectionIndexForCursor(cursor);
|
||||
if (selectionIndex == -1)
|
||||
return;
|
||||
|
||||
const QString ¤tText = selectionText(selectionIndex);
|
||||
const QList<int> &equivalents = m_equivalentSelections.at(selectionIndex);
|
||||
foreach (int i, equivalents) {
|
||||
if (i == selectionIndex)
|
||||
continue;
|
||||
const QString &equivalentText = selectionText(i);
|
||||
if (currentText != equivalentText) {
|
||||
QTextCursor selectionCursor = assembleCursorForSelection(i);
|
||||
selectionCursor.joinPreviousEditBlock();
|
||||
selectionCursor.removeSelectedText();
|
||||
selectionCursor.insertText(currentText);
|
||||
selectionCursor.endEditBlock();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user