Function when a workbench opens a new file.

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
keithsloan52
Posts: 1015
Joined: Mon Feb 27, 2012 5:31 pm

Function when a workbench opens a new file.

Postby keithsloan52 » Thu May 30, 2019 3:55 am

I wish to create some FreeCAD objects when a new file is created. I only want to do this when a particular workbench is active.

Where in the implementation of a particular workbench could I add code to perform something when a new file is opened.
wmayer
Site Admin
Posts: 14869
Joined: Thu Feb 19, 2009 10:32 am

Re: Function when a workbench opens a new file.

Postby wmayer » Thu May 30, 2019 7:39 am

Use the C++ class DocumentObserver and override its slotCreatedDocument. But note that the Document is passed as a const reference. So you can try to use const_cast to directly add a new object there which should be safe to do. The only thing you have to take care of is that the Label of the document is not yet defined at that time.

Here is a minimum example in Python only for demonstrating purposes:

Code: Select all

class DocObserver(object):
    def slotCreatedDocument(self, doc):
        doc.addObject("Part::Feature", "Shape")

doc=DocObserver()
App.addDocumentObserver(doc)
wmayer
Site Admin
Posts: 14869
Joined: Thu Feb 19, 2009 10:32 am

Re: Function when a workbench opens a new file.

Postby wmayer » Thu May 30, 2019 7:43 am

About the current workbench you can use the class WorkbenchManager which has the method active() that returns a pointer of a Workbench.

In Python you can do:

Code: Select all

wb=Gui.activeWorkbench()
wb.GetClassName()
keithsloan52
Posts: 1015
Joined: Mon Feb 27, 2012 5:31 pm

Re: Function when a workbench opens a new file.

Postby keithsloan52 » Thu May 30, 2019 12:28 pm

wmayer wrote:
Thu May 30, 2019 7:39 am
Use the C++ class DocumentObserver and override its slotCreatedDocument. But note that the Document is passed as a const reference. So you can try to use const_cast to directly add a new object there which should be safe to do. The only thing you have to take care of is that the Label of the document is not yet defined at that time.

Here is a minimum example in Python only for demonstrating purposes:

Code: Select all

class DocObserver(object):
    def slotCreatedDocument(self, doc):
        doc.addObject("Part::Feature", "Shape")

doc=DocObserver()
App.addDocumentObserver(doc)
So I do that in the workbenches InitGui.py ?
wmayer
Site Admin
Posts: 14869
Joined: Thu Feb 19, 2009 10:32 am

Re: Function when a workbench opens a new file.

Postby wmayer » Thu May 30, 2019 1:03 pm

For example.
keithsloan52
Posts: 1015
Joined: Mon Feb 27, 2012 5:31 pm

Re: Function when a workbench opens a new file.

Postby keithsloan52 » Thu May 30, 2019 3:30 pm

wmayer wrote:
Thu May 30, 2019 1:03 pm
For example.
Well I would like a workbench lets just call it bench. When it is active and somebody opens a new file I would like to initiate the new file with a couple of new objects for now lets just say a single Sphere.
wmayer
Site Admin
Posts: 14869
Joined: Thu Feb 19, 2009 10:32 am

Re: Function when a workbench opens a new file.

Postby wmayer » Thu May 30, 2019 3:52 pm

With the two Python snippets above you should be able to do it. I guess the active workbench you are talking about is the one of your InitGui.py file. So, the easiest would be to add the observer in the workbench's Activated method and remove it in its Deactivated method.
keithsloan52
Posts: 1015
Joined: Mon Feb 27, 2012 5:31 pm

Re: Function when a workbench opens a new file.

Postby keithsloan52 » Fri May 31, 2019 6:01 am

Thanks Werner

What is the function to remove the Observer? App.removeDocumentObserver(doc) ?

I tried search for doc on App.addDocumentObserver() hoping to find how to remove but not much luck with my searches.

Thanks Keith
wmayer
Site Admin
Posts: 14869
Joined: Thu Feb 19, 2009 10:32 am

Re: Function when a workbench opens a new file.

Postby wmayer » Fri May 31, 2019 8:13 am

Yes, App.removeDocumentObserver() is your friend. Actually you should be able to see this method when using FreeCAD's Python console as it automatically lists all methods of an object when pressing "."
keithsloan52
Posts: 1015
Joined: Mon Feb 27, 2012 5:31 pm

Re: Function when a workbench opens a new file.

Postby keithsloan52 » Fri May 31, 2019 9:47 am

Okay I am missing something as I get the follow error message

Code: Select all

name 'DocObserver' is not defined
Traceback (most recent call last):
  File "<string>", line 65, in Activated
My code in InitGUI.py looks like

Code: Select all

import FreeCAD

class DocObserver(object):
    def slotCreatedDocument(self, doc):
        mySphere = doc.addObject("Part::Sphere", "Globe")
        mySphere.Radius = 100

class Astro_Workbench ( Workbench ):
    "Astro workbench object"
    def __init__(self):
        self.__class__.Icon = FreeCAD.getResourceDir() + "Mod/Astro/Resources/icons/AstroWorkbench.svg"
        self.__class__.MenuText = "Astro"
        self.__class__.ToolTip = "Astro workbench"

    def Initialize(self):
        def QT_TRANSLATE_NOOP(scope, text):
            return text

        import AstroCommands
        commands=['AddRegionCommand' ]
        toolbarcommands=['AddRegionCommand']

        self.appendToolbar(QT_TRANSLATE_NOOP('Workbench','AstroTools'),toolbarcommands)
        self.appendMenu('Astro',commands)
        #FreeCADGui.addIconPath(":/icons")
        FreeCADGui.addIconPath(FreeCAD.getResourceDir() + \
                              "Mod/Astro/Resources/icons")
        FreeCADGui.addLanguagePath(":/translations")
        #FreeCADGui.addPreferencePage(":/ui/openscadprefs-base.ui","OpenSCAD")

    def Activated(self):
        "This function is executed when the workbench is activated"
        doc=DocObserver()
        App.addDocumentObserver(doc)
        return

    def Deactivated(self):
        "This function is executed when the workbench is deactivated"
        App.removeDocumentObserver(doc)
        return
        
           def GetClassName(self):
        "This is executed whenever the user right-clicks on screen"
        return "Gui::PythonWorkbench"
        "This function is executed when the workbench is deactivated"
        return

    def ContextMenu(self, recipient):
        "This is executed whenever the user right-clicks on screen"
        # "recipient" will be either "view" or "tree"
        #self.appendContextMenu("My commands",self.list) # add commands to the context menu

Gui.addWorkbench(Astro_Workbench())
Will have to give the FreeCAD python console a try I am still on the old fashioned way of doing things