diff --git a/CMakeLists.txt b/CMakeLists.txt index e45c4f763..b4aab7f40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -198,6 +198,7 @@ OPTION(BUILD_RAYTRACING "Build the FreeCAD ray tracing module" ON) OPTION(BUILD_REVERSEENGINEERING "Build the FreeCAD reverse engineering module" ON) OPTION(BUILD_ROBOT "Build the FreeCAD robot module" ON) OPTION(BUILD_SHIP "Build the FreeCAD ship module" ON) +OPTION(BUILD_SHOW "Build the FreeCAD Show module (helper module for visibility automation)" ON) OPTION(BUILD_SKETCHER "Build the FreeCAD sketcher module" ON) OPTION(BUILD_SPREADSHEET "Build the FreeCAD spreadsheet module" ON) OPTION(BUILD_START "Build the FreeCAD start module" ON) diff --git a/src/Mod/CMakeLists.txt b/src/Mod/CMakeLists.txt index a0b7b3b62..e310a30f3 100644 --- a/src/Mod/CMakeLists.txt +++ b/src/Mod/CMakeLists.txt @@ -125,3 +125,7 @@ endif(BUILD_JTREADER) if(BUILD_PATH) add_subdirectory(Path) endif(BUILD_PATH) + +if(BUILD_SHOW) + add_subdirectory(Show) +endif(BUILD_SHOW) diff --git a/src/Mod/Part/App/CMakeLists.txt b/src/Mod/Part/App/CMakeLists.txt index 18cb8f799..29af1b8ca 100644 --- a/src/Mod/Part/App/CMakeLists.txt +++ b/src/Mod/Part/App/CMakeLists.txt @@ -289,11 +289,9 @@ SET(Part_Scripts JoinFeatures.py AttachmentEditor/__init__.py AttachmentEditor/Commands.py - AttachmentEditor/DepGraphTools.py AttachmentEditor/FrozenClass.py AttachmentEditor/TaskAttachmentEditor.py AttachmentEditor/TaskAttachmentEditor.ui - AttachmentEditor/TempoVis.py ) add_library(Part SHARED ${Part_SRCS}) diff --git a/src/Mod/Part/AttachmentEditor/TaskAttachmentEditor.py b/src/Mod/Part/AttachmentEditor/TaskAttachmentEditor.py index f6b92b120..4c5537316 100644 --- a/src/Mod/Part/AttachmentEditor/TaskAttachmentEditor.py +++ b/src/Mod/Part/AttachmentEditor/TaskAttachmentEditor.py @@ -31,8 +31,16 @@ from Units import Degree as deg from Units import Quantity as Q from AttachmentEditor.FrozenClass import FrozenClass -from AttachmentEditor.TempoVis import TempoVis -from AttachmentEditor.DepGraphTools import getAllDependent +try: + from Show.TempoVis import TempoVis + from Show.DepGraphTools import getAllDependent +except ImportError as err: + def TempoVis(doc): + return None + def getAllDependent(feature): + return [] + App.Console.PrintWarning("AttachmentEditor: Failed to import some code from Show module. Functionality will be limited.\n") + App.Console.PrintWarning(err.message) if App.GuiUp: import FreeCADGui as Gui @@ -280,9 +288,10 @@ class AttachmentEditorTaskPanel(FrozenClass): self.updateRefButtons() self.tv = TempoVis(self.obj.Document) - self.tv.hide_all_dependent(self.obj) - self.tv.show(self.obj) - self.tv.show([obj for (obj,subname) in self.attacher.References]) + if self.tv: # tv will still be None if Show module is unavailable + self.tv.hide_all_dependent(self.obj) + self.tv.show(self.obj) + self.tv.show([obj for (obj,subname) in self.attacher.References]) # task dialog handling def getStandardButtons(self): @@ -582,4 +591,5 @@ class AttachmentEditorTaskPanel(FrozenClass): def cleanUp(self): '''stuff that needs to be done when dialog is closed.''' Gui.Selection.removeObserver(self) - self.tv.restore() \ No newline at end of file + if self.tv: + self.tv.restore() \ No newline at end of file diff --git a/src/Mod/Part/CMakeLists.txt b/src/Mod/Part/CMakeLists.txt index 7ed515703..d75a927e7 100644 --- a/src/Mod/Part/CMakeLists.txt +++ b/src/Mod/Part/CMakeLists.txt @@ -20,11 +20,9 @@ INSTALL( FILES AttachmentEditor/__init__.py AttachmentEditor/Commands.py - AttachmentEditor/DepGraphTools.py AttachmentEditor/FrozenClass.py AttachmentEditor/TaskAttachmentEditor.py AttachmentEditor/TaskAttachmentEditor.ui - AttachmentEditor/TempoVis.py DESTINATION Mod/Part/AttachmentEditor ) diff --git a/src/Mod/Show/CMakeLists.txt b/src/Mod/Show/CMakeLists.txt new file mode 100644 index 000000000..8f8602d4f --- /dev/null +++ b/src/Mod/Show/CMakeLists.txt @@ -0,0 +1,21 @@ + +SET(Show_SRCS + __init__.py + DepGraphTools.py + FrozenClass.py + TempoVis.py +) + +SOURCE_GROUP("" FILES ${Show_SRCS}) + +ADD_CUSTOM_TARGET(Show ALL + SOURCES ${Show_SRCS} +) + +fc_copy_sources(Show "${CMAKE_BINARY_DIR}/Mod/Show" ${Show_SRCS}) + +INSTALL( + FILES + ${Show_SRCS} + DESTINATION Mod/Show +) \ No newline at end of file diff --git a/src/Mod/Part/AttachmentEditor/DepGraphTools.py b/src/Mod/Show/DepGraphTools.py similarity index 100% rename from src/Mod/Part/AttachmentEditor/DepGraphTools.py rename to src/Mod/Show/DepGraphTools.py diff --git a/src/Mod/Show/FrozenClass.py b/src/Mod/Show/FrozenClass.py new file mode 100644 index 000000000..1fa76fb5f --- /dev/null +++ b/src/Mod/Show/FrozenClass.py @@ -0,0 +1,37 @@ +#/*************************************************************************** +# * Copyright (c) Victor Titov (DeepSOIC) * +# * (vv.titov@gmail.com) 2016 * +# * * +# * 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 * +# * * +# ***************************************************************************/ + +# adapted from http://stackoverflow.com/a/3603824/6285007 +class FrozenClass(object): + '''FrozenClass: prevents adding new attributes to class outside of __init__''' + __isfrozen = False + def __setattr__(self, key, value): + if self.__isfrozen and not hasattr(self, key): + raise TypeError( "{cls} has no attribute {attr}".format(cls= self.__class__.__name__, attr= key) ) + object.__setattr__(self, key, value) + + def _freeze(self): + self.__isfrozen = True + + def _unfreeze(self): + self.__isfrozen = False diff --git a/src/Mod/Part/AttachmentEditor/TempoVis.py b/src/Mod/Show/TempoVis.py similarity index 62% rename from src/Mod/Part/AttachmentEditor/TempoVis.py rename to src/Mod/Show/TempoVis.py index 39b1031d7..823530be8 100644 --- a/src/Mod/Part/AttachmentEditor/TempoVis.py +++ b/src/Mod/Show/TempoVis.py @@ -25,61 +25,71 @@ import FreeCAD as App if App.GuiUp: import FreeCADGui as Gui -from FrozenClass import FrozenClass +from Show.FrozenClass import FrozenClass -from DepGraphTools import getAllDependencies, getAllDependent, isContainer +from Show.DepGraphTools import getAllDependencies, getAllDependent, isContainer class TempoVis(FrozenClass): - '''TempoVis - helper object to save visibilities of objects before doing - some GUI editing, hiding or showing relevant stuff during edit, and + '''TempoVis - helper object to save visibilities of objects before doing + some GUI editing, hiding or showing relevant stuff during edit, and then restoring all visibilities after editing. - + Constructors: TempoVis(document): creates a new TempoVis. Supplying document is mandatory. Objects not belonging to the document can't be modified via TempoVis.''' - + def __define_attributes(self): self.data = {} # dict. key = ("Object","Property"), value = original value of the property + + self.cam_string = "" # inventor ASCII string representing the camera + self.viewer = None # viewer the camera is saved from + self.document = None - self.restore_on_delete = False + self.restore_on_delete = False # if true, restore() gets called upon object deletion. It becomes False after explicit call to Restore, and set to true by many methods. + + self.links_are_lost = False # set to true after restore from JSON. Indictes to attempt to use ActiveDocument/ActiveViewer instead. self._freeze() - + def __init__(self, document): self.__define_attributes() - + self.document = document - + def modifyVPProperty(self, doc_obj_or_list, prop_name, new_value): - '''modifyVPProperty(self, doc_obj_or_list, prop_name, new_value): modifies - prop_name property of ViewProvider of doc_obj_or_list, and remembers - original value of the property. Original values will be restored upon + '''modifyVPProperty(self, doc_obj_or_list, prop_name, new_value): modifies + prop_name property of ViewProvider of doc_obj_or_list, and remembers + original value of the property. Original values will be restored upon TempoVis deletion, or call to restore().''' - + if App.GuiUp: if type(doc_obj_or_list) is not list: doc_obj_or_list = [doc_obj_or_list] for doc_obj in doc_obj_or_list: + if not hasattr(doc_obj.ViewObject, prop_name): + App.Console.PrintWarning("TempoVis: object {obj} has no attribute {attr}. Skipped.\n" + .format(obj= doc_obj.Name, attr= prop_name)) + continue # silently ignore if object doesn't have the property... + if doc_obj.Document is not self.document: #ignore objects from other documents raise ValueError("Document object to be modified does not belong to document TempoVis was made for.") oldval = getattr(doc_obj.ViewObject, prop_name) setattr(doc_obj.ViewObject, prop_name, new_value) - #assert(getattr(doc_obj.ViewObject, prop_name)==new_value) if not self.data.has_key((doc_obj.Name,prop_name)): self.data[(doc_obj.Name,prop_name)] = oldval self.restore_on_delete = True - + def show(self, doc_obj_or_list): '''show(doc_obj_or_list): shows objects (sets their Visibility to True). doc_obj_or_list can be a document object, or a list of document objects''' self.modifyVPProperty(doc_obj_or_list, "Visibility", True) - + def hide(self, doc_obj_or_list): '''hide(doc_obj_or_list): hides objects (sets their Visibility to False). doc_obj_or_list can be a document object, or a list of document objects''' self.modifyVPProperty(doc_obj_or_list, "Visibility", False) - + def hide_all_dependent(self, doc_obj): '''hide_all_dependent(doc_obj): hides all objects that depend on doc_obj. Groups, Parts and Bodies are not hidden by this.''' self.hide( [o for o in getAllDependent(doc_obj) if not isContainer(o)]) - + def show_all_dependent(self, doc_obj): '''show_all_dependent(doc_obj): shows all objects that depend on doc_obj. This method is probably useless.''' self.show( getAllDependent(doc_obj) ) @@ -87,24 +97,78 @@ class TempoVis(FrozenClass): def hide_all_dependencies(self, doc_obj): '''hide_all_dependencies(doc_obj): hides all objects that doc_obj depends on (directly and indirectly).''' self.hide( getAllDependencies(doc_obj) ) - + def show_all_dependencies(self, doc_obj): '''show_all_dependencies(doc_obj): shows all objects that doc_obj depends on (directly and indirectly). This method is probably useless.''' self.show( getAllDependencies(doc_obj) ) - + + def saveCamera(self): + vw = Gui.ActiveDocument.ActiveView + self.cam_string = vw.getCamera() + self.viewer = vw + + self.restore_on_delete = True + + def restoreCamera(self): + if not self.cam_string: + return + vw = self.viewer + if self.links_are_lost: # can happen after save-restore + import FreeCADGui as Gui + vw = Gui.ActiveDocument.ActiveView + + vw.setCamera(self.cam_string) + def restore(self): - '''restore(): restore all ViewProvider properties modified via TempoVis to their original values. Called automatically when instance is destroyed, unless it was called explicitly.''' + '''restore(): restore all ViewProvider properties modified via TempoVis to their + original values, and saved camera, if any. Called automatically when instance is + destroyed, unless it was called explicitly. Should not raise exceptions.''' + + if self.links_are_lost: + self.document = App.ActiveDocument + self.viewer = Gui.ActiveDocument.ActiveView + self.links_are_lost = False + for obj_name, prop_name in self.data: - setattr(self.document.getObject(obj_name).ViewObject, prop_name, self.data[(obj_name, prop_name)]) + try: + setattr(self.document.getObject(obj_name).ViewObject, prop_name, self.data[(obj_name, prop_name)]) + except Exception as err: + App.Console.PrintWarning("TempoVis: failed to restore {obj}.{prop}. {err}\n" + .format(err= err.message, + obj= obj_name, + prop= prop_name)) + try: + self.restoreCamera() + except Exception as err: + App.Console.PrintWarning("TempoVis: failed to restore camera. {err}\n" + .format(err= err.message)) self.restore_on_delete = False - + def forget(self): '''forget(): resets TempoVis''' self.data = {} - self.restore_on_delete = False - + + self.cam_string = "" + self.viewer = None + + self.restore_on_delete = False + def __del__(self): if self.restore_on_delete: self.restore() - - \ No newline at end of file + + def __getstate__(self): + return (self.data.items(), + self.cam_string, + self.restore_on_delete) + + def __setstate__(self, state): + self.__define_attributes() + + items, self.cam_string, self.restore_on_delete = state + + # need to convert keys to tuples (dict doesn't accept list as key; tuples are converted to lists by json) + items = [(tuple(item[0]), item[1]) for item in items] + self.data = dict(items) + self.links_are_lost = True + \ No newline at end of file diff --git a/src/Mod/Show/__init__.py b/src/Mod/Show/__init__.py new file mode 100644 index 000000000..44b15b8d0 --- /dev/null +++ b/src/Mod/Show/__init__.py @@ -0,0 +1,4 @@ +__doc__ = "Show module: helper code for visibility automation." + +from Show.TempoVis import TempoVis +import Show.DepGraphTools as DepGraphTools \ No newline at end of file diff --git a/src/Mod/Sketcher/Gui/SketcherSettings.cpp b/src/Mod/Sketcher/Gui/SketcherSettings.cpp index 9c10869e5..dea9a0487 100644 --- a/src/Mod/Sketcher/Gui/SketcherSettings.cpp +++ b/src/Mod/Sketcher/Gui/SketcherSettings.cpp @@ -26,14 +26,18 @@ #ifndef _PreComp_ # include # include +# include #endif #include "SketcherSettings.h" #include "ui_SketcherSettings.h" #include "TaskSketcherGeneral.h" +#include +#include #include #include #include +#include using namespace SketcherGui; @@ -82,6 +86,8 @@ SketcherSettings::SketcherSettings(QWidget* parent) ui->comboBox->addItem(QIcon(px), QString(), QVariant(it->second)); } + + connect(ui->btnTVApply, SIGNAL(clicked(bool)), this, SLOT(onBtnTVApplyClicked(bool))); } /** @@ -119,6 +125,10 @@ void SketcherSettings::saveSettings() ui->dialogOnDistanceConstraint->onSave(); ui->continueMode->onSave(); ui->checkBoxAdvancedSolverTaskBox->onSave(); + ui->checkBoxTVHideDependent->onSave(); + ui->checkBoxTVShowLinks->onSave(); + ui->checkBoxTVShowSupport->onSave(); + ui->checkBoxTVRestoreCamera->onSave(); form->saveSettings(); ParameterGrp::handle hViewGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); @@ -157,6 +167,10 @@ void SketcherSettings::loadSettings() ui->dialogOnDistanceConstraint->onRestore(); ui->continueMode->onRestore(); ui->checkBoxAdvancedSolverTaskBox->onRestore(); + ui->checkBoxTVHideDependent->onRestore(); + ui->checkBoxTVShowLinks->onRestore(); + ui->checkBoxTVShowSupport->onRestore(); + ui->checkBoxTVRestoreCamera->onRestore(); form->loadSettings(); std::list sizes = Gui::Inventor::MarkerBitmaps::getSupportedSizes("CIRCLE_FILLED"); @@ -189,5 +203,32 @@ void SketcherSettings::changeEvent(QEvent *e) } } +void SketcherSettings::onBtnTVApplyClicked(bool) +{ + QString errMsg; + try{ + Gui::Command::doCommand(Gui::Command::Gui, + "for name,doc in App.listDocuments().items():\n" + " for sketch in doc.findObjects('Sketcher::SketchObject'):\n" + " sketch.ViewObject.HideDependent = %s\n" + " sketch.ViewObject.ShowLinks = %s\n" + " sketch.ViewObject.ShowSupport = %s\n" + " sketch.ViewObject.RestoreCamera = %s\n", + this->ui->checkBoxTVHideDependent->isChecked() ? "True": "False", + this->ui->checkBoxTVShowLinks->isChecked() ? "True": "False", + this->ui->checkBoxTVShowSupport->isChecked() ? "True": "False", + this->ui->checkBoxTVRestoreCamera->isChecked() ? "True": "False"); + } catch (Base::PyException &e){ + Base::Console().Error("SketcherSettings::onBtnTVApplyClicked:\n"); + e.ReportException(); + errMsg = QString::fromLatin1(e.what()); + } catch (...) { + errMsg = tr("Unexpected C++ exception"); + } + if(errMsg.length()>0){ + QMessageBox::warning(this, tr("Sketcher"),errMsg); + } +} + #include "moc_SketcherSettings.cpp" diff --git a/src/Mod/Sketcher/Gui/SketcherSettings.h b/src/Mod/Sketcher/Gui/SketcherSettings.h index 5f4d85bca..07c2d3b7c 100644 --- a/src/Mod/Sketcher/Gui/SketcherSettings.h +++ b/src/Mod/Sketcher/Gui/SketcherSettings.h @@ -47,6 +47,9 @@ public: protected: void changeEvent(QEvent *e); +private Q_SLOTS: + void onBtnTVApplyClicked(bool); + private: Ui_SketcherSettings* ui; SketcherGeneralWidget* form; diff --git a/src/Mod/Sketcher/Gui/SketcherSettings.ui b/src/Mod/Sketcher/Gui/SketcherSettings.ui index eb5c1285b..0b60d4197 100644 --- a/src/Mod/Sketcher/Gui/SketcherSettings.ui +++ b/src/Mod/Sketcher/Gui/SketcherSettings.ui @@ -6,14 +6,49 @@ 0 0 - 404 - 744 + 427 + 1253 Sketcher + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Sketch Solver + + + + + + Show Advanced Solver Control in the Task bar + + + ShowSolverAdvancedWidget + + + Mod/Sketcher + + + + + + @@ -40,7 +75,7 @@ The color of edges being edited - + 255 255 @@ -73,7 +108,7 @@ The color of vertices being edited - + 255 255 @@ -106,7 +141,7 @@ The color of edges being edited - + 255 255 @@ -139,7 +174,7 @@ The color of vertices being edited - + 255 38 @@ -172,7 +207,7 @@ The color of fully constrained geometry in edit mode - + 255 38 @@ -192,7 +227,7 @@ The color of construction geometry in edit mode - + 0 0 @@ -225,7 +260,7 @@ The color of external geometry in edit mode - + 204 51 @@ -271,7 +306,7 @@ The color of fully constrained geometry in edit mode - + 0 255 @@ -397,7 +432,7 @@ - + 0 0 @@ -446,7 +481,7 @@ The color of driving constraints in edit mode - + 255 38 @@ -466,7 +501,7 @@ The color of non-driving constrains or dimensions in edit mode - + 0 38 @@ -492,19 +527,6 @@ Sketch editing - - - - - 182 - 0 - - - - Font size - - - @@ -540,13 +562,16 @@ - - - - - + + + + + 182 + 0 + + - Grid line pattern + Font size @@ -573,6 +598,16 @@ + + + + + + + Grid line pattern + + + @@ -589,44 +624,156 @@ - - - - - - - Sketch Solver - - - - - - Show Advanced Solver Control in the Task bar + + + + true - - ShowSolverAdvancedWidget + + + 0 + 0 + - - Mod/Sketcher + + + 0 + 0 + + + + 16777215 + 16777215 + + + + + 0 + 0 + + + + Visibility automation + + + + + + When opening sketch, hide all features that depend on it. + + + Hide all objects that depend on the sketch + + + true + + + HideDependent + + + Mod/Sketcher/General + + + + + + + When opening sketch, show sources for external geometry links. + + + Show objects used for external geometry + + + true + + + ShowLinks + + + Mod/Sketcher/General + + + + + + + When opening sketch, show objects the sketch is attached to. + + + Show object(s) sketch is attached to + + + true + + + ShowSupport + + + Mod/Sketcher/General + + + + + + + When closing sketch, move camera back to where it was before sketch was opened. + + + Restore camera position after editing + + + true + + + RestoreCamera + + + Mod/Sketcher/General + + + + + + + + 0 + 0 + + + + Note: these settings are defaults applied to new sketches. The behavior is remembered for each sketch individually as properties on View tab. + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + true + + + + + + + + 0 + 0 + + + + Apply current smart visibility to all sketches in open documents (update properties to match). + + + Apply to existing sketches + + + + - - - - Qt::Vertical - - - - 20 - 217 - - - - @@ -652,11 +799,31 @@ - CursorTextColor + SketchEdgeColor + SketchVertexColor EditedEdgeColor EditedVertexColor ConstructionColor + ExternalColor FullyConstrainedColor + ConstrainedColor + NonDrivingConstraintColor + DatumColor + SketcherDatumWidth + DefaultSketcherVertexWidth + DefaultSketcherLineWidth + CursorTextColor + EditSketcherFontSize + EditSketcherMarkerSize + comboBox + dialogOnDistanceConstraint + continueMode + checkBoxTVHideDependent + checkBoxTVShowLinks + checkBoxTVShowSupport + checkBoxTVRestoreCamera + btnTVApply + checkBoxAdvancedSolverTaskBox diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index e1941ff46..19c301e6d 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -82,6 +82,7 @@ #include #include #include +#include #include #include #include @@ -190,7 +191,6 @@ struct EditData { std::set PreselectConstraintSet; bool blockedPreselection; bool FullyConstrained; - bool visibleBeforeEdit; // container to track our own selected parts std::set SelPointSet; @@ -255,8 +255,20 @@ ViewProviderSketch::ViewProviderSketch() : edit(0), Mode(STATUS_NONE) { - // FIXME Should this be placed in here? ADD_PROPERTY_TYPE(Autoconstraints,(true),"Auto Constraints",(App::PropertyType)(App::Prop_None),"Create auto constraints"); + ADD_PROPERTY_TYPE(TempoVis,(Py::None()),"Visibility automation",(App::PropertyType)(App::Prop_None),"Object that handles hiding and showing other objects when entering/leaving sketch."); + ADD_PROPERTY_TYPE(HideDependent,(true),"Visibility automation",(App::PropertyType)(App::Prop_None),"If true, all objects that depend on the sketch are hidden when opening editing."); + ADD_PROPERTY_TYPE(ShowLinks,(true),"Visibility automation",(App::PropertyType)(App::Prop_None),"If true, all objects used in links to external geometry are shown when opening sketch."); + ADD_PROPERTY_TYPE(ShowSupport,(true),"Visibility automation",(App::PropertyType)(App::Prop_None),"If true, all objects this sketch is attached to are shown when opening sketch."); + ADD_PROPERTY_TYPE(RestoreCamera,(true),"Visibility automation",(App::PropertyType)(App::Prop_None),"If true, camera position before entering sketch is remembered, and restored after closing it."); + + {//visibility automation: update defaults to follow preferences + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General"); + this->HideDependent.setValue(hGrp->GetBool("HideDependent", true)); + this->ShowLinks.setValue(hGrp->GetBool("ShowLinks", true)); + this->ShowSupport.setValue(hGrp->GetBool("ShowSupport", true)); + this->RestoreCamera.setValue(hGrp->GetBool("RestoreCamera", true)); + } sPixmap = "Sketcher_Sketch"; LineColor.setValue(1,1,1); @@ -4219,8 +4231,35 @@ bool ViewProviderSketch::setEdit(int ModNum) edit->MarkerSize = hGrp->GetInt("EditSketcherMarkerSize", 7); createEditInventorNodes(); - edit->visibleBeforeEdit = this->isVisible(); - this->hide(); // avoid that the wires interfere with the edit lines + + //visibility automation + try{ + Gui::Command::addModule(Gui::Command::Gui,"Show.TempoVis"); + try{ + QString cmdstr = QString::fromLatin1( + "ActiveSketch = App.ActiveDocument.getObject('{sketch_name}')\n" + "tv = Show.TempoVis(App.ActiveDocument)\n" + "if ActiveSketch.ViewObject.HideDependent:\n" + " tv.hide_all_dependent(ActiveSketch)\n" + "if ActiveSketch.ViewObject.ShowSupport:\n" + " tv.show([ref[0] for ref in ActiveSketch.Support])\n" + "if ActiveSketch.ViewObject.ShowLinks:\n" + " tv.show([ref[0] for ref in ActiveSketch.ExternalGeometry])\n" + "tv.hide(ActiveSketch)\n" + "ActiveSketch.ViewObject.TempoVis = tv\n" + "del(tv)\n" + ); + cmdstr.replace(QString::fromLatin1("{sketch_name}"),QString::fromLatin1(this->getSketchObject()->getNameInDocument())); + QByteArray cmdstr_bytearray = cmdstr.toLatin1(); + Gui::Command::doCommand(Gui::Command::Gui, cmdstr_bytearray.data()); + } catch (Base::PyException &e){ + Base::Console().Error("ViewProviderSketch::setEdit: visibility automation failed with an error: \n"); + e.ReportException(); + } + } catch (Base::PyException &){ + Base::Console().Warning("ViewProviderSketch::setEdit: could not import Show module. Visibility automation will not work.\n"); + } + ShowGrid.setValue(true); TightGrid.setValue(false); @@ -4565,10 +4604,23 @@ void ViewProviderSketch::unsetEdit(int ModNum) edit->EditRoot->removeAllChildren(); pcRoot->removeChild(edit->EditRoot); - if (edit->visibleBeforeEdit) - this->show(); - else - this->hide(); + //visibility autoation + try{ + QString cmdstr = QString::fromLatin1( + "ActiveSketch = App.ActiveDocument.getObject('{sketch_name}')\n" + "tv = ActiveSketch.ViewObject.TempoVis\n" + "if tv:\n" + " tv.restore()\n" + "ActiveSketch.ViewObject.TempoVis = None\n" + "del(tv)\n" + ); + cmdstr.replace(QString::fromLatin1("{sketch_name}"),QString::fromLatin1(this->getSketchObject()->getNameInDocument())); + QByteArray cmdstr_bytearray = cmdstr.toLatin1(); + Gui::Command::doCommand(Gui::Command::Gui, cmdstr_bytearray.data()); + } catch (Base::PyException &e){ + Base::Console().Error("ViewProviderSketch::unsetEdit: visibility automation failed with an error: \n"); + e.ReportException(); + } delete edit; edit = 0; @@ -4601,6 +4653,23 @@ void ViewProviderSketch::unsetEdit(int ModNum) void ViewProviderSketch::setEditViewer(Gui::View3DInventorViewer* viewer, int ModNum) { + //visibility automation: save camera + if (! this->TempoVis.getValue().isNone()){ + try{ + QString cmdstr = QString::fromLatin1( + "ActiveSketch = App.ActiveDocument.getObject('{sketch_name}')\n" + "if ActiveSketch.ViewObject.RestoreCamera:\n" + " ActiveSketch.ViewObject.TempoVis.saveCamera()\n" + ); + cmdstr.replace(QString::fromLatin1("{sketch_name}"),QString::fromLatin1(this->getSketchObject()->getNameInDocument())); + QByteArray cmdstr_bytearray = cmdstr.toLatin1(); + Gui::Command::doCommand(Gui::Command::Gui, cmdstr_bytearray.data()); + } catch (Base::PyException &e){ + Base::Console().Error("ViewProviderSketch::setEdit: visibility automation failed with an error: \n"); + e.ReportException(); + } + } + Base::Placement plm = getPlacement(); Base::Rotation tmp(plm.getRotation()); diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.h b/src/Mod/Sketcher/Gui/ViewProviderSketch.h index 1901404a0..01d8c3896 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.h +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.h @@ -99,6 +99,11 @@ public: virtual ~ViewProviderSketch(); App::PropertyBool Autoconstraints; + App::PropertyPythonObject TempoVis; + App::PropertyBool HideDependent; + App::PropertyBool ShowLinks; + App::PropertyBool ShowSupport; + App::PropertyBool RestoreCamera; /// Draw all constraint icons /*! Except maybe the radius and lock ones? */