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:
Leandro Melo
2010-11-02 15:35:42 +01:00
parent 7528c6d617
commit 7eecf3940c
4 changed files with 183 additions and 74 deletions

View File

@@ -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 &currentText = 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;
}