source: sasview/guiframe/gui_manager.py @ ad01b7c4

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

added choice for having open/close project file manu

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