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

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

trying to fix mac multidata set bug

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