Merge pull request #512 from WandererFan/Fix2888

TechDraw Fix #2888
This commit is contained in:
wwmayer
2017-02-09 22:12:49 +01:00
committed by GitHub
10 changed files with 171 additions and 179 deletions

View File

@@ -325,14 +325,14 @@ void DrawPage::unsetupObject()
App::Document* doc = getDocument();
std::string docName = doc->getName();
const std::vector<App::DocumentObject*> currViews = Views.getValues();
std::vector<App::DocumentObject*> emptyViews;
std::vector<App::DocumentObject*>::const_iterator it = currViews.begin();
for (; it != currViews.end(); it++) {
std::string viewName = (*it)->getNameInDocument();
while (Views.getValues().size() > 0 ) {
const std::vector<App::DocumentObject*> currViews = Views.getValues();
App::DocumentObject* child = currViews.front();
std::string viewName = child->getNameInDocument();
Base::Interpreter().runStringArg("App.getDocument(\"%s\").removeObject(\"%s\")",
docName.c_str(), viewName.c_str());
}
std::vector<App::DocumentObject*> emptyViews; //probably superfluous
Views.setValues(emptyViews);
App::DocumentObject* tmp = Template.getValue();

View File

@@ -90,6 +90,8 @@
#include "DrawViewPart.h"
#include "DrawHatch.h"
#include "DrawGeomHatch.h"
#include "DrawViewDimension.h"
#include "DrawPage.h"
#include "EdgeWalker.h"
@@ -422,6 +424,20 @@ std::vector<TechDraw::DrawGeomHatch*> DrawViewPart::getGeomHatches() const
return result;
}
std::vector<TechDraw::DrawViewDimension*> DrawViewPart::getDimensions() const
{
std::vector<TechDraw::DrawViewDimension*> result;
std::vector<App::DocumentObject*> children = getInList();
for (std::vector<App::DocumentObject*>::iterator it = children.begin(); it != children.end(); ++it) {
if ((*it)->getTypeId().isDerivedFrom(DrawViewDimension::getClassTypeId())) {
TechDraw::DrawViewDimension* dim = dynamic_cast<TechDraw::DrawViewDimension*>(*it);
result.push_back(dim);
}
}
return result;
}
const std::vector<TechDrawGeometry::Vertex *> & DrawViewPart::getVertexGeometry() const
{
return geometryObject->getVertexGeometry();
@@ -642,22 +658,46 @@ bool DrawViewPart::showSectionEdges(void)
return m_sectionEdges;
}
//! remove features that are useless without this DVP
//! hatches, geomhatches, dimensions,...
void DrawViewPart::unsetupObject()
{
nowDeleting = true;
// Remove the View's Hatches from document
App::Document* doc = getDocument();
std::string docName = doc->getName();
// Remove the View's Hatches from document
std::vector<TechDraw::DrawHatch*> hatches = getHatches();
std::vector<TechDraw::DrawHatch*>::iterator it = hatches.begin();
for (; it != hatches.end(); it++) {
std::string viewName = (*it)->getNameInDocument();
Base::Interpreter().runStringArg("App.getDocument(\"%s\").removeObject(\"%s\")",
docName.c_str(), viewName.c_str());
}
// Remove the View's GeomHatches from document
std::vector<TechDraw::DrawGeomHatch*> gHatches = getGeomHatches();
std::vector<TechDraw::DrawGeomHatch*>::iterator it2 = gHatches.begin();
for (; it2 != gHatches.end(); it2++) {
std::string viewName = (*it2)->getNameInDocument();
Base::Interpreter().runStringArg("App.getDocument(\"%s\").removeObject(\"%s\")",
docName.c_str(), viewName.c_str());
}
// Remove Dimensions which reference this DVP
// must use page->removeObject first
TechDraw::DrawPage* page = findParentPage();
if (page != nullptr) {
std::vector<TechDraw::DrawViewDimension*> dims = getDimensions();
std::vector<TechDraw::DrawViewDimension*>::iterator it3 = dims.begin();
for (; it3 != dims.end(); it3++) {
page->removeView(*it3);
std::string viewName = (*it3)->getNameInDocument();
Base::Interpreter().runStringArg("App.getDocument(\"%s\").removeObject(\"%s\")",
docName.c_str(), viewName.c_str());
}
}
}

View File

@@ -57,6 +57,7 @@ class Face;
namespace TechDraw {
class DrawHatch;
class DrawGeomHatch;
class DrawViewDimension;
class DrawProjectSplit;
class DrawViewSection;
}
@@ -100,6 +101,7 @@ public:
std::vector<TechDraw::DrawHatch*> getHatches(void) const;
std::vector<TechDraw::DrawGeomHatch*> getGeomHatches(void) const;
std::vector<TechDraw::DrawViewDimension*> getDimensions() const;
//TODO: are there use-cases for Python access to TechDrawGeometry???

View File

@@ -552,15 +552,21 @@ std::vector<TopoDS_Wire> DrawViewSection::getWireForFace(int idx) const
void DrawViewSection::unsetupObject()
{
getBaseDVP()->touch();
TechDraw::DrawViewPart* base = getBaseDVP();
if (base != nullptr) {
base->touch();
}
DrawViewPart::unsetupObject();
}
TechDraw::DrawViewPart* DrawViewSection::getBaseDVP()
{
TechDraw::DrawViewPart* baseDVP = nullptr;
App::DocumentObject* base = BaseView.getValue();
if (base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
baseDVP = static_cast<TechDraw::DrawViewPart*>(base);
if (base != nullptr) {
if (base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
baseDVP = static_cast<TechDraw::DrawViewPart*>(base);
}
}
return baseDVP;
}
@@ -569,8 +575,10 @@ TechDraw::DrawProjGroupItem* DrawViewSection::getBaseDPGI()
{
TechDraw::DrawProjGroupItem* baseDPGI = nullptr;
App::DocumentObject* base = BaseView.getValue();
if (base->getTypeId().isDerivedFrom(TechDraw::DrawProjGroupItem::getClassTypeId())) {
baseDPGI = static_cast<TechDraw::DrawProjGroupItem*>(base);
if (base != nullptr) {
if (base->getTypeId().isDerivedFrom(TechDraw::DrawProjGroupItem::getClassTypeId())) {
baseDPGI = static_cast<TechDraw::DrawProjGroupItem*>(base);
}
}
return baseDPGI;
}

View File

@@ -320,6 +320,7 @@ bool MDIViewPage::attachView(App::DocumentObject *obj)
} else if (typeId.isDerivedFrom(TechDraw::DrawHatch::getClassTypeId()) ) {
//Hatch is not attached like other Views (since it isn't really a View)
return true;
//DrawGeomHatch??
} else {
Base::Console().Log("Logic Error - Unknown view type in MDIViewPage::attachView\n");
@@ -328,11 +329,6 @@ bool MDIViewPage::attachView(App::DocumentObject *obj)
return (qview != nullptr);
}
void MDIViewPage::removeView(QGIView *view)
{
(void) m_view->removeView(view);
}
void MDIViewPage::onDeleteObject(const App::DocumentObject& obj)
{
if (obj.isDerivedFrom(TechDraw::DrawView::getClassTypeId())) {
@@ -341,7 +337,7 @@ void MDIViewPage::onDeleteObject(const App::DocumentObject& obj)
TechDraw::DrawPage* dvPg = dv->findParentPage();
if (dvPg == m_vpPage->getDrawPage()) {
//this is a DV that is on our page
(void) m_view->removeView(dv);
(void) m_view->removeQViewByDrawView(dv);
}
}
}
@@ -374,88 +370,35 @@ void MDIViewPage::updateTemplate(bool forceUpdate)
void MDIViewPage::updateDrawing(bool forceUpdate)
{
// We cannot guarantee if the number of graphical representations (QGIVxxxx) have changed so check the number (MLP)
// WF: this should be fixed now with onDeletedObject signal from App side?
// WF: the QGVP views list may still not be 100% reliable
// TODO: build list of QGIV's from scene everytime?
//logging counters
// int qgvpIn = 0;
// int qgvpValid = 0;
// int qgvpClean = 0;
// int dpIn = 0;
const std::vector<QGIView *> &graphicsList = m_view->getViews();
// qgvpIn = graphicsList.size();
const std::vector<App::DocumentObject*> &pageChildren = m_vpPage->getDrawPage()->Views.getValues();
// Count total # DocumentObjects in Page
unsigned int docObjCount = 0;
for(std::vector<App::DocumentObject*>::const_iterator it = pageChildren.begin(); it != pageChildren.end(); ++it) {
App::DocumentObject *docObj = *it;
if(docObj->getTypeId().isDerivedFrom(TechDraw::DrawViewCollection::getClassTypeId())) {
TechDraw::DrawViewCollection *collection = dynamic_cast<TechDraw::DrawViewCollection *>(docObj);
docObjCount += collection->countChildren(); // Include self
// get all the DrawViews for this page, including the second level ones
// if we ever have collections of collections, we'll need to revisit this
std::vector<App::DocumentObject*> pChildren = m_vpPage->getDrawPage()->Views.getValues();
std::vector<App::DocumentObject*> appendChildren;
for (auto& pc: pChildren) {
if(pc->getTypeId().isDerivedFrom(TechDraw::DrawViewCollection::getClassTypeId())) {
TechDraw::DrawViewCollection *collect = dynamic_cast<TechDraw::DrawViewCollection *>(pc);
std::vector<App::DocumentObject*> cChildren = collect->Views.getValues();
appendChildren.insert(std::end(appendChildren), std::begin(cChildren), std::end(cChildren));
}
docObjCount += 1;
}
// dpIn = docObjCount;
//TODO: should prune QGVP.views first always, then check if view in Page missing QGIVP
// this makes assumption that = numbers mean everythign is OK, but could be double failure - 1 extra QGIV, 1 DV missing graphics!
if(graphicsList.size() < docObjCount) {
// there are more DocumentObjects than graphical representations (QGIVxxxx's)
// Find which DocumentObjects have no graphical representation (QGIVxxxx)
// Iterate over DocumentObjects without graphical representations and create the QGIVxxxx
// TODO think of a better algorithm to deal with any changes to views list
std::vector<App::DocumentObject*> notFnd;
findMissingViews(pageChildren, notFnd);
for(std::vector<App::DocumentObject*>::const_iterator it = notFnd.begin(); it != notFnd.end(); ++it) {
attachView(*it);
pChildren.insert(std::end(pChildren),std::begin(appendChildren),std::end(appendChildren));
// if dv doesn't have a graphic, make one
for (auto& dv: pChildren) {
QGIView* qv = m_view->findQViewForDocObj(dv);
if (qv == nullptr) {
attachView(dv);
}
} else if(graphicsList.size() > docObjCount) {
// prune any invalid entries in QGVP.views
// TODO: revisit this mess. is it still required with onDeletedItem signal implementation?
std::vector<QGIView *> newGraphicsList;
QList<QGraphicsItem *> items = m_view->scene()->items();
for (auto& v: graphicsList) { //check that everything in QGVP views is valid
for (auto& i:items) {
if (v == i) { //this one is OK
newGraphicsList.push_back(v);
break;
}
}
}
// if qView doesn't have a Feature, delete it
std::vector<QGIView*> qvs = m_view->getViews();
App::Document* doc = getAppDocument();
for (auto& qv: qvs) {
App::DocumentObject* obj = doc->getObject(qv->getViewName());
if (obj == nullptr) {
m_view->removeQView(qv);
}
// qgvpValid = newGraphicsList.size();
//newGraphicsList now only contains valid QGIV's
//now prune the ones without docObjs
std::vector<QGIView *> cleanItems;
for (auto& i: newGraphicsList) {
std::string viewName = (i->data(1).toString()).toStdString();
App::DocumentObject* dObj = getAppDocument()->getObject(viewName.c_str());
if (dObj == nullptr) {
//need to remove from group/scene
QGraphicsItemGroup* grp = i->group();
if (grp) {
grp->removeFromGroup(i);
}
if (i->parentItem()) { //not top level
i->setParentItem(0);
}
if (i->scene()) {
i->scene()->removeItem(i);
}
//should delete i too to prevent leak? might be garbage pointer, though.
//add to delete list and delete outside of loop
} else {
QGIView* v = static_cast<QGIView*>(i);
cleanItems.push_back(v);
}
}
// qgvpClean = cleanItems.size();
m_view->setViews(cleanItems);
// Base::Console().Message("Log - MDIVP::updateDrawing pruning: docObjs: %d views in: %d valid views: %d views out: %d\n",
// dpIn,qgvpIn,qgvpValid, qgvpClean);
}
// Update all the QGIVxxxx
@@ -1004,7 +947,7 @@ void MDIViewPage::selectFeature(App::DocumentObject *obj, const bool isSelected)
if (hatchObj) { //Hatch does not have a QGIV of it's own. mark parent as selected.
objCopy = hatchObj->getSourceView(); //possible to highlight subObject?
}
QGIView *view = m_view->findView(objCopy);
QGIView *view = m_view->findQViewForDocObj(objCopy);
blockSelection(true);
if(view) {

View File

@@ -65,7 +65,6 @@ public:
void attachTemplate(TechDraw::DrawTemplate *obj);
void updateTemplate(bool force = false);
void updateDrawing(bool force = false);
void removeView(QGIView *view);
bool onMsg(const char* pMsg,const char** ppReturn);
bool onHasMsg(const char* pMsg) const;

View File

@@ -287,7 +287,9 @@ const char * QGIView::getViewName() const
TechDraw::DrawView * QGIView::getViewObject() const
{
return viewObj;
//DocumentObject* obj = doc->getObject(viewName.c_str());
//TechDraw::DrawView* dv = static_cast<TechDraw::DrawView*>(obj);
return viewObj;
}
void QGIView::setViewFeature(TechDraw::DrawView *obj)

View File

@@ -164,18 +164,29 @@ void QGVPage::drawBackground(QPainter *p, const QRectF &)
p->drawRect(poly.boundingRect());
p->restore();
}
int QGVPage::addView(QGIView *view)
//! retrieve the QGIView objects currently in the scene
std::vector<QGIView *> QGVPage::getViews() const
{
std::vector<QGIView*> result;
QList<QGraphicsItem*> items = scene()->items();
for (auto& v:items) {
QGIView* qv = dynamic_cast<QGIView*>(v);
if (qv != nullptr) {
result.push_back(qv);
}
}
return result;
}
int QGVPage::addQView(QGIView *view)
{
auto ourScene( scene() );
assert(ourScene);
ourScene->addItem(view);
views.push_back(view);
// Find if it belongs to a parent
QGIView *parent = 0;
parent = findParent(view);
@@ -184,10 +195,9 @@ int QGVPage::addView(QGIView *view)
Rez::guiX(view->getViewObject()->Y.getValue() * -1));
if(parent) {
// Transfer the child vierw to the parent
// move child view to center of parent
QPointF posRef(0.,0.);
QPointF mapPos = view->mapToItem(parent, posRef); //setPos is called later. this doesn't do anything?
QPointF mapPos = view->mapToItem(parent, posRef);
view->moveBy(-mapPos.x(), -mapPos.y());
parent->addToGroup(view);
@@ -195,67 +205,40 @@ int QGVPage::addView(QGIView *view)
view->setPos(viewPos);
return views.size();
return 0;
}
int QGVPage::removeView(QGIView *view)
int QGVPage::removeQView(QGIView *view)
{
std::vector<QGIView *> qviews = views;
std::vector<QGIView *> newViews;
std::vector<QGIView *>::iterator qvit = qviews.begin();
std::vector<QGIView *>::iterator qvDel = qviews.end();
for (; qvit != qviews.end(); qvit++) {
if ((*qvit) == view) {
qvDel = qvit;
break;
}
if (view != nullptr) {
removeQViewFromScene(view);
delete view;
}
if (qvDel == qviews.end()) { //didn't find view in views
return views.size();
}
removeViewFromScene(view);
qviews.erase(qvDel);
views = qviews;
delete view;
return views.size();
return 0;
}
int QGVPage::removeView(const TechDraw::DrawView* dv)
int QGVPage::removeQViewByDrawView(const TechDraw::DrawView* dv)
{
std::vector<QGIView *> newViews;
QList<QGraphicsItem *> items = scene()->items();
std::vector<QGIView*> items = getViews();
QString qsName = QString::fromUtf8(dv->getNameInDocument());
bool found = false;
QGIView* ourItem = nullptr;
for (auto& i:items) {
if (qsName == i->data(1).toString()) { //is there really a QGIV for this DV in scene?
found = true;
ourItem = static_cast<QGIView*>(i);
ourItem = i;
break;
}
}
if (found) {
for (auto&v :views) {
if (ourItem != v) {
newViews.push_back(v);
}
}
removeViewFromScene(ourItem);
removeQViewFromScene(ourItem);
delete ourItem;
views = newViews;
}
return views.size();
return 0;
}
void QGVPage::removeViewFromScene(QGIView *view)
void QGVPage::removeQViewFromScene(QGIView *view)
{
QGraphicsItemGroup* grp = view->group();
if (grp) {
@@ -278,7 +261,7 @@ QGIView * QGVPage::addViewPart(TechDraw::DrawViewPart *part)
viewPart->setViewPartFeature(part);
addView(viewPart);
addQView(viewPart);
return viewPart;
}
@@ -288,7 +271,7 @@ QGIView * QGVPage::addViewSection(TechDraw::DrawViewPart *part)
viewSection->setViewPartFeature(part);
addView(viewSection);
addQView(viewSection);
return viewSection;
}
@@ -296,7 +279,7 @@ QGIView * QGVPage::addProjectionGroup(TechDraw::DrawProjGroup *view) {
auto qview( new QGIProjGroup );
qview->setViewFeature(view);
addView(qview);
addQView(qview);
return qview;
}
@@ -305,7 +288,7 @@ QGIView * QGVPage::addDrawView(TechDraw::DrawView *view)
auto qview( new QGIView );
qview->setViewFeature(view);
addView(qview);
addQView(qview);
return qview;
}
@@ -314,31 +297,28 @@ QGIView * QGVPage::addDrawViewCollection(TechDraw::DrawViewCollection *view)
auto qview( new QGIViewCollection );
qview->setViewFeature(view);
addView(qview);
addQView(qview);
return qview;
}
// TODO change to (App?) annotation object ??
QGIView * QGVPage::addDrawViewAnnotation(TechDraw::DrawViewAnnotation *view)
{
// This essentially adds a null view feature to ensure view size is consistent
auto qview( new QGIViewAnnotation );
qview->setViewAnnoFeature(view);
addView(qview);
addQView(qview);
return qview;
}
QGIView * QGVPage::addDrawViewSymbol(TechDraw::DrawViewSymbol *view)
{
//QPoint qp(view->X.getValue(),view->Y.getValue());
// This essentially adds a null view feature to ensure view size is consistent
auto qview( new QGIViewSymbol );
qview->setViewFeature(view);
addView(qview);
addQView(qview);
return qview;
}
@@ -349,7 +329,7 @@ QGIView * QGVPage::addDrawViewClip(TechDraw::DrawViewClip *view)
qview->setPosition(Rez::guiX(view->X.getValue()), Rez::guiX(view->Y.getValue()));
qview->setViewFeature(view);
addView(qview);
addQView(qview);
return qview;
}
@@ -359,18 +339,17 @@ QGIView * QGVPage::addDrawViewSpreadsheet(TechDraw::DrawViewSpreadsheet *view)
qview->setViewFeature(view);
addView(qview);
addQView(qview);
return qview;
}
QGIView * QGVPage::addDrawViewImage(TechDraw::DrawViewImage *view)
{
//QPoint qp(view->X.getValue(),view->Y.getValue());
auto qview( new QGIViewImage );
qview->setViewFeature(view);
addView(qview);
addQView(qview);
return qview;
}
@@ -384,12 +363,6 @@ QGIView * QGVPage::addViewDimension(TechDraw::DrawViewDimension *dim)
dimGroup->setViewPartFeature(dim);
// TODO consider changing dimension feature to use another property for label position
// Instead of calling addView - the view must for now be added manually
//Note dimension X,Y is different from other views -> can't use addView
views.push_back(dimGroup);
// Find if it belongs to a parent
QGIView *parent = 0;
parent = findParent(dimGroup);
@@ -412,10 +385,11 @@ void QGVPage::addDimToParent(QGIViewDimension* dim, QGIView* parent)
dim->setZValue(ZVALUE::DIMENSION);
}
QGIView * QGVPage::findView(App::DocumentObject *obj) const
//! find the graphic for a DocumentObject
QGIView * QGVPage::findQViewForDocObj(App::DocumentObject *obj) const
{
if(obj) {
const std::vector<QGIView *> qviews = views;
const std::vector<QGIView *> qviews = getViews();
for(std::vector<QGIView *>::const_iterator it = qviews.begin(); it != qviews.end(); ++it) {
if(strcmp(obj->getNameInDocument(), (*it)->getViewName()) == 0)
return *it;
@@ -424,9 +398,27 @@ QGIView * QGVPage::findView(App::DocumentObject *obj) const
return 0;
}
//! find the graphic for DocumentObject with name
QGIView* QGVPage::getQGIVByName(std::string name)
{
QList<QGraphicsItem*> qgItems = scene()->items();
QList<QGraphicsItem*>::iterator it = qgItems.begin();
for (; it != qgItems.end(); it++) {
QGIView* qv = dynamic_cast<QGIView*>((*it));
if (qv) {
const char* qvName = qv->getViewName();
if(name.compare(qvName) == 0) {
return (qv);
}
}
}
return nullptr;
}
QGIView * QGVPage::findParent(QGIView *view) const
{
const std::vector<QGIView *> qviews = views;
const std::vector<QGIView *> qviews = getViews();
TechDraw::DrawView *myView = view->getViewObject();
//If type is dimension we check references first

View File

@@ -74,17 +74,20 @@ public:
QGIView * addDrawViewImage(TechDraw::DrawViewImage *view);
QGIView * findView(App::DocumentObject *obj) const;
QGIView * findParent(QGIView *) const;
QGIView* findQViewForDocObj(App::DocumentObject *obj) const;
QGIView* getQGIVByName(std::string name);
QGIView* findParent(QGIView *) const;
void addDimToParent(QGIViewDimension* dim, QGIView* parent);
const std::vector<QGIView *> & getViews() const { return views; }
// const std::vector<QGIView *> & getViews() const { return views; } //only used in MDIVP
std::vector<QGIView *> getViews() const; //only used in MDIVP
int addView(QGIView * view);
int removeView(QGIView *view);
int removeView(const TechDraw::DrawView* dv);
int addQView(QGIView * view);
int removeQView(QGIView *view);
int removeQViewByDrawView(const TechDraw::DrawView* dv);
void removeQViewFromScene(QGIView *view);
void setViews(const std::vector<QGIView *> &view) {views = view; }
//void setViews(const std::vector<QGIView *> &view) {views = view; }
void setPageTemplate(TechDraw::DrawTemplate *pageTemplate);
QGITemplate * getTemplate() const;
@@ -112,10 +115,9 @@ protected:
static QColor PreselectColor;
QColor getBackgroundColor();
void removeViewFromScene(QGIView *view);
QGITemplate *pageTemplate;
std::vector<QGIView *> views;
// std::vector<QGIView *> views; //<<< why? scene already has a list of all the views.
private:
RendererType m_renderer;

View File

@@ -137,6 +137,10 @@ void ViewProviderDrawingView::hide(void)
QGIView* ViewProviderDrawingView::getQView(void)
{
//TODO: vp can get its MDIView with 1 call getActiveView()?
// instead of going back to App side an up tree and back to Gui?
//MDIVPage* mdivp = static_cast<MDIVPage*>(getActiveView());
//qView = mdivp->getQGVPage()->findQViewForDocObj(getViewObject());
QGIView *qView = nullptr;
if (m_docReady){
TechDraw::DrawView* dv = getViewObject();
@@ -147,7 +151,7 @@ QGIView* ViewProviderDrawingView::getQView(void)
if (dvp) {
if (dvp->getMDIViewPage()) {
if (dvp->getMDIViewPage()->getQGVPage()) {
qView = dynamic_cast<QGIView *>(dvp->getMDIViewPage()->getQGVPage()->findView(getViewObject()));
qView = dynamic_cast<QGIView *>(dvp->getMDIViewPage()->getQGVPage()->findQViewForDocObj(getViewObject()));
}
}
}