source: sasview/guiframe/gui_manager.py @ 814524b

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

fixed key error

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