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

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 db7a82e was 9e2e7e9, checked in by Jessica Tumarkin <jtumarki@…>, 13 years ago

added event import statement

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