예제 #1
0
파일: fileMenu.py 프로젝트: dladd/pyFormex
def closeProject(save=None,clear=None):
    """Close the current project, saving it or not.

    Parameters:

    - `save`: None, True or False. Determines whether the project should be
      saved prior to closing it. If None, it will be asked from the user.
      Note that this parameter is only used for named Projects. Temporary
      Projects are never saved implicitely.
    - `clear`: None, True or False.
    """
    if pf.PF.filename is not None:
        if save is None:
            save = draw.ack("Save the current project before closing it?")
        pf.message("Closing project %s (save=%s)" % (pf.PF.filename,save))
        if save:
            saveProject()
            if pf.PF:
                listProject()
                if clear is None:
                    clear = draw.ask("What shall I do with the existing globals?",["Delete","Keep"]) == "Delete"

    if clear:
        pf.PF.clear()

    pf.PF.filename = None
    pf.GUI.setcurproj('None')
    updateSettings({
        'curproj':pf.PF.filename,
        },save=True)
예제 #2
0
def updateSettings(res,save=None):
    """Update the current settings (store) with the values in res.

    res is a dictionary with configuration values.
    The current settings will be update with the values in res.

    If res contains a key 'Save changes' and its value is True, the
    preferences will also be saved to the user's preference file.
    Else, the user will be asked whether he wants to save the changes.
    """
    pf.debug("Accepted settings:",res)
    if save is None:
        save = res.get('Save changes',None)
    if save is None:
        save = draw.ack("Save the current changes to your configuration file?")

    # Do not use 'pf.cfg.update(res)' here!
    # It will not work with our Config class!

    for k in res:
        if k.startswith('_'): # skip temporary variables
            continue
        
        if pf.cfg[k] != res[k]:
            pf.cfg[k] = res[k]
            
            if save and pf.prefcfg[k] != pf.cfg[k]:
                pf.prefcfg[k] = pf.cfg[k]

            if pf.GUI:
                if k in _activate_settings:
                    _activate_settings[k]()

    pf.debug("New settings:",pf.cfg)
    pf.debug("New preferences:",pf.prefcfg)
예제 #3
0
def askConfigPreferences(items, prefix=None, store=None):
    """Ask preferences stored in config variables.

    Items in list should only be keys. store is usually a dictionary, but
    can be any class that allow the setdefault method for lookup while
    setting the default, and the store[key]=val syntax for setting the
    value.
    If a prefix is given, actual keys will be 'prefix/key'. 
    The current values are retrieved from the store, and the type returned
    will be in accordance.
    If no store is specified, the global config GD.cfg is used.
    """
    if not store:
        store = GD.cfg
    if prefix:
        items = ["%s/%s" % (prefix, i) for i in items]
    itemlist = [[i, store.setdefault(i, "")] for i in items]
    res, accept = widgets.InputDialog(itemlist, "Config Dialog", GD.gui).getResult()
    if accept:
        GD.debug(res)
        if draw.ack("Update the settings?"):
            # This does not work for our Config class!
            # store.update(res)
            # Therefore, set individually
            for k, v in res.items():
                store[k] = v
        ##        for i,r in zip(itemlist,res):
        ##            GD.debug("IN : %s\nOUT: %s" % (i,r))
        ##            if type(i[1]) == str:
        ##                store[r[0]] = r[1]
        ##            else:
        ##                store[r[0]] = eval(r[1])
        GD.debug(GD.cfg)
    return accept
예제 #4
0
def openScript(fn=None,exist=True,create=False):
    """Open a pyFormex script and set it as the current script.

    If no filename is specified, a file selection dialog is started to select
    an existing script, or allow to create a new file if exist is False.

    If the file exists and is a pyFormex script, it is set ready to execute.

    If create is True, a default pyFormex script template will be written
    to the file, overwriting the contents if the file existed. Then, the
    script is loaded into the editor.

    We encourage the use of createScript() to create new scripts and leave
    openScript() to open existing scripts.
    """
    if fn is None:
        cur = GD.cfg.get('curfile',GD.cfg.get('workdir','.'))
        typ = "pyFormex scripts (*.py)"
        fn = widgets.FileSelection(cur,typ,exist=exist).getFilename()
    if fn:
        if create:
            if not exist and os.path.exists(fn) and not draw.ack("The file %s already exists.\n Are you sure you want to overwrite it?" % fn):
                return None
            template = GD.cfg['scripttemplate']
            if (os.path.exists(template)):
                shutil.copyfile(template,fn)
        GD.cfg['workdir'] = os.path.dirname(fn)
        GD.GUI.setcurfile(fn)
        GD.GUI.history.add(fn)
        if create:
            editScript(fn)
    return fn
예제 #5
0
파일: fileMenu.py 프로젝트: dladd/pyFormex
def recordSession(stop=0):
    """Record the current pyFormex session."""
    global _recording_pid
    from guimain import hasDRI

    print("RECORDING with dri=%s" % pf.options.dri)

    ok = utils.checkExternal('recordmydesktop')
    if not ok:
        return
    if hasDRI():
        if not draw.ack("Recording the session while using DRI may fail to correctly capture the OpenGL canvas. We recommend starting pyformex with the --nodri option to do session recording (at the expense of a slower execution). If you click YES I will nevertheless go ahead with recording."):
            return

    fn = draw.askFilename(pf.cfg['workdir'],"Theora video files (*.ogv)",exist=False)
    if not fn:
        return

    print("Recording your session to file %s" % fn)
    x,y,w,h = pf.GUI.XGeometry()
    cmd = "recordmydesktop -x %s -y %s --width %s --height %s --no-frame -o %s" % (x,y,w,h,fn)
    print(cmd)
    pid = utils.spawn(cmd)
    print("Recording pid = %s" % pid)
    _recording_pid = pid
예제 #6
0
def recordSession(stop=0):
    """Record the current pyFormex session."""
    global _recording_pid
    from guimain import hasDRI

    print("RECORDING with dri=%s" % pf.options.dri)

    ok = utils.checkExternal('recordmydesktop')
    if not ok:
        return
    if hasDRI():
        if not draw.ack(
                "Recording the session while using DRI may fail to correctly capture the OpenGL canvas. We recommend starting pyformex with the --nodri option to do session recording (at the expense of a slower execution). If you click YES I will nevertheless go ahead with recording."
        ):
            return

    fn = draw.askFilename(pf.cfg['workdir'],
                          "Theora video files (*.ogv)",
                          exist=False)
    if not fn:
        return

    print("Recording your session to file %s" % fn)
    x, y, w, h = pf.GUI.XGeometry()
    cmd = "recordmydesktop -x %s -y %s --width %s --height %s --no-frame -o %s" % (
        x, y, w, h, fn)
    print(cmd)
    pid = utils.spawn(cmd)
    print("Recording pid = %s" % pid)
    _recording_pid = pid
예제 #7
0
def closeProject(save=None, clear=None):
    """Close the current project, saving it or not.

    Parameters:

    - `save`: None, True or False. Determines whether the project should be
      saved prior to closing it. If None, it will be asked from the user.
      Note that this parameter is only used for named Projects. Temporary
      Projects are never saved implicitely.
    - `clear`: None, True or False.
    """
    if pf.PF.filename is not None:
        if save is None:
            save = draw.ack("Save the current project before closing it?")
        pf.message("Closing project %s (save=%s)" % (pf.PF.filename, save))
        if save:
            saveProject()
            if pf.PF:
                listProject()
                if clear is None:
                    clear = draw.ask(
                        "What shall I do with the existing globals?",
                        ["Delete", "Keep"]) == "Delete"

    if clear:
        pf.PF.clear()

    pf.PF.filename = None
    pf.GUI.setcurproj('None')
    updateSettings({
        'curproj': pf.PF.filename,
    }, save=True)
예제 #8
0
파일: prefMenu.py 프로젝트: dladd/pyFormex
def updateSettings(res,save=None):
    """Update the current settings (store) with the values in res.

    res is a dictionary with configuration values.
    The current settings will be updated with the values in res.

    If res contains a key '_save_', or a `save` argument is supplied,
    and its value is True, the preferences will also be saved to the
    user's preference file.
    Else, the user will be asked whether he wants to save the changes.
    """
    pf.debug("\nACCEPTED SETTINGS\n%s"% res,pf.DEBUG.CONFIG)
    if save is None:
        save = res.get('_save_',None)
    if save is None:
        save = draw.ack("Save the current changes to your configuration file?")

    # Do not use 'pf.cfg.update(res)' here!
    # It will not work with our Config class!

    # a set to uniquely register updatefunctions
    todo = set([])
    for k in res:
        if k.startswith('_'): # skip temporary variables
            continue

        changed = False
        # first try to set in prefs, as these will cascade to cfg
        if save and pf.prefcfg[k] != res[k]:
            pf.prefcfg[k] = res[k]
            changed = True

        # if not saved, set in cfg
        print("Setting %s = %s" % (k,res[k]))
        if pf.cfg[k] != res[k]:
            pf.cfg[k] = res[k]
            changed = True

        if changed and pf.GUI:
            # register the corresponding update function
            if k in _activate_settings:
                todo.add(_activate_settings[k])

    # We test for pf.GUI in case we want to call updateSettings before
    # the GUI is created
    if pf.GUI:
        for f in todo:
            f()

    pf.debug("\nNEW SETTINGS\n%s"%pf.cfg,pf.DEBUG.CONFIG)
    pf.debug("\nNEW PREFERENCES\n%s"%pf.prefcfg,pf.DEBUG.CONFIG)
예제 #9
0
def updateSettings(res, save=None):
    """Update the current settings (store) with the values in res.

    res is a dictionary with configuration values.
    The current settings will be updated with the values in res.

    If res contains a key '_save_', or a `save` argument is supplied,
    and its value is True, the preferences will also be saved to the
    user's preference file.
    Else, the user will be asked whether he wants to save the changes.
    """
    pf.debug("\nACCEPTED SETTINGS\n%s" % res, pf.DEBUG.CONFIG)
    if save is None:
        save = res.get('_save_', None)
    if save is None:
        save = draw.ack("Save the current changes to your configuration file?")

    # Do not use 'pf.cfg.update(res)' here!
    # It will not work with our Config class!

    # a set to uniquely register updatefunctions
    todo = set([])
    for k in res:
        if k.startswith('_'):  # skip temporary variables
            continue

        changed = False
        # first try to set in prefs, as these will cascade to cfg
        if save and pf.prefcfg[k] != res[k]:
            pf.prefcfg[k] = res[k]
            changed = True

        # if not saved, set in cfg
        print("Setting %s = %s" % (k, res[k]))
        if pf.cfg[k] != res[k]:
            pf.cfg[k] = res[k]
            changed = True

        if changed and pf.GUI:
            # register the corresponding update function
            if k in _activate_settings:
                todo.add(_activate_settings[k])

    # We test for pf.GUI in case we want to call updateSettings before
    # the GUI is created
    if pf.GUI:
        for f in todo:
            f()

    pf.debug("\nNEW SETTINGS\n%s" % pf.cfg, pf.DEBUG.CONFIG)
    pf.debug("\nNEW PREFERENCES\n%s" % pf.prefcfg, pf.DEBUG.CONFIG)
예제 #10
0
def updateSettings(res,store):
    """Update the current settings (store) with the values in res.

    store and res are both dictionaries
    This asks the users to confirm that he wants to update the settings.
    """
    GD.debug(res)
    if res.get('Save changes',None) or draw.ack("Save the changes to your configuration file?\n\nCurrently, the changes will be rejected if you do not save them!\n"):
        # Do not use 'store.update(res)' here!
        # It will not work with our Config class!
        for k,v in res.items():
            store[k] = v
        GD.debug(store)
        return True
    return False
예제 #11
0
def updateSettings(res,store):
    """Update the current settings (store) with the values in res.

    store and res are both dictionaries
    This asks the users to confirm that he wants to update the settings.
    """
    GD.debug(res)
    if draw.ack("Update the settings?"):
        # The following does not work for our Config class!
        # store.update(res)
        # Therefore, set individually
        for k,v in res.items():
            store[k] = v
        GD.debug(store)
        return True
    return False
예제 #12
0
파일: fileMenu.py 프로젝트: dladd/pyFormex
def exportWebGL():
    """Export the current scene to WebGL"""
    from plugins.webgl import WebGL
    types = [ utils.fileDescription('html') ]
    fn = draw.askNewFilename(pf.cfg['workdir'],types)
    if fn:
        pf.message("Exporting current scene to %s" % fn)
        pf.GUI.setBusy()
        fn = os.path.basename(fn)
        name = utils.projectName(fn)
        W = WebGL(name)
        W.addScene()
        fn = W.export(title="%s WebGL model"%name,createdby=50)
        pf.GUI.setBusy(False)
        if draw.ack("Show the scene in your browser?"):
            fn = os.path.join(os.getcwd(),fn)
            print(fn)
            from gui.helpMenu import help
            help('file:%s' % fn)
예제 #13
0
def exportWebGL():
    """Export the current scene to WebGL"""
    from plugins.webgl import WebGL
    types = [utils.fileDescription('html')]
    fn = draw.askNewFilename(pf.cfg['workdir'], types)
    if fn:
        pf.message("Exporting current scene to %s" % fn)
        pf.GUI.setBusy()
        fn = os.path.basename(fn)
        name = utils.projectName(fn)
        W = WebGL(name)
        W.addScene()
        fn = W.export(title="%s WebGL model" % name, createdby=50)
        pf.GUI.setBusy(False)
        if draw.ack("Show the scene in your browser?"):
            fn = os.path.join(os.getcwd(), fn)
            print(fn)
            from gui.helpMenu import help
            help('file:%s' % fn)
예제 #14
0
def openScript(fn=None, exist=True, create=False):
    """Open a pyFormex script and set it as the current script.

    If no filename is specified, a file selection dialog is started to select
    an existing script, or allow to create a new file if exist is False.

    If the file exists and is a pyFormex script, it is set ready to execute.

    If create is True, a default pyFormex script template will be written
    to the file, overwriting the contents if the file existed. Then, the
    script is loaded into the editor.

    We encourage the use of createScript() to create new scripts and leave
    openScript() to open existing scripts.
    """
    if fn is None:
        cur = pf.cfg['curfile']
        if cur is None:
            cur = pf.cfg['workdir']
        if cur is None:
            cur = '.'
        typ = utils.fileDescription('pyformex')
        fn = widgets.FileSelection(cur, typ, exist=exist).getFilename()
    if fn:
        if create:
            if not exist and os.path.exists(fn) and not draw.ack(
                    "The file %s already exists.\n Are you sure you want to overwrite it?"
                    % fn):
                return None
            template = pf.cfg['scripttemplate']
            if (os.path.exists(template)):
                shutil.copyfile(template, fn)
        updateSettings({'workdir': os.path.dirname(fn)}, save=True)
        pf.GUI.setcurfile(fn)
        pf.GUI.scripthistory.add(fn)
        if create:
            draw.editFile(fn)
    return fn
예제 #15
0
def createProject(create=True,compression=0,addGlobals=None):
    """Open a file selection dialog and let the user select a project.

    The default will let the user create new project files as well as open
    existing ones.
    Use create=False or the convenience function openProject to only accept
    existing project files.

    If a compression level (1..9) is given, the contents will be compressed,
    resulting in much smaller project files at the cost of  

    Only one pyFormex project can be open at any time. The open project
    owns all the global data created and exported by any script.
    If addGlobals is None, the user is asked whether the current globals
    should be added to the project. Set True or False to force or reject
    the adding without asking.
    """
    global the_project

    # ask filename from user
    if the_project is None:
        cur = GD.cfg.get('workdir','.')
    else:
        options = ['Cancel','Close without saving','Save and Close']
        ans = draw.ask("Another project is still open. Shall I close it first?",
                    options)
        if ans == 'Cancel':
            return
        if ans == options[2]:
            the_project.save()
        cur = the_project.filename
    typ = [ 'pyFormex projects (*.pyf)', 'All files (*)' ]
    res = widgets.ProjectSelection(cur,typ,exist=not create).getResult()
    if res is None:
        # user canceled
        return

    fn = res.fn
    if not fn.endswith('.pyf'):
        fn += '.pyf'
    legacy = res.leg
    compression = res.cpr
    print fn,legacy,compression

    if create and os.path.exists(fn):
        res = draw.ask("The project file '%s' already exists\nShall I delete the contents or add to it?" % fn,['Delete','Add','Cancel'])
        if res == 'Cancel':
            return
        if res == 'Add':
            create = False
    GD.message("Opening project %s" % fn)
    
    if GD.PF:
        GD.message("Exported symbols: %s" % GD.PF.keys())
        if addGlobals is None:
            res = draw.ask("pyFormex already contains exported symbols.\nShall I delete them or add them to your project?",['Delete','Add','Cancel'])
            if res == 'Cancel':
                # ESCAPE FROM CREATING THE PROJECT
                return

            addGlobals = res == 'Add'

    # OK, we have all data, now create/open the project
        
    GD.cfg['workdir'] = os.path.dirname(fn)
    GD.GUI.setBusy()
    try:
        sig = GD.Version[:GD.Version.rfind('-')]
        the_project = project.Project(fn,create=create,signature=sig,compression=compression,legacy=legacy)
        if GD.PF and addGlobals:
            the_project.update(GD.PF)
        GD.PF = the_project
        GD.GUI.setcurproj(fn)
        GD.message("Project contents: %s" % the_project.keys())
        if hasattr(the_project,'autofile') and draw.ack("The project has an autofile attribute: %s\nShall I execute this script?" % the_project.autofile):
            processArgs([the_project.autofile])
    finally:
        GD.GUI.setBusy(False)
예제 #16
0
def createProject(create=True,compression=0,addGlobals=None,makeDefault=True):
    """Open a file selection dialog and let the user select a project.

    The default will let the user create new project files as well as open
    existing ones.
    Use create=False or the convenience function openProject to only accept
    existing project files.

    If a compression level (1..9) is given, the contents will be compressed,
    resulting in much smaller project files at the cost of  

    Only one pyFormex project can be open at any time. The open project
    owns all the global data created and exported by any script.

    If makeDefault is True, an already open project will be closed and
    the opened project becomes the current project.
    If makeDefault is False, the project data are imported into GD.PF
    and the current project does not change. This means that if a project was
    open, the imported data will be added to it.
    
    If addGlobals is None, the user is asked whether the current globals
    should be added to the project. Set True or False to force or reject
    the adding without asking.
    """
    global the_project

    # ask filename from user
    if the_project is None:
        cur = GD.cfg.get('workdir','.')
    else:
        if makeDefault:
            options = ['Cancel','Close without saving','Save and Close']
            ans = draw.ask("Another project is still open. Shall I close it first?",
                        options)
            if ans == 'Cancel':
                return
            if ans == options[2]:
                the_project.save()
        cur = the_project.filename
    typ = utils.fileDescription(['pyf','all'])
    res = widgets.ProjectSelection(cur,typ,exist=not create).getResult()
    if res is None:
        # user canceled
        return

    fn = res.fn
    if not fn.endswith('.pyf'):
        fn += '.pyf'
    legacy = res.leg
    ignoresig = res.sig
    compression = res.cpr
    #print(fn,legacy,compression)

    if create and os.path.exists(fn):
        res = draw.ask("The project file '%s' already exists\nShall I delete the contents or add to it?" % fn,['Delete','Add','Cancel'])
        if res == 'Cancel':
            return
        if res == 'Add':
            create = False
    GD.message("Opening project %s" % fn)
    
    if GD.PF:
        GD.message("Exported symbols: %s" % GD.PF.keys())
        if addGlobals is None:
            res = draw.ask("pyFormex already contains exported symbols.\nShall I delete them or add them to your project?",['Delete','Add','Cancel'])
            if res == 'Cancel':
                # ESCAPE FROM CREATING THE PROJECT
                return

            addGlobals = res == 'Add'

    # OK, we have all data, now create/open the project
        
    updateSettings({'workdir':os.path.dirname(fn)},save=True)
    sig = GD.Version[:GD.Version.rfind('-')]
    if ignoresig:
        sig = ''

    proj = _open_project(fn,create,sig,compression,legacy)
        
    GD.message("Project contents: %s" % proj.keys())
    
    if hasattr(proj,'_autoscript_'):
        _ignore = "Ignore it!"
        _show = "Show it"
        _edit = "Load it in the editor"
        _exec = "Execute it"
        res = draw.ask("There is an autoscript stored inside the project.\nIf you received this project file from an untrusted source, you should probably not execute it.",[_ignore,_show,_edit,_exec])
        if res == _show:
            res = draw.showText(proj._autoscript_)#,actions=[_ignore,_edit,_show])
            return
        if res == _exec:
            draw.playScript(proj._autoscript_)
        elif res == _edit:
            fn = "_autoscript_.py"
            draw.checkWorkdir()
            f = file(fn,'w')
            f.write(proj._autoscript_)
            f.close()
            openScript(fn)
            editScript(fn)

    if hasattr(proj,'autofile') and draw.ack("The project has an autofile attribute: %s\nShall I execute this script?" % proj.autofile):
        processArgs([proj.autofile])

    if makeDefault:
        the_project = proj
        if GD.PF and addGlobals:
            the_project.update(GD.PF)
        GD.PF = the_project
        GD.GUI.setcurproj(fn)

    else:
        # Just import the data into current project
        GD.PF.update(proj)

    GD.message("Exported symbols: %s" % GD.PF.keys())
예제 #17
0
파일: fileMenu.py 프로젝트: dladd/pyFormex
def setProject(proj):
    """Make the specified project the current project.

    proj is an open project.
    If a filename, the project file is opened.

    .. note: The remainder is obsolete

    The user is asked for a Project file name and the access modalities.
    Depending on the results of the dialog:

    - either an new project is create or an old is opened,
    - the old data may be discarded, added to the current pyFormex globals,
      or replace them
    - the opened Project may become the current Project, or its data are
      just imported in the current Project.


    The default will let the user create new project files as well as open
    existing ones.
    Use create=False or the convenience function openProject to only accept
    existing project files.

    If a compression level (1..9) is given, the contents will be compressed,
    resulting in much smaller project files at the cost of

    Only one pyFormex project can be open at any time. The open project
    owns all the global data created and exported by any script.

    If makeDefault is True, an already open project will be closed and
    the opened project becomes the current project.
    If makeDefault is False, the project data are imported into pf.PF
    and the current project does not change. This means that if a project was
    open, the imported data will be added to it.

    If addGlobals is None, the user is asked whether the current globals
    should be added to the project. Set True or False to force or reject
    the adding without asking.
    """
    pf.message("Setting current project to %s" % proj.filename)
    pf.message("Project contents: %s" % utils.sortedKeys(proj))
    keep = {}
    if pf.PF:
        pf.message("Current pyFormex globals: %s" % utils.sortedKeys(pf.PF))
        _delete = "Delete"
        _add = "Keep non existing"
        _overwrite = "Keep all (overwrite project)"
        res = draw.ask("What shall I do with the current pyFormex globals?",[_delete,_add,_overwrite])
        if res == _add:
            keep = utils.removeDict(pf.PF,proj)
        elif res == _overwrite:
            keep = pf.PF
    pf.PF = proj
    if keep:
        pf.PF.update(keep)
    if pf.PF.filename:
        updateSettings({
            'curproj':pf.PF.filename,
            'workdir':os.path.dirname(pf.PF.filename),
            },save=True)
    pf.GUI.setcurproj(pf.PF.filename)

    if hasattr(proj,'_autoscript_'):
        _ignore = "Ignore it!"
        _show = "Show it"
        _edit = "Load it in the editor"
        _exec = "Execute it"
        res = draw.ask("There is an autoscript stored inside the project.\nIf you received this project file from an untrusted source, you should probably not execute it.",[_ignore,_show,_edit,_exec])
        if res == _show:
            res = draw.showText(proj._autoscript_)#,actions=[_ignore,_edit,_show])
            return
        if res == _exec:
            draw.playScript(proj._autoscript_)
        elif res == _edit:
            fn = "_autoscript_.py"
            draw.checkWorkdir()
            f = open(fn,'w')
            f.write(proj._autoscript_)
            f.close()
            openScript(fn)
            editApp(fn)

    if hasattr(proj,'autofile') and draw.ack("The project has an autofile attribute: %s\nShall I execute this script?" % proj.autofile):
        draw.processArgs([proj.autofile])

    listProject()
예제 #18
0
def setProject(proj):
    """Make the specified project the current project.

    proj is an open project.
    If a filename, the project file is opened.

    .. note: The remainder is obsolete

    The user is asked for a Project file name and the access modalities.
    Depending on the results of the dialog:

    - either an new project is create or an old is opened,
    - the old data may be discarded, added to the current pyFormex globals,
      or replace them
    - the opened Project may become the current Project, or its data are
      just imported in the current Project.


    The default will let the user create new project files as well as open
    existing ones.
    Use create=False or the convenience function openProject to only accept
    existing project files.

    If a compression level (1..9) is given, the contents will be compressed,
    resulting in much smaller project files at the cost of

    Only one pyFormex project can be open at any time. The open project
    owns all the global data created and exported by any script.

    If makeDefault is True, an already open project will be closed and
    the opened project becomes the current project.
    If makeDefault is False, the project data are imported into pf.PF
    and the current project does not change. This means that if a project was
    open, the imported data will be added to it.

    If addGlobals is None, the user is asked whether the current globals
    should be added to the project. Set True or False to force or reject
    the adding without asking.
    """
    pf.message("Setting current project to %s" % proj.filename)
    pf.message("Project contents: %s" % utils.sortedKeys(proj))
    keep = {}
    if pf.PF:
        pf.message("Current pyFormex globals: %s" % utils.sortedKeys(pf.PF))
        _delete = "Delete"
        _add = "Keep non existing"
        _overwrite = "Keep all (overwrite project)"
        res = draw.ask("What shall I do with the current pyFormex globals?",
                       [_delete, _add, _overwrite])
        if res == _add:
            keep = utils.removeDict(pf.PF, proj)
        elif res == _overwrite:
            keep = pf.PF
    pf.PF = proj
    if keep:
        pf.PF.update(keep)
    if pf.PF.filename:
        updateSettings(
            {
                'curproj': pf.PF.filename,
                'workdir': os.path.dirname(pf.PF.filename),
            },
            save=True)
    pf.GUI.setcurproj(pf.PF.filename)

    if hasattr(proj, '_autoscript_'):
        _ignore = "Ignore it!"
        _show = "Show it"
        _edit = "Load it in the editor"
        _exec = "Execute it"
        res = draw.ask(
            "There is an autoscript stored inside the project.\nIf you received this project file from an untrusted source, you should probably not execute it.",
            [_ignore, _show, _edit, _exec])
        if res == _show:
            res = draw.showText(
                proj._autoscript_)  #,actions=[_ignore,_edit,_show])
            return
        if res == _exec:
            draw.playScript(proj._autoscript_)
        elif res == _edit:
            fn = "_autoscript_.py"
            draw.checkWorkdir()
            f = open(fn, 'w')
            f.write(proj._autoscript_)
            f.close()
            openScript(fn)
            editApp(fn)

    if hasattr(proj, 'autofile') and draw.ack(
            "The project has an autofile attribute: %s\nShall I execute this script?"
            % proj.autofile):
        draw.processArgs([proj.autofile])

    listProject()