From 381a60b7db2e31ad68e970b42065b7540d467d11 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 9 Oct 2012 22:32:44 +0200 Subject: [PATCH] BaseTextEditor: make ITextMarks draggable Change-Id: I36fd6d49ec99975d059f201aa23db11dd80e4ad6 Reviewed-by: Daniel Teske --- src/plugins/texteditor/basetexteditor.cpp | 58 ++++++++++++++++------- src/plugins/texteditor/basetexteditor_p.h | 3 ++ src/plugins/texteditor/itextmark.cpp | 10 ++++ src/plugins/texteditor/itextmark.h | 2 + 4 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index e2dbc434ce6..ccc7e7b138a 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -2497,6 +2497,7 @@ BaseTextEditorWidgetPrivate::BaseTextEditorWidgetPrivate() m_codeAssistant(new CodeAssistant), m_assistRelevantContentAdded(false), m_cursorBlockNumber(-1), + m_markDragging(false), m_autoCompleter(new AutoCompleter), m_indenter(new Indenter), m_clipboardAssistProvider(new Internal::ClipboardAssistProvider) @@ -4363,6 +4364,7 @@ void BaseTextEditorWidget::extraAreaMouseEvent(QMouseEvent *e) int markWidth; extraAreaWidth(&markWidth); + const bool inMarkArea = e->pos().x() <= markWidth && e->pos().x() >= 0; if (d->m_codeFoldingVisible && e->type() == QEvent::MouseMove && e->buttons() == 0) { // mouse tracking @@ -4383,15 +4385,22 @@ void BaseTextEditorWidget::extraAreaMouseEvent(QMouseEvent *e) // Set whether the mouse cursor is a hand or normal arrow if (e->type() == QEvent::MouseMove) { - bool hand = (e->pos().x() <= markWidth); - if (hand) { + if (inMarkArea) { //Find line by cursor position int line = cursor.blockNumber() + 1; emit editor()->markTooltipRequested(editor(), mapToGlobal(e->pos()), line); } - if (hand != (d->m_extraArea->cursor().shape() == Qt::PointingHandCursor)) - d->m_extraArea->setCursor(hand ? Qt::PointingHandCursor : Qt::ArrowCursor); + if (e->buttons() & Qt::LeftButton) { + int dist = (e->pos() - d->m_markDragStart).manhattanLength(); + if (dist > QApplication::startDragDistance()) + d->m_markDragging = true; + } + + if (d->m_markDragging) + d->m_extraArea->setCursor(inMarkArea ? Qt::DragMoveCursor : Qt::ForbiddenCursor); + else if (inMarkArea != (d->m_extraArea->cursor().shape() == Qt::PointingHandCursor)) + d->m_extraArea->setCursor(inMarkArea ? Qt::PointingHandCursor : Qt::ArrowCursor); } if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonDblClick) { @@ -4409,7 +4418,7 @@ void BaseTextEditorWidget::extraAreaMouseEvent(QMouseEvent *e) toggleBlockVisible(c); d->moveCursorVisible(false); } - } else if (d->m_lineNumbersVisible && e->pos().x() > markWidth) { + } else if (d->m_lineNumbersVisible && !inMarkArea) { QTextCursor selection = cursor; selection.setVisualNavigation(true); d->extraAreaSelectionAnchorBlockNumber = selection.blockNumber(); @@ -4418,6 +4427,8 @@ void BaseTextEditorWidget::extraAreaMouseEvent(QMouseEvent *e) setTextCursor(selection); } else { d->extraAreaToggleMarkBlockNumber = cursor.blockNumber(); + d->m_markDragging = false; + d->m_markDragStart = e->pos(); } } } else if (d->extraAreaSelectionAnchorBlockNumber >= 0) { @@ -4451,25 +4462,38 @@ void BaseTextEditorWidget::extraAreaMouseEvent(QMouseEvent *e) if (e->type() == QEvent::MouseButtonRelease && e->button() == Qt::LeftButton) { int n = d->extraAreaToggleMarkBlockNumber; d->extraAreaToggleMarkBlockNumber = -1; - if (cursor.blockNumber() == n) { - if (TextBlockUserData *data = static_cast(cursor.block().userData())) { - foreach (ITextMark *mark, data->marks()) { + const bool sameLine = cursor.blockNumber() == n; + const bool wasDragging = d->m_markDragging; + d->m_markDragging = false; + QTextBlock block = cursor.document()->findBlockByNumber(n); + if (TextBlockUserData *data = static_cast(block.userData())) { + foreach (ITextMark *mark, data->marks()) { + if (sameLine) { if (mark->isClickable()) { mark->clicked(); return; } + } else { + if (wasDragging && mark->isDraggable()) { + if (inMarkArea) { + mark->dragToLine(cursor.blockNumber() + 1); + d->m_extraArea->setCursor(Qt::PointingHandCursor); + } else { + d->m_extraArea->setCursor(Qt::ArrowCursor); + } + return; + } } } - - int line = n + 1; - ITextEditor::MarkRequestKind kind; - if (QApplication::keyboardModifiers() & Qt::ShiftModifier) - kind = ITextEditor::BookmarkRequest; - else - kind = ITextEditor::BreakpointRequest; - - emit editor()->markRequested(editor(), line, kind); } + int line = n + 1; + ITextEditor::MarkRequestKind kind; + if (QApplication::keyboardModifiers() & Qt::ShiftModifier) + kind = ITextEditor::BookmarkRequest; + else + kind = ITextEditor::BreakpointRequest; + + emit editor()->markRequested(editor(), line, kind); } } } diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h index 837cd47f65c..8847f2ee943 100644 --- a/src/plugins/texteditor/basetexteditor_p.h +++ b/src/plugins/texteditor/basetexteditor_p.h @@ -292,6 +292,9 @@ public: QPointer m_animator; int m_cursorBlockNumber; + QPoint m_markDragStart; + bool m_markDragging; + QScopedPointer m_autoCompleter; QScopedPointer m_indenter; diff --git a/src/plugins/texteditor/itextmark.cpp b/src/plugins/texteditor/itextmark.cpp index d655de0304c..0ed2309562b 100644 --- a/src/plugins/texteditor/itextmark.cpp +++ b/src/plugins/texteditor/itextmark.cpp @@ -110,6 +110,16 @@ bool ITextMark::isClickable() const void ITextMark::clicked() {} +bool ITextMark::isDraggable() const +{ + return false; +} + +void ITextMark::dragToLine(int lineNumber) +{ + Q_UNUSED(lineNumber); +} + ITextMarkable *ITextMark::markableInterface() const { return m_markableInterface; diff --git a/src/plugins/texteditor/itextmark.h b/src/plugins/texteditor/itextmark.h index 0013c6f2eea..95dafedbba9 100644 --- a/src/plugins/texteditor/itextmark.h +++ b/src/plugins/texteditor/itextmark.h @@ -76,6 +76,8 @@ public: virtual void removedFromEditor(); virtual bool isClickable() const; virtual void clicked(); + virtual bool isDraggable() const; + virtual void dragToLine(int lineNumber); void setIcon(const QIcon &icon); // call this if the icon has changed.