source: sasview/guiframe/gui_manager.py @ 6ac1cf5

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 6ac1cf5 was 24adb89, checked in by Gervaise Alina <gervyh@…>, 13 years ago

working on guiframe in batch mode

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