/*************************************************************************** * Copyright (c) 2002 Jürgen Riegel * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #include "PreCompiled.h" #ifndef _PreComp_ # include #endif #include #include #include #include #include #include "DrawViewCollection.h" using namespace TechDraw; //=========================================================================== // DrawViewCollection //=========================================================================== PROPERTY_SOURCE(TechDraw::DrawViewCollection, TechDraw::DrawView) DrawViewCollection::DrawViewCollection() { nowUnsetting = false; static const char *group = "Collection"; ADD_PROPERTY_TYPE(Views ,(nullptr), group, App::Prop_None, "Collection Views"); Views.setScope(App::LinkScope::Global); } DrawViewCollection::~DrawViewCollection() { } void DrawViewCollection::onChanged(const App::Property* prop) { TechDraw::DrawView::onChanged(prop); } short DrawViewCollection::mustExecute() const { if (Views.isTouched()) { return 1; } else { return TechDraw::DrawView::mustExecute(); } } App::DocumentObjectExecReturn *DrawViewCollection::execute() { if (!keepUpdated()) { return App::DocumentObject::StdReturn; } lockChildren(); overrideKeepUpdated(false); return DrawView::execute(); } int DrawViewCollection::addView(App::DocumentObject* docObj) { // Add the new view to the collection if (!docObj->isDerivedFrom() && !docObj->isDerivedFrom()) { return -1; } auto* view = dynamic_cast(docObj); if (!view) { auto* link = dynamic_cast(docObj); if (!link) { return -1; } if (link) { view = dynamic_cast(link->getLinkedObject()); if (!view) { return -1; } } } std::vector newViews(Views.getValues()); newViews.push_back(docObj); Views.setValues(newViews); return Views.getSize(); } int DrawViewCollection::removeView(App::DocumentObject* docObj) { // Remove the view from the collection std::vector newViews; std::string viewName = docObj->getNameInDocument(); for (auto* view : Views.getValues()) { if (viewName.compare(view->getNameInDocument()) != 0) { newViews.push_back(view); } } Views.setValues(newViews); return Views.getSize(); } std::vector DrawViewCollection::getViews() const { std::vector views = Views.getValues(); std::vector allViews; for (auto& v : views) { if (v->isDerivedFrom(App::Link::getClassTypeId())) { v = static_cast(v)->getLinkedObject(); } if (!v->isDerivedFrom(TechDraw::DrawView::getClassTypeId())) { continue; } allViews.push_back(v); } return allViews; } //make sure everything in View list represents a real DrawView docObj and occurs only once void DrawViewCollection::rebuildViewList() { const std::vector currViews = Views.getValues(); std::vector newViews; for (auto* child : getOutList()) { if (child->isDerivedFrom() || (child->isDerivedFrom() && static_cast(child)->getLinkedObject()->isDerivedFrom())) { bool found = false; for (auto& v:currViews) { if (v == child) { found = true; break; } } if (found) { newViews.push_back(child); } } } // newViews contains only valid items, but may have duplicates sort( newViews.begin(), newViews.end() ); newViews.erase( unique( newViews.begin(), newViews.end() ), newViews.end() ); Views.setValues(newViews); } int DrawViewCollection::countChildren() { //Count the children recursively if needed int numChildren = 0; for(auto* view : Views.getValues()) { if(view->isDerivedFrom()) { auto *viewCollection = static_cast(view); numChildren += viewCollection->countChildren() + 1; } else { numChildren += 1; } } return numChildren; } void DrawViewCollection::onDocumentRestored() { DrawView::execute(); } void DrawViewCollection::lockChildren() { for (auto& v : getViews()) { auto *view = dynamic_cast(v); if (!view) { throw Base::ValueError("DrawViewCollection::lockChildren bad View\n"); } view->handleXYLock(); } } void DrawViewCollection::unsetupObject() { nowUnsetting = true; // Remove the collection's views from document std::string docName = getDocument()->getName(); for (auto* view : Views.getValues()) { if (view->isAttachedToDocument()) { std::string viewName = view->getNameInDocument(); Base::Interpreter().runStringArg("App.getDocument(\"%s\").removeObject(\"%s\")", docName.c_str(), viewName.c_str()); } } std::vector emptyViews; Views.setValues(emptyViews); } QRectF DrawViewCollection::getRect() const { QRectF result; for (auto& v : getViews()) { auto *view = dynamic_cast(v); if (!view) { throw Base::ValueError("DrawViewCollection::getRect bad View\n"); } result = result.united(view->getRect().translated(view->X.getValue(), view->Y.getValue())); } return { 0, 0, getScale() * result.width(), getScale() * result.height()}; }