Skip to content

Commit

Permalink
[TD] fix dragging of balloons
Browse files Browse the repository at this point in the history
as reported in https://forum.freecadweb.org/viewtopic.php?f=10&t=55109&start=30#p478147
dragging a balloon pollutes the undo steps destroying working with undo and drawings.
  • Loading branch information
donovaly committed Feb 15, 2021
1 parent 4d3ecda commit 1061c0e
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 35 deletions.
99 changes: 64 additions & 35 deletions src/Mod/TechDraw/Gui/QGIViewBalloon.cpp
Expand Up @@ -153,13 +153,13 @@ void QGIBalloonLabel::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
void QGIBalloonLabel::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * event)
{
QGIViewBalloon* qgivBalloon = dynamic_cast<QGIViewBalloon*>(parentItem());
if (qgivBalloon == nullptr) {
if (!qgivBalloon) {
qWarning() << "QGIBalloonLabel::mouseDoubleClickEvent: No parent item";
return;
}

auto ViewProvider = dynamic_cast<ViewProviderBalloon*>(qgivBalloon->getViewProvider(qgivBalloon->getViewObject()));
if (ViewProvider == nullptr) {
if (!ViewProvider) {
qWarning() << "QGIBalloonLabel::mouseDoubleClickEvent: No valid view provider";
return;
}
Expand Down Expand Up @@ -408,13 +408,12 @@ void QGIViewBalloon::updateView(bool update)
// Base::Console().Message("QGIVB::updateView()\n");
Q_UNUSED(update);
auto balloon( dynamic_cast<TechDraw::DrawViewBalloon*>(getViewObject()) );
if( balloon == nullptr )
if (!balloon)
return;

auto vp = static_cast<ViewProviderBalloon*>(getViewProvider(getViewObject()));
if ( vp == nullptr ) {
if (!vp)
return;
}

if (update) {
QString labelText = QString::fromUtf8(balloon->Text.getStrValue().data());
Expand All @@ -437,15 +436,15 @@ void QGIViewBalloon::updateBalloon(bool obtuse)
// Base::Console().Message("QGIVB::updateBalloon()\n");
(void) obtuse;
const auto balloon( dynamic_cast<TechDraw::DrawViewBalloon *>(getViewObject()) );
if( balloon == nullptr ) {
if (!balloon) {
return;
}
auto vp = static_cast<ViewProviderBalloon*>(getViewProvider(getViewObject()));
if ( vp == nullptr ) {
if (!vp) {
return;
}
const TechDraw::DrawViewPart *refObj = balloon->getViewPart();
if (refObj == nullptr) {
if (!refObj) {
return;
}

Expand Down Expand Up @@ -476,10 +475,9 @@ void QGIViewBalloon::updateBalloon(bool obtuse)

void QGIViewBalloon::balloonLabelDragged(bool ctrl)
{
// Base::Console().Message("QGIVB::bLabelDragged(%d)\n", ctrl);
m_ctrl = ctrl;
auto dvb( dynamic_cast<TechDraw::DrawViewBalloon *>(getViewObject()) );
if (dvb == nullptr)
if (!dvb)
return;

if (!m_dragInProgress) { //first drag movement
Expand All @@ -489,33 +487,50 @@ void QGIViewBalloon::balloonLabelDragged(bool ctrl)
}
}

DrawView* balloonParent = getSourceView();
if (balloonParent)
// redraw the balloon at the new position
// note that we don't store the new position to the X/Y properties
// since the dragging is not yet finished
drawBalloon(true);

// store if origin is also moving to be able to later calc new origin and update feature
if (ctrl)
m_originDragged = true;
}

void QGIViewBalloon::balloonLabelDragFinished()
{
// stores the final drag position for undo

auto dvb(dynamic_cast<TechDraw::DrawViewBalloon*>(getViewObject()));
if (!dvb)
return;

double scale = 1.0;
DrawView* balloonParent = getSourceView();
if (balloonParent != nullptr) {
if (balloonParent)
scale = balloonParent->getScale();
}

//set feature position (x,y) from graphic position
double x = Rez::appX(balloonLabel->X() / scale),
y = Rez::appX(balloonLabel->Y() / scale);
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Drag Balloon"));
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.X = %f", dvb->getNameInDocument(), x);
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Y = %f", dvb->getNameInDocument(), -y);
//if origin is also moving, calc new origin and update feature
if (ctrl) {
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.X = %f", dvb->getNameInDocument(), x);
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.Y = %f", dvb->getNameInDocument(), -y);

// for the case that origin was also dragged, calc new origin and update feature
if (m_originDragged) {
Base::Vector3d pos(x, -y, 0.0);
Base::Vector3d newOrg = pos - m_saveOffset;
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.OriginX = %f",
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.OriginX = %f",
dvb->getNameInDocument(), newOrg.x);
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.OriginY = %f",
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.OriginY = %f",
dvb->getNameInDocument(), newOrg.y);
}

Gui::Command::commitCommand();
}

void QGIViewBalloon::balloonLabelDragFinished()
{
//really nothing to do here. position has been update by drag already
m_dragInProgress = false;
}

Expand All @@ -525,22 +540,22 @@ void QGIViewBalloon::placeBalloon(QPointF pos)
// Base::Console().Message("QGIVB::placeBalloon(%s)\n",
// DrawUtil::formatVector(pos).c_str());
auto balloon( dynamic_cast<TechDraw::DrawViewBalloon*>(getViewObject()) );
if( balloon == nullptr ) {
if (!balloon) {
return;
}

DrawView* balloonParent = dynamic_cast<DrawView*>(balloon->SourceView.getValue());
if (balloonParent == nullptr) {
if (!balloonParent) {
return;
}

auto featPage = balloonParent->findParentPage();
if (featPage == nullptr) {
if (!featPage) {
return;
}

auto vp = static_cast<ViewProviderBalloon*>(getViewProvider(getViewObject()));
if ( vp == nullptr ) {
if (!vp) {
return;
}

Expand All @@ -549,9 +564,9 @@ void QGIViewBalloon::placeBalloon(QPointF pos)
QPointF viewPos;
Gui::ViewProvider* objVp = QGIView::getViewProvider(balloonParent);
auto partVP = dynamic_cast<ViewProviderViewPart*>(objVp);
if ( partVP != nullptr ) {
if (partVP) {
qgivParent = partVP->getQView();
if (qgivParent != nullptr) {
if (qgivParent) {
//tip position is mouse release pos in parentView coords ==> OriginX, OriginY
//bubble pos is some arbitrary shift from tip position ==> X,Y
viewPos = qgivParent->mapFromScene(pos);
Expand Down Expand Up @@ -580,6 +595,12 @@ void QGIViewBalloon::placeBalloon(QPointF pos)
}

void QGIViewBalloon::draw()
{
// just redirect
drawBalloon(false);
}

void QGIViewBalloon::drawBalloon(bool dragged)
{
// Base::Console().Message("QGIVB::draw()\n");
if (!isVisible()) {
Expand All @@ -598,7 +619,7 @@ void QGIViewBalloon::draw()
show();

const TechDraw::DrawViewPart *refObj = balloon->getViewPart();
if (refObj == nullptr) {
if (!refObj) {
return;
}
if(!refObj->hasGeometry()) { //nothing to draw yet (restoring)
Expand All @@ -608,16 +629,24 @@ void QGIViewBalloon::draw()
}

auto vp = static_cast<ViewProviderBalloon*>(getViewProvider(getViewObject()));
if ( vp == nullptr ) {
if (!vp) {
return;
}

m_lineWidth = Rez::guiX(vp->LineWidth.getValue());

double textWidth = balloonLabel->getDimText()->boundingRect().width();
double textHeight = balloonLabel->getDimText()->boundingRect().height();
float x = Rez::guiX(balloon->X.getValue() * refObj->getScale());
float y = Rez::guiX(balloon->Y.getValue() * refObj->getScale());
float x, y;
// when not dragging take the X/Y properties otherwise the current label position
if (!dragged) {
x = Rez::guiX(balloon->X.getValue() * refObj->getScale());
y = Rez::guiX(balloon->Y.getValue() * refObj->getScale());
}
else {
x = Rez::guiX(balloonLabel->X() / refObj->getScale());
y = -Rez::guiX(balloonLabel->Y() / refObj->getScale());
}
Base::Vector3d lblCenter(x, -y, 0.0);

float arrowTipX = Rez::guiX(balloon->OriginX.getValue() * refObj->getScale());
Expand Down Expand Up @@ -871,11 +900,11 @@ QColor QGIViewBalloon::getNormalColor()
m_colNormal = PreferencesGui::dimQColor();

auto balloon( dynamic_cast<TechDraw::DrawViewBalloon*>(getViewObject()) );
if( balloon == nullptr )
if(!balloon)
return m_colNormal;

auto vp = static_cast<ViewProviderBalloon*>(getViewProvider(getViewObject()));
if ( vp == nullptr ) {
if (!vp) {
return m_colNormal;
}

Expand Down Expand Up @@ -905,7 +934,7 @@ DrawView* QGIViewBalloon::getSourceView() const
DrawView* balloonParent = nullptr;
App::DocumentObject* docObj = getViewObject();
DrawViewBalloon* dvb = dynamic_cast<DrawViewBalloon*>(docObj);
if (dvb != nullptr) {
if (dvb) {
balloonParent = dynamic_cast<DrawView*>(dvb->SourceView.getValue());
}
return balloonParent;
Expand Down
2 changes: 2 additions & 0 deletions src/Mod/TechDraw/Gui/QGIViewBalloon.h
Expand Up @@ -164,6 +164,7 @@ public Q_SLOTS:

protected:
void draw() override;
void drawBalloon(bool dragged = false);
virtual QVariant itemChange( GraphicsItemChange change,
const QVariant &value ) override;
virtual void setSvgPens(void);
Expand All @@ -183,6 +184,7 @@ public Q_SLOTS:

TechDraw::DrawView* getSourceView() const;
bool m_dragInProgress;
bool m_originDragged = false;
bool m_ctrl;
Base::Vector3d m_saveOffset;

Expand Down

0 comments on commit 1061c0e

Please sign in to comment.