source: sasview/guiframe/gui_manager.py @ 12cd4ec

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

removed print statement

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