Fix #3367: view/data pane is unselected
- error in coordination of Tree & QGraphicsScene selection logic caused Feature to become unselected during update.
This commit is contained in:
@@ -147,7 +147,7 @@ MDIViewPage::MDIViewPage(ViewProviderPage *pageVp, Gui::Document* doc, QWidget*
|
||||
// Connect Signals and Slots
|
||||
QObject::connect(
|
||||
m_view->scene(), SIGNAL(selectionChanged()),
|
||||
this , SLOT (selectionChanged())
|
||||
this , SLOT (sceneSelectionChanged())
|
||||
);
|
||||
|
||||
//get informed by App side about deleted DocumentObjects
|
||||
@@ -833,6 +833,7 @@ void MDIViewPage::saveSVG(std::string file)
|
||||
/////////////// Selection Routines ///////////////////
|
||||
// wf: this is never executed???
|
||||
// needs a signal from Scene? hoverEvent? Scene does not emit signal for "preselect"
|
||||
// there is no "preSelect" signal from Gui either.
|
||||
void MDIViewPage::preSelectionChanged(const QPoint &pos)
|
||||
{
|
||||
QObject *obj = QObject::sender();
|
||||
@@ -892,13 +893,15 @@ void MDIViewPage::preSelectionChanged(const QPoint &pos)
|
||||
}
|
||||
}
|
||||
|
||||
//flag to prevent selection activity within mdivp
|
||||
void MDIViewPage::blockSelection(const bool state)
|
||||
{
|
||||
isSelectionBlocked = state;
|
||||
}
|
||||
|
||||
|
||||
void MDIViewPage::clearSelection()
|
||||
//Set all QGIViews to unselected state
|
||||
void MDIViewPage::clearSceneSelection()
|
||||
{
|
||||
blockSelection(true);
|
||||
std::vector<QGIView *> views = m_view->getViews();
|
||||
@@ -913,9 +916,8 @@ void MDIViewPage::clearSelection()
|
||||
blockSelection(false);
|
||||
}
|
||||
|
||||
//!Update QGVPage's selection based on Selection made outside Drawing Interface
|
||||
//invoked from VPP
|
||||
void MDIViewPage::selectFeature(App::DocumentObject *obj, const bool isSelected)
|
||||
//!Update QGIView's selection state based on Selection made outside Drawing Interface
|
||||
void MDIViewPage::selectQGIView(App::DocumentObject *obj, const bool isSelected)
|
||||
{
|
||||
App::DocumentObject* objCopy = obj;
|
||||
TechDraw::DrawHatch* hatchObj = dynamic_cast<TechDraw::DrawHatch*>(objCopy);
|
||||
@@ -932,39 +934,61 @@ void MDIViewPage::selectFeature(App::DocumentObject *obj, const bool isSelected)
|
||||
blockSelection(false);
|
||||
}
|
||||
|
||||
//! invoked by selection change made in Tree?
|
||||
// wf: seems redundant? executed, but no real logic.
|
||||
//! invoked by selection change made in Tree via father MDIView
|
||||
//really "onTreeSelectionChanged"
|
||||
void MDIViewPage::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
{
|
||||
std::vector<Gui::SelectionSingleton::SelObj> selObjs = Gui::Selection().getSelection(msg.pDocName);
|
||||
if (msg.Type == Gui::SelectionChanges::ClrSelection) {
|
||||
|
||||
}
|
||||
else if (msg.Type == Gui::SelectionChanges::AddSelection ||
|
||||
msg.Type == Gui::SelectionChanges::RmvSelection) {
|
||||
//bool add = (msg.Type == Gui::SelectionChanges::AddSelection);
|
||||
// Check if it is a view object
|
||||
std::string feat = msg.pObjectName;
|
||||
std::string sub = msg.pSubName;
|
||||
}
|
||||
else if (msg.Type == Gui::SelectionChanges::SetSelection) {
|
||||
// do nothing here wf: handled by VPP::onSelectionChanged?
|
||||
clearSceneSelection();
|
||||
} else if(msg.Type == Gui::SelectionChanges::SetSelection) { //replace entire selection set
|
||||
clearSceneSelection();
|
||||
blockSelection(true);
|
||||
for (auto& so: selObjs){
|
||||
if (so.pObject->isDerivedFrom(TechDraw::DrawView::getClassTypeId())) {
|
||||
selectQGIView(so.pObject, true);
|
||||
}
|
||||
}
|
||||
blockSelection(false);
|
||||
} else {
|
||||
bool selectState = (msg.Type == Gui::SelectionChanges::AddSelection) ? true : false;
|
||||
blockSelection(true);
|
||||
for (auto& so: selObjs){
|
||||
if (so.pObject->isDerivedFrom(TechDraw::DrawView::getClassTypeId())) {
|
||||
selectQGIView(so.pObject, selectState);
|
||||
}
|
||||
}
|
||||
blockSelection(false);
|
||||
}
|
||||
}
|
||||
|
||||
//! update FC Selection from QGraphicsScene selection
|
||||
//! update Tree Selection from QGraphicsScene selection
|
||||
//trigged by m_view->scene() signal
|
||||
void MDIViewPage::selectionChanged()
|
||||
void MDIViewPage::sceneSelectionChanged()
|
||||
{
|
||||
if(isSelectionBlocked) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QGraphicsItem*> selection = m_view->scene()->selectedItems();
|
||||
bool saveBlock = blockConnection(true); // avoid to be notified by itself
|
||||
blockSelection(true);
|
||||
std::vector<Gui::SelectionObject> treeSel = Gui::Selection().getSelectionEx();
|
||||
QList<QGraphicsItem*> sceneSel = m_view->scene()->selectedItems();
|
||||
|
||||
//check if really need to change selection
|
||||
bool sameSel = compareSelections(treeSel,sceneSel);
|
||||
if (sameSel) {
|
||||
return;
|
||||
}
|
||||
|
||||
setTreeToSceneSelect();
|
||||
}
|
||||
|
||||
void MDIViewPage::setTreeToSceneSelect(void)
|
||||
{
|
||||
bool saveBlock = blockConnection(true); // block selectionChanged signal from Tree/Observer
|
||||
blockSelection(true);
|
||||
Gui::Selection().clearSelection();
|
||||
for (QList<QGraphicsItem*>::iterator it = selection.begin(); it != selection.end(); ++it) {
|
||||
QList<QGraphicsItem*> sceneSel = m_view->scene()->selectedItems();
|
||||
for (QList<QGraphicsItem*>::iterator it = sceneSel.begin(); it != sceneSel.end(); ++it) {
|
||||
QGIView *itemView = dynamic_cast<QGIView *>(*it);
|
||||
if(itemView == 0) {
|
||||
QGIEdge *edge = dynamic_cast<QGIEdge *>(*it);
|
||||
@@ -1056,7 +1080,7 @@ void MDIViewPage::selectionChanged()
|
||||
}
|
||||
const char* name = dimObj->getNameInDocument();
|
||||
if (!name) { //can happen during undo/redo if Dim is selected???
|
||||
//Base::Console().Log("INFO - MDIVP::selectionChanged - dimObj name is null!\n");
|
||||
//Base::Console().Log("INFO - MDIVP::sceneSelectionChanged - dimObj name is null!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1077,9 +1101,78 @@ void MDIViewPage::selectionChanged()
|
||||
}
|
||||
}
|
||||
|
||||
blockConnection(saveBlock);
|
||||
blockSelection(false);
|
||||
} // end MDIViewPage::selectionChanged()
|
||||
blockConnection(saveBlock);
|
||||
}
|
||||
|
||||
bool MDIViewPage::compareSelections(std::vector<Gui::SelectionObject>& treeSel,QList<QGraphicsItem*>& sceneSel)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
if (treeSel.empty() && sceneSel.empty()) {
|
||||
return true;
|
||||
} else if (treeSel.empty() && !sceneSel.empty()) {
|
||||
return false;
|
||||
} else if (!treeSel.empty() && sceneSel.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int treeCount = 0;
|
||||
int sceneCount = 0;
|
||||
int subCount = 0;
|
||||
int ppCount = 0;
|
||||
std::vector<std::string> treeNames;
|
||||
std::vector<std::string> sceneNames;
|
||||
|
||||
for (auto& tn: treeSel) {
|
||||
if (tn.getObject()->isDerivedFrom(TechDraw::DrawView::getClassTypeId())) {
|
||||
int treeSubs = tn.getSubNames().size();
|
||||
subCount += treeSubs;
|
||||
std::string s = tn.getObject()->getNameInDocument();
|
||||
treeNames.push_back(s);
|
||||
}
|
||||
}
|
||||
std::sort(treeNames.begin(),treeNames.end());
|
||||
treeCount = treeNames.size();
|
||||
|
||||
for (auto& sn:sceneSel){
|
||||
QGIView *itemView = dynamic_cast<QGIView *>(sn);
|
||||
if(itemView == 0) {
|
||||
QGIPrimPath* pp = dynamic_cast<QGIPrimPath*>(sn); //count Vertex/Edge/Face
|
||||
if (pp != nullptr) {
|
||||
ppCount++;
|
||||
}
|
||||
} else {
|
||||
std::string s = itemView->getViewNameAsString();
|
||||
sceneNames.push_back(s);
|
||||
}
|
||||
}
|
||||
std::sort(sceneNames.begin(),sceneNames.end());
|
||||
sceneCount = sceneNames.size();
|
||||
|
||||
//different # of DrawView* vs QGIV*
|
||||
if (sceneCount != treeCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// even of counts match, have to check that names in scene == names in tree
|
||||
auto treePtr = treeNames.begin();
|
||||
for (auto& s: sceneNames){
|
||||
if (s == (*treePtr)) {
|
||||
treePtr++;
|
||||
continue;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Objects all match, check subs
|
||||
if (treeCount != ppCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
///////////////////end Selection Routines //////////////////////
|
||||
|
||||
|
||||
@@ -55,11 +55,13 @@ public:
|
||||
MDIViewPage(ViewProviderPage *page, Gui::Document* doc, QWidget* parent = 0);
|
||||
virtual ~MDIViewPage();
|
||||
|
||||
/// Observer message from the Selection
|
||||
/// Observer message from the Tree Selection mechanism
|
||||
void onSelectionChanged(const Gui::SelectionChanges& msg);
|
||||
void preSelectionChanged(const QPoint &pos);
|
||||
void selectFeature(App::DocumentObject *obj, bool state);
|
||||
void clearSelection();
|
||||
|
||||
/// QGraphicsScene seletion routines
|
||||
void selectQGIView(App::DocumentObject *obj, bool state);
|
||||
void clearSceneSelection();
|
||||
void blockSelection(bool isBlocked);
|
||||
|
||||
void attachTemplate(TechDraw::DrawTemplate *obj);
|
||||
@@ -100,7 +102,7 @@ public Q_SLOTS:
|
||||
void setRenderer(QAction *action);
|
||||
void viewAll();
|
||||
void saveSVG(void);
|
||||
void selectionChanged();
|
||||
void sceneSelectionChanged();
|
||||
|
||||
protected:
|
||||
void findMissingViews( const std::vector<App::DocumentObject*> &list, std::vector<App::DocumentObject*> &missing);
|
||||
@@ -121,6 +123,9 @@ protected:
|
||||
typedef boost::BOOST_SIGNALS_NAMESPACE::connection Connection;
|
||||
Connection connectDeletedObject;
|
||||
|
||||
bool compareSelections(std::vector<Gui::SelectionObject>& treeSel,QList<QGraphicsItem*>& sceneSel);
|
||||
void setTreeToSceneSelect(void);
|
||||
|
||||
private:
|
||||
QAction *m_nativeAction;
|
||||
QAction *m_glAction;
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
#include "QGCustomClip.h"
|
||||
#include "QGIViewClip.h"
|
||||
#include "ViewProviderDrawingView.h"
|
||||
#include "MDIViewPage.h"
|
||||
|
||||
#include <Mod/TechDraw/App/DrawViewClip.h>
|
||||
#include <Mod/TechDraw/App/DrawProjGroup.h>
|
||||
@@ -296,6 +297,11 @@ const char * QGIView::getViewName() const
|
||||
{
|
||||
return viewName.c_str();
|
||||
}
|
||||
const std::string QGIView::getViewNameAsString() const
|
||||
{
|
||||
return viewName;
|
||||
}
|
||||
|
||||
|
||||
TechDraw::DrawView * QGIView::getViewObject() const
|
||||
{
|
||||
@@ -481,6 +487,22 @@ Gui::ViewProvider* QGIView::getViewProvider(App::DocumentObject* obj)
|
||||
return result;
|
||||
}
|
||||
|
||||
MDIViewPage* QGIView::getMDIViewPage(void) const
|
||||
{
|
||||
MDIViewPage* result = nullptr;
|
||||
QGraphicsScene* s = scene();
|
||||
QObject* parent = nullptr;
|
||||
if (s != nullptr) {
|
||||
parent = s->parent();
|
||||
}
|
||||
if (parent != nullptr) {
|
||||
MDIViewPage* mdi = dynamic_cast<MDIViewPage*>(parent);
|
||||
if (mdi != nullptr) {
|
||||
result = mdi;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QColor QGIView::getNormalColor()
|
||||
{
|
||||
|
||||
@@ -46,6 +46,7 @@ class QGCustomBorder;
|
||||
class QGCustomLabel;
|
||||
class QGCustomText;
|
||||
class QGICaption;
|
||||
class MDIViewPage;
|
||||
|
||||
class TechDrawGuiExport QGIView : public QGraphicsItemGroup
|
||||
{
|
||||
@@ -61,7 +62,8 @@ public:
|
||||
const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget = nullptr ) override;
|
||||
|
||||
const char * getViewName() const;
|
||||
const char * getViewName() const;
|
||||
const std::string getViewNameAsString() const;
|
||||
void setViewFeature(TechDraw::DrawView *obj);
|
||||
TechDraw::DrawView * getViewObject() const;
|
||||
|
||||
@@ -92,6 +94,7 @@ public:
|
||||
virtual QColor getSelectColor(void);
|
||||
|
||||
static Gui::ViewProvider* getViewProvider(App::DocumentObject* obj);
|
||||
MDIViewPage* getMDIViewPage(void) const;
|
||||
|
||||
protected:
|
||||
QGIView* getQGIVByName(std::string name);
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
#include "ViewProviderGeomHatch.h"
|
||||
#include "ViewProviderHatch.h"
|
||||
#include "ViewProviderViewPart.h"
|
||||
#include "MDIViewPage.h"
|
||||
|
||||
using namespace TechDrawGui;
|
||||
using namespace TechDrawGeometry;
|
||||
@@ -99,20 +100,7 @@ QGIViewPart::~QGIViewPart()
|
||||
QVariant QGIViewPart::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (change == ItemSelectedHasChanged && scene()) {
|
||||
QList<QGraphicsItem*> items = childItems();
|
||||
for(QList<QGraphicsItem*>::iterator it = items.begin(); it != items.end(); ++it) {
|
||||
//Highlight the children if this is highlighted!? seems to mess up Face selection?
|
||||
QGIEdge *edge = dynamic_cast<QGIEdge *>(*it);
|
||||
QGIVertex *vert = dynamic_cast<QGIVertex *>(*it);
|
||||
QGIFace *face = dynamic_cast<QGIFace *>(*it);
|
||||
if(edge) {
|
||||
//edge->setHighlighted(isSelected());
|
||||
} else if(vert){
|
||||
//vert->setHighlighted(isSelected());
|
||||
} else if(face){
|
||||
//face->setHighlighted(isSelected());
|
||||
}
|
||||
}
|
||||
//There's nothing special for QGIVP to do when selection changes!
|
||||
} else if(change == ItemSceneChange && scene()) {
|
||||
tidy();
|
||||
}
|
||||
@@ -334,15 +322,6 @@ void QGIViewPart::updateView(bool update)
|
||||
} else if (update ||
|
||||
vp->LineWidth.isTouched() ||
|
||||
vp->HiddenWidth.isTouched()) {
|
||||
QList<QGraphicsItem*> items = childItems();
|
||||
for(QList<QGraphicsItem*>::iterator it = items.begin(); it != items.end(); ++it) {
|
||||
QGIEdge *edge = dynamic_cast<QGIEdge *>(*it);
|
||||
if(edge && edge->getHiddenEdge()) {
|
||||
edge->setWidth(vp->HiddenWidth.getValue() * lineScaleFactor);
|
||||
} else if (edge){
|
||||
edge->setWidth(vp->LineWidth.getValue() * lineScaleFactor);
|
||||
}
|
||||
}
|
||||
draw();
|
||||
} else {
|
||||
QGIView::draw();
|
||||
@@ -557,9 +536,14 @@ QGIFace* QGIViewPart::drawFace(TechDrawGeometry::Face* f, int idx)
|
||||
}
|
||||
|
||||
//! Remove all existing QGIPrimPath items(Vertex,Edge,Face)
|
||||
//note this triggers scene selectionChanged signal if vertex/edge/face is selected
|
||||
void QGIViewPart::removePrimitives()
|
||||
{
|
||||
QList<QGraphicsItem*> children = childItems();
|
||||
MDIViewPage* mdi = getMDIViewPage();
|
||||
if (mdi != nullptr) {
|
||||
getMDIViewPage()->blockSelection(true);
|
||||
}
|
||||
for (auto& c:children) {
|
||||
QGIPrimPath* prim = dynamic_cast<QGIPrimPath*>(c);
|
||||
if (prim) {
|
||||
@@ -568,6 +552,9 @@ void QGIViewPart::removePrimitives()
|
||||
delete prim;
|
||||
}
|
||||
}
|
||||
if (mdi != nullptr) {
|
||||
getMDIViewPage()->blockSelection(false);
|
||||
}
|
||||
}
|
||||
|
||||
//! Remove all existing QGIDecoration items(SectionLine,SectionMark,...)
|
||||
|
||||
@@ -38,10 +38,12 @@
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/Material.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Stream.h>
|
||||
#include <Gui/FileDialog.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/WaitCursor.h>
|
||||
|
||||
#include <Mod/TechDraw/App/Geometry.h>
|
||||
|
||||
@@ -37,8 +37,6 @@
|
||||
/// Here the FreeCAD includes sorted by Base,App,Gui......
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Parameter.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Sequencer.h>
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
@@ -46,15 +44,9 @@
|
||||
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Control.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/ViewProvider.h>
|
||||
#include <Gui/ViewProviderDocumentObject.h>
|
||||
#include <Gui/ViewProviderDocumentObjectGroup.h>
|
||||
|
||||
|
||||
#include "MDIViewPage.h"
|
||||
#include "ViewProviderPage.h"
|
||||
@@ -291,50 +283,6 @@ MDIViewPage* ViewProviderPage::getMDIViewPage()
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderPage::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
{
|
||||
if(!m_mdiView.isNull()) {
|
||||
if(msg.Type == Gui::SelectionChanges::SetSelection) {
|
||||
m_mdiView->clearSelection();
|
||||
std::vector<Gui::SelectionSingleton::SelObj> objs = Gui::Selection().getSelection(msg.pDocName);
|
||||
|
||||
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = objs.begin(); it != objs.end(); ++it) {
|
||||
Gui::SelectionSingleton::SelObj selObj = *it;
|
||||
if(selObj.pObject == getDrawPage())
|
||||
continue;
|
||||
|
||||
std::string str = msg.pSubName;
|
||||
// If it's a subfeature, don't select feature
|
||||
if (!str.empty()) {
|
||||
if (TechDraw::DrawUtil::getGeomTypeFromName(str) == "Face" ||
|
||||
TechDraw::DrawUtil::getGeomTypeFromName(str) == "Edge" ||
|
||||
TechDraw::DrawUtil::getGeomTypeFromName(str) == "Vertex") {
|
||||
// TODO implement me wf: don't think this is ever executed
|
||||
}
|
||||
} else {
|
||||
m_mdiView->selectFeature(selObj.pObject, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool selectState = (msg.Type == Gui::SelectionChanges::AddSelection) ? true : false;
|
||||
Gui::Document* doc = Gui::Application::Instance->getDocument(pcObject->getDocument());
|
||||
App::DocumentObject *obj = doc->getDocument()->getObject(msg.pObjectName);
|
||||
if(obj) {
|
||||
std::string str = msg.pSubName;
|
||||
// If it's a subfeature, don't select feature
|
||||
if (!str.empty()) {
|
||||
if (TechDraw::DrawUtil::getGeomTypeFromName(str) == "Face" ||
|
||||
TechDraw::DrawUtil::getGeomTypeFromName(str) == "Edge" ||
|
||||
TechDraw::DrawUtil::getGeomTypeFromName(str) == "Vertex") {
|
||||
// TODO implement me
|
||||
} else {
|
||||
m_mdiView->selectFeature(obj, selectState);
|
||||
}
|
||||
}
|
||||
}
|
||||
} //else (Gui::SelectionChanges::SetPreselect)
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderPage::onChanged(const App::Property *prop)
|
||||
{
|
||||
|
||||
@@ -26,9 +26,7 @@
|
||||
#define DRAWINGGUI_VIEWPROVIDERPAGE_H
|
||||
|
||||
#include <QPointer>
|
||||
#include <Gui/ViewProviderFeature.h>
|
||||
#include <Gui/ViewProviderDocumentObjectGroup.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/ViewProviderDocumentObject.h>
|
||||
|
||||
namespace TechDraw{
|
||||
class DrawPage;
|
||||
@@ -38,8 +36,7 @@ namespace TechDrawGui {
|
||||
|
||||
class MDIViewPage;
|
||||
|
||||
class TechDrawGuiExport ViewProviderPage : public Gui::ViewProviderDocumentObject,
|
||||
public Gui::SelectionObserver
|
||||
class TechDrawGuiExport ViewProviderPage : public Gui::ViewProviderDocumentObject
|
||||
{
|
||||
PROPERTY_HEADER(TechDrawGui::ViewProviderPage);
|
||||
|
||||
@@ -49,10 +46,6 @@ public:
|
||||
/// destructor
|
||||
virtual ~ViewProviderPage();
|
||||
|
||||
//App::PropertyFloat HintScale;
|
||||
//App::PropertyFloat HintOffsetX;
|
||||
//App::PropertyFloat HintOffsetY;
|
||||
|
||||
virtual void attach(App::DocumentObject *);
|
||||
virtual void setDisplayMode(const char* ModeName);
|
||||
virtual bool useNewSelectionModel(void) const {return false;}
|
||||
@@ -64,8 +57,6 @@ public:
|
||||
virtual void show(void);
|
||||
virtual bool isShow(void) const;
|
||||
|
||||
void onSelectionChanged(const Gui::SelectionChanges& msg);
|
||||
|
||||
/// Claim all the views for the page
|
||||
std::vector<App::DocumentObject*> claimChildren(void) const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user