source: sasview/guiframe/gui_manager.py @ 60ad1d4e

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

finished tutorial help menu

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