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

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

changed exit mesg.

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