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

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

Can change plotpanel 1D 2D title and set Graph as default: update datapanel cb and menu_graph accordingly

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