source: sasview/guiframe/gui_manager.py @ 4d1dce4

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 4d1dce4 was 4d1dce4, checked in by Jae Cho <jhjcho@…>, 13 years ago

improved welcome page behavior

  • Property mode set to 100644
File size: 83.6 KB
Line 
1
2################################################################################
3#This software was developed by the University of Tennessee as part of the
4#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
5#project funded by the US National Science Foundation.
6#
7#See the license text in license.txt
8#
9#copyright 2008, University of Tennessee
10################################################################################
11
12
13import wx
14import wx.aui
15import os
16import sys
17import xml
18
19try:
20    # Try to find a local config
21    import imp
22    path = os.getcwd()
23    if(os.path.isfile("%s/%s.py" % (path, 'local_config'))) or \
24        (os.path.isfile("%s/%s.pyc" % (path, 'local_config'))):
25        fObj, path, descr = imp.find_module('local_config', [path])
26        config = imp.load_module('local_config', fObj, path, descr) 
27    else:
28        # Try simply importing local_config
29        import local_config as config
30except:
31    # Didn't find local config, load the default
32    import config
33   
34import warnings
35warnings.simplefilter("ignore")
36
37import logging
38
39from sans.guiframe.events import EVT_STATUS
40from sans.guiframe.events import EVT_APPEND_BOOKMARK
41from sans.guiframe.events import EVT_PANEL_ON_FOCUS
42from sans.guiframe.events import StatusEvent
43from sans.guiframe.events import NewPlotEvent
44from sans.guiframe.gui_style import GUIFRAME
45from sans.guiframe.gui_style import GUIFRAME_ID
46from sans.guiframe.events import NewLoadedDataEvent
47from sans.guiframe.data_panel import DataPanel
48from sans.guiframe.panel_base import PanelBase
49from sans.guiframe.gui_toolbar import GUIToolBar
50from DataLoader.loader import Loader
51
52
53#read some constants from config
54APPLICATION_STATE_EXTENSION = config.APPLICATION_STATE_EXTENSION
55APPLICATION_NAME = config.__appname__
56SPLASH_SCREEN_PATH = config.SPLASH_SCREEN_PATH
57DEFAULT_STYLE = config.DEFAULT_STYLE
58SPLASH_SCREEN_WIDTH = config.SPLASH_SCREEN_WIDTH
59SPLASH_SCREEN_HEIGHT = config.SPLASH_SCREEN_HEIGHT
60SS_MAX_DISPLAY_TIME = config.SS_MAX_DISPLAY_TIME
61PLOPANEL_WIDTH = config.PLOPANEL_WIDTH
62PLOPANEL_HEIGTH = config.PLOPANEL_HEIGTH
63GUIFRAME_WIDTH = config.GUIFRAME_WIDTH
64GUIFRAME_HEIGHT = config.GUIFRAME_HEIGHT
65PLUGIN_STATE_EXTENSIONS =  config.PLUGIN_STATE_EXTENSIONS
66extension_list = []
67if APPLICATION_STATE_EXTENSION is not None:
68    extension_list.append(APPLICATION_STATE_EXTENSION)
69EXTENSIONS = PLUGIN_STATE_EXTENSIONS + extension_list
70try:
71    PLUGINS_WLIST = '|'.join(config.PLUGINS_WLIST)
72except:
73    PLUGINS_WLIST = ''
74APPLICATION_WLIST = config.APPLICATION_WLIST
75
76class ViewerFrame(wx.Frame):
77    """
78    Main application frame
79    """
80   
81    def __init__(self, parent, title, 
82                 size=(GUIFRAME_WIDTH, GUIFRAME_HEIGHT),
83                 gui_style=GUIFRAME.DEFAULT_STYLE, 
84                 pos=wx.DefaultPosition):
85        """
86        Initialize the Frame object
87        """
88       
89        wx.Frame.__init__(self, parent=parent, title=title, pos=pos,size=size)
90        # title
91        self.title = title
92        # Preferred window size
93        self._window_width, self._window_height = size
94        self.__gui_style = gui_style
95       
96        # Logging info
97        logging.basicConfig(level=logging.DEBUG,
98                    format='%(asctime)s %(levelname)s %(message)s',
99                    filename='sans_app.log',
100                    filemode='w')       
101        path = os.path.dirname(__file__)
102        temp_path = os.path.join(path,'images')
103        ico_file = os.path.join(temp_path,'ball.ico')
104        if os.path.isfile(ico_file):
105            self.SetIcon(wx.Icon(ico_file, wx.BITMAP_TYPE_ICO))
106        else:
107            temp_path = os.path.join(os.getcwd(),'images')
108            ico_file = os.path.join(temp_path,'ball.ico')
109            if os.path.isfile(ico_file):
110                self.SetIcon(wx.Icon(ico_file, wx.BITMAP_TYPE_ICO))
111       
112        ## Application manager
113        self._input_file = None
114        self.app_manager = None
115        self._mgr = None
116        #add current perpsective
117        self._current_perspective = None
118        self._plotting_plugin = None
119        self._data_plugin = None
120        #Menu bar and item
121        self._menubar = None
122        self._file_menu = None
123        self._data_menu = None
124        self._window_menu = None
125        self._data_panel_menu = None
126        self._help_menu = None
127        self._tool_menu = None
128        self._applications_menu_pos = -1
129        self._applications_menu_name = None
130        self._applications_menu = None
131        self._edit_menu = None
132        self._toolbar_menu = None
133        self._save_appl_menu = None
134        #tool bar
135        self._toolbar = None
136        # (un)-focus color
137        #self.color = '#b3b3b3'
138        ## Find plug-ins
139        # Modify this so that we can specify the directory to look into
140        self.plugins = []
141        #add local plugin
142        self.plugins += self._get_local_plugins()
143        self.plugins += self._find_plugins()
144        ## List of panels
145        self.panels = {}
146
147        # Default locations
148        self._default_save_location = os.getcwd()       
149       
150        # Welcome panel
151        self.defaultPanel = None
152        #panel on focus
153        self.panel_on_focus = None
154        self.loader = Loader()   
155        #data manager
156        from data_manager import DataManager
157        self._data_manager = DataManager()
158        self._data_panel = DataPanel(parent=self)
159        if self.panel_on_focus is not None:
160            self._data_panel.set_panel_on_focus(self.panel_on_focus.window_caption)
161        # list of plot panels in schedule to full redraw
162        self.schedule = False
163        #self.callback = True
164        self._idle_count = 0
165        self.schedule_full_draw_list = []
166        self.idletimer = wx.CallLater(1, self._onDrawIdle)
167
168        # Check for update
169        #self._check_update(None)
170        # Register the close event so it calls our own method
171        wx.EVT_CLOSE(self, self.Close)
172        # Register to status events
173        self.Bind(EVT_STATUS, self._on_status_event)
174        #Register add extra data on the same panel event on load
175        self.Bind(EVT_PANEL_ON_FOCUS, self.set_panel_on_focus)
176        self.Bind(EVT_APPEND_BOOKMARK, self.append_bookmark)
177       
178       
179    def set_input_file(self, input_file):
180        """
181        :param input_file: file to read
182        """
183        self._input_file = input_file
184       
185    def get_data_manager(self):
186        """
187        """
188        return self._data_manager
189   
190    def get_toolbar(self):
191        """
192        """
193        return self._toolbar
194   
195    def set_panel_on_focus(self, event):
196        """
197        Store reference to the last panel on focus
198        update the toolbar if available
199        update edit menu if available
200        """
201        self.panel_on_focus = event.panel
202        panel_name = 'No panel on focus'
203        application_name = 'No Selected Application'
204        if self.panel_on_focus is not None and self._data_panel is not None:
205            panel_name = self.panel_on_focus.window_caption
206            self._data_panel.set_panel_on_focus(panel_name)
207            #update toolbar
208            self._update_toolbar_helper()
209            #update edit menu
210            self.enable_edit_menu()
211
212    def build_gui(self):
213        """
214        """
215        # set tool bar
216        self._setup_tool_bar()
217        # Set up the layout
218        self._setup_layout()
219        # Set up the menu
220        self._setup_menus()
221       
222        try:
223            self.load_from_cmd(self._input_file)
224        except:
225            msg = "%s Cannot load file %s\n" %(str(APPLICATION_NAME), 
226                                             str(self._input_file))
227            msg += str(sys.exc_value) + '\n'
228            print msg
229        self.post_init()
230        self.show_welcome_panel(None)
231        self.Show(True)
232        #self._check_update(None)
233             
234    def _setup_layout(self):
235        """
236        Set up the layout
237        """
238        # Status bar
239        from gui_statusbar import StatusBar
240        self.sb = StatusBar(self, wx.ID_ANY)
241        self.SetStatusBar(self.sb)
242        # Add panel
243        default_flag = wx.aui.AUI_MGR_DEFAULT| wx.aui.AUI_MGR_ALLOW_ACTIVE_PANE
244        self._mgr = wx.aui.AuiManager(self, flags=default_flag)
245        self._mgr.SetDockSizeConstraint(0.5, 0.5)
246        # border color
247        #self.b_color = wx.aui.AUI_DOCKART_BORDER_COLOUR 
248        #self._mgr.GetArtProvider().SetColor(self.b_color, self.color)
249        #self._mgr.SetArtProvider(wx.aui.AuiDockArt(wx.AuiDefaultDockArt))
250        #print "set", self._dockart.GetColour(13)
251        # Load panels
252        self._load_panels()
253        self.set_default_perspective()
254        self._mgr.Update()
255       
256    def SetStatusText(self, *args, **kwds):
257        """
258        """
259        number = self.sb.get_msg_position()
260        wx.Frame.SetStatusText(number=number, *args, **kwds)
261       
262    def PopStatusText(self, *args, **kwds):
263        """
264        """
265        field = self.sb.get_msg_position()
266        wx.Frame.PopStatusText(field=field)
267       
268    def PushStatusText(self, *args, **kwds):
269        """
270        """
271        field = self.sb.get_msg_position()
272        wx.Frame.PushStatusText(self, field=field, string=string)
273
274    def add_perspective(self, plugin):
275        """
276        Add a perspective if it doesn't already
277        exist.
278        """
279        is_loaded = False
280        for item in self.plugins:
281            if plugin.__class__ == item.__class__:
282                msg = "Plugin %s already loaded" % plugin.sub_menu
283                logging.info(msg)
284                is_loaded = True   
285        if not is_loaded:
286            self.plugins.append(plugin)
287     
288    def _get_local_plugins(self):
289        """
290        get plugins local to guiframe and others
291        """
292        plugins = []
293        #import guiframe local plugins
294        #check if the style contain guiframe.dataloader
295        style1 = self.__gui_style & GUIFRAME.DATALOADER_ON
296        style2 = self.__gui_style & GUIFRAME.PLOTTING_ON
297        if style1 == GUIFRAME.DATALOADER_ON:
298            try:
299                from sans.guiframe.local_perspectives.data_loader import data_loader
300                self._data_plugin = data_loader.Plugin()
301                plugins.append(self._data_plugin)
302            except:
303                msg = "ViewerFrame._get_local_plugins:"
304                msg += "cannot import dataloader plugin.\n %s" % sys.exc_value
305                logging.error(msg)
306        if style2 == GUIFRAME.PLOTTING_ON:
307            try:
308                from sans.guiframe.local_perspectives.plotting import plotting
309                self._plotting_plugin = plotting.Plugin()
310                plugins.append(self._plotting_plugin)
311            except:
312                msg = "ViewerFrame._get_local_plugins:"
313                msg += "cannot import plotting plugin.\n %s" % sys.exc_value
314                logging.error(msg)
315     
316        return plugins
317   
318    def _find_plugins(self, dir="perspectives"):
319        """
320        Find available perspective plug-ins
321       
322        :param dir: directory in which to look for plug-ins
323       
324        :return: list of plug-ins
325       
326        """
327        import imp
328        plugins = []
329        # Go through files in panels directory
330        try:
331            list = os.listdir(dir)
332            ## the default panel is the panel is the last plugin added
333            for item in list:
334                toks = os.path.splitext(os.path.basename(item))
335                name = ''
336                if not toks[0] == '__init__':
337                    if toks[1] == '.py' or toks[1] == '':
338                        name = toks[0]
339                    #check the validity of the module name parsed
340                    #before trying to import it
341                    if name is None or name.strip() == '':
342                        continue
343                    path = [os.path.abspath(dir)]
344                    file = ''
345                    try:
346                        if toks[1] == '':
347                            mod_path = '.'.join([dir, name])
348                            module = __import__(mod_path, globals(),
349                                                locals(), [name])
350                        else:
351                            (file, path, info) = imp.find_module(name, path)
352                            module = imp.load_module( name, file, item, info)
353                        if hasattr(module, "PLUGIN_ID"):
354                            try: 
355                                plug = module.Plugin()
356                                if plug.set_default_perspective():
357                                    self._current_perspective = plug
358                                plugins.append(plug)
359                                msg = "Found plug-in: %s" % module.PLUGIN_ID
360                                logging.info(msg)
361                            except:
362                                msg = "Error accessing PluginPanel"
363                                msg += " in %s\n  %s" % (name, sys.exc_value)
364                                config.printEVT(msg)
365                    except:
366                        msg = "ViewerFrame._find_plugins: %s" % sys.exc_value
367                        #print msg
368                        logging.error(msg)
369                    finally:
370                        if not file == None:
371                            file.close()
372        except:
373            # Should raise and catch at a higher level and
374            # display error on status bar
375            pass   
376        return plugins
377   
378    def set_welcome_panel(self, panel_class):
379        """
380        Sets the default panel as the given welcome panel
381       
382        :param panel_class: class of the welcome panel to be instantiated
383       
384        """
385        self.defaultPanel = panel_class(self, -1, style=wx.RAISED_BORDER)
386       
387    def _get_panels_size(self, p):
388        """
389        find the proper size of the current panel
390        get the proper panel width and height
391        """
392        panel_height_min = self._window_height
393        panel_width_min = self._window_width
394        style = self.__gui_style & (GUIFRAME.MANAGER_ON)
395        if self._data_panel is not None  and (p == self._data_panel):
396            panel_width_min = self._window_width * 4/25 
397            panel_height_min = self._window_height * 0.8
398            return panel_width_min, panel_height_min
399        if hasattr(p, "CENTER_PANE") and p.CENTER_PANE:
400            style = self.__gui_style & (GUIFRAME.PLOTTING_ON|GUIFRAME.MANAGER_ON)
401            if style == (GUIFRAME.PLOTTING_ON|GUIFRAME.MANAGER_ON):
402                panel_width_min = self._window_width * 15/25 
403            return panel_width_min, panel_height_min
404        return panel_width_min, panel_height_min
405   
406    def _load_panels(self):
407        """
408        Load all panels in the panels directory
409        """
410       
411        # Look for plug-in panels
412        panels = []   
413        for item in self.plugins:
414            if hasattr(item, "get_panels"):
415                ps = item.get_panels(self)
416                panels.extend(ps)
417       
418        # Show a default panel with some help information
419        # It also sets the size of the application windows
420        #TODO: Use this for slpash screen
421        if self.defaultPanel is None:
422            self.defaultPanel = DefaultPanel(self, -1, style=wx.RAISED_BORDER)
423        # add a blank default panel always present
424        self.panels["default"] = self.defaultPanel
425        self._mgr.AddPane(self.defaultPanel, wx.aui.AuiPaneInfo().
426                              Name("default").
427                              CenterPane().
428                              #CloseButton(False).
429                              #MinimizeButton(False).
430                              # This is where we set the size of
431                              # the application window
432                              BestSize(wx.Size(self._window_width, 
433                                               self._window_height)).
434                              Show())
435
436        #add data panel
437        self.panels["data_panel"] = self._data_panel
438        w, h = self._get_panels_size(self._data_panel)
439        self._mgr.AddPane(self._data_panel, wx.aui.AuiPaneInfo().
440                              Name(self._data_panel.window_name).
441                              Caption(self._data_panel.window_caption).
442                              Left().
443                              MinimizeButton().
444                              CloseButton(True).
445                              TopDockable(False).
446                              BottomDockable(False).
447                              LeftDockable(True).
448                              RightDockable(False).
449                              BestSize(wx.Size(w, h)).
450                              Hide())
451
452        style = self.__gui_style & GUIFRAME.MANAGER_ON
453        data_pane = self._mgr.GetPane(self.panels["data_panel"].window_name)
454        if style != GUIFRAME.MANAGER_ON:
455            self._mgr.GetPane(self.panels["data_panel"].window_name).Hide()
456        else:
457            self._mgr.GetPane(self.panels["data_panel"].window_name).Show()
458           
459        # Add the panels to the AUI manager
460        for panel_class in panels:
461            p = panel_class
462            id = wx.NewId()
463            #w, h = self._get_panels_size(p)
464            # Check whether we need to put this panel
465            # in the center pane
466            if hasattr(p, "CENTER_PANE") and p.CENTER_PANE:
467                w, h = self._get_panels_size(p)
468                if p.CENTER_PANE:
469                    self.panels[str(id)] = p
470                    self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
471                                          Name(p.window_name).
472                                          Caption(p.window_caption).
473                                          #CenterPane().
474                                          Center().
475                                          CloseButton(False).
476                                          #MinimizeButton(False).
477                                          #BestSize(wx.Size(w, h)).
478                                          Hide())
479            else:
480                self.panels[str(id)] = p
481                self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
482                                  Name(p.window_name).Caption(p.window_caption).
483                                  Right().
484                                  Dock().
485                                  TopDockable().
486                                  BottomDockable().
487                                  LeftDockable().
488                                  RightDockable().
489                                  MinimizeButton().
490                                  Hide())       
491     
492    def update_data(self, prev_data, new_data):
493        """
494        """
495        prev_id, data_state = self._data_manager.update_data(prev_data=prev_data, 
496                                       new_data=new_data)
497       
498        self._data_panel.remove_by_id(prev_id)
499        self._data_panel.load_data_list(data_state)
500       
501    def update_theory(self, data_id, theory, state=None):
502        """
503        """ 
504        data_state = self._data_manager.update_theory(data_id=data_id, 
505                                         theory=theory,
506                                         state=state) 
507        self._data_panel.load_data_list(data_state)
508       
509    def onfreeze(self, theory_id):
510        """
511        """
512        data_state_list = self._data_manager.freeze(theory_id)
513        self._data_panel.load_data_list(list=data_state_list)
514        for data_state in data_state_list.values():
515            new_plot = data_state.get_data()
516           
517            wx.PostEvent(self, NewPlotEvent(plot=new_plot,
518                                             title=new_plot.title))
519       
520    def freeze(self, data_id, theory_id):
521        """
522        """
523        data_state_list = self._data_manager.freeze_theory(data_id=data_id, 
524                                                theory_id=theory_id)
525        self._data_panel.load_data_list(list=data_state_list)
526        for data_state in data_state_list.values():
527            new_plot = data_state.get_data()
528            wx.PostEvent(self, NewPlotEvent(plot=new_plot,
529                                             title=new_plot.title))
530       
531    def delete_data(self, data):
532        """
533        """
534        self._current_perspective.delete_data(data)
535       
536   
537    def get_context_menu(self, plotpanel=None):
538        """
539        Get the context menu items made available
540        by the different plug-ins.
541        This function is used by the plotting module
542        """
543        if plotpanel is None:
544            return
545        menu_list = []
546        for item in self.plugins:
547            menu_list.extend(item.get_context_menu(plotpanel=plotpanel))
548        return menu_list
549       
550    def popup_panel(self, p):
551        """
552        Add a panel object to the AUI manager
553       
554        :param p: panel object to add to the AUI manager
555       
556        :return: ID of the event associated with the new panel [int]
557       
558        """
559        ID = wx.NewId()
560        self.panels[str(ID)] = p
561        count = 0
562        for item in self.panels:
563            if self.panels[item].window_name.startswith(p.window_name): 
564                count += 1
565        windowname = p.window_name
566        caption = p.window_caption
567        if count > 0:
568            windowname += str(count+1)
569            caption += (' '+str(count))
570        p.window_name = windowname
571        p.window_caption = caption
572           
573        style1 = self.__gui_style & GUIFRAME.FIXED_PANEL
574        style2 = self.__gui_style & GUIFRAME.FLOATING_PANEL
575        if style1 == GUIFRAME.FIXED_PANEL:
576            self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
577                              Name(windowname).
578                              Caption(caption).
579                              Position(10).
580                              Floatable().
581                              Right().
582                              Dock().
583                              MinimizeButton().
584                              Resizable(True).
585                              # Use a large best size to make sure the AUI
586                              # manager takes all the available space
587                              BestSize(wx.Size(PLOPANEL_WIDTH, 
588                                               PLOPANEL_HEIGTH)))
589                              #MinSize(wx.Size(PLOPANEL_WIDTH*0.9,
590                              #                PLOPANEL_HEIGTH)))
591            self._popup_fixed_panel(p)
592   
593        elif style2 == GUIFRAME.FLOATING_PANEL:
594            self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
595                              Name(windowname).Caption(caption).
596                              MinimizeButton().
597                              Resizable(True).
598                              # Use a large best size to make sure the AUI
599                              #  manager takes all the available space
600                              BestSize(wx.Size(PLOPANEL_WIDTH, 
601                                               PLOPANEL_HEIGTH)))
602            self._popup_floating_panel(p)
603           
604        pane = self._mgr.GetPane(windowname)
605        self._mgr.MaximizePane(pane)
606        self._mgr.RestoreMaximizedPane()
607        # Register for showing/hiding the panel
608        wx.EVT_MENU(self, ID, self._on_view)
609       
610        self._mgr.Update()
611        return ID
612       
613    def _setup_menus(self):
614        """
615        Set up the application menus
616        """
617        # Menu
618        self._menubar = wx.MenuBar()
619        self._add_menu_file()
620        self._add_menu_data()
621        self._add_menu_application()
622        self._add_menu_edit()
623        self._add_menu_tool()
624        self._add_current_plugin_menu()
625        self._add_menu_window()
626        self._add_help_menu()
627        self.SetMenuBar(self._menubar)
628       
629    def _setup_tool_bar(self):
630        """
631        add toolbar to the frame
632        """
633        #set toolbar
634        self._toolbar = GUIToolBar(self, -1)
635        self.SetToolBar(self._toolbar)
636        self._update_toolbar_helper()
637        #self._on_hide_toolbar(event=None)
638   
639    def _update_toolbar_helper(self):
640        """
641        """
642        application_name = 'No Selected Application'
643        panel_name = 'No Panel on Focus'
644        if self._toolbar is  None:
645            return
646        self._toolbar.update_toolbar(self.panel_on_focus)
647        if self._current_perspective is not None:
648            application_name = self._current_perspective.sub_menu
649        if self.panel_on_focus is not None:
650            panel_name = self.panel_on_focus.window_caption
651        self._toolbar.update_button(application_name=application_name, 
652                                        panel_name=panel_name)
653        self._toolbar.Realize()
654       
655    def _add_menu_tool(self):
656        """
657        Tools menu
658        Go through plug-ins and find tools to populate the tools menu
659        """
660        style = self.__gui_style & GUIFRAME.TOOL_ON
661        if style == GUIFRAME.TOOL_ON:
662            self._tool_menu = None
663            for item in self.plugins:
664                if hasattr(item, "get_tools"):
665                    for tool in item.get_tools():
666                        # Only create a menu if we have at least one tool
667                        if self._tool_menu is None:
668                            self._tool_menu = wx.Menu()
669                        id = wx.NewId()
670                        self._tool_menu.Append(id, tool[0], tool[1])
671                        wx.EVT_MENU(self, id, tool[2])
672            if self._tool_menu is not None:
673                self._menubar.Append(self._tool_menu, '&Tools')
674               
675    def _add_current_plugin_menu(self):
676        """
677        add current plugin menu
678        Look for plug-in menus
679        Add available plug-in sub-menus.
680        """
681        if (self._menubar is None) or (self._current_perspective is None):
682            return
683        #replace or add a new menu for the current plugin
684       
685        pos = self._menubar.FindMenu(str(self._applications_menu_name))
686        if pos != -1:
687            menu_list = self._current_perspective.populate_menu(self)
688            if menu_list:
689                for (menu, name) in menu_list:
690                    hidden_menu = self._menubar.Replace(pos, menu, name) 
691                    self._applications_menu_name = name
692                #self._applications_menu_pos = pos
693            else:
694                hidden_menu = self._menubar.Remove(pos)
695                self._applications_menu_name = None
696            #get the position of the menu when it first added
697            self._applications_menu_pos = pos
698           
699        else:
700            menu_list = self._current_perspective.populate_menu(self)
701            if menu_list:
702                for (menu,name) in menu_list:
703                    if self._applications_menu_pos == -1:
704                        self._menubar.Append(menu, name)
705                    else:
706                        self._menubar.Insert(self._applications_menu_pos, menu, name)
707                    self._applications_menu_name = name
708                 
709    def _add_help_menu(self):
710        """
711        add help menu
712        """
713        # Help menu
714        self._help_menu = wx.Menu()
715        style = self.__gui_style & GUIFRAME.WELCOME_PANEL_ON
716        if style == GUIFRAME.WELCOME_PANEL_ON:
717            # add the welcome panel menu item
718            if self.defaultPanel is not None:
719                id = wx.NewId()
720                self._help_menu.Append(id, '&Welcome', '')
721                self._help_menu.AppendSeparator()
722                wx.EVT_MENU(self, id, self.show_welcome_panel)
723        # Look for help item in plug-ins
724        for item in self.plugins:
725            if hasattr(item, "help"):
726                id = wx.NewId()
727                self._help_menu.Append(id,'&%s help' % item.sub_menu, '')
728                wx.EVT_MENU(self, id, item.help)
729        if config._do_aboutbox:
730            id = wx.NewId()
731            self._help_menu.Append(id,'&About', 'Software information')
732            wx.EVT_MENU(self, id, self._onAbout)
733       
734        # Checking for updates needs major refactoring to work with py2exe
735        # We need to make sure it doesn't hang the application if the server
736        # is not up. We also need to make sure there's a proper executable to
737        # run if we spawn a new background process.
738        #id = wx.NewId()
739        #self._help_menu.Append(id,'&Check for update',
740        #'Check for the latest version of %s' % config.__appname__)
741        #wx.EVT_MENU(self, id, self._check_update)
742        self._menubar.Append(self._help_menu, '&Help')
743           
744    def _add_menu_window(self):
745        """
746        add a menu window to the menu bar
747        Window menu
748        Attach a menu item for each panel in our
749        panel list that also appears in a plug-in.
750       
751        Only add the panel menu if there is only one perspective and
752        it has more than two panels.
753        Note: the first plug-in is always the plotting plug-in.
754        The first application
755        #plug-in is always the second one in the list.
756        """
757        self._window_menu = wx.Menu()
758        if self._plotting_plugin is not None:
759            for (menu, name) in self._plotting_plugin.populate_menu(self):
760                self._window_menu.AppendSubMenu(menu, name)
761        self._menubar.Append(self._window_menu, '&Window')
762     
763        style = self.__gui_style & GUIFRAME.MANAGER_ON
764        id = wx.NewId()
765        self._data_panel_menu = self._window_menu.Append(id,
766                                                '&Data Explorer ON', '')
767        wx.EVT_MENU(self, id, self.show_data_panel)
768        if style == GUIFRAME.MANAGER_ON:
769            self._data_panel_menu.SetText('Data Explorer OFF')
770        else:
771            self._data_panel_menu.SetText('Data Explorer ON')
772           
773        style = self.__gui_style & GUIFRAME.PLOTTING_ON
774        if style == GUIFRAME.PLOTTING_ON:
775            self._window_menu.AppendSeparator()
776            id = wx.NewId()
777            preferences_menu = wx.Menu()
778            hint = "Plot panels will floating"
779            preferences_menu.Append(id, '&Floating Plot Panel', hint)
780            wx.EVT_MENU(self, id, self.set_plotpanel_floating)
781            id = wx.NewId()
782            hint = "Plot panels will displayed within the frame"
783            preferences_menu.Append(id, '&Fixed Plot Panel', hint)
784            wx.EVT_MENU(self, id, self.set_plotpanel_fixed)
785            id = wx.NewId()
786            style1 = self.__gui_style & GUIFRAME.MULTIPLE_APPLICATIONS
787            if style1 == GUIFRAME.MULTIPLE_APPLICATIONS:
788                id = wx.NewId()
789                self._toolbar_menu = preferences_menu.Append(id,'&Show Toolbar', '')
790                wx.EVT_MENU(self, id, self._on_hide_toolbar)
791            self._window_menu.AppendSubMenu(preferences_menu,'&Preferences')
792        if self._window_menu.GetMenuItemCount() == 0:
793            pos = self._menubar.FindMenu('Window')
794            self._menubar.Remove(pos)
795        #wx.EVT_MENU(self, id, self.show_preferences_panel)   
796        """
797        if len(self.plugins) == 2:
798            plug = self.plugins[1]
799            pers = plug.get_perspective()
800       
801            if len(pers) > 1:
802                self._window_menu = wx.Menu()
803                for item in self.panels:
804                    if item == 'default':
805                        continue
806                    panel = self.panels[item]
807                    if panel.window_name in pers:
808                        self._window_menu.Append(int(item),
809                                                  panel.window_caption,
810                                        "Show %s window" % panel.window_caption)
811                        wx.EVT_MENU(self, int(item), self._on_view)
812                self._menubar.Append(self._window_menu, '&Window')
813                """
814               
815    def _add_menu_application(self):
816        """
817       
818        # Attach a menu item for each defined perspective or application.
819        # Only add the perspective menu if there are more than one perspectives
820        add menu application
821        """
822        style = self.__gui_style & GUIFRAME.MULTIPLE_APPLICATIONS
823        if style == GUIFRAME.MULTIPLE_APPLICATIONS:
824            plug_data_count = False
825            plug_no_data_count = False
826            self._applications_menu = wx.Menu()
827            pos = 0
828            separator = self._applications_menu.AppendSeparator()
829            for plug in self.plugins:
830                if len(plug.get_perspective()) > 0:
831                    id = wx.NewId()
832                    if plug.use_data():
833                       
834                        self._applications_menu.InsertCheckItem(pos, id, plug.sub_menu,
835                                      "Switch to application: %s" % plug.sub_menu)
836                        plug_data_count = True
837                        pos += 1
838                    else:
839                        plug_no_data_count = True
840                        self._applications_menu.AppendCheckItem(id, plug.sub_menu,
841                                      "Switch to application: %s" % plug.sub_menu)
842                    wx.EVT_MENU(self, id, plug.on_perspective)
843            #self._applications_menu.
844            if (not plug_data_count or not plug_no_data_count):
845                self._applications_menu.RemoveItem(separator)
846            self._menubar.Append(self._applications_menu, '&Applications')
847            self._check_applications_menu()
848           
849    def _add_menu_file(self):
850        """
851        add menu file
852        """
853       
854         # File menu
855        self._file_menu = wx.Menu()
856        style = self.__gui_style & GUIFRAME.DATALOADER_ON
857        style1 = self.__gui_style & GUIFRAME.MULTIPLE_APPLICATIONS
858        if style == GUIFRAME.DATALOADER_ON:
859            if style1 == GUIFRAME.MULTIPLE_APPLICATIONS:
860                # some menu of plugin to be seen under file menu
861                hint_load_file = "Read state's files and load"
862                hint_load_file += " them into the application"
863                id = wx.NewId()
864                self._save_appl_menu = self._file_menu.Append(id, 
865                                        '&Load Application', hint_load_file)
866                wx.EVT_MENU(self, id, self._on_open_state_application)
867               
868            id = wx.NewId()
869            hint_load_file = "read all applications states save previously"
870            self._save_appl_menu = self._file_menu.Append(id, 
871                                    '&Load Project', hint_load_file)
872            wx.EVT_MENU(self, id, self._on_open_state_project)
873           
874            if style1 == GUIFRAME.MULTIPLE_APPLICATIONS:
875                self._file_menu.AppendSeparator()
876                id = wx.NewId()
877                self._save_appl_menu = self._file_menu.Append(id, 
878                                                          '&Save Application',
879                                 'Save state of the current active application')
880                wx.EVT_MENU(self, id, self._on_save_application)
881            id = wx.NewId()
882            self._file_menu.Append(id, '&Save Project',
883                                 'Save the state of the whole application')
884            wx.EVT_MENU(self, id, self._on_save_project)
885            self._file_menu.AppendSeparator()
886       
887        id = wx.NewId()
888        self._file_menu.Append(id, '&Quit', 'Exit') 
889        wx.EVT_MENU(self, id, self.Close)
890        # Add sub menus
891        self._menubar.Append(self._file_menu, '&File')
892       
893    def _add_menu_edit(self):
894        """
895        add menu edit
896        """
897        # Edit Menu
898        self._edit_menu = wx.Menu()
899        self._edit_menu.Append(GUIFRAME_ID.UNDO_ID, '&Undo', 
900                               'Undo the previous action')
901        wx.EVT_MENU(self, GUIFRAME_ID.UNDO_ID, self.on_undo_panel)
902        self._edit_menu.Append(GUIFRAME_ID.REDO_ID, '&Redo', 
903                               'Redo the previous action')
904        wx.EVT_MENU(self, GUIFRAME_ID.REDO_ID, self.on_redo_panel)
905        self._edit_menu.AppendSeparator()
906        self._edit_menu.Append(GUIFRAME_ID.PREVIEW_ID, '&Report',
907                               'Preview current panel')
908        wx.EVT_MENU(self, GUIFRAME_ID.PREVIEW_ID, self.on_preview_panel)
909        self._edit_menu.Append(GUIFRAME_ID.PRINT_ID, '&Print',
910                               'Print current panel')
911        wx.EVT_MENU(self, GUIFRAME_ID.PRINT_ID, self.on_print_panel)
912        self._edit_menu.Append(GUIFRAME_ID.RESET_ID, '&Reset', 
913                               'Reset current panel')
914        wx.EVT_MENU(self, GUIFRAME_ID.RESET_ID, self.on_reset_panel)
915        self._menubar.Append(self._edit_menu,  '&Edit')
916        self.enable_edit_menu()
917       
918    def get_style(self):
919        """
920        """
921        return  self.__gui_style
922   
923    def _add_menu_data(self):
924        """
925        Add menu item item data to menu bar
926        """
927        if self._data_plugin is not None:
928            menu_list = self._data_plugin.populate_menu(self)
929            if menu_list:
930                for (menu, name) in menu_list:
931                    self._menubar.Append(menu, name)
932           
933    def _on_hide_toolbar(self, event=None):
934        """
935        hide or show toolbar
936        """
937        if self._toolbar is None:
938            return
939        if self._toolbar.IsShown():
940            if self._toolbar_menu is not None:
941                self._toolbar_menu.SetItemLabel('Show Toolbar')
942            self._toolbar.Hide()
943        else:
944            if self._toolbar_menu is not None:
945                self._toolbar_menu.SetItemLabel('Hide Toolbar')
946            self._toolbar.Show()
947        self._toolbar.Realize()
948       
949    def _on_status_event(self, evt):
950        """
951        Display status message
952        """
953        self.sb.set_status(event=evt)
954       
955    def _on_view(self, evt):
956        """
957        A panel was selected to be shown. If it's not already
958        shown, display it.
959       
960        :param evt: menu event
961       
962        """
963        self.show_panel(evt.GetId(), 'on')
964        wx.CallLater(5, self.set_schedule(True))
965       
966    def on_close_welcome_panel(self):
967        """
968        Close the welcome panel
969        """
970        if self.defaultPanel is None:
971            return 
972        default_panel = self._mgr.GetPane(self.panels["default"].window_name)
973        if default_panel.IsShown():
974            default_panel.Hide()
975            # Recover current perspective
976            perspective = self._current_perspective
977            perspective.on_perspective(event=None)
978            self._mgr.Update()
979            # Show toolbar
980            style = self.__gui_style & GUIFRAME.TOOL_ON
981            if (style == GUIFRAME.TOOL_ON) & (not self._toolbar.IsShown()):
982                self._on_hide_toolbar()
983           
984    def show_welcome_panel(self, event):
985        """   
986        Display the welcome panel
987        """
988        if self.defaultPanel is None:
989            return 
990        for id in self.panels.keys():
991            if id  ==  'default':
992                # Show default panel
993                if not self._mgr.GetPane(self.panels["default"].window_name).IsShown():
994                    self._mgr.GetPane(self.panels["default"].window_name).Show(True)
995            elif id == "data_panel":
996                flag = self._mgr.GetPane(self.panels["data_panel"].window_name).IsShown()
997                self._mgr.GetPane(self.panels["data_panel"].window_name).Show(flag)
998            else:
999                self._mgr.GetPane(self.panels[id].window_name).IsShown()
1000                self._mgr.GetPane(self.panels[id].window_name).Hide()
1001            if self._toolbar != None and not self._toolbar.IsShown():
1002                self._toolbar.Show(True)
1003            self._on_hide_toolbar()
1004
1005        self._mgr.Update()
1006       
1007    def show_panel(self, uid, show=None):
1008        """
1009        Shows the panel with the given id
1010       
1011        :param uid: unique ID number of the panel to show
1012       
1013        """
1014        ID = str(uid)
1015        config.printEVT("show_panel: %s" % ID)
1016        if ID in self.panels.keys():
1017            if not self._mgr.GetPane(self.panels[ID].window_name).IsShown(): 
1018                if show == 'on':
1019                    self._mgr.GetPane(self.panels[ID].window_name).Show()   
1020                elif self.panels[ID].window_name.split(" ")[0] == "Residuals":
1021                    self._mgr.GetPane(self.panels[ID].window_name).Hide()
1022                else:
1023                    self._mgr.GetPane(self.panels[ID].window_name).Show()
1024                # Hide default panel
1025                self._mgr.GetPane(self.panels["default"].window_name).Hide()
1026        self._mgr.Update()     
1027        self._redraw_idle()
1028                   
1029    def hide_panel(self, uid):
1030        """
1031        hide panel
1032        """
1033        ID = str(uid)
1034        config.printEVT("hide_panel: %s" % ID)
1035        if ID in self.panels.keys():
1036            if self._mgr.GetPane(self.panels[ID].window_name).IsShown():
1037                self._mgr.GetPane(self.panels[ID].window_name).Hide()
1038                # Hide default panel
1039                self._mgr.GetPane(self.panels["default"].window_name).Hide()
1040            self._mgr.Update()
1041           
1042    def delete_panel(self, uid):
1043        """
1044        delete panel given uid
1045        """
1046        ID = str(uid)
1047        config.printEVT("delete_panel: %s" % ID)
1048       
1049        if ID in self.panels.keys():
1050            panel = self.panels[ID]
1051            self._plotting_plugin.delete_panel(panel.group_id)
1052            self._mgr.DetachPane(panel)
1053            panel.Destroy()
1054            del self.panels[ID]
1055            self._mgr.Update()
1056     
1057    def clear_panel(self):
1058        """
1059        """
1060        for item in self.panels:
1061            try:
1062                self.panels[item].clear_panel()
1063            except:
1064                pass
1065           
1066    def create_gui_data(self, data, path=None):
1067        """
1068        """
1069        return self._data_manager.create_gui_data(data, path)
1070   
1071    def get_data(self, path):
1072        """
1073        """
1074        message = ""
1075        log_msg = ''
1076        output = []
1077        error_message = ""
1078        basename  = os.path.basename(path)
1079        root, extension = os.path.splitext(basename)
1080        if extension.lower() not in EXTENSIONS:
1081            log_msg = "File Loader cannot "
1082            log_msg += "load: %s\n" % str(basename)
1083            log_msg += "Try Data opening...."
1084            logging.info(log_msg)
1085            self.load_complete(output=output, error_message=error_message,
1086                   message=log_msg, path=path)   
1087            return
1088       
1089        #reading a state file
1090        for plug in self.plugins:
1091            reader, ext = plug.get_extensions()
1092            if reader is not None:
1093                #read the state of the single plugin
1094                if extension == ext:
1095                    reader.read(path)
1096                    return
1097                elif extension == APPLICATION_STATE_EXTENSION:
1098                    reader.read(path)
1099       
1100        style = self.__gui_style & GUIFRAME.MANAGER_ON
1101        if style == GUIFRAME.MANAGER_ON:
1102            if self._data_panel is not None:
1103                data_state = self._data_manager.get_selected_data()
1104                self._data_panel.load_data_list(data_state)
1105                self._mgr.GetPane(self._data_panel.window_name).Show(True)
1106     
1107    def load_from_cmd(self,  path):   
1108        """
1109        load data from cmd or application
1110        """ 
1111        if path is None:
1112            return
1113        else:
1114            path = os.path.abspath(path)
1115            if not os.path.isfile(path):
1116               return
1117        basename  = os.path.basename(path)
1118        root, extension = os.path.splitext(basename)
1119        if extension.lower() not in EXTENSIONS:
1120            self.load_data(path)
1121        else:
1122            self.load_state(path)
1123         
1124    def load_state(self, path):   
1125        """
1126        load data from command line or application
1127        """
1128        if path and (path is not None) and os.path.isfile(path):
1129            basename  = os.path.basename(path)
1130            if APPLICATION_STATE_EXTENSION is not None \
1131                and basename.endswith(APPLICATION_STATE_EXTENSION):
1132                #remove panels for new states
1133                for plug in self.plugins:
1134                    reader, ext = plug.get_extensions()
1135                    if ext is not None and ext.strip() != ''\
1136                        and ext.lower() not in EXTENSIONS:
1137                        plug.clear_panel() 
1138            self.panel_on_focus = None   
1139            self.get_data(path)
1140        if self.defaultPanel is not None and \
1141            self._mgr.GetPane(self.panels["default"].window_name).IsShown():
1142            self.on_close_welcome_panel()
1143           
1144    def load_data(self, path):
1145        """
1146        load data from command line
1147        """
1148        if not os.path.isfile(path):
1149            return
1150        basename  = os.path.basename(path)
1151        root, extension = os.path.splitext(basename)
1152        if extension.lower() in EXTENSIONS:
1153            log_msg = "Data Loader cannot "
1154            log_msg += "load: %s\n" % str(path)
1155            log_msg += "Try File opening ...."
1156            print log_msg
1157            return
1158        message = ""
1159        log_msg = ''
1160        output = {}
1161        error_message = ""
1162        try:
1163            print "Loading Data...:\n" + str(path) + "\n"
1164            temp =  self.loader.load(path)
1165            if temp.__class__.__name__ == "list":
1166                for item in temp:
1167                    data = self.create_gui_data(item, path)
1168                    output[data.id] = data
1169            else:
1170                data = self.create_gui_data(temp, path)
1171                output[data.id] = data
1172           
1173            self.add_data(data_list=output)
1174        except:
1175            error_message = "Error while loading"
1176            error_message += " Data from cmd:\n %s\n" % str(path)
1177            error_message += str(sys.exc_value) + "\n"
1178            print error_message
1179           
1180     
1181    def _on_open_state_application(self, event):
1182        """
1183        """
1184        path = None
1185        if self._default_save_location == None:
1186            self._default_save_location = os.getcwd()
1187 
1188        dlg = wx.FileDialog(self, 
1189                            "Choose a file", 
1190                            self._default_save_location, "",
1191                             PLUGINS_WLIST)
1192        if dlg.ShowModal() == wx.ID_OK:
1193            path = dlg.GetPath()
1194            if path is not None:
1195                self._default_save_location = os.path.dirname(path)
1196        dlg.Destroy()
1197        self.load_state(path=path) 
1198           
1199    def _on_open_state_project(self, event):
1200        """
1201        """
1202        path = None
1203        if self._default_save_location == None:
1204            self._default_save_location = os.getcwd()
1205 
1206        dlg = wx.FileDialog(self, 
1207                            "Choose a file", 
1208                            self._default_save_location, "",
1209                             APPLICATION_WLIST)
1210        if dlg.ShowModal() == wx.ID_OK:
1211            path = dlg.GetPath()
1212            if path is not None:
1213                self._default_save_location = os.path.dirname(path)
1214        dlg.Destroy()
1215        self.load_state(path=path)
1216   
1217    def _on_save_application(self, event):
1218        """
1219        save the state of the current active application
1220        """
1221        if self.panel_on_focus is not None:
1222            self.panel_on_focus.on_save(event)
1223           
1224    def _on_save_project(self, event):
1225        """
1226        save the state of the current active application
1227        """
1228        ## Default file location for save
1229        self._default_save_location = os.getcwd()
1230        if self._current_perspective is  None:
1231            return
1232        reader, ext = self._current_perspective.get_extensions()
1233        path = None
1234        dlg = wx.FileDialog(self, "Save Project file",
1235                            self._default_save_location, "",
1236                             APPLICATION_STATE_EXTENSION, 
1237                             wx.SAVE)
1238        if dlg.ShowModal() == wx.ID_OK:
1239            path = dlg.GetPath()
1240            self._default_save_location = os.path.dirname(path)
1241        else:
1242            return None
1243        dlg.Destroy()
1244        if path is None:
1245            return
1246        # default cansas xml doc
1247        doc = None
1248        for panel in self.panels.values():
1249            doc = self.on_save_helper(doc, reader, panel, path)
1250       
1251           
1252    def on_save_helper(self, doc, reader, panel, path):
1253        """
1254        Save state into a file
1255        """
1256        try:
1257            data = panel.get_data()
1258            state = panel.get_state()
1259            if reader is not None:
1260                if data is not None:
1261                    new_doc = reader.write_toXML(data, state)
1262                    if hasattr(doc, "firstChild"):
1263                        child = new_doc.firstChild.firstChild
1264                        doc.firstChild.appendChild(child) 
1265                    else:
1266                        doc = new_doc
1267        except: 
1268            raise
1269            #pass
1270        # Write the XML document
1271        if doc != None:
1272            fd = open(path, 'w')
1273            fd.write(doc.toprettyxml())
1274            fd.close()
1275        else:
1276            msg = "%s cannot read %s\n" % (str(APPLICATION_NAME), str(path))
1277            raise RuntimeError, msg
1278        return doc
1279
1280    def quit_guiframe(self):
1281        """
1282        Pop up message to make sure the user wants to quit the application
1283        """
1284        message = "Do you really want to quit \n"
1285        message += "this application?"
1286        dial = wx.MessageDialog(self, message, 'Question',
1287                           wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
1288        if dial.ShowModal() == wx.ID_YES:
1289            return True
1290        else:
1291            return False   
1292       
1293    def Close(self, event=None):
1294        """
1295        Quit the application
1296        """
1297        #flag = self.quit_guiframe()
1298        if True:
1299            wx.Exit()
1300            sys.exit()
1301
1302    def _check_update(self, event=None): 
1303        """
1304        Check with the deployment server whether a new version
1305        of the application is available.
1306        A thread is started for the connecting with the server. The thread calls
1307        a call-back method when the current version number has been obtained.
1308        """
1309        if hasattr(config, "__update_URL__"):
1310            import version
1311            checker = version.VersionThread(config.__update_URL__,
1312                                            self._process_version,
1313                                            baggage=event==None)
1314            checker.start() 
1315   
1316    def _process_version(self, version, standalone=True):
1317        """
1318        Call-back method for the process of checking for updates.
1319        This methods is called by a VersionThread object once the current
1320        version number has been obtained. If the check is being done in the
1321        background, the user will not be notified unless there's an update.
1322       
1323        :param version: version string
1324        :param standalone: True of the update is being checked in
1325           the background, False otherwise.
1326           
1327        """
1328        try:
1329            if cmp(version, config.__version__) > 0:
1330                msg = "Version %s is available! See the Help "
1331                msg += "menu to download it." % version
1332                self.SetStatusText(msg)
1333                if not standalone:
1334                    import webbrowser
1335                    webbrowser.open(config.__download_page__)
1336            else:
1337                if not standalone:
1338                    msg = "You have the latest version"
1339                    msg += " of %s" % config.__appname__
1340                    self.SetStatusText(msg)
1341        except:
1342            msg = "guiframe: could not get latest application"
1343            msg += " version number\n  %s" % sys.exc_value
1344            logging.error(msg)
1345            if not standalone:
1346                msg = "Could not connect to the application server."
1347                msg += " Please try again later."
1348                self.SetStatusText(msg)
1349                   
1350    def _onAbout(self, evt):
1351        """
1352        Pop up the about dialog
1353       
1354        :param evt: menu event
1355       
1356        """
1357        if config._do_aboutbox:
1358            import aboutbox 
1359            dialog = aboutbox.DialogAbout(None, -1, "")
1360            dialog.ShowModal()           
1361           
1362    def set_manager(self, manager):
1363        """
1364        Sets the application manager for this frame
1365       
1366        :param manager: frame manager
1367        """
1368        self.app_manager = manager
1369       
1370    def post_init(self):
1371        """
1372        This initialization method is called after the GUI
1373        has been created and all plug-ins loaded. It calls
1374        the post_init() method of each plug-in (if it exists)
1375        so that final initialization can be done.
1376        """
1377        for item in self.plugins:
1378            if hasattr(item, "post_init"):
1379                item.post_init()
1380       
1381    def set_default_perspective(self):
1382        """
1383        Choose among the plugin the first plug-in that has
1384        "set_default_perspective" method and its return value is True will be
1385        as a default perspective when the welcome page is closed
1386        """
1387        for item in self.plugins:
1388            if hasattr(item, "set_default_perspective"):
1389                if item.set_default_perspective():
1390                    item.on_perspective(event=None)
1391                    return 
1392       
1393    def set_perspective(self, panels):
1394        """
1395        Sets the perspective of the GUI.
1396        Opens all the panels in the list, and closes
1397        all the others.
1398       
1399        :param panels: list of panels
1400        """
1401        style = self.__gui_style & GUIFRAME.TOOL_ON
1402        if (style == GUIFRAME.TOOL_ON) & (not self._toolbar.IsShown()):
1403            self._on_hide_toolbar()
1404        for item in self.panels:
1405            # Check whether this is a sticky panel
1406            if hasattr(self.panels[item], "ALWAYS_ON"):
1407                if self.panels[item].ALWAYS_ON:
1408                    continue 
1409           
1410            if self.panels[item].window_name in panels:
1411                if not self._mgr.GetPane(self.panels[item].window_name).IsShown():
1412                    self._mgr.GetPane(self.panels[item].window_name).Show()
1413            else:
1414                # always show the data panel if enable
1415                style = self.__gui_style & GUIFRAME.MANAGER_ON
1416                if (style == GUIFRAME.MANAGER_ON) and self.panels[item] == self._data_panel:
1417                    if 'data_panel' in self.panels.keys():
1418                        flag = self._mgr.GetPane(self.panels['data_panel'].window_name).IsShown()
1419                        self._mgr.GetPane(self.panels['data_panel'].window_name).Show(flag)
1420                else:
1421                    if self._mgr.GetPane(self.panels[item].window_name).IsShown():
1422                        self._mgr.GetPane(self.panels[item].window_name).Hide()
1423               
1424        self._mgr.Update()
1425       
1426    def show_data_panel(self, event=None, action=True):
1427        """
1428        show the data panel
1429        """
1430        if self._data_panel_menu == None:
1431            return
1432        label = self._data_panel_menu.GetText()
1433        if label == 'Data Explorer ON':
1434            pane = self._mgr.GetPane(self.panels["data_panel"].window_name)
1435            #if not pane.IsShown():
1436            if action: 
1437                pane.Show(True)
1438                self._mgr.Update()
1439            self.__gui_style = self.__gui_style | GUIFRAME.MANAGER_ON
1440           
1441            self._data_panel_menu.SetText('Data Explorer OFF')
1442        else:
1443            pane = self._mgr.GetPane(self.panels["data_panel"].window_name)
1444            #if not pane.IsShown():
1445            if action:
1446                pane.Show(False)
1447                self._mgr.Update()
1448            self.__gui_style = self.__gui_style & (~GUIFRAME.MANAGER_ON)
1449            self._data_panel_menu.SetText('Data Explorer ON')
1450   
1451    def add_data_helper(self, data_list):
1452        """
1453        """
1454        if self._data_manager is not None:
1455            self._data_manager.add_data(data_list)
1456       
1457    def add_data(self, data_list):
1458        """
1459        receive a dictionary of data from loader
1460        store them its data manager if possible
1461        send to data the current active perspective if the data panel
1462        is not active.
1463        :param data_list: dictionary of data's ID and value Data
1464        """
1465        #Store data into manager
1466        self.add_data_helper(data_list)
1467        # set data in the data panel
1468        if self._data_panel is not None:
1469            data_state = self._data_manager.get_data_state(data_list.keys())
1470            self._data_panel.load_data_list(data_state)
1471        #if the data panel is shown wait for the user to press a button
1472        #to send data to the current perspective. if the panel is not
1473        #show  automatically send the data to the current perspective
1474        style = self.__gui_style & GUIFRAME.MANAGER_ON
1475        if style == GUIFRAME.MANAGER_ON:
1476            #wait for button press from the data panel to set_data
1477            if self._data_panel is not None:
1478                self._mgr.GetPane(self._data_panel.window_name).Show(True)
1479                self._mgr.Update() 
1480        else:
1481            #automatically send that to the current perspective
1482            self.set_data(data_id=data_list.keys())
1483            self.on_close_welcome_panel()
1484       
1485    def set_data(self, data_id): 
1486        """
1487        set data to current perspective
1488        """
1489        list_data, _ = self._data_manager.get_by_id(data_id)
1490        if self._current_perspective is not None:
1491            self._current_perspective.set_data(list_data.values())
1492            self.on_close_welcome_panel()
1493        else:
1494            msg = "Guiframe does not have a current perspective"
1495            logging.info(msg)
1496           
1497    def set_theory(self, state_id, theory_id=None):
1498        """
1499        """
1500        _, list_theory = self._data_manager.get_by_id(theory_id)
1501        if self._current_perspective is not None:
1502            try:
1503                self._current_perspective.set_theory(list_theory.values())
1504            except:
1505                msg = "Guiframe set_theory: \n" + str(sys.exc_value)
1506                logging.info(msg)
1507                wx.PostEvent(self, StatusEvent(status=msg, info="error"))
1508        else:
1509            msg = "Guiframe does not have a current perspective"
1510            logging.info(msg)
1511           
1512    def plot_data(self,  state_id, data_id=None,
1513                  theory_id=None, append=False):
1514        """
1515        send a list of data to plot
1516        """
1517        total_plot_list = []
1518        data_list, _ = self._data_manager.get_by_id(data_id)
1519        _, temp_list_theory = self._data_manager.get_by_id(theory_id)
1520        total_plot_list = data_list.values()
1521        for item in temp_list_theory.values():
1522            theory_data, theory_state = item
1523            total_plot_list.append(theory_data)
1524        GROUP_ID = wx.NewId()
1525        for new_plot in total_plot_list:
1526            if append:
1527                if self.panel_on_focus is None:
1528                    message = "cannot append plot. No plot panel on focus!"
1529                    message += "please click on any available plot to set focus"
1530                    wx.PostEvent(self, StatusEvent(status=message, 
1531                                                   info='warning'))
1532                    return 
1533                else:
1534                    if self.enable_add_data(new_plot):
1535                        new_plot.group_id = self.panel_on_focus.group_id
1536                    else:
1537                        message = "Only 1D Data can be append to plot panel\n"
1538                        message += "%s will be plot separetly\n" %str(new_plot.name)
1539                        wx.PostEvent(self, StatusEvent(status=message, 
1540                                                   info='warning'))
1541            else:
1542                #if not append then new plot
1543                new_plot.group_id = GROUP_ID
1544            title = "PLOT " + str(new_plot.title)
1545            wx.PostEvent(self, NewPlotEvent(plot=new_plot,
1546                                                  title=title))
1547           
1548    def remove_data(self, data_id, theory_id=None):
1549        """
1550        Delete data state if data_id is provide
1551        delete theory created with data of id data_id if theory_id is provide
1552        if delete all true: delete the all state
1553        else delete theory
1554        """
1555        for plug in self.plugins:
1556            plug.delete_data(data_id)
1557        total_plot_list = []
1558        data_list, _ = self._data_manager.get_by_id(data_id)
1559        _, temp_list_theory = self._data_manager.get_by_id(theory_id)
1560        total_plot_list = data_list.values()
1561        for item in temp_list_theory.values():
1562            theory_data, theory_state = item
1563            total_plot_list.append(theory_data)
1564        for new_plot in total_plot_list:
1565            id = new_plot.id
1566            for group_id in new_plot.list_group_id:
1567                wx.PostEvent(self, NewPlotEvent(id=id,
1568                                                   group_id=group_id,
1569                                                   action='remove'))
1570        self._data_manager.delete_data(data_id=data_id, 
1571                                       theory_id=theory_id)
1572           
1573       
1574    def set_current_perspective(self, perspective):
1575        """
1576        set the current active perspective
1577        """
1578        self._current_perspective = perspective
1579        name = "No current Application selected"
1580        if self._current_perspective is not None:
1581            self._add_current_plugin_menu()
1582            for panel in self.panels.values():
1583                if hasattr(panel, 'CENTER_PANE') and panel.CENTER_PANE:
1584                    for name in self._current_perspective.get_perspective():
1585                        if name == panel.window_name:
1586                            panel.on_set_focus(event=None)
1587                            break
1588                           
1589            name = self._current_perspective.sub_menu
1590            if self._data_panel is not None:
1591                self._data_panel.set_active_perspective(name)
1592                self._check_applications_menu()
1593            #Set the SansView title
1594            self._set_title_name(name)
1595           
1596           
1597    def _set_title_name(self, name):
1598        """
1599        Set the SansView title w/ the current application name
1600       
1601        : param name: application name [string]
1602        """
1603        # Set SanView Window title w/ application anme
1604        title = self.title + "  - " + name + " -"
1605        self.SetTitle(title)
1606           
1607    def _check_applications_menu(self):
1608        """
1609        check the menu of the current application
1610        """
1611        if self._applications_menu is not None:
1612            for menu in self._applications_menu.GetMenuItems():
1613                if self._current_perspective is not None:
1614                    name = self._current_perspective.sub_menu
1615                    if menu.IsCheckable():
1616                        if menu.GetLabel() == name:
1617                            menu.Check(True)
1618                        else:
1619                             menu.Check(False) 
1620           
1621    def set_plotpanel_floating(self, event=None):
1622        """
1623        make the plot panel floatable
1624        """
1625        self.__gui_style &= (~GUIFRAME.FIXED_PANEL)
1626        self.__gui_style |= GUIFRAME.FLOATING_PANEL
1627        for p in self.panels.values():
1628            plot_panel = self._plotting_plugin.plot_panels.values()
1629            for p in self.panels.values():
1630                if p in plot_panel:
1631                    self._popup_floating_panel(p)
1632       
1633    def set_plotpanel_fixed(self, event=None):
1634        """
1635        make the plot panel fixed
1636        """
1637        self.__gui_style &= (~GUIFRAME.FLOATING_PANEL)
1638        self.__gui_style |= GUIFRAME.FIXED_PANEL
1639        plot_panel = []
1640        if self._plotting_plugin is not None:
1641            plot_panel = self._plotting_plugin.plot_panels.values()
1642            for p in self.panels.values():
1643                if p in plot_panel:
1644                    self._popup_fixed_panel(p)
1645                   
1646    def _popup_fixed_panel(self, p):
1647        """
1648        """
1649        style = self.__gui_style & GUIFRAME.FIXED_PANEL
1650        if style == GUIFRAME.FIXED_PANEL:
1651            self._mgr.GetPane(p.window_name).Floatable()
1652            self._mgr.GetPane(p.window_name).Right()
1653            self._mgr.GetPane(p.window_name).TopDockable(False)
1654            self._mgr.GetPane(p.window_name).BottomDockable(False)
1655            self._mgr.GetPane(p.window_name).LeftDockable(False)
1656            self._mgr.GetPane(p.window_name).RightDockable(True)
1657            flag = self._mgr.GetPane(p.window_name).IsShown()
1658            self._mgr.GetPane(p.window_name).Show(flag)
1659            self._mgr.Update()
1660           
1661    def _popup_floating_panel(self, p):
1662        """
1663        """
1664        style = self.__gui_style &  GUIFRAME.FLOATING_PANEL
1665        if style == GUIFRAME.FLOATING_PANEL: 
1666            self._mgr.GetPane(p.window_name).Floatable(True)
1667            self._mgr.GetPane(p.window_name).Float()
1668            self._mgr.GetPane(p.window_name).Dockable(False)
1669            flag = self._mgr.GetPane(p.window_name).IsShown()
1670            self._mgr.GetPane(p.window_name).Show(flag)
1671            self._mgr.Update()
1672           
1673    def enable_add_data(self, new_plot):
1674        """
1675        Enable append data on a plot panel
1676        """
1677        if self.panel_on_focus not in self._plotting_plugin.plot_panels.values():
1678            return
1679        is_theory = len(self.panel_on_focus.plots) <= 1 and \
1680            self.panel_on_focus.plots.values()[0].__class__.__name__ == "Theory1D"
1681           
1682        is_data2d = hasattr(new_plot, 'data')
1683        is_data1d = self.panel_on_focus.__class__.__name__ == "ModelPanel1D"\
1684            and self.panel_on_focus.group_id is not None
1685        has_meta_data = hasattr(new_plot, 'meta_data')
1686       
1687        #disable_add_data if the data is being recovered from  a saved state file.
1688        is_state_data = False
1689        if has_meta_data:
1690            if 'invstate' in new_plot.meta_data: is_state_data = True
1691            if  'prstate' in new_plot.meta_data: is_state_data = True
1692            if  'fitstate' in new_plot.meta_data: is_state_data = True
1693   
1694        return is_data1d and not is_data2d and not is_theory and not is_state_data
1695   
1696    def enable_edit_menu(self):
1697        """
1698        enable menu item under edit menu depending on the panel on focus
1699        """
1700        if self.panel_on_focus is not None and self._edit_menu is not None:
1701            flag = self.panel_on_focus.get_undo_flag()
1702            self._edit_menu.Enable(GUIFRAME_ID.UNDO_ID, flag)
1703            flag = self.panel_on_focus.get_redo_flag()
1704            self._edit_menu.Enable(GUIFRAME_ID.REDO_ID, flag)
1705            flag = self.panel_on_focus.get_print_flag()
1706            self._edit_menu.Enable(GUIFRAME_ID.PRINT_ID, flag)
1707            flag = self.panel_on_focus.get_preview_flag()
1708            self._edit_menu.Enable(GUIFRAME_ID.PREVIEW_ID, flag)
1709            flag = self.panel_on_focus.get_reset_flag()
1710            self._edit_menu.Enable(GUIFRAME_ID.RESET_ID, flag)
1711        else:
1712            flag = False
1713            self._edit_menu.Enable(GUIFRAME_ID.UNDO_ID, flag)
1714            self._edit_menu.Enable(GUIFRAME_ID.REDO_ID, flag)
1715            self._edit_menu.Enable(GUIFRAME_ID.PRINT_ID, flag)
1716            self._edit_menu.Enable(GUIFRAME_ID.PREVIEW_ID, flag)
1717            self._edit_menu.Enable(GUIFRAME_ID.RESET_ID, flag)
1718           
1719    def on_undo_panel(self, event=None):
1720        """
1721        undo previous action of the last panel on focus if possible
1722        """
1723        if self.panel_on_focus is not None:
1724            self.panel_on_focus.on_undo(event)
1725           
1726    def on_redo_panel(self, event=None):
1727        """
1728        redo the last cancel action done on the last panel on focus
1729        """
1730        if self.panel_on_focus is not None:
1731            self.panel_on_focus.on_redo(event)
1732           
1733    def on_bookmark_panel(self, event=None):
1734        """
1735        bookmark panel
1736        """
1737        if self.panel_on_focus is not None:
1738            self.panel_on_focus.on_bookmark(event)
1739           
1740    def append_bookmark(self, event=None):
1741        """
1742        Bookmark available information of the panel on focus
1743        """
1744        self._toolbar.append_bookmark(event)
1745           
1746    def on_save_panel(self, event=None):
1747        """
1748        save possible information on the current panel
1749        """
1750        if self.panel_on_focus is not None:
1751            self.panel_on_focus.on_save(event)
1752           
1753    def on_preview_panel(self, event=None):
1754        """
1755        preview information on the panel on focus
1756        """
1757        if self.panel_on_focus is not None:
1758            self.panel_on_focus.on_preview(event)
1759           
1760    def on_print_panel(self, event=None):
1761        """
1762        print available information on the last panel on focus
1763        """
1764        if self.panel_on_focus is not None:
1765            self.panel_on_focus.on_print(event)
1766           
1767    def on_zoom_panel(self, event=None):
1768        """
1769        zoom on the current panel if possible
1770        """
1771        if self.panel_on_focus is not None:
1772            self.panel_on_focus.on_zoom(event)
1773           
1774    def on_zoom_in_panel(self, event=None):
1775        """
1776        zoom in of the panel on focus
1777        """
1778        if self.panel_on_focus is not None:
1779            self.panel_on_focus.on_zoom_in(event)
1780           
1781    def on_zoom_out_panel(self, event=None):
1782        """
1783        zoom out on the panel on focus
1784        """
1785        if self.panel_on_focus is not None:
1786            self.panel_on_focus.on_zoom_out(event)
1787           
1788    def on_drag_panel(self, event=None):
1789        """
1790        drag apply to the panel on focus
1791        """
1792        if self.panel_on_focus is not None:
1793            self.panel_on_focus.on_drag(event)
1794           
1795    def on_reset_panel(self, event=None):
1796        """
1797        reset the current panel
1798        """
1799        if self.panel_on_focus is not None:
1800            self.panel_on_focus.on_reset(event)
1801           
1802    def enable_undo(self):
1803        """
1804        enable undo related control
1805        """
1806        if self.panel_on_focus is not None:
1807            self._toolbar.enable_undo(self.panel_on_focus)
1808           
1809    def enable_redo(self):
1810        """
1811        enable redo
1812        """
1813        if self.panel_on_focus is not None:
1814            self._toolbar.enable_redo(self.panel_on_focus)
1815           
1816    def enable_bookmark(self):
1817        """
1818        Bookmark
1819        """
1820        if self.panel_on_focus is not None:
1821            self._toolbar.enable_bookmark(self.panel_on_focus)
1822           
1823    def enable_save(self):
1824        """
1825        save
1826        """
1827        if self.panel_on_focus is not None:
1828            self._toolbar.enable_save(self.panel_on_focus)
1829           
1830    def enable_preview(self):
1831        """
1832        preview
1833        """
1834        if self.panel_on_focus is not None:
1835            self._toolbar.enable_preview(self.panel_on_focus)
1836           
1837    def enable_print(self):
1838        """
1839        print
1840        """
1841        if self.panel_on_focus is not None:
1842            self._toolbar.enable_print(self.panel_on_focus)
1843           
1844    def enable_zoom(self):
1845        """
1846        zoom
1847        """
1848        if self.panel_on_focus is not None:
1849            self._toolbar.enable_zoom(self.panel_on_focus)
1850           
1851    def enable_zoom_in(self):
1852        """
1853        zoom in
1854        """
1855        if self.panel_on_focus is not None:
1856            self._toolbar.enable_zoom_in(self.panel_on_focus)
1857           
1858    def enable_zoom_out(self):
1859        """
1860        zoom out
1861        """
1862        if self.panel_on_focus is not None:
1863            self._toolbar.enable_zoom_out(self.panel_on_focus)
1864           
1865    def enable_drag(self, event=None):
1866        """
1867        drag
1868        """
1869        if self.panel_on_focus is not None:
1870            self._toolbar.enable_drag(self.panel_on_focus)
1871           
1872    def enable_reset(self):
1873        """
1874        reset the current panel
1875        """
1876        if self.panel_on_focus is not None:
1877            self._toolbar.enable_reset(self.panel_on_focus)
1878
1879    def set_schedule_full_draw(self, panel=None, func='del'):
1880        """
1881        Add/subtract the schedule full draw list with the panel given
1882       
1883        :param panel: plot panel
1884        :param func: append or del [string]
1885        """
1886
1887        # append this panel in the schedule list if not in yet
1888        if func == 'append':
1889            if not panel in self.schedule_full_draw_list:
1890                self.schedule_full_draw_list.append(panel) 
1891        # remove this panel from schedule list
1892        elif func == 'del':
1893            if len(self.schedule_full_draw_list) > 0:
1894                if panel in self.schedule_full_draw_list:
1895                    self.schedule_full_draw_list.remove(panel)
1896
1897        # reset the schdule
1898        if len(self.schedule_full_draw_list) == 0:
1899            self.schedule = False
1900        else:
1901            self.schedule = True   
1902       
1903    def full_draw(self):
1904        """
1905        Draw the panels with axes in the schedule to full dwar list
1906        """
1907        count = len(self.schedule_full_draw_list)
1908        #if not self.schedule:
1909        if count < 1:
1910            self.set_schedule(False)
1911            return
1912        else:
1913            ind = 0
1914            # if any of the panel is shown do full_draw
1915            for panel in self.schedule_full_draw_list:
1916                ind += 1
1917                if self._mgr.GetPane(panel.window_name).IsShown():
1918                    break
1919                # otherwise, return
1920                if ind == count:
1921                    return
1922
1923        #Simple redraw only for a panel shown
1924        def f_draw(panel):
1925            """
1926            Draw A panel in the full dwar list
1927            """
1928            # Check if the panel is shown
1929            if self._mgr.GetPane(panel.window_name).IsShown():
1930                try:
1931                    # This checking of GetCapture is to stop redrawing
1932                    # while any panel is capture.
1933                    if self.GetCapture() == None:
1934                        # draw if possible
1935                        panel.set_resizing(False)
1936                        panel.draw_plot()
1937                except:
1938                    pass
1939        #print self.callback,self.schedule,self.schedule_full_draw_list
1940       
1941        # Draw all panels       
1942        map(f_draw, self.schedule_full_draw_list)
1943       
1944        # Reset the attr 
1945        if len(self.schedule_full_draw_list) == 0:
1946            self.set_schedule(False)
1947        else:
1948            self.set_schedule(True)
1949        # update mgr
1950        self._mgr.Update()
1951       
1952    def set_schedule(self, schedule=False): 
1953        """
1954        Set schedule
1955        """
1956        self.schedule = schedule
1957               
1958    def get_schedule(self): 
1959        """
1960        Get schedule
1961        """
1962        return self.schedule
1963   
1964       
1965    def _onDrawIdle(self, *args, **kwargs):
1966        """
1967        ReDraw with axes
1968        """
1969        # check if it is time to redraw
1970        if self.GetCapture() == None:
1971            # Draw plot, changes resizing too
1972            self.full_draw()
1973           
1974        # restart idle       
1975        self._redraw_idle(*args, **kwargs)
1976
1977           
1978    def _redraw_idle(self, *args, **kwargs):
1979        """
1980        Restart Idle
1981        """
1982        # restart idle   
1983        self.idletimer.Restart(55, *args, **kwargs)
1984
1985       
1986class DefaultPanel(wx.Panel, PanelBase):
1987    """
1988    Defines the API for a panels to work with
1989    the GUI manager
1990    """
1991    ## Internal nickname for the window, used by the AUI manager
1992    window_name = "default"
1993    ## Name to appear on the window title bar
1994    window_caption = "Welcome panel"
1995    ## Flag to tell the AUI manager to put this panel in the center pane
1996    CENTER_PANE = True
1997    def __init__(self, parent, *args, **kwds):
1998        wx.Panel.__init__(self, parent, *args, **kwds)
1999        PanelBase.__init__(self, parent)
2000   
2001
2002
2003# Toy application to test this Frame
2004class ViewApp(wx.App):
2005    """
2006    """
2007    def OnInit(self):
2008        """
2009        """
2010        pos, size = self.window_placement((GUIFRAME_WIDTH, GUIFRAME_HEIGHT))
2011        self.frame = ViewerFrame(parent=None, 
2012                                 title=APPLICATION_NAME, 
2013                                 pos=pos, 
2014                                 gui_style = DEFAULT_STYLE,
2015                                 size=size) 
2016        self.s_screen = None
2017        # Display a splash screen on top of the frame.
2018        if len(sys.argv) > 1 and '--time' in sys.argv[1:]:
2019            log_time("Starting to display the splash screen")
2020       
2021        try:
2022            if os.path.isfile(SPLASH_SCREEN_PATH):
2023                self.s_screen = self.display_splash_screen(parent=self.frame, 
2024                                        path=SPLASH_SCREEN_PATH)
2025            else:
2026                self.frame.Show()   
2027        except:
2028           msg = "Cannot display splash screen\n"
2029           msg += str (sys.exc_value)
2030           logging.error(msg)
2031           self.frame.Show()
2032           
2033        if hasattr(self.frame, 'special'):
2034            self.frame.special.SetCurrent()
2035        self.SetTopWindow(self.frame)
2036        try:
2037            self.open_file()
2038        except:
2039            msg = "%s Could not load " % str(APPLICATION_NAME)
2040            msg += "input file from command line.\n"
2041            logging.error(msg)
2042        return True
2043
2044    def open_file(self):
2045        """
2046        open a state file at the start of the application
2047        """
2048        input_file = None
2049        if len(sys.argv) >= 2:
2050            cmd = sys.argv[0].lower()
2051            if os.path.isfile(cmd):
2052                basename  = os.path.basename(cmd)
2053                app_py = str(APPLICATION_NAME).lower() + '.py'
2054                app_exe = str(APPLICATION_NAME).lower() + '.exe'
2055                if basename.lower() in [app_py, app_exe]:
2056                    input_file = sys.argv[1]
2057        if input_file is None:
2058            return
2059        if self.frame is not None:
2060            self.frame.set_input_file(input_file=input_file)
2061         
2062           
2063    def set_manager(self, manager):
2064        """
2065        Sets a reference to the application manager
2066        of the GUI manager (Frame)
2067        """
2068        self.frame.set_manager(manager)
2069       
2070    def build_gui(self):
2071        """
2072        Build the GUI
2073        """
2074        #try to load file at the start
2075        try:
2076            self.open_file()
2077        except:
2078            raise
2079        self.frame.build_gui()
2080        if self.s_screen is not None and self.s_screen.IsShown():
2081            self.s_screen.Close()
2082       
2083    def set_welcome_panel(self, panel_class):
2084        """
2085        Set the welcome panel
2086       
2087        :param panel_class: class of the welcome panel to be instantiated
2088       
2089        """
2090        self.frame.set_welcome_panel(panel_class)
2091       
2092    def add_perspective(self, perspective):
2093        """
2094        Manually add a perspective to the application GUI
2095        """
2096        self.frame.add_perspective(perspective)
2097   
2098    def window_placement(self, size):
2099        """
2100        Determines the position and size of the application frame such that it
2101        fits on the user's screen without obstructing (or being obstructed by)
2102        the Windows task bar.  The maximum initial size in pixels is bounded by
2103        WIDTH x HEIGHT.  For most monitors, the application
2104        will be centered on the screen; for very large monitors it will be
2105        placed on the left side of the screen.
2106        """
2107        window_width, window_height = size
2108        screen_size = wx.GetDisplaySize()
2109        window_height = window_height if screen_size[1]>window_height else screen_size[1]-50
2110        window_width  = window_width if screen_size[0]> window_width else screen_size[0]-50
2111        xpos = ypos = 0
2112
2113        # Note that when running Linux and using an Xming (X11) server on a PC
2114        # with a dual  monitor configuration, the reported display size may be
2115        # that of both monitors combined with an incorrect display count of 1.
2116        # To avoid displaying this app across both monitors, we check for
2117        # screen 'too big'.  If so, we assume a smaller width which means the
2118        # application will be placed towards the left hand side of the screen.
2119
2120        _, _, x, y = wx.Display().GetClientArea() # size excludes task bar
2121        if len(sys.argv) > 1 and '--platform' in sys.argv[1:]:
2122            w, h = wx.DisplaySize()  # size includes task bar area
2123        if x > 1920: x = 1280  # display on left side, not centered on screen
2124        if x > window_width:  xpos = (x - window_width)/2
2125        if y > window_height: ypos = (y - window_height)/2
2126
2127        # Return the suggested position and size for the application frame.
2128        return (xpos, ypos), (min(x, window_width), min(y, window_height))
2129   
2130    def display_splash_screen(self, parent, 
2131                              path=SPLASH_SCREEN_PATH):
2132        """Displays the splash screen.  It will exactly cover the main frame."""
2133       
2134        # Prepare the picture.  On a 2GHz intel cpu, this takes about a second.
2135        x, y = parent.GetSizeTuple()
2136        image = wx.Image(path, wx.BITMAP_TYPE_PNG)
2137        image.Rescale(SPLASH_SCREEN_WIDTH, 
2138                      SPLASH_SCREEN_HEIGHT, wx.IMAGE_QUALITY_HIGH)
2139        bm = image.ConvertToBitmap()
2140
2141        # Create and show the splash screen.  It will disappear only when the
2142        # program has entered the event loop AND either the timeout has expired
2143        # or the user has left clicked on the screen.  Thus any processing
2144        # performed in this routine (including sleeping) or processing in the
2145        # calling routine (including doing imports) will prevent the splash
2146        # screen from disappearing.
2147        #
2148        # Note that on Linux, the timeout appears to occur immediately in which
2149        # case the splash screen disappears upon entering the event loop.
2150        s_screen = wx.SplashScreen(bitmap=bm,
2151                         splashStyle=(wx.SPLASH_TIMEOUT|
2152                                              wx.SPLASH_CENTRE_ON_SCREEN),
2153                                 style=(wx.SIMPLE_BORDER|
2154                                        wx.FRAME_NO_TASKBAR|
2155                                        wx.STAY_ON_TOP),
2156                                       
2157                        milliseconds=SS_MAX_DISPLAY_TIME,
2158                        parent=parent,
2159                        id=wx.ID_ANY)
2160
2161        s_screen.Bind(wx.EVT_CLOSE, self.on_close_splash_screen)
2162        s_screen.Show()
2163        return s_screen
2164       
2165       
2166    def on_close_splash_screen(self, event):
2167        """
2168        """
2169        self.frame.Show(True)
2170        event.Skip()
2171     
2172if __name__ == "__main__": 
2173    app = ViewApp(0)
2174    app.MainLoop()
2175
2176             
Note: See TracBrowser for help on using the repository browser.