Merge pull request #27094 from WandererFan/ProjGroupDragGoesToOrigin4

TechDraw: Projection Group jumps to origin
This commit is contained in:
Chris Hennes
2026-01-29 12:52:59 +01:00
committed by GitHub
11 changed files with 147 additions and 50 deletions

View File

@@ -152,7 +152,6 @@ void DrawProjGroupItem::autoPosition()
if (!pGroup) {
return;
}
// Base::Console().message("DPGI::autoPosition(%s)\n", Label.getValue());
if (LockPosition.getValue()) {
return;
}

View File

@@ -83,11 +83,12 @@ public:
DrawPage* findParentPage() const override;
std::vector<DrawPage*> findAllParentPages() const override;
protected:
void onChanged(const App::Property* prop) override;
bool isLocked() const override;
bool showLock() const override;
protected:
void onChanged(const App::Property* prop) override;
private:
static const char* TypeEnums[];
};

View File

@@ -675,21 +675,25 @@ void DrawView::setScaleAttribute()
}
//! Due to changes made for the "intelligent" view creation tool, testing for a view being an
//! instance of DrawProjGroupItem is no longer reliable, as views not in a group are sometimes
//! created as DrawProjGroupItem without belonging to a group. We now need to test for the
//! existence of the parent DrawProjGroup
//! instance of DrawProjGroupItem is no longer reliable, as views are sometimes
//! created as DrawProjGroupItem without belonging to a group or as a DrawViewPart that does
//! belong to a group. We now need to test for the existence of the parent DrawProjGroup
bool DrawView::isProjGroupItem(DrawViewPart* item)
{
auto dpgi = freecad_cast<DrawProjGroupItem*>(item);
if (!dpgi) {
return false;
// we check if any object that points to us (as in the Views property of a collection)
// is a projection group.
std::vector<App::DocumentObject*> inlist = item->getInList();
for (auto& obj : inlist) {
auto* dpg = freecad_cast<DrawProjGroup*>(obj);
if (dpg) {
// if a dpg points at item, item must be considered a dpgi. Front is sometime a dvp,
// and not a dpgi.
return true;
}
}
auto group = dpgi->getPGroup();
if (!group) {
return false;
}
return true;
return false;
}
int DrawView::prefScaleType()
{
return Preferences::getPreferenceGroup("General")->GetInt("DefaultScaleType", 0);

View File

@@ -32,17 +32,15 @@
#include <Mod/TechDraw/App/DrawProjGroupItem.h>
#include "QGIProjGroup.h"
#include "QGIViewDimension.h"
#include "QGIViewPart.h"
#include "Rez.h"
#include "QGSPage.h"
using namespace TechDrawGui;
using namespace TechDraw;
QGIProjGroup::QGIProjGroup()
{
m_origin = new QGraphicsItemGroup(); //QGIG added to this QGIG??
m_origin = new QGraphicsItemGroup();
m_origin->setParentItem(this);
setFlag(ItemIsSelectable, false);
@@ -50,7 +48,7 @@ QGIProjGroup::QGIProjGroup()
setFiltersChildEvents(true);
}
TechDraw::DrawProjGroup * QGIProjGroup::getDrawView() const
TechDraw::DrawProjGroup * QGIProjGroup::getPGroupFeature() const
{
App::DocumentObject *obj = getViewObject();
return dynamic_cast<TechDraw::DrawProjGroup *>(obj);
@@ -58,7 +56,7 @@ TechDraw::DrawProjGroup * QGIProjGroup::getDrawView() const
bool QGIProjGroup::autoDistributeEnabled() const
{
return getDrawView() && getDrawView()->AutoDistribute.getValue();
return getPGroupFeature() && getPGroupFeature()->AutoDistribute.getValue();
}
@@ -85,13 +83,6 @@ bool QGIProjGroup::sceneEventFilter(QGraphicsItem* watched, QEvent *event)
auto *mEvent = dynamic_cast<QGraphicsSceneMouseEvent*>(event);
// Disable moves on the view to prevent double drag
std::vector<QGraphicsItem*> modifiedChildren;
for (auto* child : childItems()) {
if (child->isSelected() && (child->flags() & QGraphicsItem::ItemIsMovable)) {
child->setFlag(QGraphicsItem::ItemIsMovable, false);
modifiedChildren.push_back(child);
}
}
switch (event->type()) {
case QEvent::GraphicsSceneMousePress:
@@ -106,9 +97,6 @@ bool QGIProjGroup::sceneEventFilter(QGraphicsItem* watched, QEvent *event)
default:
break;
}
for (auto* child : modifiedChildren) {
child->setFlag(QGraphicsItem::ItemIsMovable, true);
}
return false;
}
@@ -168,7 +156,6 @@ void QGIProjGroup::mousePressEvent(QGraphicsSceneMouseEvent * event)
void QGIProjGroup::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
{
QGIView *qAnchor = getAnchorQItem();
// this is obsolete too?
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);
@@ -201,7 +188,7 @@ void QGIProjGroup::mouseReleaseEvent(QGIView* originator, QGraphicsSceneMouseEve
QGIView * QGIProjGroup::getAnchorQItem() const
{
// Get the currently assigned anchor view
App::DocumentObject *anchorObj = getDrawView()->Anchor.getValue();
App::DocumentObject *anchorObj = getPGroupFeature()->Anchor.getValue();
auto anchorView( dynamic_cast<TechDraw::DrawView *>(anchorObj) );
if (!anchorView) {
return nullptr;
@@ -243,4 +230,23 @@ bool QGIProjGroup::isMember(App::DocumentObject* dvpObj) const
return itMatch != groupOutlist.end();
}
QList<QGIViewPart*> QGIProjGroup::secondaryQViews() const
{
auto* qgspage = static_cast<QGSPage*>(scene());
if (!qgspage) {
return {};
}
DrawProjGroup* pgFeature = getPGroupFeature();
auto pgViewsAll = pgFeature->getViewsAsDPGI();
QList<QGIViewPart*> result;
for (auto& pgView : pgViewsAll) {
auto* qview = dynamic_cast<QGIViewPart *>(qgspage->findQViewForDocObj(pgView));
if (!qview) {
continue;
}
result.emplace_back(qview);
}
return result;
}

View File

@@ -41,6 +41,7 @@ namespace TechDraw {
namespace TechDrawGui
{
class QGIViewPart;
class TechDrawGuiExport QGIProjGroup : public QGIViewCollection
{
@@ -60,6 +61,9 @@ public:
void drawBorder() override;
bool isMember(App::DocumentObject* dvpObj) const;
QGIView* getAnchorQItem() const;
TechDraw::DrawProjGroup* getPGroupFeature() const;
QList<QGIViewPart*> secondaryQViews() const;
protected:
bool sceneEventFilter(QGraphicsItem* watched, QEvent *event) override;
@@ -70,11 +74,9 @@ protected:
void mouseReleaseEvent(QGraphicsSceneMouseEvent * event) override;
void mouseReleaseEvent(QGIView* originator, QGraphicsSceneMouseEvent* event);
QGIView* getAnchorQItem() const;
private:
/// Convenience function
TechDraw::DrawProjGroup* getDrawView() const;
bool autoDistributeEnabled() const;
QGraphicsItem* m_origin;

View File

@@ -277,7 +277,7 @@ void QGIView::snapPosition(QPointF& newPosition)
return;
}
auto feature = getViewObject();
DrawView* feature = getViewObject();
if (!feature) {
return;
}
@@ -286,14 +286,18 @@ void QGIView::snapPosition(QPointF& newPosition)
return;
}
auto dvp = freecad_cast<DrawViewPart*>(feature);
auto* dvp = freecad_cast<DrawViewPart*>(feature);
if (dvp &&
!dvp->hasGeometry()) {
// too early. wait for updates to finish.
return;
}
auto vpPage = getViewProviderPage(feature);
ViewProviderPage* vpPage = getViewProviderPage(feature);
if (!vpPage) {
// too early. not added to page yet?
return;
}
QGSPage* scenePage = vpPage->getQGSPage();
if (!scenePage) {
@@ -577,12 +581,7 @@ QGIViewClip* QGIView::getClipGroup()
void QGIView::updateView(bool forceUpdate)
{
//allow/prevent dragging
if (getViewObject()->isLocked()) {
setFlag(QGraphicsItem::ItemIsMovable, false);
} else {
setFlag(QGraphicsItem::ItemIsMovable, true);
}
setMovableFlag();
if (getViewObject() && forceUpdate) {
setPosition(Rez::guiX(getViewObject()->X.getValue()),
@@ -1140,6 +1139,15 @@ bool QGIView::isExporting() const
return scenePage->getExportingAny();
}
void QGIView::setMovableFlag()
{
if (getViewObject()->isLocked()) {
setFlag(QGraphicsItem::ItemIsMovable, false);
} else {
setFlag(QGraphicsItem::ItemIsMovable, true);
}
}
//! Retrieves objects of type T with given indexes
template <typename T>
std::vector<T> QGIView::getObjects(std::vector<int> indexes)

View File

@@ -187,6 +187,7 @@ public:
bool isExporting() const;
virtual void setMovableFlag();
protected:
QGIView* getQGIVByName(std::string name) const;

View File

@@ -44,6 +44,8 @@
#include <Mod/TechDraw/App/DrawViewSection.h>
#include <Mod/TechDraw/App/Geometry.h>
#include <Mod/TechDraw/App/DrawBrokenView.h>
#include <Mod/TechDraw/App/DrawProjGroup.h>
#include <Mod/TechDraw/App/DrawProjGroupItem.h>
#include "DrawGuiUtil.h"
#include "MDIViewPage.h"
@@ -65,6 +67,7 @@
#include "PathBuilder.h"
#include "QGIBreakLine.h"
#include "QGSPage.h"
#include "QGIProjGroup.h"
using namespace TechDraw;
using namespace TechDrawGui;
@@ -220,18 +223,23 @@ QPainterPath QGIViewPart::drawPainterPath(TechDraw::BaseGeomPtr baseGeom) const
double rot = getViewObject()->Rotation.getValue();
return m_pathBuilder->geomToPainterPath(baseGeom, rot);
}
void QGIViewPart::updateView(bool update)
{
// Base::Console().message("QGIVP::updateView() - %s\n", getViewObject()->getNameInDocument());
auto viewPart(dynamic_cast<TechDraw::DrawViewPart*>(getViewObject()));
if (!viewPart)
return;
auto vp = static_cast<ViewProviderViewPart*>(getViewProvider(getViewObject()));
if (!vp)
if (!viewPart) {
return;
}
if (update)
auto vp = static_cast<ViewProviderViewPart*>(getViewProvider(getViewObject()));
if (!vp) {
return;
}
if (update) {
draw();
}
QGIView::updateView(update);
}
@@ -1427,3 +1435,36 @@ bool QGIViewPart::hideCenterMarks() const
return true;
}
void QGIViewPart::setMovableFlag()
{
auto* dvp(dynamic_cast<TechDraw::DrawViewPart*>(getViewObject()));
if (TechDraw::DrawView::isProjGroupItem(dvp)) {
setMovableFlagProjGroupItem();
return;
}
QGIView::setMovableFlag();
}
void QGIViewPart::setMovableFlagProjGroupItem()
{
auto* dpgi(dynamic_cast<TechDraw::DrawProjGroupItem*>(getViewObject()));
if (!dpgi) {
return;
}
if (dpgi->isLocked()) {
setFlag(QGraphicsItem::ItemIsMovable, false);
return;
}
bool isAutoDist{dpgi->getPGroup()->AutoDistribute.getValue()};
if (isAutoDist) {
setFlag(QGraphicsItem::ItemIsMovable, false);
return;
}
// not locked, not autoDistribute
setFlag(QGraphicsItem::ItemIsMovable, true);
}

View File

@@ -129,7 +129,8 @@ public:
bool hideCenterMarks() const;
void setMovableFlag() override;
void setMovableFlagProjGroupItem();
protected:
bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override;

View File

@@ -43,6 +43,7 @@
#include "TaskProjGroup.h"
#include "QGIViewPart.h"
#include "QGIProjGroup.h"
#include "QGSPage.h"
#include "ViewProviderPage.h"
#include "ViewProviderProjGroup.h"
@@ -240,3 +241,33 @@ void ViewProviderProjGroup::regroupSubViews()
}
}
void ViewProviderProjGroup::updateData(const App::Property* prop)
{
TechDraw::DrawProjGroup* group = getViewObject();
if (prop == &group->AutoDistribute) {
onChangeAutoDistribute();
return;
}
ViewProviderDrawingView::updateData(prop);
}
void ViewProviderProjGroup::onChangeAutoDistribute()
{
auto* groupQGI = static_cast<QGIProjGroup*>(getQView());
if (!groupQGI) {
// our QGItem does not exist yet
return;
}
QList<QGIViewPart*> secondaryQViews = groupQGI->secondaryQViews();
for (auto& secondary : secondaryQViews) {
if (secondary == groupQGI->getAnchorQItem()) {
// do not touch the anchor
continue;
}
secondary->updateView(false);
}
}

View File

@@ -55,6 +55,9 @@ public:
bool canDelete(App::DocumentObject* obj) const override;
void regroupSubViews();
void updateData(const App::Property* prop) override;
void onChangeAutoDistribute();
protected:
bool setEdit(int ModNum) override;