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:
@@ -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);
|
||||
|
||||
@@ -66,11 +66,14 @@ protected:
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent * event ) override;
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent * event) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent * event) override;
|
||||
QGIView * getAnchorQItem() const;
|
||||
|
||||
void mouseReleaseEvent(QGIView* originator, QGraphicsSceneMouseEvent* event);
|
||||
QGIView* getAnchorQItem() const;
|
||||
|
||||
private:
|
||||
/// Convenience function
|
||||
TechDraw::DrawProjGroup* getDrawView() const;
|
||||
bool autoDistributeEnabled() const;
|
||||
|
||||
QGraphicsItem* m_origin;
|
||||
QPoint mousePos;
|
||||
|
||||
@@ -32,10 +32,12 @@
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Tools.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/Selection/Selection.h>
|
||||
@@ -91,6 +93,7 @@ QGIView::QGIView()
|
||||
setCacheMode(QGraphicsItem::NoCache);
|
||||
setHandlesChildEvents(false);
|
||||
setAcceptHoverEvents(true);
|
||||
|
||||
setFlag(QGraphicsItem::ItemIsSelectable, true);
|
||||
setFlag(QGraphicsItem::ItemIsMovable, true);
|
||||
setFlag(QGraphicsItem::ItemSendsScenePositionChanges, true);
|
||||
@@ -168,8 +171,7 @@ QVariant QGIView::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
// Base::Console().message("QGIV::itemChange(%d)\n", change);
|
||||
if(change == ItemPositionChange && scene()) {
|
||||
QPointF newPos = value.toPointF(); //position within parent!
|
||||
|
||||
TechDraw::DrawView *viewObj = getViewObject();
|
||||
TechDraw::DrawView* viewObj = getViewObject();
|
||||
auto* dpgi = dynamic_cast<TechDraw::DrawProjGroupItem*>(viewObj);
|
||||
if (dpgi && dpgi->getPGroup()) {
|
||||
// restrict movements of secondary views.
|
||||
@@ -191,14 +193,6 @@ QVariant QGIView::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
}
|
||||
}
|
||||
|
||||
// tell the feature that we have moved
|
||||
Gui::ViewProvider *vp = getViewProvider(viewObj);
|
||||
if (vp && !vp->isRestoring()) {
|
||||
snapping = true; // avoid triggering updateView by the VP updateData
|
||||
viewObj->setPosition(Rez::appX(newPos.x()), Rez::appX(-newPos.y()));
|
||||
snapping = false;
|
||||
}
|
||||
|
||||
return newPos;
|
||||
}
|
||||
|
||||
@@ -217,6 +211,8 @@ QVariant QGIView::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
m_label->show();
|
||||
m_lock->setVisible(getViewObject()->isLocked() && getViewObject()->showLock());
|
||||
} else {
|
||||
dragFinished();
|
||||
|
||||
if (!m_isHovered) {
|
||||
m_colCurrent = PreferencesGui::getAccessibleQColor(PreferencesGui::normalQColor());
|
||||
m_border->hide();
|
||||
@@ -232,6 +228,55 @@ QVariant QGIView::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
|
||||
return QGraphicsItemGroup::itemChange(change, value);
|
||||
}
|
||||
void QGIView::dragFinished()
|
||||
{
|
||||
if (!viewObj) {
|
||||
return;
|
||||
}
|
||||
|
||||
double currX = viewObj->X.getValue();
|
||||
double currY = viewObj->Y.getValue();
|
||||
double candidateX = Rez::appX(pos().x());
|
||||
double candidateY = Rez::appX(-pos().y());
|
||||
bool setX = false;
|
||||
bool setY = false;
|
||||
|
||||
const double tolerance = 0.001; // mm
|
||||
if (!DrawUtil::fpCompare(currX, candidateX, tolerance)) {
|
||||
setX = true;
|
||||
}
|
||||
if (!DrawUtil::fpCompare(currY, candidateY, tolerance)) {
|
||||
setY = true;
|
||||
}
|
||||
|
||||
if (!setX && !setY) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool ownTransaction = (viewObj->getDocument()->getTransactionID(true) == 0);
|
||||
|
||||
if (ownTransaction) {
|
||||
Gui::Command::openCommand("Drag view");
|
||||
}
|
||||
// tell the feature that we have moved
|
||||
Gui::ViewProvider *vp = getViewProvider(viewObj);
|
||||
if (vp && !vp->isRestoring()) {
|
||||
snapping = true; // avoid triggering updateView by the VP updateData
|
||||
if (setX) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.X = %f",
|
||||
viewObj->getNameInDocument(), candidateX);
|
||||
}
|
||||
if (setY) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.Y = %f",
|
||||
viewObj->getNameInDocument(), candidateY);
|
||||
}
|
||||
|
||||
snapping = false;
|
||||
}
|
||||
if (ownTransaction) {
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
}
|
||||
|
||||
//! align this view with others. newPosition is in this view's parent's coord
|
||||
//! system. if this view is not in a ProjectionGroup, then this is the scene
|
||||
@@ -463,6 +508,7 @@ void QGIView::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
|
||||
m_multiselectActivated = false;
|
||||
}
|
||||
|
||||
dragFinished();
|
||||
QGraphicsItemGroup::mouseReleaseEvent(event);
|
||||
|
||||
event->setModifiers(originalModifiers);
|
||||
|
||||
@@ -176,6 +176,8 @@ protected:
|
||||
QGIView* getQGIVByName(std::string name);
|
||||
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
|
||||
void dragFinished();
|
||||
|
||||
// Preselection events:
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <Mod/TechDraw/App/DrawProjGroup.h>
|
||||
#include <Mod/TechDraw/App/DrawProjGroupItem.h>
|
||||
|
||||
#include "QGIView.h"
|
||||
#include "ViewProviderProjGroupItem.h"
|
||||
|
||||
using namespace TechDrawGui;
|
||||
|
||||
Reference in New Issue
Block a user