Techdraw: Undo/redo when dragging views and rework projection group drag (#22875)

* TechDraw: create a transaction when finished dragging a view

* TechDraw: drag projection group when dragging a subview in AutoDistribute is enabled

* TechDraw: avoid creating 'Drag View' transaction if the document is already in a transaction

* TechDraw: Apply suggestions from code review

---------

Co-authored-by: Benjamin Nauck <benjamin@nauck.se>
This commit is contained in:
theo-vt
2025-08-24 02:36:41 -04:00
committed by GitHub
parent cf951bae6b
commit c61ad05789
5 changed files with 103 additions and 39 deletions

View File

@@ -55,6 +55,10 @@ TechDraw::DrawProjGroup * QGIProjGroup::getDrawView() const
App::DocumentObject *obj = getViewObject();
return dynamic_cast<TechDraw::DrawProjGroup *>(obj);
}
bool QGIProjGroup::autoDistributeEnabled() const
{
return getDrawView() && getDrawView()->AutoDistribute.getValue();
}
bool QGIProjGroup::sceneEventFilter(QGraphicsItem* watched, QEvent *event)
{
@@ -64,27 +68,34 @@ bool QGIProjGroup::sceneEventFilter(QGraphicsItem* watched, QEvent *event)
event->type() == QEvent::GraphicsSceneMouseRelease) {
QGIView *qAnchor = getAnchorQItem();
if(qAnchor && watched == qAnchor) {
QGIView* qWatched = dynamic_cast<QGIView*>(watched);
// If AutoDistribute is enabled, catch events and move the anchor directly
if(qAnchor && (watched == qAnchor || (autoDistributeEnabled() && qWatched != nullptr))) {
auto *mEvent = dynamic_cast<QGraphicsSceneMouseEvent*>(event);
switch(event->type()) {
case QEvent::GraphicsSceneMousePress:
// TODO - Perhaps just pass the mouse event on to the anchor somehow?
if (scene() && !qAnchor->isSelected()) {
scene()->clearSelection();
qAnchor->setSelected(true);
}
mousePressEvent(mEvent);
break;
case QEvent::GraphicsSceneMouseMove:
mouseMoveEvent(mEvent);
break;
case QEvent::GraphicsSceneMouseRelease:
mouseReleaseEvent(mEvent);
break;
default:
break;
// Disable moves on the view to prevent double drag
bool initCanMove = qWatched->flags() & QGraphicsItem::ItemIsMovable;
qWatched->setFlag(QGraphicsItem::ItemIsMovable, false);
switch (event->type()) {
case QEvent::GraphicsSceneMousePress:
// TODO - Perhaps just pass the mouse event on to the watched item somehow?
if (scene() && !qWatched->isSelected()) {
scene()->clearSelection();
qWatched->setSelected(true);
}
mousePressEvent(mEvent);
break;
case QEvent::GraphicsSceneMouseMove:
mouseMoveEvent(mEvent);
break;
case QEvent::GraphicsSceneMouseRelease:
mouseReleaseEvent(qWatched, mEvent);
break;
default:
break;
}
// Restore flag
qWatched->setFlag(QGraphicsItem::ItemIsMovable, initCanMove);
return true;
}
}
@@ -134,7 +145,7 @@ void QGIProjGroup::mousePressEvent(QGraphicsSceneMouseEvent * event)
QGIView *qAnchor = getAnchorQItem();
if(qAnchor) {
QPointF transPos = qAnchor->mapFromScene(event->scenePos());
if(qAnchor->shape().contains(transPos)) {
if(qAnchor->shape().contains(transPos) || autoDistributeEnabled()) {
mousePos = event->screenPos();
}
}
@@ -144,28 +155,29 @@ void QGIProjGroup::mousePressEvent(QGraphicsSceneMouseEvent * event)
void QGIProjGroup::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
{
QGIView *qAnchor = getAnchorQItem();
if(scene() && qAnchor && (qAnchor == scene()->mouseGrabberItem())) {
if(scene() && qAnchor && (qAnchor == scene()->mouseGrabberItem() || autoDistributeEnabled())) {
if((mousePos - event->screenPos()).manhattanLength() > 5) { //if the mouse has moved more than 5, process the mouse event
QGIViewCollection::mouseMoveEvent(event);
}
}
event->accept();
}
void QGIProjGroup::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
{
if(scene()) {
QGIView *qAnchor = getAnchorQItem();
mouseReleaseEvent(getAnchorQItem(), event);
}
void QGIProjGroup::mouseReleaseEvent(QGIView* originator, QGraphicsSceneMouseEvent* event)
{
if(scene()) {
if((mousePos - event->screenPos()).manhattanLength() < 5) {
if(qAnchor && qAnchor->shape().contains(event->pos())) {
if(originator && originator->shape().contains(event->pos())) {
event->ignore();
qAnchor->mouseReleaseEvent(event);
originator->mouseReleaseEvent(event);
}
}
else if(scene() && qAnchor) {
// End of Drag
getViewObject()->setPosition(Rez::appX(x()), Rez::appX(getY()));
else if(scene() && originator) {
dragFinished();
}
}
QGIViewCollection::mouseReleaseEvent(event);