diff --git a/src/Mod/TechDraw/App/DrawViewClip.h b/src/Mod/TechDraw/App/DrawViewClip.h index 9a8362832f..c9bfbbec06 100644 --- a/src/Mod/TechDraw/App/DrawViewClip.h +++ b/src/Mod/TechDraw/App/DrawViewClip.h @@ -31,6 +31,7 @@ #include "DrawView.h" +// ?? this (and DrawViewCollection) could use App::GroupExtension instead?? namespace TechDraw { diff --git a/src/Mod/TechDraw/Gui/QGIView.cpp b/src/Mod/TechDraw/Gui/QGIView.cpp index 6952d47879..d00853a3ec 100644 --- a/src/Mod/TechDraw/Gui/QGIView.cpp +++ b/src/Mod/TechDraw/Gui/QGIView.cpp @@ -830,7 +830,7 @@ QRectF QGIView::boundingRect() const return totalRect; } -QGIView* QGIView::getQGIVByName(std::string name) +QGIView* QGIView::getQGIVByName(std::string name) const { QList qgItems = scene()->items(); QList::iterator it = qgItems.begin(); diff --git a/src/Mod/TechDraw/Gui/QGIView.h b/src/Mod/TechDraw/Gui/QGIView.h index 6fb1ce3a41..a63c3e034e 100644 --- a/src/Mod/TechDraw/Gui/QGIView.h +++ b/src/Mod/TechDraw/Gui/QGIView.h @@ -172,8 +172,10 @@ public: template std::vector getObjects(std::vector indexes); + bool pseudoEventFilter(QGraphicsItem *watched, QEvent *event) { return sceneEventFilter(watched, event); } + protected: - QGIView* getQGIVByName(std::string name); + QGIView* getQGIVByName(std::string name) const; QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; void dragFinished(); diff --git a/src/Mod/TechDraw/Gui/QGIViewClip.cpp b/src/Mod/TechDraw/Gui/QGIViewClip.cpp index a92b68003d..c22c9a60b1 100644 --- a/src/Mod/TechDraw/Gui/QGIViewClip.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewClip.cpp @@ -25,10 +25,14 @@ #ifndef _PreComp_ # include // std::find # include +# include #endif +#include +#include #include #include +#include #include "QGIViewClip.h" #include "QGCustomClip.h" @@ -37,31 +41,36 @@ using namespace TechDrawGui; +using namespace TechDraw; -QGIViewClip::QGIViewClip() +QGIViewClip::QGIViewClip() : + m_frame(new QGCustomRect()), + m_cliparea(new QGCustomClip()) { setHandlesChildEvents(false); + // setHandlesChildEvents(true); setCacheMode(QGraphicsItem::NoCache); setAcceptHoverEvents(true); setFlag(QGraphicsItem::ItemIsSelectable, true); setFlag(QGraphicsItem::ItemIsMovable, true); - m_cliparea = new QGCustomClip(); addToGroup(m_cliparea); - m_cliparea->setPos(0., 0.); - m_cliparea->setRect(0., 0., Rez::guiX(5.), Rez::guiX(5.)); - m_frame = new QGCustomRect(); + constexpr double DefaultSize{5}; + m_cliparea->setPos(0., 0.); + m_cliparea->setRect(0., 0., Rez::guiX(DefaultSize), Rez::guiX(DefaultSize)); + addToGroup(m_frame); m_frame->setPos(0., 0.); - m_frame->setRect(0., 0., Rez::guiX(5.), Rez::guiX(5.)); + m_frame->setRect(0., 0., Rez::guiX(DefaultSize), Rez::guiX(DefaultSize)); } void QGIViewClip::updateView(bool update) { auto viewClip( dynamic_cast(getViewObject()) ); - if (!viewClip) + if (!viewClip) { return; + } if (update || viewClip->isTouched() || @@ -69,7 +78,6 @@ void QGIViewClip::updateView(bool update) viewClip->Width.isTouched() || viewClip->ShowFrame.isTouched() || viewClip->Views.isTouched() ) { - draw(); } @@ -90,13 +98,14 @@ void QGIViewClip::drawClip() { auto viewClip( dynamic_cast(getViewObject()) ); - if (!viewClip) + if (!viewClip) { return; + } prepareGeometryChange(); double h = viewClip->Height.getValue(); double w = viewClip->Width.getValue(); - QRectF r = QRectF(-Rez::guiX(w)/2.0, -Rez::guiX(h)/2.0, Rez::guiX(w), Rez::guiX(h)); + QRectF r = QRectF(-Rez::guiX(w)/2, -Rez::guiX(h)/2, Rez::guiX(w), Rez::guiX(h)); m_frame->setRect(r); // (-50, -50) -> (50, 50) m_frame->setPos(0., 0.); if (viewClip->ShowFrame.getValue()) { @@ -114,8 +123,8 @@ void QGIViewClip::drawClip() std::vector childNames = viewClip->getChildViewNames(); //for all child Views in Clip, add the graphics representation of the View to the Clip group - for(std::vector::iterator it = childNames.begin(); it != childNames.end(); it++) { - QGIView* qgiv = getQGIVByName((*it)); + for (auto& name : childNames) { + QGIView* qgiv = getQGIVByName((name)); if (qgiv) { //TODO: why is qgiv never already in a group? if (qgiv->group() != m_cliparea) { @@ -126,31 +135,80 @@ void QGIViewClip::drawClip() double x = Rez::guiX(qgiv->getViewObject()->X.getValue()); double y = Rez::guiX(qgiv->getViewObject()->Y.getValue()); qgiv->setPosition(clipOrigin.x() + x, clipOrigin.y() + y); -// if (viewClip->ShowLabels.getValue()) { -// qgiv->toggleBorder(true); -// } else { -// qgiv->toggleBorder(false); -// } qgiv->show(); } } else { - Base::Console().warning("Logic error? - drawClip() - qgiv for %s not found\n", (*it).c_str()); //gview for feature !exist + Base::Console().warning("Logic error? - drawClip() - qgiv for %s not found\n", name.c_str()); //gview for feature !exist } } //for all graphic views in qgigroup, remove from qgigroup the ones that aren't in ViewClip QList qgItems = m_cliparea->childItems(); - QList::iterator it = qgItems.begin(); - for (; it != qgItems.end(); it++) { - QGIView* qv = dynamic_cast((*it)); + for (auto& item : qgItems) { + auto* qv = dynamic_cast(item); if (qv) { if (auto qvName = std::string(qv->getViewName()); std::ranges::find(childNames, qvName) == childNames.end()) { m_cliparea->removeFromGroup(qv); removeFromGroup(qv); qv->isInnerView(false); -// qv->toggleBorder(true); } } } } + + +bool QGIViewClip::sceneEventFilter(QGraphicsItem *watched, QEvent *event) +{ + if (event->type() == QEvent::ShortcutOverride) { + // if we accept this event, we should get a regular keystroke event next + // which will be processed by QGVPage/QGVNavStyle keypress logic, but not forwarded to + // Std_Delete + auto* keyEvent = static_cast(event); + if (keyEvent->matches(QKeySequence::Delete)) { + DrawView* selectedView = selectionIsInGroup(); + if (selectedView) { + return forwardEventToSelection(getQGIVByName(selectedView->getNameInDocument()), + event); + } + } + } + + return QGraphicsItem::sceneEventFilter(watched, event); +} + + +//! returns first view in the selection that is a member of this clip group with subelements selected. +DrawView* QGIViewClip::selectionIsInGroup() const +{ + bool single = false; + std::vector selection = Gui::Selection().getSelectionEx(nullptr, DrawView::getClassTypeId(), + Gui::ResolveMode::OldStyleElement, single); + if (selection.empty()) { + return {}; + } + + auto* clipGroup = freecad_cast(getViewObject()); + for (auto& selItem : selection) { + auto view = freecad_cast(selItem.getObject()); + if (view && + clipGroup->isViewInClip(view) && + selItem.hasSubNames()) { + return view; + } + } + + return {}; +} + + +bool QGIViewClip::forwardEventToSelection(QGIView* qview, QEvent* event) const +{ + if (!qview) { + return false; + } + + return qview->pseudoEventFilter(qview, event); +} + + diff --git a/src/Mod/TechDraw/Gui/QGIViewClip.h b/src/Mod/TechDraw/Gui/QGIViewClip.h index 35a4be645d..cbb67bb83d 100644 --- a/src/Mod/TechDraw/Gui/QGIViewClip.h +++ b/src/Mod/TechDraw/Gui/QGIViewClip.h @@ -28,6 +28,11 @@ #include "QGIView.h" #include "QGIUserTypes.h" +namespace TechDraw +{ +class DrawView; +} + namespace TechDrawGui { class QGCustomRect; @@ -42,6 +47,9 @@ public: enum {Type = UserType::QGIViewClip}; int type() const override { return Type;} + bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override; + TechDraw::DrawView* selectionIsInGroup() const; + bool forwardEventToSelection(QGIView* qview, QEvent *event) const; void updateView(bool update = false) override; diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp index 286f73a28f..d23e746b89 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp @@ -130,13 +130,11 @@ QVariant QGIViewPart::itemChange(GraphicsItemChange change, const QVariant& valu bool QGIViewPart::sceneEventFilter(QGraphicsItem *watched, QEvent *event) { - // Base::Console().message("QGIVP::sceneEventFilter - event: %d watchedtype: %d\n", - // event->type(), watched->type() - QGraphicsItem::UserType); if (event->type() == QEvent::ShortcutOverride) { // if we accept this event, we should get a regular keystroke event next // which will be processed by QGVPage/QGVNavStyle keypress logic, but not forwarded to // Std_Delete - QKeyEvent *keyEvent = static_cast(event); + auto *keyEvent = static_cast(event); if (keyEvent->matches(QKeySequence::Delete)) { bool success = removeSelectedCosmetic(); if (success) { diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.h b/src/Mod/TechDraw/Gui/QGIViewPart.h index bb00959875..28e94e588a 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.h +++ b/src/Mod/TechDraw/Gui/QGIViewPart.h @@ -69,7 +69,6 @@ public: void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = nullptr ) override; - bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override; void toggleCache(bool state) override; void toggleCosmeticLines(bool state); @@ -128,6 +127,7 @@ public: virtual double getVertexSize(); protected: + bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override; QPainterPath drawPainterPath(TechDraw::BaseGeomPtr baseGeom) const; void drawViewPart(); QGIFace* drawFace(TechDraw::FacePtr f, int idx); diff --git a/src/Mod/TechDraw/Gui/QGSPage.cpp b/src/Mod/TechDraw/Gui/QGSPage.cpp index 95c5999aa0..b441801722 100644 --- a/src/Mod/TechDraw/Gui/QGSPage.cpp +++ b/src/Mod/TechDraw/Gui/QGSPage.cpp @@ -560,7 +560,7 @@ QGIView* QGSPage::addDrawViewClip(TechDraw::DrawViewClip* view) qview->setViewFeature(view); addItemToScene(qview); qview->setPosition(Rez::guiX(view->X.getValue()), Rez::guiX(view->Y.getValue())); - + qview->installSceneEventFilter(qview); return qview; }