source: sasview/guiframe/gui_manager.py @ cb26857

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 cb26857 was 60c7011, checked in by Jae Cho <jhjcho@…>, 13 years ago

added tutorial viewer

  • Property mode set to 100644
File size: 104.0 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_tutorial:
948            self._help_menu.AppendSeparator()
949            id = wx.NewId()
950            self._help_menu.Append(id,'&Tutorial', 'Software tutorial')
951            wx.EVT_MENU(self, id, self._onTutorial)
952           
953        if config._do_aboutbox:
954            self._help_menu.AppendSeparator()
955            id = wx.NewId()
956            self._help_menu.Append(id,'&About', 'Software information')
957            wx.EVT_MENU(self, id, self._onAbout)
958       
959        # Checking for updates needs major refactoring to work with py2exe
960        # We need to make sure it doesn't hang the application if the server
961        # is not up. We also need to make sure there's a proper executable to
962        # run if we spawn a new background process.
963        #id = wx.NewId()
964        #self._help_menu.Append(id,'&Check for update',
965        #'Check for the latest version of %s' % config.__appname__)
966        #wx.EVT_MENU(self, id, self._check_update)
967        self._menubar.Append(self._help_menu, '&Help')
968           
969    def _add_menu_view(self):
970        """
971        add menu items under view menu
972        """
973        self._view_menu = wx.Menu()
974        style = self.__gui_style & GUIFRAME.MANAGER_ON
975        id = wx.NewId()
976        self._data_panel_menu = self._view_menu.Append(id,
977                                                '&Show Data Explorer', '')
978        wx.EVT_MENU(self, id, self.show_data_panel)
979        if style == GUIFRAME.MANAGER_ON:
980            self._data_panel_menu.SetText('Hide Data Explorer')
981        else:
982            self._data_panel_menu.SetText('Show Data Explorer')
983        self._view_menu.AppendSeparator()
984        id = wx.NewId()
985        style1 = self.__gui_style & GUIFRAME.TOOLBAR_ON
986        if style1 == GUIFRAME.TOOLBAR_ON:
987            self._toolbar_menu = self._view_menu.Append(id,'&Hide Toolbar', '')
988        else:
989            self._toolbar_menu = self._view_menu.Append(id,'&Show Toolbar', '')
990        wx.EVT_MENU(self, id, self._on_toggle_toolbar)
991       
992        if custom_config != None:
993            self._view_menu.AppendSeparator()
994            id = wx.NewId()
995            preference_menu = self._view_menu.Append(id,'Startup Setting', '')
996            wx.EVT_MENU(self, id, self._on_preference_menu)
997           
998        self._menubar.Append(self._view_menu, '&View')   
999         
1000    def _on_preference_menu(self, event):     
1001        """
1002        Build a panel to allow to edit Mask
1003        """
1004       
1005        from sans.guiframe.startup_configuration \
1006        import StartupConfiguration as ConfDialog
1007       
1008        self.panel = ConfDialog(parent=self, gui=self.__gui_style)
1009        self.panel.ShowModal()
1010        #wx.PostEvent(self.parent, event)
1011       
1012
1013    def _add_menu_window(self):
1014        """
1015        add a menu window to the menu bar
1016        Window menu
1017        Attach a menu item for each panel in our
1018        panel list that also appears in a plug-in.
1019       
1020        Only add the panel menu if there is only one perspective and
1021        it has more than two panels.
1022        Note: the first plug-in is always the plotting plug-in.
1023        The first application
1024        #plug-in is always the second one in the list.
1025        """
1026        self._window_menu = wx.Menu()
1027        if self._plotting_plugin is not None:
1028            for (menu, name) in self._plotting_plugin.populate_menu(self):
1029                self._window_menu.AppendSubMenu(menu, name)
1030        self._menubar.Append(self._window_menu, '&Graph')
1031
1032        style = self.__gui_style & GUIFRAME.PLOTTING_ON
1033        if style == GUIFRAME.PLOTTING_ON:
1034            self._window_menu.AppendSeparator()
1035            id = wx.NewId()
1036            preferences_menu = wx.Menu()
1037            hint = "All plot panels will floating"
1038            preferences_menu.AppendRadioItem(id, '&Float All', hint)
1039            wx.EVT_MENU(self, id, self.set_plotpanel_floating)
1040            style = self.__gui_style & GUIFRAME.FLOATING_PANEL
1041            f_menu = preferences_menu.FindItemById(id)
1042            if style == GUIFRAME.FLOATING_PANEL: 
1043                f_checked = True
1044            else:
1045                f_checked = False
1046            f_menu.Check(f_checked)
1047
1048            id = wx.NewId()
1049            hint = "All plot panels will displayed within the frame"
1050            preferences_menu.AppendRadioItem(id, '&Dock All', hint)
1051            wx.EVT_MENU(self, id, self.set_plotpanel_fixed) 
1052            if not f_checked:
1053                d_menu = preferences_menu.FindItemById(id)
1054                d_menu.Check(True)
1055            preferences_menu.AppendSeparator()
1056            id = wx.NewId()
1057            hint = "Clean up the dock area for plots on new-plot"
1058            preferences_menu.AppendCheckItem(id, '&CleanUp Dock on NewPlot', hint)
1059            wx.EVT_MENU(self, id, self.on_cleanup_dock)
1060            flag = self.cleanup_plots
1061            if self.cleanup_plots:
1062                c_menu = preferences_menu.FindItemById(id)
1063                c_menu.Check(True) 
1064            self._window_menu.AppendSubMenu(preferences_menu,'&Preferences')
1065        if self._window_menu.GetMenuItemCount() == 0:
1066            pos = self._menubar.FindMenu('Graph')
1067            self._menubar.Remove(pos)
1068        #wx.EVT_MENU(self, id, self.show_preferences_panel)   
1069        """
1070        if len(self.plugins) == 2:
1071            plug = self.plugins[1]
1072            pers = plug.get_perspective()
1073       
1074            if len(pers) > 1:
1075                self._window_menu = wx.Menu()
1076                for item in self.panels:
1077                    if item == 'default':
1078                        continue
1079                    panel = self.panels[item]
1080                    if panel.window_name in pers:
1081                        self._window_menu.Append(int(item),
1082                                                  panel.window_caption,
1083                                        "Show %s window" % panel.window_caption)
1084                        wx.EVT_MENU(self, int(item), self.on_view)
1085                self._menubar.Append(self._window_menu, '&Window')
1086                """
1087
1088               
1089    def _add_menu_application(self):
1090        """
1091       
1092        # Attach a menu item for each defined perspective or application.
1093        # Only add the perspective menu if there are more than one perspectives
1094        add menu application
1095        """
1096        #style = self.__gui_style & GUIFRAME.MULTIPLE_APPLICATIONS
1097        #if style == GUIFRAME.MULTIPLE_APPLICATIONS:
1098        if self._num_perspectives  > 1:
1099            plug_data_count = False
1100            plug_no_data_count = False
1101            self._applications_menu = wx.Menu()
1102            pos = 0
1103            separator = self._applications_menu.AppendSeparator()
1104            for plug in self.plugins:
1105                if len(plug.get_perspective()) > 0:
1106                    id = wx.NewId()
1107                    if plug.use_data():
1108                       
1109                        self._applications_menu.InsertCheckItem(pos, id, plug.sub_menu,
1110                                      "Switch to analysis: %s" % plug.sub_menu)
1111                        plug_data_count = True
1112                        pos += 1
1113                    else:
1114                        plug_no_data_count = True
1115                        self._applications_menu.AppendCheckItem(id, plug.sub_menu,
1116                                      "Switch to analysis: %s" % plug.sub_menu)
1117                    wx.EVT_MENU(self, id, plug.on_perspective)
1118            #self._applications_menu.
1119            if (not plug_data_count or not plug_no_data_count):
1120                self._applications_menu.RemoveItem(separator)
1121            self._menubar.Append(self._applications_menu, '&Analysis')
1122            self._check_applications_menu()
1123           
1124    def _populate_file_menu(self):
1125        """
1126        Insert menu item under file menu
1127        """
1128        for plugin in self.plugins:
1129            if len(plugin.populate_file_menu()) > 0:
1130                for item in plugin.populate_file_menu():
1131                    m_name, m_hint, m_handler = item
1132                    id = wx.NewId()
1133                    self._file_menu.Append(id, m_name, m_hint)
1134                    wx.EVT_MENU(self, id, m_handler)
1135                self._file_menu.AppendSeparator()
1136               
1137    def _add_menu_file(self):
1138        """
1139        add menu file
1140        """
1141       
1142         # File menu
1143        self._file_menu = wx.Menu()
1144        #append item from plugin under menu file if necessary
1145        self._populate_file_menu()
1146        style = self.__gui_style & GUIFRAME.DATALOADER_ON
1147        style1 = self.__gui_style & GUIFRAME.MULTIPLE_APPLICATIONS
1148       
1149        id = wx.NewId()
1150        hint_load_file = "read all analysis states saved previously"
1151        self._save_appl_menu = self._file_menu.Append(id, 
1152                                '&Open Project', hint_load_file)
1153        wx.EVT_MENU(self, id, self._on_open_state_project)
1154           
1155        if style1 == GUIFRAME.MULTIPLE_APPLICATIONS:
1156            # some menu of plugin to be seen under file menu
1157            hint_load_file = "Read a status files and load"
1158            hint_load_file += " them into the analysis"
1159            id = wx.NewId()
1160            self._save_appl_menu = self._file_menu.Append(id, 
1161                                    '&Open Analysis', hint_load_file)
1162            wx.EVT_MENU(self, id, self._on_open_state_application)
1163               
1164        self._file_menu.AppendSeparator()
1165        id = wx.NewId()
1166        self._file_menu.Append(id, '&Save Project',
1167                             'Save the state of the whole analysis')
1168        wx.EVT_MENU(self, id, self._on_save_project)
1169        if style1 == GUIFRAME.MULTIPLE_APPLICATIONS:
1170            #self._file_menu.AppendSeparator()
1171            id = wx.NewId()
1172            self._save_appl_menu = self._file_menu.Append(id, 
1173                                                      '&Save Analysis',
1174                        'Save state of the current active analysis panel')
1175            wx.EVT_MENU(self, id, self._on_save_application)
1176       
1177        self._file_menu.AppendSeparator()
1178       
1179        id = wx.NewId()
1180        self._file_menu.Append(id, '&Quit', 'Exit') 
1181        wx.EVT_MENU(self, id, self.Close)
1182        # Add sub menus
1183        self._menubar.Append(self._file_menu, '&File')
1184       
1185    def _add_menu_edit(self):
1186        """
1187        add menu edit
1188        """
1189        # Edit Menu
1190        self._edit_menu = wx.Menu()
1191        self._edit_menu.Append(GUIFRAME_ID.UNDO_ID, '&Undo', 
1192                               'Undo the previous action')
1193        wx.EVT_MENU(self, GUIFRAME_ID.UNDO_ID, self.on_undo_panel)
1194        self._edit_menu.Append(GUIFRAME_ID.REDO_ID, '&Redo', 
1195                               'Redo the previous action')
1196        wx.EVT_MENU(self, GUIFRAME_ID.REDO_ID, self.on_redo_panel)
1197        self._edit_menu.AppendSeparator()
1198        self._edit_menu.Append(GUIFRAME_ID.COPY_ID, '&Copy Params', 
1199                               'Copy parameter values')
1200        wx.EVT_MENU(self, GUIFRAME_ID.COPY_ID, self.on_copy_panel)
1201        self._edit_menu.Append(GUIFRAME_ID.PASTE_ID, '&Paste Params', 
1202                               'Paste parameter values')
1203        wx.EVT_MENU(self, GUIFRAME_ID.PASTE_ID, self.on_paste_panel)
1204        self._edit_menu.AppendSeparator()
1205       
1206        self._edit_menu.Append(GUIFRAME_ID.PREVIEW_ID, '&Report Results',
1207                               'Preview current panel')
1208        wx.EVT_MENU(self, GUIFRAME_ID.PREVIEW_ID, self.on_preview_panel)
1209        #self._edit_menu.Append(GUIFRAME_ID.PRINT_ID, '&Print',
1210        #                       'Print current panel')
1211        #wx.EVT_MENU(self, GUIFRAME_ID.PRINT_ID, self.on_print_panel)
1212        self._edit_menu.Append(GUIFRAME_ID.RESET_ID, '&Reset Page', 
1213                               'Reset current panel')
1214        wx.EVT_MENU(self, GUIFRAME_ID.RESET_ID, self.on_reset_panel)
1215   
1216        self._menubar.Append(self._edit_menu,  '&Edit')
1217        self.enable_edit_menu()
1218       
1219    def get_style(self):
1220        """
1221        """
1222        return  self.__gui_style
1223   
1224    def _add_menu_data(self):
1225        """
1226        Add menu item item data to menu bar
1227        """
1228        if self._data_plugin is not None:
1229            menu_list = self._data_plugin.populate_menu(self)
1230            if menu_list:
1231                for (menu, name) in menu_list:
1232                    self._menubar.Append(menu, name)
1233       
1234                       
1235    def _on_toggle_toolbar(self, event=None):
1236        """
1237        hide or show toolbar
1238        """
1239        if self._toolbar is None:
1240            return
1241        if self._toolbar.IsShown():
1242            if self._toolbar_menu is not None:
1243                self._toolbar_menu.SetItemLabel('Show Toolbar')
1244            self._toolbar.Hide()
1245        else:
1246            if self._toolbar_menu is not None:
1247                self._toolbar_menu.SetItemLabel('Hide Toolbar')
1248            self._toolbar.Show()
1249        self._toolbar.Realize()
1250       
1251    def _on_status_event(self, evt):
1252        """
1253        Display status message
1254        """
1255        # This CallAfter fixes many crashes on MAC.
1256        wx.CallAfter(self.sb.set_status, evt)
1257       
1258    def on_view(self, evt):
1259        """
1260        A panel was selected to be shown. If it's not already
1261        shown, display it.
1262       
1263        :param evt: menu event
1264       
1265        """
1266        panel_id = str(evt.GetId())
1267        self.on_set_plot_focus(self.panels[panel_id])
1268        self.show_panel(evt.GetId(), 'on')     
1269        wx.CallLater(5, self.set_schedule(True))
1270        self.set_plot_unfocus()
1271       
1272    def on_close_welcome_panel(self):
1273        """
1274        Close the welcome panel
1275        """
1276        if self.defaultPanel is None:
1277            return 
1278        default_panel = self._mgr.GetPane(self.panels["default"].window_name)
1279        if default_panel.IsShown():
1280            default_panel.Hide()
1281            # Recover current perspective
1282            perspective = self._current_perspective
1283            perspective.on_perspective(event=None)
1284            self._mgr.Update()
1285            # Show toolbar
1286            #style = self.__gui_style & GUIFRAME.TOOLBAR_ON
1287            #if (style == GUIFRAME.TOOLBAR_ON) & (not self._toolbar.IsShown()):
1288            #    self._on_toggle_toolbar()
1289           
1290    def show_welcome_panel(self, event):
1291        """   
1292        Display the welcome panel
1293        """
1294        if self.defaultPanel is None:
1295            return 
1296        for id, panel in self.panels.iteritems():
1297            if id  ==  'default':
1298                # Show default panel
1299                if not self._mgr.GetPane(self.panels["default"].window_name).IsShown():
1300                    self._mgr.GetPane(self.panels["default"].window_name).Show(True)
1301            elif id == "data_panel":
1302                flag = self._mgr.GetPane(self.panels["data_panel"].window_name).IsShown()
1303                self._mgr.GetPane(self.panels["data_panel"].window_name).Show(flag)
1304            elif panel not in self.plot_panels.values() :
1305                self._mgr.GetPane(self.panels[id].window_name).IsShown()
1306                self._mgr.GetPane(self.panels[id].window_name).Hide()
1307        #style = self.__gui_style & GUIFRAME.TOOLBAR_ON
1308        #if (style == GUIFRAME.TOOLBAR_ON) & (self._toolbar.IsShown()):
1309        #    #    self._toolbar.Show(True)
1310        #    self._on_toggle_toolbar()
1311
1312        self._mgr.Update()
1313       
1314    def show_panel(self, uid, show=None):
1315        """
1316        Shows the panel with the given id
1317       
1318        :param uid: unique ID number of the panel to show
1319       
1320        """
1321        ID = str(uid)
1322        config.printEVT("show_panel: %s" % ID)
1323        if ID in self.panels.keys():
1324            if not self._mgr.GetPane(self.panels[ID].window_name).IsShown(): 
1325                if show == 'on':
1326                    self._mgr.GetPane(self.panels[ID].window_name).Show()   
1327                elif self.panels[ID].window_caption.split(" ")[0] == \
1328                                                            "Residuals":
1329                    self._mgr.GetPane(self.panels[ID].window_name).Hide()
1330                else:
1331                    self._mgr.GetPane(self.panels[ID].window_name).Show()
1332                # Hide default panel
1333                self._mgr.GetPane(self.panels["default"].window_name).Hide()
1334        self._mgr.Update()     
1335        self._redraw_idle()
1336                   
1337    def hide_panel(self, uid):
1338        """
1339        hide panel except default panel
1340        """
1341        ID = str(uid)
1342        caption = self.panels[ID].window_caption
1343        config.printEVT("hide_panel: %s" % ID)
1344        if ID in self.panels.keys():
1345            if self._mgr.GetPane(self.panels[ID].window_name).IsShown():
1346                self._mgr.GetPane(self.panels[ID].window_name).Hide()
1347                if self._data_panel is not None and \
1348                            ID in self.plot_panels.keys():
1349                    self._data_panel.cb_plotpanel.Append(str(caption), p)
1350                # Do not Hide default panel here...
1351                #self._mgr.GetPane(self.panels["default"].window_name).Hide()
1352            self._mgr.Update()
1353               
1354    def delete_panel(self, uid):
1355        """
1356        delete panel given uid
1357        """
1358        ID = str(uid)
1359        config.printEVT("delete_panel: %s" % ID)
1360        caption = self.panels[ID].window_caption
1361        if ID in self.panels.keys():
1362            self.panel_on_focus = None
1363            panel = self.panels[ID]
1364            self._plotting_plugin.delete_panel(panel.group_id)
1365            self._mgr.DetachPane(panel)
1366            panel.Hide()
1367            panel.clear()
1368            panel.Close()
1369            self._mgr.Update()
1370            #delete uid number not str(uid)
1371            if uid in self.plot_panels.keys():
1372                del self.plot_panels[uid]
1373            return 
1374     
1375    def clear_panel(self):
1376        """
1377        """
1378        for item in self.panels:
1379            try:
1380                self.panels[item].clear_panel()
1381            except:
1382                pass
1383           
1384    def create_gui_data(self, data, path=None):
1385        """
1386        """
1387        return self._data_manager.create_gui_data(data, path)
1388   
1389    def get_data(self, path):
1390        """
1391        """
1392        message = ""
1393        log_msg = ''
1394        output = []
1395        error_message = ""
1396        basename  = os.path.basename(path)
1397        root, extension = os.path.splitext(basename)
1398        if extension.lower() not in EXTENSIONS:
1399            log_msg = "File Loader cannot "
1400            log_msg += "load: %s\n" % str(basename)
1401            log_msg += "Try Data opening...."
1402            logging.info(log_msg)
1403            self.load_complete(output=output, error_message=error_message,
1404                   message=log_msg, path=path)   
1405            return
1406       
1407        #reading a state file
1408        for plug in self.plugins:
1409            reader, ext = plug.get_extensions()
1410            if reader is not None:
1411                #read the state of the single plugin
1412                if extension == ext:
1413                    reader.read(path)
1414                    return
1415                elif extension == APPLICATION_STATE_EXTENSION:
1416                    reader.read(path)
1417       
1418        style = self.__gui_style & GUIFRAME.MANAGER_ON
1419        if style == GUIFRAME.MANAGER_ON:
1420            if self._data_panel is not None:
1421                #data_state = self._data_manager.get_selected_data()
1422                #self._data_panel.load_data_list(data_state)
1423                self._mgr.GetPane(self._data_panel.window_name).Show(True)
1424     
1425    def load_from_cmd(self,  path):   
1426        """
1427        load data from cmd or application
1428        """ 
1429        if path is None:
1430            return
1431        else:
1432            path = os.path.abspath(path)
1433            if not os.path.isfile(path) and not os.path.isdir(path):
1434               return
1435           
1436            if os.path.isdir(path):
1437                self.load_folder(path)
1438                return
1439
1440        basename  = os.path.basename(path)
1441        root, extension = os.path.splitext(basename)
1442        if extension.lower() not in EXTENSIONS:
1443            self.load_data(path)
1444        else:
1445            self.load_state(path)
1446
1447        self._default_save_location = os.path.dirname(path)
1448
1449    def load_state(self, path):   
1450        """
1451        load data from command line or application
1452        """
1453        if path and (path is not None) and os.path.isfile(path):
1454            basename  = os.path.basename(path)
1455            if APPLICATION_STATE_EXTENSION is not None \
1456                and basename.endswith(APPLICATION_STATE_EXTENSION):
1457                #Hide current plot_panels i
1458                for ID in self.plot_panels.keys():
1459                    panel = self._mgr.GetPane(self.plot_panels[ID].window_name)
1460                    if panel.IsShown():
1461                        panel.Hide()
1462            self.get_data(path)
1463        if self.defaultPanel is not None and \
1464            self._mgr.GetPane(self.panels["default"].window_name).IsShown():
1465            self.on_close_welcome_panel()
1466           
1467    def load_data(self, path):
1468        """
1469        load data from command line
1470        """
1471        if not os.path.isfile(path):
1472            return
1473        basename  = os.path.basename(path)
1474        root, extension = os.path.splitext(basename)
1475        if extension.lower() in EXTENSIONS:
1476            log_msg = "Data Loader cannot "
1477            log_msg += "load: %s\n" % str(path)
1478            log_msg += "Try File opening ...."
1479            print log_msg
1480            return
1481        message = ""
1482        log_msg = ''
1483        output = {}
1484        error_message = ""
1485        try:
1486            print "Loading Data...:\n" + str(path) + "\n"
1487            temp =  self.loader.load(path)
1488            if temp.__class__.__name__ == "list":
1489                for item in temp:
1490                    data = self.create_gui_data(item, path)
1491                    output[data.id] = data
1492            else:
1493                data = self.create_gui_data(temp, path)
1494                output[data.id] = data
1495           
1496            self.add_data(data_list=output)
1497        except:
1498            error_message = "Error while loading"
1499            error_message += " Data from cmd:\n %s\n" % str(path)
1500            error_message += str(sys.exc_value) + "\n"
1501            print error_message
1502           
1503    def load_folder(self, path):
1504        """
1505        Load entire folder
1506        """   
1507        if not os.path.isdir(path):
1508            return
1509        if self._data_plugin is None:
1510            return
1511        try:
1512            if path is not None:
1513                self._default_save_location = os.path.dirname(path)
1514                file_list = self._data_plugin.get_file_path(path)
1515                self._data_plugin.get_data(file_list)
1516            else:
1517                return 
1518        except:
1519            error_message = "Error while loading"
1520            error_message += " Data folder from cmd:\n %s\n" % str(path)
1521            error_message += str(sys.exc_value) + "\n"
1522            print error_message
1523           
1524    def _on_open_state_application(self, event):
1525        """
1526        """
1527        path = None
1528        if self._default_save_location == None:
1529            self._default_save_location = os.getcwd()
1530       
1531        plug_wlist = self._on_open_state_app_helper()
1532        dlg = wx.FileDialog(self, 
1533                            "Choose a file", 
1534                            self._default_save_location, "",
1535                            plug_wlist)
1536        if dlg.ShowModal() == wx.ID_OK:
1537            path = dlg.GetPath()
1538            if path is not None:
1539                self._default_save_location = os.path.dirname(path)
1540        dlg.Destroy()
1541        self.load_state(path=path) 
1542   
1543    def _on_open_state_app_helper(self):
1544        """
1545        Helps '_on_open_state_application()' to find the extension of
1546        the current perspective/application
1547        """
1548        # No current perspective or no extension attr
1549        if self._current_perspective is None:
1550            return PLUGINS_WLIST
1551        try:
1552            # Find the extension of the perspective and get that as 1st item in list
1553            ind = None
1554            app_ext = self._current_perspective._extensions
1555            plug_wlist = config.PLUGINS_WLIST
1556            for ext in set(plug_wlist):
1557                if ext.count(app_ext) > 0:
1558                    ind = ext
1559                    break
1560            # Found the extension
1561            if ind != None:
1562                plug_wlist.remove(ind)
1563                plug_wlist.insert(0, ind)
1564                try:
1565                    plug_wlist ='|'.join(plug_wlist)
1566                except:
1567                    plug_wlist = ''
1568
1569        except:
1570            plug_wlist = PLUGINS_WLIST
1571           
1572        return plug_wlist
1573           
1574    def _on_open_state_project(self, event):
1575        """
1576        """
1577        path = None
1578        if self._default_save_location == None:
1579            self._default_save_location = os.getcwd()
1580       
1581        dlg = wx.FileDialog(self, 
1582                            "Choose a file", 
1583                            self._default_save_location, "",
1584                             APPLICATION_WLIST)
1585        if dlg.ShowModal() == wx.ID_OK:
1586            path = dlg.GetPath()
1587            if path is not None:
1588                self._default_save_location = os.path.dirname(path)
1589        dlg.Destroy()
1590       
1591        #try:   
1592        #    os.popen(path)
1593        #    #self.Close()
1594        #except:
1595        self.load_state(path=path)
1596       
1597    def _on_save_application(self, event):
1598        """
1599        save the state of the current active application
1600        """
1601        if self.cpanel_on_focus is not None:
1602            self.cpanel_on_focus.on_save(event)
1603           
1604    def _on_save_project(self, event):
1605        """
1606        save the state of the SansView as *.svs
1607        """
1608        ## Default file location for save
1609        self._default_save_location = os.getcwd()
1610        if self._current_perspective is  None:
1611            return
1612        reader, ext = self._current_perspective.get_extensions()
1613        path = None
1614        extension = '*' + APPLICATION_STATE_EXTENSION
1615        dlg = wx.FileDialog(self, "Save Project file",
1616                            self._default_save_location, "",
1617                             extension, 
1618                             wx.SAVE)
1619        if dlg.ShowModal() == wx.ID_OK:
1620            path = dlg.GetPath()
1621            self._default_save_location = os.path.dirname(path)
1622        else:
1623            return None
1624        dlg.Destroy()
1625        if path is None:
1626            return
1627        # default cansas xml doc
1628        doc = None
1629        for panel in self.panels.values():
1630            temp = panel.save_project(doc)
1631            if temp is not None:
1632                doc = temp
1633         
1634        # Write the XML document
1635        extens = APPLICATION_STATE_EXTENSION
1636        fName = os.path.splitext(path)[0] + extens
1637        if doc != None:
1638            fd = open(fName, 'w')
1639            fd.write(doc.toprettyxml())
1640            fd.close()
1641        else:
1642            msg = "%s cannot read %s\n" % (str(APPLICATION_NAME), str(path))
1643            logging.error(msg)
1644                   
1645    def on_save_helper(self, doc, reader, panel, path):
1646        """
1647        Save state into a file
1648        """
1649        try:
1650            if reader is not None:
1651                # case of a panel with multi-pages
1652                if hasattr(panel, "opened_pages"):
1653                    for uid, page in panel.opened_pages.iteritems():
1654                        data = page.get_data()
1655                        # state must be cloned
1656                        state = page.get_state().clone()
1657                        if data is not None:
1658                            new_doc = reader.write_toXML(data, state)
1659                            if doc != None and hasattr(doc, "firstChild"):
1660                                child = new_doc.firstChild.firstChild
1661                                doc.firstChild.appendChild(child) 
1662                            else:
1663                                doc = new_doc
1664                # case of only a panel
1665                else:
1666                    data = panel.get_data()
1667                    state = panel.get_state()
1668                    if data is not None:
1669                        new_doc = reader.write_toXML(data, state)
1670                        if doc != None and hasattr(doc, "firstChild"):
1671                            child = new_doc.firstChild.firstChild
1672                            doc.firstChild.appendChild(child) 
1673                        else:
1674                            doc = new_doc
1675        except: 
1676            raise
1677            #pass
1678
1679        return doc
1680
1681    def quit_guiframe(self):
1682        """
1683        Pop up message to make sure the user wants to quit the application
1684        """
1685        message = "Do you really want to quit \n"
1686        message += "this application?"
1687        dial = wx.MessageDialog(self, message, 'Question',
1688                           wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
1689        if dial.ShowModal() == wx.ID_YES:
1690            return True
1691        else:
1692            return False   
1693       
1694    def Close(self, event=None):
1695        """
1696        Quit the application
1697        """
1698        #flag = self.quit_guiframe()
1699        if True:
1700            wx.Exit()
1701            sys.exit()
1702
1703    def _check_update(self, event=None): 
1704        """
1705        Check with the deployment server whether a new version
1706        of the application is available.
1707        A thread is started for the connecting with the server. The thread calls
1708        a call-back method when the current version number has been obtained.
1709        """
1710        if hasattr(config, "__update_URL__"):
1711            import version
1712            checker = version.VersionThread(config.__update_URL__,
1713                                            self._process_version,
1714                                            baggage=event==None)
1715            checker.start() 
1716   
1717    def _process_version(self, version, standalone=True):
1718        """
1719        Call-back method for the process of checking for updates.
1720        This methods is called by a VersionThread object once the current
1721        version number has been obtained. If the check is being done in the
1722        background, the user will not be notified unless there's an update.
1723       
1724        :param version: version string
1725        :param standalone: True of the update is being checked in
1726           the background, False otherwise.
1727           
1728        """
1729        try:
1730            if cmp(version, config.__version__) > 0:
1731                msg = "Version %s is available! See the Help "
1732                msg += "menu to download it." % version
1733                self.SetStatusText(msg)
1734                if not standalone:
1735                    import webbrowser
1736                    webbrowser.open(config.__download_page__)
1737            else:
1738                if not standalone:
1739                    msg = "You have the latest version"
1740                    msg += " of %s" % config.__appname__
1741                    self.SetStatusText(msg)
1742        except:
1743            msg = "guiframe: could not get latest application"
1744            msg += " version number\n  %s" % sys.exc_value
1745            logging.error(msg)
1746            if not standalone:
1747                msg = "Could not connect to the application server."
1748                msg += " Please try again later."
1749                self.SetStatusText(msg)
1750                   
1751    def _onAbout(self, evt):
1752        """
1753        Pop up the about dialog
1754       
1755        :param evt: menu event
1756       
1757        """
1758        if config._do_aboutbox:
1759            import aboutbox 
1760            dialog = aboutbox.DialogAbout(None, -1, "")
1761            dialog.ShowModal()   
1762                     
1763    def _onTutorial(self, evt):
1764        """
1765        Pop up the tutorial dialog
1766       
1767        :param evt: menu event
1768       
1769        """
1770        if config._do_tutorial:
1771            try:
1772                #if IS_WIN:
1773                import pdfview 
1774                path = config.TUTORIAL_PATH
1775                dialog = pdfview.PDFFrame(None, -1, "Tutorial", path)
1776                #self.SetTopWindow(dialog)
1777                dialog.Show(True) 
1778                #else:
1779                #    command = "open"
1780                #    command += path
1781                #    os.system(command)
1782            except:
1783                msg = "This feature requires 'Adobe Acrobat pdf Reader'\n"
1784                msg += "Please install it first (Free from Adobe)..."
1785                wx.MessageBox(msg, 'Error')
1786                #wx.PostEvent(self, StatusEvent(status=msg, info="error"))
1787                     
1788    def set_manager(self, manager):
1789        """
1790        Sets the application manager for this frame
1791       
1792        :param manager: frame manager
1793        """
1794        self.app_manager = manager
1795       
1796    def post_init(self):
1797        """
1798        This initialization method is called after the GUI
1799        has been created and all plug-ins loaded. It calls
1800        the post_init() method of each plug-in (if it exists)
1801        so that final initialization can be done.
1802        """
1803        for item in self.plugins:
1804            if hasattr(item, "post_init"):
1805                item.post_init()
1806       
1807    def set_default_perspective(self):
1808        """
1809        Choose among the plugin the first plug-in that has
1810        "set_default_perspective" method and its return value is True will be
1811        as a default perspective when the welcome page is closed
1812        """
1813        for item in self.plugins:
1814            if hasattr(item, "set_default_perspective"):
1815                if item.set_default_perspective():
1816                    item.on_perspective(event=None)
1817                    return 
1818       
1819    def set_perspective(self, panels):
1820        """
1821        Sets the perspective of the GUI.
1822        Opens all the panels in the list, and closes
1823        all the others.
1824       
1825        :param panels: list of panels
1826        """
1827        #style = self.__gui_style & GUIFRAME.TOOLBAR_ON
1828        #if (style == GUIFRAME.TOOLBAR_ON) & (not self._toolbar.IsShown()):
1829        #    self._on_toggle_toolbar()
1830        for item in self.panels:
1831            # Check whether this is a sticky panel
1832            if hasattr(self.panels[item], "ALWAYS_ON"):
1833                if self.panels[item].ALWAYS_ON:
1834                    continue 
1835           
1836            if self.panels[item].window_name in panels:
1837                if not self._mgr.GetPane(self.panels[item].window_name).IsShown():
1838                    self._mgr.GetPane(self.panels[item].window_name).Show()
1839            else:
1840                # always show the data panel if enable
1841                style = self.__gui_style & GUIFRAME.MANAGER_ON
1842                if (style == GUIFRAME.MANAGER_ON) and self.panels[item] == self._data_panel:
1843                    if 'data_panel' in self.panels.keys():
1844                        flag = self._mgr.GetPane(self.panels['data_panel'].window_name).IsShown()
1845                        self._mgr.GetPane(self.panels['data_panel'].window_name).Show(flag)
1846                else:
1847                    if self._mgr.GetPane(self.panels[item].window_name).IsShown():
1848                        self._mgr.GetPane(self.panels[item].window_name).Hide()
1849               
1850        self._mgr.Update()
1851       
1852    def show_data_panel(self, event=None, action=True):
1853        """
1854        show the data panel
1855        """
1856        if self._data_panel_menu == None:
1857            return
1858        label = self._data_panel_menu.GetText()
1859        if label == 'Show Data Explorer':
1860            pane = self._mgr.GetPane(self.panels["data_panel"].window_name)
1861            #if not pane.IsShown():
1862            if action: 
1863                pane.Show(True)
1864                self._mgr.Update()
1865            self.__gui_style = self.__gui_style | GUIFRAME.MANAGER_ON
1866           
1867            self._data_panel_menu.SetText('Hide Data Explorer')
1868        else:
1869            pane = self._mgr.GetPane(self.panels["data_panel"].window_name)
1870            #if not pane.IsShown():
1871            if action:
1872                pane.Show(False)
1873                self._mgr.Update()
1874            self.__gui_style = self.__gui_style & (~GUIFRAME.MANAGER_ON)
1875            self._data_panel_menu.SetText('Show Data Explorer')
1876   
1877    def add_data_helper(self, data_list):
1878        """
1879        """
1880        if self._data_manager is not None:
1881            self._data_manager.add_data(data_list)
1882       
1883    def add_data(self, data_list):
1884        """
1885        receive a dictionary of data from loader
1886        store them its data manager if possible
1887        send to data the current active perspective if the data panel
1888        is not active.
1889        :param data_list: dictionary of data's ID and value Data
1890        """
1891        #Store data into manager
1892        self.add_data_helper(data_list)
1893        # set data in the data panel
1894        if self._data_panel is not None:
1895            data_state = self._data_manager.get_data_state(data_list.keys())
1896            self._data_panel.load_data_list(data_state)
1897        #if the data panel is shown wait for the user to press a button
1898        #to send data to the current perspective. if the panel is not
1899        #show  automatically send the data to the current perspective
1900        style = self.__gui_style & GUIFRAME.MANAGER_ON
1901        if style == GUIFRAME.MANAGER_ON:
1902            #wait for button press from the data panel to set_data
1903            if self._data_panel is not None:
1904                self._mgr.GetPane(self._data_panel.window_name).Show(True)
1905                self._mgr.Update() 
1906        else:
1907            #automatically send that to the current perspective
1908            self.set_data(data_id=data_list.keys())
1909            self.on_close_welcome_panel()
1910       
1911    def set_data(self, data_id, theory_id=None): 
1912        """
1913        set data to current perspective
1914        """
1915        list_data, _ = self._data_manager.get_by_id(data_id)
1916        if self._current_perspective is not None:
1917            if self.cleanup_plots:
1918                for uid, panel in self.plot_panels.iteritems():
1919                    #panel = self.plot_panels[uid]
1920                    window = self._mgr.GetPane(panel.window_name)
1921                    # To hide all docked plot panels when set the data
1922                    if not window.IsFloating():
1923                        self.hide_panel(uid)
1924            self._current_perspective.set_data(list_data.values())
1925            self.on_close_welcome_panel()
1926        else:
1927            msg = "Guiframe does not have a current perspective"
1928            logging.info(msg)
1929           
1930    def set_theory(self, state_id, theory_id=None):
1931        """
1932        """
1933        _, list_theory = self._data_manager.get_by_id(theory_id)
1934        if self._current_perspective is not None:
1935            try:
1936                self._current_perspective.set_theory(list_theory.values())
1937            except:
1938                msg = "Guiframe set_theory: \n" + str(sys.exc_value)
1939                logging.info(msg)
1940                wx.PostEvent(self, StatusEvent(status=msg, info="error"))
1941        else:
1942            msg = "Guiframe does not have a current perspective"
1943            logging.info(msg)
1944           
1945    def plot_data(self,  state_id, data_id=None,
1946                  theory_id=None, append=False):
1947        """
1948        send a list of data to plot
1949        """
1950        total_plot_list = []
1951        data_list, _ = self._data_manager.get_by_id(data_id)
1952        _, temp_list_theory = self._data_manager.get_by_id(theory_id)
1953        total_plot_list = data_list.values()
1954        for item in temp_list_theory.values():
1955            theory_data, theory_state = item
1956            total_plot_list.append(theory_data)
1957        GROUP_ID = wx.NewId()
1958        for new_plot in total_plot_list:
1959            if append:
1960                if self.panel_on_focus is None:
1961                    message = "cannot append plot. No plot panel on focus!"
1962                    message += "please click on any available plot to set focus"
1963                    wx.PostEvent(self, StatusEvent(status=message, 
1964                                                   info='warning'))
1965                    return 
1966                else:
1967                    if self.enable_add_data(new_plot):
1968                        new_plot.group_id = self.panel_on_focus.group_id
1969                    else:
1970                        message = "Only 1D Data can be append to"
1971                        message += " plot panel containing 1D data.\n"
1972                        message += "%s not be appended.\n" %str(new_plot.name)
1973                        message += "try new plot option.\n"
1974                        wx.PostEvent(self, StatusEvent(status=message, 
1975                                                   info='warning'))
1976            else:
1977                if self.cleanup_plots:
1978                    for id, panel in self.plot_panels.iteritems():
1979                        window = self._mgr.GetPane(panel.window_name)
1980                        # To hide all docked plot panels when set the data
1981                        if not window.IsFloating():
1982                            self.hide_panel(id)
1983                #if not append then new plot
1984                from sans.guiframe.dataFitting import Data2D
1985                if issubclass(Data2D, new_plot.__class__):
1986                    #for 2 D always plot in a separated new plot
1987                    new_plot.group_id = wx.NewId()
1988                else:
1989                    # plot all 1D in a new plot
1990                    new_plot.group_id = GROUP_ID
1991            title = "PLOT " + str(new_plot.title)
1992            wx.PostEvent(self, NewPlotEvent(plot=new_plot,
1993                                                  title=title,
1994                                                  group_id = new_plot.group_id))
1995           
1996    def remove_data(self, data_id, theory_id=None):
1997        """
1998        Delete data state if data_id is provide
1999        delete theory created with data of id data_id if theory_id is provide
2000        if delete all true: delete the all state
2001        else delete theory
2002        """
2003        temp = data_id + theory_id
2004        """
2005        value = [plug.is_in_use(temp) for plug in self.plugins]
2006        if len(value) > 0:
2007            print "value"
2008            return
2009            from data_panel import DataDialog
2010            dlg = DataDialog(data_list=data_list, nb_data=MAX_NBR_DATA)
2011            if dlg.ShowModal() == wx.ID_OK:
2012                selected_data_list = dlg.get_data()
2013            dlg.Destroy()
2014        """
2015        for plug in self.plugins:
2016            plug.delete_data(temp)
2017        total_plot_list = []
2018        data_list, _ = self._data_manager.get_by_id(data_id)
2019        _, temp_list_theory = self._data_manager.get_by_id(theory_id)
2020        total_plot_list = data_list.values()
2021        for item in temp_list_theory.values():
2022            theory_data, theory_state = item
2023            total_plot_list.append(theory_data)
2024        for new_plot in total_plot_list:
2025            id = new_plot.id
2026            for group_id in new_plot.list_group_id:
2027                wx.PostEvent(self, NewPlotEvent(id=id,
2028                                                   group_id=group_id,
2029                                                   action='remove'))
2030        self._data_manager.delete_data(data_id=data_id, 
2031                                       theory_id=theory_id)
2032           
2033       
2034    def set_current_perspective(self, perspective):
2035        """
2036        set the current active perspective
2037        """
2038        self._current_perspective = perspective
2039        name = "No current analysis selected"
2040        if self._current_perspective is not None:
2041            self._add_current_plugin_menu()
2042            for panel in self.panels.values():
2043                if hasattr(panel, 'CENTER_PANE') and panel.CENTER_PANE:
2044                    for name in self._current_perspective.get_perspective():
2045                        if name == panel.window_name:
2046                            panel.on_set_focus(event=None)
2047                            break               
2048            name = self._current_perspective.sub_menu
2049            if self._data_panel is not None:
2050                self._data_panel.set_active_perspective(name)
2051                self._check_applications_menu()
2052            #Set the SansView title
2053            self._set_title_name(name)
2054         
2055           
2056    def _set_title_name(self, name):
2057        """
2058        Set the SansView title w/ the current application name
2059       
2060        : param name: application name [string]
2061        """
2062        # Set SanView Window title w/ application anme
2063        title = self.title + "  - " + name + " -"
2064        self.SetTitle(title)
2065           
2066    def _check_applications_menu(self):
2067        """
2068        check the menu of the current application
2069        """
2070        if self._applications_menu is not None:
2071            for menu in self._applications_menu.GetMenuItems():
2072                if self._current_perspective is not None:
2073                    name = self._current_perspective.sub_menu
2074                    if menu.IsCheckable():
2075                        if menu.GetLabel() == name:
2076                            menu.Check(True)
2077                        else:
2078                             menu.Check(False) 
2079           
2080    def set_plotpanel_floating(self, event=None):
2081        """
2082        make the plot panel floatable
2083        """
2084       
2085        self.__gui_style &= (~GUIFRAME.FIXED_PANEL)
2086        self.__gui_style |= GUIFRAME.FLOATING_PANEL
2087        plot_panel = []
2088        id = event.GetId()
2089        menu = self._window_menu.FindItemById(id)
2090        if self._plotting_plugin is not None:
2091            plot_panel = self._plotting_plugin.plot_panels.values()
2092            for p in plot_panel:
2093                self._popup_floating_panel(p)
2094            menu.Check(True)
2095           
2096    def set_plotpanel_fixed(self, event=None):
2097        """
2098        make the plot panel fixed
2099        """
2100        self.__gui_style &= (~GUIFRAME.FLOATING_PANEL)
2101        self.__gui_style |= GUIFRAME.FIXED_PANEL
2102        plot_panel = []
2103        id = event.GetId()
2104        menu = self._window_menu.FindItemById(id)
2105        if self._plotting_plugin is not None:
2106            plot_panel = self._plotting_plugin.plot_panels.values()
2107            for p in plot_panel:
2108                self._popup_fixed_panel(p)
2109            menu.Check(True)
2110           
2111    def on_cleanup_dock(self, event=None):     
2112        """
2113        Set Cleanup Dock option
2114        """
2115        if event == None:
2116            return
2117        id = event.GetId()
2118        menu = self._window_menu.FindItemById(id)
2119        Flag = self.cleanup_plots
2120        if not Flag:
2121            menu.Check(True)
2122            self.cleanup_plots = True
2123            msg = "Cleanup-Dock option set to 'ON'."
2124        else:
2125            menu.Check(False)
2126            self.cleanup_plots = False
2127            msg = "Cleanup-Dock option set to 'OFF'."
2128
2129        wx.PostEvent(self, StatusEvent(status= msg))
2130         
2131    def _popup_fixed_panel(self, p):
2132        """
2133        """
2134        style = self.__gui_style & GUIFRAME.FIXED_PANEL
2135        if style == GUIFRAME.FIXED_PANEL:
2136            self._mgr.GetPane(p.window_name).Dock()
2137            self._mgr.GetPane(p.window_name).Floatable()
2138            self._mgr.GetPane(p.window_name).Right()
2139            self._mgr.GetPane(p.window_name).TopDockable(False)
2140            self._mgr.GetPane(p.window_name).BottomDockable(False)
2141            self._mgr.GetPane(p.window_name).LeftDockable(False)
2142            self._mgr.GetPane(p.window_name).RightDockable(True)
2143            self._mgr.Update()
2144           
2145    def _popup_floating_panel(self, p):
2146        """
2147        """
2148        style = self.__gui_style &  GUIFRAME.FLOATING_PANEL
2149        if style == GUIFRAME.FLOATING_PANEL: 
2150            self._mgr.GetPane(p.window_name).Floatable(True)
2151            self._mgr.GetPane(p.window_name).Float()
2152            self._mgr.GetPane(p.window_name).Dockable(False)
2153            self._mgr.Update()
2154           
2155    def enable_add_data(self, new_plot):
2156        """
2157        Enable append data on a plot panel
2158        """
2159
2160        if self.panel_on_focus not in self._plotting_plugin.plot_panels.values():
2161            return
2162        is_theory = len(self.panel_on_focus.plots) <= 1 and \
2163            self.panel_on_focus.plots.values()[0].__class__.__name__ == "Theory1D"
2164           
2165        is_data2d = hasattr(new_plot, 'data')
2166       
2167        is_data1d = self.panel_on_focus.__class__.__name__ == "ModelPanel1D"\
2168            and self.panel_on_focus.group_id is not None
2169        has_meta_data = hasattr(new_plot, 'meta_data')
2170       
2171        #disable_add_data if the data is being recovered from  a saved state file.
2172        is_state_data = False
2173        if has_meta_data:
2174            if 'invstate' in new_plot.meta_data: is_state_data = True
2175            if  'prstate' in new_plot.meta_data: is_state_data = True
2176            if  'fitstate' in new_plot.meta_data: is_state_data = True
2177   
2178        return is_data1d and not is_data2d and not is_theory and not is_state_data
2179   
2180    def enable_edit_menu(self):
2181        """
2182        enable menu item under edit menu depending on the panel on focus
2183        """
2184        if self.cpanel_on_focus is not None and self._edit_menu is not None:
2185            flag = self.cpanel_on_focus.get_undo_flag()
2186            self._edit_menu.Enable(GUIFRAME_ID.UNDO_ID, flag)
2187            flag = self.cpanel_on_focus.get_redo_flag()
2188            self._edit_menu.Enable(GUIFRAME_ID.REDO_ID, flag)
2189            flag = self.cpanel_on_focus.get_copy_flag()
2190            self._edit_menu.Enable(GUIFRAME_ID.COPY_ID, flag)
2191            flag = self.cpanel_on_focus.get_paste_flag()
2192            self._edit_menu.Enable(GUIFRAME_ID.PASTE_ID, flag)
2193            #flag = self.cpanel_on_focus.get_print_flag()
2194            #self._edit_menu.Enable(GUIFRAME_ID.PRINT_ID, flag)
2195            flag = self.cpanel_on_focus.get_preview_flag()
2196            self._edit_menu.Enable(GUIFRAME_ID.PREVIEW_ID, flag)
2197            flag = self.cpanel_on_focus.get_reset_flag()
2198            self._edit_menu.Enable(GUIFRAME_ID.RESET_ID, flag)
2199        else:
2200            flag = False
2201            self._edit_menu.Enable(GUIFRAME_ID.UNDO_ID, flag)
2202            self._edit_menu.Enable(GUIFRAME_ID.REDO_ID, flag)
2203            self._edit_menu.Enable(GUIFRAME_ID.COPY_ID, flag)
2204            self._edit_menu.Enable(GUIFRAME_ID.PASTE_ID, flag)
2205            #self._edit_menu.Enable(GUIFRAME_ID.PRINT_ID, flag)
2206            self._edit_menu.Enable(GUIFRAME_ID.PREVIEW_ID, flag)
2207            self._edit_menu.Enable(GUIFRAME_ID.RESET_ID, flag)
2208           
2209    def on_undo_panel(self, event=None):
2210        """
2211        undo previous action of the last panel on focus if possible
2212        """
2213        if self.cpanel_on_focus is not None:
2214            self.cpanel_on_focus.on_undo(event)
2215           
2216    def on_redo_panel(self, event=None):
2217        """
2218        redo the last cancel action done on the last panel on focus
2219        """
2220        if self.cpanel_on_focus is not None:
2221            self.cpanel_on_focus.on_redo(event)
2222           
2223    def on_copy_panel(self, event=None):
2224        """
2225        copy the last panel on focus if possible
2226        """
2227        if self.cpanel_on_focus is not None:
2228            self.cpanel_on_focus.on_copy(event)
2229           
2230    def on_paste_panel(self, event=None):
2231        """
2232        paste clipboard to the last panel on focus
2233        """
2234        if self.cpanel_on_focus is not None:
2235            self.cpanel_on_focus.on_paste(event)
2236                   
2237    def on_bookmark_panel(self, event=None):
2238        """
2239        bookmark panel
2240        """
2241        if self.cpanel_on_focus is not None:
2242            self.cpanel_on_focus.on_bookmark(event)
2243           
2244    def append_bookmark(self, event=None):
2245        """
2246        Bookmark available information of the panel on focus
2247        """
2248        self._toolbar.append_bookmark(event)
2249           
2250    def on_save_panel(self, event=None):
2251        """
2252        save possible information on the current panel
2253        """
2254        if self.cpanel_on_focus is not None:
2255            self.cpanel_on_focus.on_save(event)
2256           
2257    def on_preview_panel(self, event=None):
2258        """
2259        preview information on the panel on focus
2260        """
2261        if self.cpanel_on_focus is not None:
2262            self.cpanel_on_focus.on_preview(event)
2263           
2264    def on_print_panel(self, event=None):
2265        """
2266        print available information on the last panel on focus
2267        """
2268        if self.cpanel_on_focus is not None:
2269            self.cpanel_on_focus.on_print(event)
2270           
2271    def on_zoom_panel(self, event=None):
2272        """
2273        zoom on the current panel if possible
2274        """
2275        if self.cpanel_on_focus is not None:
2276            self.cpanel_on_focus.on_zoom(event)
2277           
2278    def on_zoom_in_panel(self, event=None):
2279        """
2280        zoom in of the panel on focus
2281        """
2282        if self.cpanel_on_focus is not None:
2283            self.cpanel_on_focus.on_zoom_in(event)
2284           
2285    def on_zoom_out_panel(self, event=None):
2286        """
2287        zoom out on the panel on focus
2288        """
2289        if self.cpanel_on_focus is not None:
2290            self.cpanel_on_focus.on_zoom_out(event)
2291           
2292    def on_drag_panel(self, event=None):
2293        """
2294        drag apply to the panel on focus
2295        """
2296        if self.cpanel_on_focus is not None:
2297            self.cpanel_on_focus.on_drag(event)
2298           
2299    def on_reset_panel(self, event=None):
2300        """
2301        reset the current panel
2302        """
2303        if self.cpanel_on_focus is not None:
2304            self.cpanel_on_focus.on_reset(event)
2305           
2306    def enable_undo(self):
2307        """
2308        enable undo related control
2309        """
2310        if self.cpanel_on_focus is not None:
2311            self._toolbar.enable_undo(self.cpanel_on_focus)
2312           
2313    def enable_redo(self):
2314        """
2315        enable redo
2316        """
2317        if self.cpanel_on_focus is not None:
2318            self._toolbar.enable_redo(self.cpanel_on_focus)
2319           
2320    def enable_copy(self):
2321        """
2322        enable copy related control
2323        """
2324        if self.cpanel_on_focus is not None:
2325            self._toolbar.enable_copy(self.cpanel_on_focus)
2326           
2327    def enable_paste(self):
2328        """
2329        enable paste
2330        """
2331        if self.cpanel_on_focus is not None:
2332            self._toolbar.enable_paste(self.cpanel_on_focus)
2333                       
2334    def enable_bookmark(self):
2335        """
2336        Bookmark
2337        """
2338        if self.cpanel_on_focus is not None:
2339            self._toolbar.enable_bookmark(self.cpanel_on_focus)
2340           
2341    def enable_save(self):
2342        """
2343        save
2344        """
2345        if self.cpanel_on_focus is not None:
2346            self._toolbar.enable_save(self.cpanel_on_focus)
2347           
2348    def enable_preview(self):
2349        """
2350        preview
2351        """
2352        if self.cpanel_on_focus is not None:
2353            self._toolbar.enable_preview(self.cpanel_on_focus)
2354           
2355    def enable_print(self):
2356        """
2357        print
2358        """
2359        if self.cpanel_on_focus is not None:
2360            self._toolbar.enable_print(self.cpanel_on_focus)
2361           
2362    def enable_zoom(self):
2363        """
2364        zoom
2365        """
2366        if self.cpanel_on_focus is not None:
2367            self._toolbar.enable_zoom(self.panel_on_focus)
2368           
2369    def enable_zoom_in(self):
2370        """
2371        zoom in
2372        """
2373        if self.cpanel_on_focus is not None:
2374            self._toolbar.enable_zoom_in(self.panel_on_focus)
2375           
2376    def enable_zoom_out(self):
2377        """
2378        zoom out
2379        """
2380        if self.cpanel_on_focus is not None:
2381            self._toolbar.enable_zoom_out(self.panel_on_focus)
2382           
2383    def enable_drag(self, event=None):
2384        """
2385        drag
2386        """
2387        if self.cpanel_on_focus is not None:
2388            self._toolbar.enable_drag(self.panel_on_focus)
2389           
2390    def enable_reset(self):
2391        """
2392        reset the current panel
2393        """
2394        if self.cpanel_on_focus is not None:
2395            self._toolbar.enable_reset(self.panel_on_focus)
2396
2397    def set_schedule_full_draw(self, panel=None, func='del'):
2398        """
2399        Add/subtract the schedule full draw list with the panel given
2400       
2401        :param panel: plot panel
2402        :param func: append or del [string]
2403        """
2404
2405        # append this panel in the schedule list if not in yet
2406        if func == 'append':
2407            if not panel in self.schedule_full_draw_list:
2408                self.schedule_full_draw_list.append(panel) 
2409        # remove this panel from schedule list
2410        elif func == 'del':
2411            if len(self.schedule_full_draw_list) > 0:
2412                if panel in self.schedule_full_draw_list:
2413                    self.schedule_full_draw_list.remove(panel)
2414
2415        # reset the schdule
2416        if len(self.schedule_full_draw_list) == 0:
2417            self.schedule = False
2418        else:
2419            self.schedule = True   
2420       
2421    def full_draw(self):
2422        """
2423        Draw the panels with axes in the schedule to full dwar list
2424        """
2425        count = len(self.schedule_full_draw_list)
2426        #if not self.schedule:
2427        if count < 1:
2428            self.set_schedule(False)
2429            return
2430        else:
2431            ind = 0
2432            # if any of the panel is shown do full_draw
2433            for panel in self.schedule_full_draw_list:
2434                ind += 1
2435                if self._mgr.GetPane(panel.window_name).IsShown():
2436                    break
2437                # otherwise, return
2438                if ind == count:
2439                    return
2440
2441        #Simple redraw only for a panel shown
2442        def f_draw(panel):
2443            """
2444            Draw A panel in the full dwar list
2445            """
2446            try:
2447                # This checking of GetCapture is to stop redrawing
2448                # while any panel is capture.
2449                if self.GetCapture() == None:
2450                    # draw if possible
2451                    panel.set_resizing(False)
2452                    panel.Show(False)
2453                    panel.draw_plot()
2454                   
2455                    # Check if the panel is not shown
2456                    if not self._mgr.GetPane(panel.window_name).IsShown():
2457                        self._mgr.GetPane(panel.window_name).Hide()
2458                    else:
2459                        panel.Show(True)
2460            except:
2461                pass
2462        #print self.callback,self.schedule,self.schedule_full_draw_list
2463       
2464        # Draw all panels       
2465        map(f_draw, self.schedule_full_draw_list)
2466       
2467        # Reset the attr 
2468        if len(self.schedule_full_draw_list) == 0:
2469            self.set_schedule(False)
2470        else:
2471            self.set_schedule(True)
2472        # do not update mgr
2473        #self._mgr.Update()
2474       
2475    def set_schedule(self, schedule=False): 
2476        """
2477        Set schedule
2478        """
2479        self.schedule = schedule
2480               
2481    def get_schedule(self): 
2482        """
2483        Get schedule
2484        """
2485        return self.schedule
2486   
2487    def on_set_plot_focus(self, panel):
2488        """
2489        Set focus on a plot panel
2490        """
2491        self.set_plot_unfocus()
2492        panel.on_set_focus(None) 
2493        # set focusing panel
2494        self.panel_on_focus = panel 
2495        self.set_panel_on_focus(None)
2496   
2497    def set_plot_unfocus(self): 
2498        """
2499        Un focus all plot panels
2500        """
2501        for plot in self.plot_panels.values():
2502            plot.on_kill_focus(None)
2503
2504    def _onDrawIdle(self, *args, **kwargs):
2505        """
2506        ReDraw with axes
2507        """
2508        try:
2509            # check if it is time to redraw
2510            if self.GetCapture() == None:
2511                # Draw plot, changes resizing too
2512                self.full_draw()
2513        except:
2514            pass
2515           
2516        # restart idle       
2517        self._redraw_idle(*args, **kwargs)
2518
2519           
2520    def _redraw_idle(self, *args, **kwargs):
2521        """
2522        Restart Idle
2523        """
2524        # restart idle   
2525        self.idletimer.Restart(55, *args, **kwargs)
2526
2527       
2528class DefaultPanel(wx.Panel, PanelBase):
2529    """
2530    Defines the API for a panels to work with
2531    the GUI manager
2532    """
2533    ## Internal nickname for the window, used by the AUI manager
2534    window_name = "default"
2535    ## Name to appear on the window title bar
2536    window_caption = "Welcome panel"
2537    ## Flag to tell the AUI manager to put this panel in the center pane
2538    CENTER_PANE = True
2539    def __init__(self, parent, *args, **kwds):
2540        wx.Panel.__init__(self, parent, *args, **kwds)
2541        PanelBase.__init__(self, parent)
2542   
2543
2544
2545# Toy application to test this Frame
2546class ViewApp(wx.App):
2547    """
2548    """
2549    def OnInit(self):
2550        """
2551        """
2552        pos, size = self.window_placement((GUIFRAME_WIDTH, GUIFRAME_HEIGHT))
2553        self.frame = ViewerFrame(parent=None, 
2554                                 title=APPLICATION_NAME, 
2555                                 pos=pos, 
2556                                 gui_style = DEFAULT_STYLE,
2557                                 size=size) 
2558        self.frame.Hide()
2559        self.s_screen = None
2560        temp_path = None
2561        try:
2562            # make sure the current dir is App dir when it starts
2563            temp_path = os.path.dirname(sys.path[0])
2564            os.chdir(temp_path)
2565        except:
2566            pass
2567        try:
2568            self.open_file()
2569        except:
2570            msg = "%s Could not load " % str(APPLICATION_NAME)
2571            msg += "input file from command line.\n"
2572            logging.error(msg)
2573        # Display a splash screen on top of the frame.
2574        if len(sys.argv) > 1 and '--time' in sys.argv[1:]:
2575            log_time("Starting to display the splash screen")
2576        try:
2577            if os.path.isfile(SPLASH_SCREEN_PATH):
2578                self.s_screen = self.display_splash_screen(parent=self.frame, 
2579                                        path=SPLASH_SCREEN_PATH)
2580            else:
2581                self.frame.Show()   
2582        except:
2583            if self.s_screen is not None:
2584                self.s_screen.Close()
2585            msg = "Cannot display splash screen\n"
2586            msg += str (sys.exc_value)
2587            logging.error(msg)
2588            self.frame.Show()
2589 
2590        if hasattr(self.frame, 'special'):
2591            self.frame.special.SetCurrent()
2592        self.SetTopWindow(self.frame)
2593 
2594        return True
2595
2596    def open_file(self):
2597        """
2598        open a state file at the start of the application
2599        """
2600        input_file = None
2601        if len(sys.argv) >= 2:
2602            cmd = sys.argv[0].lower()
2603            basename  = os.path.basename(cmd)
2604            app_base = str(APPLICATION_NAME).lower()
2605            if os.path.isfile(cmd) or basename.lower() == app_base:
2606                app_py = app_base + '.py'
2607                app_exe = app_base + '.exe'
2608                app_app = app_base + '.app'
2609                if basename.lower() in [app_py, app_exe, app_app, app_base]:
2610                    input_file = sys.argv[1]
2611        if input_file is None:
2612            return
2613        if self.frame is not None:
2614            self.frame.set_input_file(input_file=input_file)
2615         
2616           
2617    def set_manager(self, manager):
2618        """
2619        Sets a reference to the application manager
2620        of the GUI manager (Frame)
2621        """
2622        self.frame.set_manager(manager)
2623       
2624    def build_gui(self):
2625        """
2626        Build the GUI
2627        """
2628        #try to load file at the start
2629        try:
2630            self.open_file()
2631        except:
2632            raise
2633        self.frame.build_gui()
2634        #if self.s_screen is not None and self.s_screen.IsShown():
2635        #    self.s_screen.Close()
2636       
2637    def set_welcome_panel(self, panel_class):
2638        """
2639        Set the welcome panel
2640       
2641        :param panel_class: class of the welcome panel to be instantiated
2642       
2643        """
2644        self.frame.set_welcome_panel(panel_class)
2645       
2646    def add_perspective(self, perspective):
2647        """
2648        Manually add a perspective to the application GUI
2649        """
2650        self.frame.add_perspective(perspective)
2651   
2652    def window_placement(self, size):
2653        """
2654        Determines the position and size of the application frame such that it
2655        fits on the user's screen without obstructing (or being obstructed by)
2656        the Windows task bar.  The maximum initial size in pixels is bounded by
2657        WIDTH x HEIGHT.  For most monitors, the application
2658        will be centered on the screen; for very large monitors it will be
2659        placed on the left side of the screen.
2660        """
2661        window_width, window_height = size
2662        screen_size = wx.GetDisplaySize()
2663        window_height = window_height if screen_size[1]>window_height else screen_size[1]-10
2664        window_width  = window_width if screen_size[0]> window_width else screen_size[0]-10
2665        xpos = ypos = 0
2666
2667        # Note that when running Linux and using an Xming (X11) server on a PC
2668        # with a dual  monitor configuration, the reported display size may be
2669        # that of both monitors combined with an incorrect display count of 1.
2670        # To avoid displaying this app across both monitors, we check for
2671        # screen 'too big'.  If so, we assume a smaller width which means the
2672        # application will be placed towards the left hand side of the screen.
2673
2674        _, _, x, y = wx.Display().GetClientArea() # size excludes task bar
2675        if len(sys.argv) > 1 and '--platform' in sys.argv[1:]:
2676            w, h = wx.DisplaySize()  # size includes task bar area
2677        # display on left side, not centered on screen
2678        if x > 1920 and x > (2*y): x = x / 2 
2679        if x > window_width:  xpos = (x - window_width)/2
2680        if y > window_height: ypos = (y - window_height)/2
2681
2682        # Return the suggested position and size for the application frame.
2683        return (xpos, ypos), (min(x, window_width), min(y, window_height))
2684   
2685    def display_splash_screen(self, parent, 
2686                              path=SPLASH_SCREEN_PATH):
2687        """Displays the splash screen.  It will exactly cover the main frame."""
2688       
2689        # Prepare the picture.  On a 2GHz intel cpu, this takes about a second.
2690        x, y = parent.GetSizeTuple()
2691        image = wx.Image(path, wx.BITMAP_TYPE_PNG)
2692        image.Rescale(SPLASH_SCREEN_WIDTH, 
2693                      SPLASH_SCREEN_HEIGHT, wx.IMAGE_QUALITY_HIGH)
2694        bm = image.ConvertToBitmap()
2695
2696        # Create and show the splash screen.  It will disappear only when the
2697        # program has entered the event loop AND either the timeout has expired
2698        # or the user has left clicked on the screen.  Thus any processing
2699        # performed in this routine (including sleeping) or processing in the
2700        # calling routine (including doing imports) will prevent the splash
2701        # screen from disappearing.
2702        #
2703        # Note that on Linux, the timeout appears to occur immediately in which
2704        # case the splash screen disappears upon entering the event loop.
2705        s_screen = wx.SplashScreen(bitmap=bm,
2706                         splashStyle=(wx.SPLASH_TIMEOUT|
2707                                              wx.SPLASH_CENTRE_ON_SCREEN),
2708                                 style=(wx.SIMPLE_BORDER|
2709                                        wx.FRAME_NO_TASKBAR|
2710                                        wx.STAY_ON_TOP),
2711                                       
2712                        milliseconds=SS_MAX_DISPLAY_TIME,
2713                        parent=parent,
2714                        id=wx.ID_ANY)
2715        from gui_statusbar import SPageStatusbar
2716        statusBar = SPageStatusbar(s_screen)
2717        s_screen.SetStatusBar(statusBar)
2718        s_screen.Bind(wx.EVT_CLOSE, self.on_close_splash_screen)
2719        s_screen.Show()
2720        return s_screen
2721       
2722       
2723    def on_close_splash_screen(self, event):
2724        """
2725        """
2726        self.frame.Show(True)
2727        event.Skip()
2728     
2729if __name__ == "__main__": 
2730    app = ViewApp(0)
2731    app.MainLoop()
2732
2733             
Note: See TracBrowser for help on using the repository browser.