Example #1
0
def startGUI(args):
    """Create the QT4 application and GUI.

    A (possibly empty) list of command line options should be provided.
    QT4 wil remove the recognized QT4 and X11 options.
    """
    # This seems to be the only way to make sure the numeric conversion is
    # always correct
    #
    QtCore.QLocale.setDefault(QtCore.QLocale.c())
    #
    #pf.options.debug = -1
    pf.debug("Arguments passed to the QApplication: %s" % args)
    pf.app = QtGui.QApplication(args)
    
    #
    pf.debug("Arguments left after constructing the QApplication: %s" % args)
    pf.debug("Arguments left after constructing the QApplication: %s" % pf.app.arguments().join('\n'))
    #pf.options.debug = 0
    # As far as I have been testing this, the args passed to the Qt application are
    # NOT acknowledged and neither are they removed!!


    pf.app.setOrganizationName("pyformex.org")
    pf.app.setOrganizationDomain("pyformex.org")
    pf.app.setApplicationName("pyFormex")
    pf.app.setApplicationVersion(pf.__version__)
    ## pf.settings = QtCore.QSettings("pyformex.org", "pyFormex")
    ## pf.settings.setValue("testje","testvalue")
    
    #QtCore.QObject.connect(pf.app,QtCore.SIGNAL("lastWindowClosed()"),pf.app,QtCore.SLOT("quit()"))
    QtCore.QObject.connect(pf.app,QtCore.SIGNAL("lastWindowClosed()"),quitGUI)
    #QtCore.QObject.connect(pf.app,QtCore.SIGNAL("aboutToQuit()"),quitGUI)

    # Check if we have DRI
    viewport.setOpenGLFormat()
    dri = viewport.opengl_format.directRendering()


    # Check for existing pyFormex processes
    windowname,running = findOldProcesses()

    while len(running) > 0:
        if len(running) >= 16:
            print("Too many open pyFormex windows --- bailing out")
            return -1

        pids = [ i[2] for i in running if i[2] is not None ]
        warning = """..

pyFormex is already running on this screen
------------------------------------------
A main pyFormex window already exists on your screen. 

If you really intended to start another instance of pyFormex, you
can just continue now.

The window might however be a leftover from a previously crashed pyFormex
session, in which case you might not even see the window anymore, nor be able
to shut down that running process. In that case, you would better bail out now
and try to fix the problem by killing the related process(es).

If you think you have already killed those processes, you may check it by
rerunning the tests.
"""
        actions = ['Really Continue','Rerun the tests','Bail out and fix the problem']
        if pids:
            warning += """

I have identified the process(es) by their PID as::

%s

If you trust me enough, you can also have me kill this processes for you.
""" % pids
            actions[2:2] = ['Kill the running processes']
            
        if dri:
            answer = draw.ask(warning,actions)
        else:
            warning += """
I have detected that the Direct Rendering Infrastructure
is not activated on your system. Continuing with a second
instance of pyFormex may crash your XWindow system.
You should seriously consider to bail out now!!!
"""
            answer = draw.warning(warning,actions)


        if answer == 'Really Continue':
            break # OK, Go ahead

        elif answer == 'Rerun the tests':
            windowname,running = findOldProcesses() # try again
        
        elif answer == 'Kill the running processes':
            killProcesses(pids)
            windowname,running = findOldProcesses() # try again
            
        else:
            return -1 # I'm out of here!

        
    # Load the splash image
    splash = None
    if os.path.exists(pf.cfg['gui/splash']):
        pf.debug('Loading splash %s' % pf.cfg['gui/splash'])
        splashimage = QtGui.QPixmap(pf.cfg['gui/splash'])
        splash = QtGui.QSplashScreen(splashimage)
        splash.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        splash.setFont(QtGui.QFont("Helvetica",24))
        splash.showMessage(pf.Version,QtCore.Qt.AlignHCenter,QtCore.Qt.red)
        splash.show()

    # create GUI, show it, run it

    pf.GUI = GUI(windowname,
                 pf.cfg.get('gui/size',(800,600)),
                 pf.cfg.get('gui/pos',(0,0)),
                 pf.cfg.get('gui/bdsize',(800,600)),
                 )

    # set the appearance
    pf.GUI.setAppearence()


    # setup the message board
    pf.board = pf.GUI.board
    pf.board.write("""%s  (C) Benedict Verhegghe

pyFormex comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under the conditions of the GNU General Public License, version 3 or later. See Help->License or the file COPYING for details.
""" % pf.Version)
    
    # Set interaction functions
    
    def show_warning(message,category,filename,lineno,file=None,line=None):
        """Replace the default warnings.showwarning

        We display the warnings using our interactive warning widget.
        This feature can be turned off by setting
        cfg['warnings/popup'] = False
        """
        full_message = warnings.formatwarning(message,category,filename,lineno,line)
        ## from widgets import simpleInputItem as I
        ## res = draw.askItems([
        ##     I('message',message,itemtype='label',text='warning'),
        ##     I('filter',False,text='Suppress this message in future sessions'),
        ##     ],actions=[('OK',)],legacy=False)
        #print res
        pf.message(full_message)
        res,check = draw.showMessage(full_message,level='warning',check="Do not show this warning anymore in future sessions")
        if check[0]:
            oldfilters = pf.prefcfg['warnings/filters']
            newfilters = oldfilters + [(str(message),)]
            pf.prefcfg.update({'filters':newfilters},name='warnings')


##     def format_warning(message,category,filename,lineno,line=None):
##         """Replace the default warnings.formatwarning

##         We display the warnings using our interactive warning widget.
##         This feature can be turned off by setting
##         cfg['nice_warnings'] = False
##         """
##         import messages
##         message = messages.getMessage(message)
##         message = """..

## pyFormex Warning
## ================
## %s

## `Called from:` %s `line:` %s
## """ % (message,filename,lineno)
##         if line:
##             message += "%s\n" % line
##         return message


##     if pf.cfg['warnings/nice']:
##         warnings.formatwarning = format_warning

    if pf.cfg['warnings/popup']:
        warnings.showwarning = show_warning
    
    
    pf.message = draw.message
    pf.warning = draw.warning

    # setup the canvas
    pf.GUI.viewports.changeLayout(1)
    pf.GUI.viewports.setCurrent(0)
    pf.canvas = pf.GUI.viewports.current
    draw.reset()

    # setup the status bar
    pf.GUI.addInputBox()
    pf.GUI.toggleInputBox(False)
    pf.GUI.addCoordsTracker()
    pf.GUI.toggleCoordsTracker(pf.cfg.get('gui/coordsbox',False))
    pf.debug("Using window name %s" % pf.GUI.windowTitle())
    
    # Create additional menus (put them in a list to save)
    
    # History Menu
    pf.GUI.history = scriptMenu.ScriptMenu('History',files=pf.cfg['gui/history'],max=pf.cfg['gui/history_max'])

    if pf.cfg.get('gui/history_in_main_menu',False):
        before = pf.GUI.menu.item('help')
        pf.GUI.menu.insertMenu(before,pf.GUI.history)
    else:
        filemenu = pf.GUI.menu.item('file')
        before = filemenu.item('---1')
        filemenu.insertMenu(before,pf.GUI.history)
    

    # Scripts menu
    pf.GUI.scriptmenu = scriptMenu.createScriptMenu(pf.GUI.menu,before='help')

    # Create databases
    createDatabases()
 
    # PLugin menus
    import plugins
    ## filemenu = pf.GUI.menu.item('file')
    ## pf.gui.saveobj = plugins.create_plugin_menus(filemenu,before='options')
    ## # Load configured plugins, ignore if not found
    plugins.loadConfiguredPlugins()
    #for p in pf.cfg['gui/plugins']:
    #    plugins.load(p)

    pf.GUI.setBusy(False)
    pf.GUI.addStatusBarButtons()

    # remove the splash window
    if splash is not None:
        splash.finish(pf.GUI)

    pf.GUI.setBusy(False)

    if os.path.isdir(pf.cfg['workdir']):
        # Make the workdir the current dir
        os.chdir(pf.cfg['workdir'])
        pf.debug("Setting workdir to %s" % pf.cfg['workdir'])
    else:
        # Save the current dir as workdir
        prefMenu.updateSettings({'workdir':os.getcwd(),'Save changes':True})

    pf.GUI.show()
    pf.GUI.update()
    pf.app_started = True
    pf.GUI.processEvents()
    return 0