source: sasview/sansguiframe/src/sans/guiframe/gui_manager.py @ 9f4f8f4

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 9f4f8f4 was d81008e, checked in by Gervaise Alina <gervyh@…>, 13 years ago

refactore import config code

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