source: sasview/guiframe/gui_manager.py @ f7d0b74

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 f7d0b74 was f7d0b74, checked in by Gervaise Alina <gervyh@…>, 13 years ago

working on remove data ,remove data manager unexisting method call

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