source: sasview/guiframe/gui_manager.py @ be98b3d

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

fixing a problem in path/mac

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