Skip to content
This repository has been archived by the owner on Dec 14, 2021. It is now read-only.

Commit

Permalink
ui: drag and drop selected source code from code view into other appl…
Browse files Browse the repository at this point in the history
…ications (#817) (issue #707)
  • Loading branch information
Alexey Andronov authored and egraether committed Dec 2, 2019
1 parent 042ccb5 commit 136f3b5
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 37 deletions.
126 changes: 89 additions & 37 deletions src/lib_gui/qt/element/code/QtCodeArea.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
#include <algorithm>

#include <QApplication>
#include <QDrag>
#include <QFont>
#include <QHBoxLayout>
#include <QMenu>
#include <QMimeData>
#include <QPainter>
#include <QPropertyAnimation>
#include <QPushButton>
#include <QScrollBar>
#include <QTextBlock>
#include <QTextDocumentFragment>
#include <QToolTip>

#include "ApplicationSettings.h"
Expand Down Expand Up @@ -80,6 +83,7 @@ QtCodeArea::QtCodeArea(
, m_digits(0)
, m_isSelecting(false)
, m_isPanning(false)
, m_isDragging(false)
, m_setIDECursorPositionAction(nullptr)
, m_eventPosition(0, 0)
, m_isActiveFile(false)
Expand Down Expand Up @@ -581,70 +585,89 @@ void QtCodeArea::mousePressEvent(QMouseEvent* event)
{
if (event->button() == Qt::LeftButton)
{
clearSelection();

m_oldMousePosition = event->pos();
m_panningDistance = 0;

if (Qt::KeyboardModifier::ShiftModifier & QApplication::keyboardModifiers())
const QPoint clickPosition(event->pos());
m_oldMousePosition = clickPosition;
if (isSelectionPosition(clickPosition))
{
m_isPanning = true;
viewport()->setCursor(Qt::ClosedHandCursor);
m_isDragging = true;
}
else
{
m_isSelecting = true;
QTextCursor cursor = this->cursorForPosition(event->pos());
setNewTextCursor(cursor);
clearSelection();

m_panningDistance = 0;

if (Qt::KeyboardModifier::ShiftModifier & QApplication::keyboardModifiers())
{
m_isPanning = true;
viewport()->setCursor(Qt::ClosedHandCursor);
}
else
{
m_isSelecting = true;
QTextCursor cursor = this->cursorForPosition(event->pos());
setNewTextCursor(cursor);

viewport()->setCursor(Qt::IBeamCursor);
viewport()->setCursor(Qt::IBeamCursor);
}
}
}
}

void QtCodeArea::mouseReleaseEvent(QMouseEvent* event)
{
const int panningThreshold = 5;
if (event->button() != Qt::LeftButton)
{
QtCodeField::mouseReleaseEvent(event);
return;
}

if (event->button() == Qt::LeftButton)
m_isSelecting = false;
m_isPanning = false;

if (m_isDragging)
{
m_isSelecting = false;
m_isPanning = false;
const int distance = (event->pos() - m_oldMousePosition).manhattanLength();
if (distance < QApplication::startDragDistance())
{
clearSelection();
}

viewport()->setCursor(Qt::ArrowCursor);
m_isDragging = false;
return;
}

viewport()->setCursor(Qt::ArrowCursor);

if (m_panningDistance < panningThreshold) // dont do anything if mouse is release to end
// some real panning action.
const int panningThreshold = 5;
if (m_panningDistance < panningThreshold) // dont do anything if mouse is release to end
// some real panning action.
{
if (Qt::KeyboardModifier::ControlModifier & QApplication::keyboardModifiers())
{
if (Qt::KeyboardModifier::ControlModifier & QApplication::keyboardModifiers())
m_eventPosition = event->pos();
setIDECursorPosition();
}
else
{
std::vector<const Annotation*> annotations = getInteractiveAnnotationsForPosition(
event->pos());
if (annotations.size())
{
m_eventPosition = event->pos();
setIDECursorPosition();
activateAnnotationsOrErrors(annotations);
}
else
else if (m_navigator->getActiveLocalTokenIds().size())
{
std::vector<const Annotation*> annotations = getInteractiveAnnotationsForPosition(
event->pos());
if (annotations.size())
{
activateAnnotationsOrErrors(annotations);
}
else if (m_navigator->getActiveLocalTokenIds().size())
{
MessageActivateLocalSymbols(std::vector<Id>()).dispatch();
}
MessageActivateLocalSymbols(std::vector<Id>()).dispatch();
}
}
}
else
{
QtCodeField::mouseReleaseEvent(event);
}
}

void QtCodeArea::mouseMoveEvent(QMouseEvent* event)
{
const QPoint currentMousePosition = event->pos();
const int delta = (currentMousePosition - m_oldMousePosition).manhattanLength();
const int deltaX = currentMousePosition.x() - m_oldMousePosition.x();
const int deltaY = currentMousePosition.y() - m_oldMousePosition.y();
m_oldMousePosition = currentMousePosition;
Expand All @@ -663,6 +686,14 @@ void QtCodeArea::mouseMoveEvent(QMouseEvent* event)
float deltaPosRatio = float(deltaX) / (visibleContentWidth);
scrollbar->setValue(scrollbar->value() - std::round(deltaPosRatio * scrollbar->pageStep()));
}
else if (m_isDragging)
{
if (delta >= QApplication::startDragDistance())
{
dragSelectedText();
m_isDragging = false;
}
}

std::vector<const Annotation*> annotations = getInteractiveAnnotationsForPosition(event->pos());

Expand Down Expand Up @@ -805,6 +836,27 @@ void QtCodeArea::setNewTextCursor(const QTextCursor& cursor)
verticalScrollBar()->setValue(verticalValue);
}

void QtCodeArea::dragSelectedText()
{
QMimeData* mimeData = new QMimeData;
const QString text = textCursor().selection().toPlainText();
mimeData->setText(text);

QDrag* drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->exec(Qt::CopyAction);
}

bool QtCodeArea::isSelectionPosition(const QPoint positionPoint) const
{
const QTextCursor textCursor = QtCodeArea::textCursor();
const int selectionStart = textCursor.selectionStart();
const int selectionEnd = textCursor.selectionEnd();
const QTextCursor positionCursor = this->cursorForPosition(positionPoint);
const int position = positionCursor.position();
return selectionStart != selectionEnd && selectionStart <= position && position <= selectionEnd;
}

void QtCodeArea::activateAnnotationsOrErrors(const std::vector<const Annotation*>& annotations)
{
if (m_navigator->hasErrors())
Expand Down
3 changes: 3 additions & 0 deletions src/lib_gui/qt/element/code/QtCodeArea.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ private slots:
private:
void clearSelection();
void setNewTextCursor(const QTextCursor& cursor);
void dragSelectedText();
bool isSelectionPosition(QPoint positionPoint) const;

void activateAnnotationsOrErrors(const std::vector<const Annotation*>& annotations);

Expand All @@ -121,6 +123,7 @@ private slots:

bool m_isSelecting;
bool m_isPanning;
bool m_isDragging;
QPoint m_oldMousePosition;
int m_panningDistance;

Expand Down

0 comments on commit 136f3b5

Please sign in to comment.