source: sasview/guiframe/gui_manager.py @ 41c284a

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

minor fix on Setting View

  • Property mode set to 100644
File size: 97.3 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                    self._data_panel.cb_plotpanel.SetStringSelection(str\
331                                         (self.panel_on_focus.window_caption))
332                elif self.panel_on_focus != self._data_panel:
333                    cpanel = self.panel_on_focus
334                    if self.cpanel_on_focus != cpanel:
335                        self.cpanel_on_focus = self.panel_on_focus
336                #update toolbar
337                self._update_toolbar_helper()
338                #update edit menu
339                self.enable_edit_menu()
340
341    def reset_bookmark_menu(self, panel):
342        """
343        Reset Bookmark menu list
344       
345        : param panel: a control panel or tap where the bookmark is
346        """
347        cpanel = panel
348        if self._toolbar != None and cpanel._bookmark_flag:
349            for item in  self._toolbar.get_bookmark_items():
350                self._toolbar.remove_bookmark_item(item)
351            self._toolbar.add_bookmark_default()
352            pos = 0
353            for bitem in cpanel.popUpMenu.GetMenuItems():
354                pos += 1
355                if pos < 3:
356                    continue
357                id =  bitem.GetId()
358                label = bitem.GetLabel()
359                self._toolbar.append_bookmark_item(id, label)
360                wx.EVT_MENU(self, id, cpanel._back_to_bookmark)
361            self._toolbar.Realize()
362             
363
364    def build_gui(self):
365        """
366        """
367        # set tool bar
368        self._setup_tool_bar()
369        # Set up the layout
370        self._setup_layout()
371        # Set up the menu
372        self._setup_menus()
373       
374        try:
375            self.load_from_cmd(self._input_file)
376        except:
377            msg = "%s Cannot load file %s\n" %(str(APPLICATION_NAME), 
378                                             str(self._input_file))
379            msg += str(sys.exc_value) + '\n'
380            print msg
381        if self._data_panel is not None:
382            self._data_panel.fill_cbox_analysis(self.plugins)
383        self.post_init()
384        # Set Custom default
385        self.set_custom_default_perspective()
386
387        style = self.__gui_style & GUIFRAME.TOOLBAR_ON
388        if (style == GUIFRAME.TOOLBAR_ON) & (not self._toolbar.IsShown()):
389            self._on_toggle_toolbar() 
390       
391        # Set Custom deafult start page
392        welcome_style = self.__gui_style & GUIFRAME.WELCOME_PANEL_ON
393        if welcome_style == GUIFRAME.WELCOME_PANEL_ON:
394            self.show_welcome_panel(None)
395 
396        #self.Show(True)
397        #self._check_update(None)
398             
399    def _setup_layout(self):
400        """
401        Set up the layout
402        """
403        # Status bar
404        from gui_statusbar import StatusBar
405        self.sb = StatusBar(self, wx.ID_ANY)
406        self.SetStatusBar(self.sb)
407        # Add panel
408        default_flag = wx.aui.AUI_MGR_DEFAULT#| wx.aui.AUI_MGR_ALLOW_ACTIVE_PANE
409        self._mgr = wx.aui.AuiManager(self, flags=default_flag)
410        self._mgr.SetDockSizeConstraint(0.5, 0.5)
411        # border color
412        #self.b_color = wx.aui.AUI_DOCKART_BORDER_COLOUR 
413        #self._mgr.GetArtProvider().SetColor(self.b_color, self.color)
414        #self._mgr.SetArtProvider(wx.aui.AuiDockArt(wx.AuiDefaultDockArt))
415        #print "set", self._dockart.GetColour(13)
416        # Load panels
417        self._load_panels()
418        self.set_default_perspective()
419        self._mgr.Update()
420       
421    def SetStatusText(self, *args, **kwds):
422        """
423        """
424        number = self.sb.get_msg_position()
425        wx.Frame.SetStatusText(number=number, *args, **kwds)
426       
427    def PopStatusText(self, *args, **kwds):
428        """
429        """
430        field = self.sb.get_msg_position()
431        wx.Frame.PopStatusText(field=field)
432       
433    def PushStatusText(self, *args, **kwds):
434        """
435        """
436        field = self.sb.get_msg_position()
437        wx.Frame.PushStatusText(self, field=field, string=string)
438
439    def add_perspective(self, plugin):
440        """
441        Add a perspective if it doesn't already
442        exist.
443        """
444        is_loaded = False
445        for item in self.plugins:
446            if plugin.__class__ == item.__class__:
447                msg = "Plugin %s already loaded" % plugin.sub_menu
448                logging.info(msg)
449                is_loaded = True 
450        if not is_loaded:
451           
452            self.plugins.append(plugin)
453             
454     
455    def _get_local_plugins(self):
456        """
457        get plugins local to guiframe and others
458        """
459        plugins = []
460        #import guiframe local plugins
461        #check if the style contain guiframe.dataloader
462        style1 = self.__gui_style & GUIFRAME.DATALOADER_ON
463        style2 = self.__gui_style & GUIFRAME.PLOTTING_ON
464        if style1 == GUIFRAME.DATALOADER_ON:
465            try:
466                from sans.guiframe.local_perspectives.data_loader import data_loader
467                self._data_plugin = data_loader.Plugin()
468                plugins.append(self._data_plugin)
469            except:
470                msg = "ViewerFrame._get_local_plugins:"
471                msg += "cannot import dataloader plugin.\n %s" % sys.exc_value
472                logging.error(msg)
473        if style2 == GUIFRAME.PLOTTING_ON:
474            try:
475                from sans.guiframe.local_perspectives.plotting import plotting
476                self._plotting_plugin = plotting.Plugin()
477                plugins.append(self._plotting_plugin)
478            except:
479                msg = "ViewerFrame._get_local_plugins:"
480                msg += "cannot import plotting plugin.\n %s" % sys.exc_value
481                logging.error(msg)
482     
483        return plugins
484   
485    def _find_plugins(self, dir="perspectives"):
486        """
487        Find available perspective plug-ins
488       
489        :param dir: directory in which to look for plug-ins
490       
491        :return: list of plug-ins
492       
493        """
494        import imp
495        plugins = []
496        # Go through files in panels directory
497        try:
498            list = os.listdir(dir)
499            ## the default panel is the panel is the last plugin added
500            for item in list:
501                toks = os.path.splitext(os.path.basename(item))
502                name = ''
503                if not toks[0] == '__init__':
504                    if toks[1] == '.py' or toks[1] == '':
505                        name = toks[0]
506                    #check the validity of the module name parsed
507                    #before trying to import it
508                    if name is None or name.strip() == '':
509                        continue
510                    path = [os.path.abspath(dir)]
511                    file = ''
512                    try:
513                        if toks[1] == '':
514                            mod_path = '.'.join([dir, name])
515                            module = __import__(mod_path, globals(),
516                                                locals(), [name])
517                        else:
518                            (file, path, info) = imp.find_module(name, path)
519                            module = imp.load_module( name, file, item, info)
520                        if hasattr(module, "PLUGIN_ID"):
521                            try: 
522                                plug = module.Plugin()
523                                if plug.set_default_perspective():
524                                    self._current_perspective = plug
525                                plugins.append(plug)
526                               
527                                msg = "Found plug-in: %s" % module.PLUGIN_ID
528                                logging.info(msg)
529                            except:
530                                msg = "Error accessing PluginPanel"
531                                msg += " in %s\n  %s" % (name, sys.exc_value)
532                                config.printEVT(msg)
533                    except:
534                        msg = "ViewerFrame._find_plugins: %s" % sys.exc_value
535                        #print msg
536                        logging.error(msg)
537                    finally:
538                        if not file == None:
539                            file.close()
540        except:
541            # Should raise and catch at a higher level and
542            # display error on status bar
543            pass   
544        return plugins
545   
546    def set_welcome_panel(self, panel_class):
547        """
548        Sets the default panel as the given welcome panel
549       
550        :param panel_class: class of the welcome panel to be instantiated
551       
552        """
553        self.defaultPanel = panel_class(self, -1, style=wx.RAISED_BORDER)
554       
555    def _get_panels_size(self, p):
556        """
557        find the proper size of the current panel
558        get the proper panel width and height
559        """
560        panel_height_min = self._window_height
561        panel_width_min = self._window_width
562        style = self.__gui_style & (GUIFRAME.MANAGER_ON)
563        if self._data_panel is not None  and (p == self._data_panel):
564            panel_width_min = DATAPANEL_WIDTH
565            panel_height_min = self._window_height * 0.8
566            return panel_width_min, panel_height_min
567        if hasattr(p, "CENTER_PANE") and p.CENTER_PANE:
568            style = self.__gui_style & (GUIFRAME.PLOTTING_ON|GUIFRAME.MANAGER_ON)
569            if style == (GUIFRAME.PLOTTING_ON|GUIFRAME.MANAGER_ON):
570                panel_width_min = self._window_width -\
571                            (DATAPANEL_WIDTH +config.PLOPANEL_WIDTH)
572            return panel_width_min, panel_height_min
573        return panel_width_min, panel_height_min
574   
575    def _load_panels(self):
576        """
577        Load all panels in the panels directory
578        """
579       
580        # Look for plug-in panels
581        panels = []   
582        for item in self.plugins:
583            if hasattr(item, "get_panels"):
584                ps = item.get_panels(self)
585                panels.extend(ps)
586       
587        # Show a default panel with some help information
588        # It also sets the size of the application windows
589        #TODO: Use this for slpash screen
590        if self.defaultPanel is None:
591            self.defaultPanel = DefaultPanel(self, -1, style=wx.RAISED_BORDER)
592        # add a blank default panel always present
593        self.panels["default"] = self.defaultPanel
594        self._mgr.AddPane(self.defaultPanel, wx.aui.AuiPaneInfo().
595                              Name("default").
596                              CenterPane().
597                              #CloseButton(False).
598                              #MinimizeButton(False).
599                              # This is where we set the size of
600                              # the application window
601                              BestSize(wx.Size(self._window_width, 
602                                               self._window_height)).
603                              Show())
604
605        #add data panel
606        self.panels["data_panel"] = self._data_panel
607        w, h = self._get_panels_size(self._data_panel)
608        self._mgr.AddPane(self._data_panel, wx.aui.AuiPaneInfo().
609                              Name(self._data_panel.window_name).
610                              Caption(self._data_panel.window_caption).
611                              Left().
612                              MinimizeButton().
613                              CloseButton(IS_WIN).
614                              TopDockable(False).
615                              BottomDockable(False).
616                              LeftDockable(True).
617                              RightDockable(False).
618                              BestSize(wx.Size(w, h)).
619                              Hide())
620
621        style = self.__gui_style & GUIFRAME.MANAGER_ON
622        data_pane = self._mgr.GetPane(self.panels["data_panel"].window_name)
623        if style != GUIFRAME.MANAGER_ON:
624            self._mgr.GetPane(self.panels["data_panel"].window_name).Hide()
625        else:
626            self._mgr.GetPane(self.panels["data_panel"].window_name).Show()
627           
628        # Add the panels to the AUI manager
629        for panel_class in panels:
630            p = panel_class
631            id = wx.NewId()
632            #w, h = self._get_panels_size(p)
633            # Check whether we need to put this panel
634            # in the center pane
635            if hasattr(p, "CENTER_PANE") and p.CENTER_PANE:
636                w, h = self._get_panels_size(p)
637                if p.CENTER_PANE:
638                    self.panels[str(id)] = p
639                    self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
640                                          Name(p.window_name).
641                                          CenterPane().
642                                          Center().
643                                          CloseButton(False).
644                                          Hide())
645            else:
646                self.panels[str(id)] = p
647                self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
648                                  Name(p.window_name).Caption(p.window_caption).
649                                  Right().
650                                  Dock().
651                                  TopDockable().
652                                  BottomDockable().
653                                  LeftDockable().
654                                  RightDockable().
655                                  MinimizeButton().
656                                  Hide())       
657     
658    def update_data(self, prev_data, new_data):
659        """
660        """
661        prev_id, data_state = self._data_manager.update_data(prev_data=prev_data, 
662                                       new_data=new_data)
663       
664        self._data_panel.remove_by_id(prev_id)
665        self._data_panel.load_data_list(data_state)
666       
667    def update_theory(self, data_id, theory, state=None):
668        """
669        """ 
670        data_state = self._data_manager.update_theory(data_id=data_id, 
671                                         theory=theory,
672                                         state=state) 
673        self._data_panel.load_data_list(data_state)
674       
675    def onfreeze(self, theory_id):
676        """
677        """
678        data_state_list = self._data_manager.freeze(theory_id)
679        self._data_panel.load_data_list(list=data_state_list)
680        for data_state in data_state_list.values():
681            new_plot = data_state.get_data()
682           
683            wx.PostEvent(self, NewPlotEvent(plot=new_plot,
684                                             title=new_plot.title))
685       
686    def freeze(self, data_id, theory_id):
687        """
688        """
689        data_state_list = self._data_manager.freeze_theory(data_id=data_id, 
690                                                theory_id=theory_id)
691        self._data_panel.load_data_list(list=data_state_list)
692        for data_state in data_state_list.values():
693            new_plot = data_state.get_data()
694            wx.PostEvent(self, NewPlotEvent(plot=new_plot,
695                                             title=new_plot.title))
696       
697    def delete_data(self, data):
698        """
699        """
700        self._current_perspective.delete_data(data)
701       
702   
703    def get_context_menu(self, plotpanel=None):
704        """
705        Get the context menu items made available
706        by the different plug-ins.
707        This function is used by the plotting module
708        """
709        if plotpanel is None:
710            return
711        menu_list = []
712        for item in self.plugins:
713            menu_list.extend(item.get_context_menu(plotpanel=plotpanel))
714        return menu_list
715       
716    def popup_panel(self, p):
717        """
718        Add a panel object to the AUI manager
719       
720        :param p: panel object to add to the AUI manager
721       
722        :return: ID of the event associated with the new panel [int]
723       
724        """
725        ID = wx.NewId()
726        self.panels[str(ID)] = p
727        count = 0
728        for item in self.panels:
729            if self.panels[item].window_name.startswith(p.window_name): 
730                count += 1
731        windowname = p.window_name
732        caption = p.window_caption
733        if count > 0:
734            windowname += str(count+1)
735            caption += (' '+str(count))
736        p.window_name = windowname
737        p.window_caption = caption
738           
739        style1 = self.__gui_style & GUIFRAME.FIXED_PANEL
740        style2 = self.__gui_style & GUIFRAME.FLOATING_PANEL
741        if style1 == GUIFRAME.FIXED_PANEL:
742            self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
743                              Name(windowname).
744                              Caption(caption).
745                              Position(10).
746                              Floatable().
747                              Right().
748                              Dock().
749                              MinimizeButton().
750                              Resizable(True).
751                              # Use a large best size to make sure the AUI
752                              # manager takes all the available space
753                              BestSize(wx.Size(PLOPANEL_WIDTH, 
754                                               PLOPANEL_HEIGTH)))
755       
756            self._popup_fixed_panel(p)
757   
758        elif style2 == GUIFRAME.FLOATING_PANEL:
759            self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
760                              Name(windowname).Caption(caption).
761                              MinimizeButton().
762                              Resizable(True).
763                              # Use a large best size to make sure the AUI
764                              #  manager takes all the available space
765                              BestSize(wx.Size(PLOPANEL_WIDTH, 
766                                               PLOPANEL_HEIGTH)))
767
768            self._popup_floating_panel(p)
769           
770        pane = self._mgr.GetPane(windowname)
771        self._mgr.MaximizePane(pane)
772        self._mgr.RestoreMaximizedPane()
773        # Register for showing/hiding the panel
774        wx.EVT_MENU(self, ID, self.on_view)
775        if p not in self.plot_panels.values():
776            self.plot_panels[ID] = p
777            if len(self.plot_panels) == 1:
778                self.panel_on_focus = p
779                self.set_panel_on_focus(None)
780            if self._data_panel is not None and \
781                self._plotting_plugin is not None:
782                ind = self._data_panel.cb_plotpanel.FindString('None')
783                if ind != wx.NOT_FOUND:
784                    self._data_panel.cb_plotpanel.Delete(ind)
785                if caption not in self._data_panel.cb_plotpanel.GetItems():
786                    self._data_panel.cb_plotpanel.Append(str(caption), p)
787
788        self._mgr.Update()
789        return ID
790       
791    def _setup_menus(self):
792        """
793        Set up the application menus
794        """
795        # Menu
796        self._menubar = wx.MenuBar()
797        self._add_menu_file()
798        self._add_menu_edit()
799        self._add_menu_view()
800        #self._add_menu_data()
801        self._add_menu_application()
802        self._add_menu_tool()
803        self._add_current_plugin_menu()
804        self._add_menu_window()
805        self._add_help_menu()
806        self.SetMenuBar(self._menubar)
807       
808    def _setup_tool_bar(self):
809        """
810        add toolbar to the frame
811        """
812        #set toolbar
813        self._toolbar = GUIToolBar(self, -1)
814        self.SetToolBar(self._toolbar)
815        self._update_toolbar_helper()
816        self._on_toggle_toolbar(event=None)
817   
818    def _update_toolbar_helper(self):
819        """
820        """
821        application_name = 'No Selected Analysis'
822        panel_name = 'No Panel on Focus'
823        if self._toolbar is  None:
824            return
825        if self.cpanel_on_focus is not None:
826            self.reset_bookmark_menu(self.cpanel_on_focus)
827        self._toolbar.update_toolbar(self.cpanel_on_focus)
828        if self._current_perspective is not None:
829            application_name = self._current_perspective.sub_menu
830        if self.cpanel_on_focus is not None:
831            panel_name = self.cpanel_on_focus.window_caption
832           
833        self._toolbar.update_button(application_name=application_name, 
834                                        panel_name=panel_name)
835       
836        self._toolbar.Realize()
837       
838    def _add_menu_tool(self):
839        """
840        Tools menu
841        Go through plug-ins and find tools to populate the tools menu
842        """
843        style = self.__gui_style & GUIFRAME.CALCULATOR_ON
844        if style == GUIFRAME.CALCULATOR_ON:
845            self._tool_menu = None
846            for item in self.plugins:
847                if hasattr(item, "get_tools"):
848                    for tool in item.get_tools():
849                        # Only create a menu if we have at least one tool
850                        if self._tool_menu is None:
851                            self._tool_menu = wx.Menu()
852                        id = wx.NewId()
853                        self._tool_menu.Append(id, tool[0], tool[1])
854                        wx.EVT_MENU(self, id, tool[2])
855            if self._tool_menu is not None:
856                self._menubar.Append(self._tool_menu, '&Tool')
857               
858    def _add_current_plugin_menu(self):
859        """
860        add current plugin menu
861        Look for plug-in menus
862        Add available plug-in sub-menus.
863        """
864        if (self._menubar is None) or (self._current_perspective is None):
865            return
866        #replace or add a new menu for the current plugin
867       
868        pos = self._menubar.FindMenu(str(self._applications_menu_name))
869        if pos != -1:
870            menu_list = self._current_perspective.populate_menu(self)
871            if menu_list:
872                for (menu, name) in menu_list:
873                    hidden_menu = self._menubar.Replace(pos, menu, name) 
874                    self._applications_menu_name = name
875                #self._applications_menu_pos = pos
876            else:
877                hidden_menu = self._menubar.Remove(pos)
878                self._applications_menu_name = None
879            #get the position of the menu when it first added
880            self._applications_menu_pos = pos
881           
882        else:
883            menu_list = self._current_perspective.populate_menu(self)
884            if menu_list:
885                for (menu,name) in menu_list:
886                    if self._applications_menu_pos == -1:
887                        self._menubar.Append(menu, name)
888                    else:
889                        self._menubar.Insert(self._applications_menu_pos, menu, name)
890                    self._applications_menu_name = name
891                 
892    def _add_help_menu(self):
893        """
894        add help menu
895        """
896        # Help menu
897        self._help_menu = wx.Menu()
898        style = self.__gui_style & GUIFRAME.WELCOME_PANEL_ON
899        if style == GUIFRAME.WELCOME_PANEL_ON or custom_config != None:
900            # add the welcome panel menu item
901            if self.defaultPanel is not None:
902                id = wx.NewId()
903                self._help_menu.Append(id, '&Welcome', '')
904                self._help_menu.AppendSeparator()
905                wx.EVT_MENU(self, id, self.show_welcome_panel)
906        # Look for help item in plug-ins
907        for item in self.plugins:
908            if hasattr(item, "help"):
909                id = wx.NewId()
910                self._help_menu.Append(id,'&%s Help' % item.sub_menu, '')
911                wx.EVT_MENU(self, id, item.help)
912        if config._do_aboutbox:
913            self._help_menu.AppendSeparator()
914            id = wx.NewId()
915            self._help_menu.Append(id,'&About', 'Software information')
916            wx.EVT_MENU(self, id, self._onAbout)
917       
918        # Checking for updates needs major refactoring to work with py2exe
919        # We need to make sure it doesn't hang the application if the server
920        # is not up. We also need to make sure there's a proper executable to
921        # run if we spawn a new background process.
922        #id = wx.NewId()
923        #self._help_menu.Append(id,'&Check for update',
924        #'Check for the latest version of %s' % config.__appname__)
925        #wx.EVT_MENU(self, id, self._check_update)
926        self._menubar.Append(self._help_menu, '&Help')
927           
928    def _add_menu_view(self):
929        """
930        add menu items under view menu
931        """
932        self._view_menu = wx.Menu()
933        style = self.__gui_style & GUIFRAME.MANAGER_ON
934        id = wx.NewId()
935        self._data_panel_menu = self._view_menu.Append(id,
936                                                '&Data Explorer ON', '')
937        wx.EVT_MENU(self, id, self.show_data_panel)
938        if style == GUIFRAME.MANAGER_ON:
939            self._data_panel_menu.SetText('Data Explorer OFF')
940        else:
941            self._data_panel_menu.SetText('Data Explorer ON')
942        self._view_menu.AppendSeparator()
943        id = wx.NewId()
944        style1 = self.__gui_style & GUIFRAME.TOOLBAR_ON
945        if style1 == GUIFRAME.TOOLBAR_ON:
946            self._toolbar_menu = self._view_menu.Append(id,'&Hide Toolbar', '')
947        else:
948            self._toolbar_menu = self._view_menu.Append(id,'&Show Toolbar', '')
949        wx.EVT_MENU(self, id, self._on_toggle_toolbar)
950       
951        if custom_config != None:
952            self._view_menu.AppendSeparator()
953            id = wx.NewId()
954            preference_menu = self._view_menu.Append(id,'Startup Setting', '')
955            wx.EVT_MENU(self, id, self._on_preference_menu)
956           
957        self._menubar.Append(self._view_menu, '&View')   
958         
959    def _on_preference_menu(self, event):     
960        """
961        Build a panel to allow to edit Mask
962        """
963       
964        from sans.guiframe.startup_configuration \
965        import StartupConfiguration as ConfDialog
966       
967        self.panel = ConfDialog(parent=self, gui=self.__gui_style)
968        #self.panel.Bind(wx.EVT_CLOSE, self._draw_masked_model)
969        self.panel.ShowModal()
970        #wx.PostEvent(self.parent, event)
971       
972    def _draw_masked_model(self,event):
973        """
974        Draw model image w/mask
975        """
976        event.Skip()
977
978        is_valid_qrange = self._update_paramv_on_fit()
979
980        if is_valid_qrange:
981            # try re draw the model plot if it exists
982            self._draw_model()
983            self.panel.Destroy() # frame
984            self.set_npts2fit()
985        elif self.model == None:
986            self.panel.Destroy()
987            self.set_npts2fit()
988            msg= "No model is found on updating MASK in the model plot... "
989            wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
990        else:
991            msg = ' Please consider your Q range, too.'
992            self.panel.ShowMessage(msg)
993
994    def _add_menu_window(self):
995        """
996        add a menu window to the menu bar
997        Window menu
998        Attach a menu item for each panel in our
999        panel list that also appears in a plug-in.
1000       
1001        Only add the panel menu if there is only one perspective and
1002        it has more than two panels.
1003        Note: the first plug-in is always the plotting plug-in.
1004        The first application
1005        #plug-in is always the second one in the list.
1006        """
1007        self._window_menu = wx.Menu()
1008        if self._plotting_plugin is not None:
1009            for (menu, name) in self._plotting_plugin.populate_menu(self):
1010                self._window_menu.AppendSubMenu(menu, name)
1011        self._menubar.Append(self._window_menu, '&Graph')
1012
1013        style = self.__gui_style & GUIFRAME.PLOTTING_ON
1014        if style == GUIFRAME.PLOTTING_ON:
1015            self._window_menu.AppendSeparator()
1016            id = wx.NewId()
1017            preferences_menu = wx.Menu()
1018            hint = "All plot panels will floating"
1019            preferences_menu.Append(id, '&Float', hint)
1020            wx.EVT_MENU(self, id, self.set_plotpanel_floating)
1021            id = wx.NewId()
1022            hint = "All plot panels will displayed within the frame"
1023            preferences_menu.Append(id, '&Dock', hint)
1024            wx.EVT_MENU(self, id, self.set_plotpanel_fixed)
1025
1026            self._window_menu.AppendSubMenu(preferences_menu,'&Preferences')
1027        if self._window_menu.GetMenuItemCount() == 0:
1028            pos = self._menubar.FindMenu('Graph')
1029            self._menubar.Remove(pos)
1030        #wx.EVT_MENU(self, id, self.show_preferences_panel)   
1031        """
1032        if len(self.plugins) == 2:
1033            plug = self.plugins[1]
1034            pers = plug.get_perspective()
1035       
1036            if len(pers) > 1:
1037                self._window_menu = wx.Menu()
1038                for item in self.panels:
1039                    if item == 'default':
1040                        continue
1041                    panel = self.panels[item]
1042                    if panel.window_name in pers:
1043                        self._window_menu.Append(int(item),
1044                                                  panel.window_caption,
1045                                        "Show %s window" % panel.window_caption)
1046                        wx.EVT_MENU(self, int(item), self.on_view)
1047                self._menubar.Append(self._window_menu, '&Window')
1048                """
1049               
1050    def _add_menu_application(self):
1051        """
1052       
1053        # Attach a menu item for each defined perspective or application.
1054        # Only add the perspective menu if there are more than one perspectives
1055        add menu application
1056        """
1057        style = self.__gui_style & GUIFRAME.MULTIPLE_APPLICATIONS
1058        if style == GUIFRAME.MULTIPLE_APPLICATIONS:
1059            plug_data_count = False
1060            plug_no_data_count = False
1061            self._applications_menu = wx.Menu()
1062            pos = 0
1063            separator = self._applications_menu.AppendSeparator()
1064            for plug in self.plugins:
1065                if len(plug.get_perspective()) > 0:
1066                    id = wx.NewId()
1067                    if plug.use_data():
1068                       
1069                        self._applications_menu.InsertCheckItem(pos, id, plug.sub_menu,
1070                                      "Switch to analysis: %s" % plug.sub_menu)
1071                        plug_data_count = True
1072                        pos += 1
1073                    else:
1074                        plug_no_data_count = True
1075                        self._applications_menu.AppendCheckItem(id, plug.sub_menu,
1076                                      "Switch to analysis: %s" % plug.sub_menu)
1077                    wx.EVT_MENU(self, id, plug.on_perspective)
1078            #self._applications_menu.
1079            if (not plug_data_count or not plug_no_data_count):
1080                self._applications_menu.RemoveItem(separator)
1081            self._menubar.Append(self._applications_menu, '&Analysis')
1082            self._check_applications_menu()
1083           
1084    def _populate_file_menu(self):
1085        """
1086        Insert menu item under file menu
1087        """
1088        for plugin in self.plugins:
1089            if len(plugin.populate_file_menu()) > 0:
1090                for item in plugin.populate_file_menu():
1091                    m_name, m_hint, m_handler = item
1092                    id = wx.NewId()
1093                    self._file_menu.Append(id, m_name, m_hint)
1094                    wx.EVT_MENU(self, id, m_handler)
1095                self._file_menu.AppendSeparator()
1096               
1097    def _add_menu_file(self):
1098        """
1099        add menu file
1100        """
1101       
1102         # File menu
1103        self._file_menu = wx.Menu()
1104        #append item from plugin under menu file if necessary
1105        self._populate_file_menu()
1106        style = self.__gui_style & GUIFRAME.DATALOADER_ON
1107        style1 = self.__gui_style & GUIFRAME.MULTIPLE_APPLICATIONS
1108       
1109        id = wx.NewId()
1110        hint_load_file = "read all analysis states save previously"
1111        self._save_appl_menu = self._file_menu.Append(id, 
1112                                '&Open Project', hint_load_file)
1113        wx.EVT_MENU(self, id, self._on_open_state_project)
1114           
1115        if style1 == GUIFRAME.MULTIPLE_APPLICATIONS:
1116            # some menu of plugin to be seen under file menu
1117            hint_load_file = "Read a status files and load"
1118            hint_load_file += " them into the analysis"
1119            id = wx.NewId()
1120            self._save_appl_menu = self._file_menu.Append(id, 
1121                                    '&Open Analysis', hint_load_file)
1122            wx.EVT_MENU(self, id, self._on_open_state_application)
1123               
1124        self._file_menu.AppendSeparator()
1125        id = wx.NewId()
1126        self._file_menu.Append(id, '&Save Project',
1127                             'Save the state of the whole analysis')
1128        wx.EVT_MENU(self, id, self._on_save_project)
1129        if style1 == GUIFRAME.MULTIPLE_APPLICATIONS:
1130            #self._file_menu.AppendSeparator()
1131            id = wx.NewId()
1132            self._save_appl_menu = self._file_menu.Append(id, 
1133                                                      '&Save Analysis',
1134                        'Save state of the current active analysis panel')
1135            wx.EVT_MENU(self, id, self._on_save_application)
1136       
1137        self._file_menu.AppendSeparator()
1138       
1139        id = wx.NewId()
1140        self._file_menu.Append(id, '&Quit', 'Exit') 
1141        wx.EVT_MENU(self, id, self.Close)
1142        # Add sub menus
1143        self._menubar.Append(self._file_menu, '&File')
1144       
1145    def _add_menu_edit(self):
1146        """
1147        add menu edit
1148        """
1149        # Edit Menu
1150        self._edit_menu = wx.Menu()
1151        self._edit_menu.Append(GUIFRAME_ID.UNDO_ID, '&Undo', 
1152                               'Undo the previous action')
1153        wx.EVT_MENU(self, GUIFRAME_ID.UNDO_ID, self.on_undo_panel)
1154        self._edit_menu.Append(GUIFRAME_ID.REDO_ID, '&Redo', 
1155                               'Redo the previous action')
1156        wx.EVT_MENU(self, GUIFRAME_ID.REDO_ID, self.on_redo_panel)
1157        self._edit_menu.AppendSeparator()
1158        self._edit_menu.Append(GUIFRAME_ID.PREVIEW_ID, '&Report',
1159                               'Preview current panel')
1160        wx.EVT_MENU(self, GUIFRAME_ID.PREVIEW_ID, self.on_preview_panel)
1161        self._edit_menu.Append(GUIFRAME_ID.PRINT_ID, '&Print',
1162                               'Print current panel')
1163        wx.EVT_MENU(self, GUIFRAME_ID.PRINT_ID, self.on_print_panel)
1164        self._edit_menu.Append(GUIFRAME_ID.RESET_ID, '&Reset', 
1165                               'Reset current panel')
1166        wx.EVT_MENU(self, GUIFRAME_ID.RESET_ID, self.on_reset_panel)
1167   
1168        self._menubar.Append(self._edit_menu,  '&Edit')
1169        self.enable_edit_menu()
1170       
1171    def get_style(self):
1172        """
1173        """
1174        return  self.__gui_style
1175   
1176    def _add_menu_data(self):
1177        """
1178        Add menu item item data to menu bar
1179        """
1180        if self._data_plugin is not None:
1181            menu_list = self._data_plugin.populate_menu(self)
1182            if menu_list:
1183                for (menu, name) in menu_list:
1184                    self._menubar.Append(menu, name)
1185       
1186                       
1187    def _on_toggle_toolbar(self, event=None):
1188        """
1189        hide or show toolbar
1190        """
1191        if self._toolbar is None:
1192            return
1193        if self._toolbar.IsShown():
1194            if self._toolbar_menu is not None:
1195                self._toolbar_menu.SetItemLabel('Show Toolbar')
1196            self._toolbar.Hide()
1197        else:
1198            if self._toolbar_menu is not None:
1199                self._toolbar_menu.SetItemLabel('Hide Toolbar')
1200            self._toolbar.Show()
1201        self._toolbar.Realize()
1202       
1203    def _on_status_event(self, evt):
1204        """
1205        Display status message
1206        """
1207        self.sb.set_status(event=evt)
1208       
1209    def on_view(self, evt):
1210        """
1211        A panel was selected to be shown. If it's not already
1212        shown, display it.
1213       
1214        :param evt: menu event
1215       
1216        """
1217        panel_id = str(evt.GetId())
1218        self.on_set_plot_focus(self.panels[panel_id])
1219        self.show_panel(evt.GetId(), 'on')     
1220        wx.CallLater(5, self.set_schedule(True))
1221        self.set_plot_unfocus()
1222       
1223    def on_close_welcome_panel(self):
1224        """
1225        Close the welcome panel
1226        """
1227        if self.defaultPanel is None:
1228            return 
1229        default_panel = self._mgr.GetPane(self.panels["default"].window_name)
1230        if default_panel.IsShown():
1231            default_panel.Hide()
1232            # Recover current perspective
1233            perspective = self._current_perspective
1234            perspective.on_perspective(event=None)
1235            self._mgr.Update()
1236            # Show toolbar
1237            style = self.__gui_style & GUIFRAME.TOOLBAR_ON
1238            if (style == GUIFRAME.TOOLBAR_ON) & (not self._toolbar.IsShown()):
1239                self._on_toggle_toolbar()
1240           
1241    def show_welcome_panel(self, event):
1242        """   
1243        Display the welcome panel
1244        """
1245        if self.defaultPanel is None:
1246            return 
1247        for id, panel in self.panels.iteritems():
1248            if id  ==  'default':
1249                # Show default panel
1250                if not self._mgr.GetPane(self.panels["default"].window_name).IsShown():
1251                    self._mgr.GetPane(self.panels["default"].window_name).Show(True)
1252            elif id == "data_panel":
1253                flag = self._mgr.GetPane(self.panels["data_panel"].window_name).IsShown()
1254                self._mgr.GetPane(self.panels["data_panel"].window_name).Show(flag)
1255            elif panel not in self.plot_panels.values() :
1256                self._mgr.GetPane(self.panels[id].window_name).IsShown()
1257                self._mgr.GetPane(self.panels[id].window_name).Hide()
1258        #style = self.__gui_style & GUIFRAME.TOOLBAR_ON
1259        #if (style == GUIFRAME.TOOLBAR_ON) & (self._toolbar.IsShown()):
1260        #    #    self._toolbar.Show(True)
1261        #    self._on_toggle_toolbar()
1262
1263        self._mgr.Update()
1264       
1265    def show_panel(self, uid, show=None):
1266        """
1267        Shows the panel with the given id
1268       
1269        :param uid: unique ID number of the panel to show
1270       
1271        """
1272        ID = str(uid)
1273        config.printEVT("show_panel: %s" % ID)
1274        if ID in self.panels.keys():
1275            if not self._mgr.GetPane(self.panels[ID].window_name).IsShown(): 
1276                if show == 'on':
1277                    self._mgr.GetPane(self.panels[ID].window_name).Show()   
1278                elif self.panels[ID].window_caption.split(" ")[0] == \
1279                                                            "Residuals":
1280                    self._mgr.GetPane(self.panels[ID].window_name).Hide()
1281                else:
1282                    self._mgr.GetPane(self.panels[ID].window_name).Show()
1283                # Hide default panel
1284                self._mgr.GetPane(self.panels["default"].window_name).Hide()
1285        self._mgr.Update()     
1286        self._redraw_idle()
1287                   
1288    def hide_panel(self, uid):
1289        """
1290        hide panel
1291        """
1292        ID = str(uid)
1293        caption = self.panels[ID].window_caption
1294        config.printEVT("hide_panel: %s" % ID)
1295        if ID in self.panels.keys():
1296            if self._mgr.GetPane(self.panels[ID].window_name).IsShown():
1297                self._mgr.GetPane(self.panels[ID].window_name).Hide()
1298                if self._data_panel is not None and \
1299                            ID in self.plot_panels.keys():
1300                    self._data_panel.cb_plotpanel.Append(str(caption), p)
1301                # Hide default panel
1302                self._mgr.GetPane(self.panels["default"].window_name).Hide()
1303            self._mgr.Update()
1304               
1305    def delete_panel(self, uid):
1306        """
1307        delete panel given uid
1308        """
1309        ID = str(uid)
1310        config.printEVT("delete_panel: %s" % ID)
1311        caption = self.panels[ID].window_caption
1312        if ID in self.panels.keys():
1313            self.panel_on_focus = None
1314            panel = self.panels[ID]
1315            self._plotting_plugin.delete_panel(panel.group_id)
1316            self._mgr.DetachPane(panel)
1317            panel.Hide()
1318            panel.clear()
1319            panel.Close()
1320            self._mgr.Update()
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        self.__gui_style &= (~GUIFRAME.FIXED_PANEL)
1974        self.__gui_style |= GUIFRAME.FLOATING_PANEL
1975        for p in self.panels.values():
1976            plot_panel = self._plotting_plugin.plot_panels.values()
1977            for p in self.panels.values():
1978                if p in plot_panel:
1979                    self._popup_floating_panel(p)
1980       
1981    def set_plotpanel_fixed(self, event=None):
1982        """
1983        make the plot panel fixed
1984        """
1985        self.__gui_style &= (~GUIFRAME.FLOATING_PANEL)
1986        self.__gui_style |= GUIFRAME.FIXED_PANEL
1987        plot_panel = []
1988        if self._plotting_plugin is not None:
1989            plot_panel = self._plotting_plugin.plot_panels.values()
1990            for p in self.panels.values():
1991                if 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            flag = self._mgr.GetPane(p.window_name).IsShown()
2007            self._mgr.GetPane(p.window_name).Show(flag)
2008            self._mgr.Update()
2009           
2010    def _popup_floating_panel(self, p):
2011        """
2012        """
2013        style = self.__gui_style &  GUIFRAME.FLOATING_PANEL
2014        if style == GUIFRAME.FLOATING_PANEL: 
2015            self._mgr.GetPane(p.window_name).Floatable(True)
2016            self._mgr.GetPane(p.window_name).Float()
2017            self._mgr.GetPane(p.window_name).Dockable(False)
2018            flag = self._mgr.GetPane(p.window_name).IsShown()
2019            self._mgr.GetPane(p.window_name).Show(flag)
2020            self._mgr.Update()
2021           
2022    def enable_add_data(self, new_plot):
2023        """
2024        Enable append data on a plot panel
2025        """
2026
2027        if self.panel_on_focus not in self._plotting_plugin.plot_panels.values():
2028            return
2029        is_theory = len(self.panel_on_focus.plots) <= 1 and \
2030            self.panel_on_focus.plots.values()[0].__class__.__name__ == "Theory1D"
2031           
2032        is_data2d = hasattr(new_plot, 'data')
2033       
2034        is_data1d = self.panel_on_focus.__class__.__name__ == "ModelPanel1D"\
2035            and self.panel_on_focus.group_id is not None
2036        has_meta_data = hasattr(new_plot, 'meta_data')
2037       
2038        #disable_add_data if the data is being recovered from  a saved state file.
2039        is_state_data = False
2040        if has_meta_data:
2041            if 'invstate' in new_plot.meta_data: is_state_data = True
2042            if  'prstate' in new_plot.meta_data: is_state_data = True
2043            if  'fitstate' in new_plot.meta_data: is_state_data = True
2044   
2045        return is_data1d and not is_data2d and not is_theory and not is_state_data
2046   
2047    def enable_edit_menu(self):
2048        """
2049        enable menu item under edit menu depending on the panel on focus
2050        """
2051        if self.cpanel_on_focus is not None and self._edit_menu is not None:
2052            flag = self.cpanel_on_focus.get_undo_flag()
2053            self._edit_menu.Enable(GUIFRAME_ID.UNDO_ID, flag)
2054            flag = self.cpanel_on_focus.get_redo_flag()
2055            self._edit_menu.Enable(GUIFRAME_ID.REDO_ID, flag)
2056            flag = self.cpanel_on_focus.get_print_flag()
2057            self._edit_menu.Enable(GUIFRAME_ID.PRINT_ID, flag)
2058            flag = self.cpanel_on_focus.get_preview_flag()
2059            self._edit_menu.Enable(GUIFRAME_ID.PREVIEW_ID, flag)
2060            flag = self.cpanel_on_focus.get_reset_flag()
2061            self._edit_menu.Enable(GUIFRAME_ID.RESET_ID, flag)
2062        else:
2063            flag = False
2064            self._edit_menu.Enable(GUIFRAME_ID.UNDO_ID, flag)
2065            self._edit_menu.Enable(GUIFRAME_ID.REDO_ID, flag)
2066            self._edit_menu.Enable(GUIFRAME_ID.PRINT_ID, flag)
2067            self._edit_menu.Enable(GUIFRAME_ID.PREVIEW_ID, flag)
2068            self._edit_menu.Enable(GUIFRAME_ID.RESET_ID, flag)
2069           
2070    def on_undo_panel(self, event=None):
2071        """
2072        undo previous action of the last panel on focus if possible
2073        """
2074        if self.cpanel_on_focus is not None:
2075            self.cpanel_on_focus.on_undo(event)
2076           
2077    def on_redo_panel(self, event=None):
2078        """
2079        redo the last cancel action done on the last panel on focus
2080        """
2081        if self.cpanel_on_focus is not None:
2082            self.cpanel_on_focus.on_redo(event)
2083           
2084    def on_bookmark_panel(self, event=None):
2085        """
2086        bookmark panel
2087        """
2088        if self.cpanel_on_focus is not None:
2089            self.cpanel_on_focus.on_bookmark(event)
2090           
2091    def append_bookmark(self, event=None):
2092        """
2093        Bookmark available information of the panel on focus
2094        """
2095        self._toolbar.append_bookmark(event)
2096           
2097    def on_save_panel(self, event=None):
2098        """
2099        save possible information on the current panel
2100        """
2101        if self.cpanel_on_focus is not None:
2102            self.cpanel_on_focus.on_save(event)
2103           
2104    def on_preview_panel(self, event=None):
2105        """
2106        preview information on the panel on focus
2107        """
2108        if self.cpanel_on_focus is not None:
2109            self.cpanel_on_focus.on_preview(event)
2110           
2111    def on_print_panel(self, event=None):
2112        """
2113        print available information on the last panel on focus
2114        """
2115        if self.cpanel_on_focus is not None:
2116            self.cpanel_on_focus.on_print(event)
2117           
2118    def on_zoom_panel(self, event=None):
2119        """
2120        zoom on the current panel if possible
2121        """
2122        if self.cpanel_on_focus is not None:
2123            self.cpanel_on_focus.on_zoom(event)
2124           
2125    def on_zoom_in_panel(self, event=None):
2126        """
2127        zoom in of the panel on focus
2128        """
2129        if self.cpanel_on_focus is not None:
2130            self.cpanel_on_focus.on_zoom_in(event)
2131           
2132    def on_zoom_out_panel(self, event=None):
2133        """
2134        zoom out on the panel on focus
2135        """
2136        if self.cpanel_on_focus is not None:
2137            self.cpanel_on_focus.on_zoom_out(event)
2138           
2139    def on_drag_panel(self, event=None):
2140        """
2141        drag apply to the panel on focus
2142        """
2143        if self.cpanel_on_focus is not None:
2144            self.cpanel_on_focus.on_drag(event)
2145           
2146    def on_reset_panel(self, event=None):
2147        """
2148        reset the current panel
2149        """
2150        if self.cpanel_on_focus is not None:
2151            self.cpanel_on_focus.on_reset(event)
2152           
2153    def enable_undo(self):
2154        """
2155        enable undo related control
2156        """
2157        if self.cpanel_on_focus is not None:
2158            self._toolbar.enable_undo(self.cpanel_on_focus)
2159           
2160    def enable_redo(self):
2161        """
2162        enable redo
2163        """
2164        if self.cpanel_on_focus is not None:
2165            self._toolbar.enable_redo(self.cpanel_on_focus)
2166           
2167    def enable_bookmark(self):
2168        """
2169        Bookmark
2170        """
2171        if self.cpanel_on_focus is not None:
2172            self._toolbar.enable_bookmark(self.cpanel_on_focus)
2173           
2174    def enable_save(self):
2175        """
2176        save
2177        """
2178        if self.cpanel_on_focus is not None:
2179            self._toolbar.enable_save(self.cpanel_on_focus)
2180           
2181    def enable_preview(self):
2182        """
2183        preview
2184        """
2185        if self.cpanel_on_focus is not None:
2186            self._toolbar.enable_preview(self.cpanel_on_focus)
2187           
2188    def enable_print(self):
2189        """
2190        print
2191        """
2192        if self.cpanel_on_focus is not None:
2193            self._toolbar.enable_print(self.cpanel_on_focus)
2194           
2195    def enable_zoom(self):
2196        """
2197        zoom
2198        """
2199        if self.cpanel_on_focus is not None:
2200            self._toolbar.enable_zoom(self.panel_on_focus)
2201           
2202    def enable_zoom_in(self):
2203        """
2204        zoom in
2205        """
2206        if self.cpanel_on_focus is not None:
2207            self._toolbar.enable_zoom_in(self.panel_on_focus)
2208           
2209    def enable_zoom_out(self):
2210        """
2211        zoom out
2212        """
2213        if self.cpanel_on_focus is not None:
2214            self._toolbar.enable_zoom_out(self.panel_on_focus)
2215           
2216    def enable_drag(self, event=None):
2217        """
2218        drag
2219        """
2220        if self.cpanel_on_focus is not None:
2221            self._toolbar.enable_drag(self.panel_on_focus)
2222           
2223    def enable_reset(self):
2224        """
2225        reset the current panel
2226        """
2227        if self.cpanel_on_focus is not None:
2228            self._toolbar.enable_reset(self.panel_on_focus)
2229
2230    def set_schedule_full_draw(self, panel=None, func='del'):
2231        """
2232        Add/subtract the schedule full draw list with the panel given
2233       
2234        :param panel: plot panel
2235        :param func: append or del [string]
2236        """
2237
2238        # append this panel in the schedule list if not in yet
2239        if func == 'append':
2240            if not panel in self.schedule_full_draw_list:
2241                self.schedule_full_draw_list.append(panel) 
2242        # remove this panel from schedule list
2243        elif func == 'del':
2244            if len(self.schedule_full_draw_list) > 0:
2245                if panel in self.schedule_full_draw_list:
2246                    self.schedule_full_draw_list.remove(panel)
2247
2248        # reset the schdule
2249        if len(self.schedule_full_draw_list) == 0:
2250            self.schedule = False
2251        else:
2252            self.schedule = True   
2253       
2254    def full_draw(self):
2255        """
2256        Draw the panels with axes in the schedule to full dwar list
2257        """
2258        count = len(self.schedule_full_draw_list)
2259        #if not self.schedule:
2260        if count < 1:
2261            self.set_schedule(False)
2262            return
2263        else:
2264            ind = 0
2265            # if any of the panel is shown do full_draw
2266            for panel in self.schedule_full_draw_list:
2267                ind += 1
2268                if self._mgr.GetPane(panel.window_name).IsShown():
2269                    break
2270                # otherwise, return
2271                if ind == count:
2272                    return
2273
2274        #Simple redraw only for a panel shown
2275        def f_draw(panel):
2276            """
2277            Draw A panel in the full dwar list
2278            """
2279            try:
2280                # This checking of GetCapture is to stop redrawing
2281                # while any panel is capture.
2282                if self.GetCapture() == None:
2283                    # draw if possible
2284                    panel.set_resizing(False)
2285                    panel.draw_plot()
2286                    # Check if the panel is not shown
2287                    if not self._mgr.GetPane(panel.window_name).IsShown():
2288                        self._mgr.GetPane(panel.window_name).Hide()
2289            except:
2290                pass
2291        #print self.callback,self.schedule,self.schedule_full_draw_list
2292       
2293        # Draw all panels       
2294        map(f_draw, self.schedule_full_draw_list)
2295       
2296        # Reset the attr 
2297        if len(self.schedule_full_draw_list) == 0:
2298            self.set_schedule(False)
2299        else:
2300            self.set_schedule(True)
2301        # do not update mgr
2302        #self._mgr.Update()
2303       
2304    def set_schedule(self, schedule=False): 
2305        """
2306        Set schedule
2307        """
2308        self.schedule = schedule
2309               
2310    def get_schedule(self): 
2311        """
2312        Get schedule
2313        """
2314        return self.schedule
2315   
2316    def on_set_plot_focus(self, panel):
2317        """
2318        Set focus on a plot panel
2319        """
2320        self.set_plot_unfocus()
2321        panel.on_set_focus(None) 
2322        # set focusing panel
2323        self.panel_on_focus = panel 
2324        self.set_panel_on_focus(None)
2325   
2326    def set_plot_unfocus(self): 
2327        """
2328        Un focus all plot panels
2329        """
2330        for plot in self.plot_panels.values():
2331            plot.on_kill_focus(None)
2332
2333    def _onDrawIdle(self, *args, **kwargs):
2334        """
2335        ReDraw with axes
2336        """
2337        # check if it is time to redraw
2338        if self.GetCapture() == None:
2339            # Draw plot, changes resizing too
2340            self.full_draw()
2341           
2342        # restart idle       
2343        self._redraw_idle(*args, **kwargs)
2344
2345           
2346    def _redraw_idle(self, *args, **kwargs):
2347        """
2348        Restart Idle
2349        """
2350        # restart idle   
2351        self.idletimer.Restart(55, *args, **kwargs)
2352
2353       
2354class DefaultPanel(wx.Panel, PanelBase):
2355    """
2356    Defines the API for a panels to work with
2357    the GUI manager
2358    """
2359    ## Internal nickname for the window, used by the AUI manager
2360    window_name = "default"
2361    ## Name to appear on the window title bar
2362    window_caption = "Welcome panel"
2363    ## Flag to tell the AUI manager to put this panel in the center pane
2364    CENTER_PANE = True
2365    def __init__(self, parent, *args, **kwds):
2366        wx.Panel.__init__(self, parent, *args, **kwds)
2367        PanelBase.__init__(self, parent)
2368   
2369
2370
2371# Toy application to test this Frame
2372class ViewApp(wx.App):
2373    """
2374    """
2375    def OnInit(self):
2376        """
2377        """
2378        pos, size = self.window_placement((GUIFRAME_WIDTH, GUIFRAME_HEIGHT))
2379        self.frame = ViewerFrame(parent=None, 
2380                                 title=APPLICATION_NAME, 
2381                                 pos=pos, 
2382                                 gui_style = DEFAULT_STYLE,
2383                                 size=size) 
2384        self.frame.Hide()
2385        self.s_screen = None
2386        try:
2387            # make sure the current dir is App dir when it starts
2388            temp_path = os.path.dirname(os.path.sys.path[0])
2389            os.chdir(temp_path)
2390        except:
2391            pass
2392        # Display a splash screen on top of the frame.
2393        if len(sys.argv) > 1 and '--time' in sys.argv[1:]:
2394            log_time("Starting to display the splash screen")
2395        try:
2396            if os.path.isfile(SPLASH_SCREEN_PATH):
2397                self.s_screen = self.display_splash_screen(parent=self.frame, 
2398                                        path=SPLASH_SCREEN_PATH)
2399            else:
2400                self.frame.Show()   
2401        except:
2402            if self.s_screen is not None:
2403                self.s_screen.Close()
2404            msg = "Cannot display splash screen\n"
2405            msg += str (sys.exc_value)
2406            logging.error(msg)
2407            self.frame.Show()
2408           
2409        if hasattr(self.frame, 'special'):
2410            self.frame.special.SetCurrent()
2411        self.SetTopWindow(self.frame)
2412        try:
2413            self.open_file()
2414        except:
2415            msg = "%s Could not load " % str(APPLICATION_NAME)
2416            msg += "input file from command line.\n"
2417            logging.error(msg)
2418        return True
2419
2420    def open_file(self):
2421        """
2422        open a state file at the start of the application
2423        """
2424        input_file = None
2425        if len(sys.argv) >= 2:
2426            cmd = sys.argv[0].lower()
2427            if os.path.isfile(cmd):
2428                basename  = os.path.basename(cmd)
2429                app_py = str(APPLICATION_NAME).lower() + '.py'
2430                app_exe = str(APPLICATION_NAME).lower() + '.exe'
2431                if basename.lower() in [app_py, app_exe]:
2432                    input_file = sys.argv[1]
2433        if input_file is None:
2434            return
2435        if self.frame is not None:
2436            self.frame.set_input_file(input_file=input_file)
2437         
2438           
2439    def set_manager(self, manager):
2440        """
2441        Sets a reference to the application manager
2442        of the GUI manager (Frame)
2443        """
2444        self.frame.set_manager(manager)
2445       
2446    def build_gui(self):
2447        """
2448        Build the GUI
2449        """
2450        #try to load file at the start
2451        try:
2452            self.open_file()
2453        except:
2454            raise
2455        self.frame.build_gui()
2456        #if self.s_screen is not None and self.s_screen.IsShown():
2457        #    self.s_screen.Close()
2458       
2459    def set_welcome_panel(self, panel_class):
2460        """
2461        Set the welcome panel
2462       
2463        :param panel_class: class of the welcome panel to be instantiated
2464       
2465        """
2466        self.frame.set_welcome_panel(panel_class)
2467       
2468    def add_perspective(self, perspective):
2469        """
2470        Manually add a perspective to the application GUI
2471        """
2472        self.frame.add_perspective(perspective)
2473   
2474    def window_placement(self, size):
2475        """
2476        Determines the position and size of the application frame such that it
2477        fits on the user's screen without obstructing (or being obstructed by)
2478        the Windows task bar.  The maximum initial size in pixels is bounded by
2479        WIDTH x HEIGHT.  For most monitors, the application
2480        will be centered on the screen; for very large monitors it will be
2481        placed on the left side of the screen.
2482        """
2483        window_width, window_height = size
2484        screen_size = wx.GetDisplaySize()
2485        window_height = window_height if screen_size[1]>window_height else screen_size[1]-50
2486        window_width  = window_width if screen_size[0]> window_width else screen_size[0]-50
2487        xpos = ypos = 0
2488
2489        # Note that when running Linux and using an Xming (X11) server on a PC
2490        # with a dual  monitor configuration, the reported display size may be
2491        # that of both monitors combined with an incorrect display count of 1.
2492        # To avoid displaying this app across both monitors, we check for
2493        # screen 'too big'.  If so, we assume a smaller width which means the
2494        # application will be placed towards the left hand side of the screen.
2495
2496        _, _, x, y = wx.Display().GetClientArea() # size excludes task bar
2497        if len(sys.argv) > 1 and '--platform' in sys.argv[1:]:
2498            w, h = wx.DisplaySize()  # size includes task bar area
2499        if x > 1920: x = 1280  # display on left side, not centered on screen
2500        if x > window_width:  xpos = (x - window_width)/2
2501        if y > window_height: ypos = (y - window_height)/2
2502
2503        # Return the suggested position and size for the application frame.
2504        return (xpos, ypos), (min(x, window_width), min(y, window_height))
2505   
2506    def display_splash_screen(self, parent, 
2507                              path=SPLASH_SCREEN_PATH):
2508        """Displays the splash screen.  It will exactly cover the main frame."""
2509       
2510        # Prepare the picture.  On a 2GHz intel cpu, this takes about a second.
2511        x, y = parent.GetSizeTuple()
2512        image = wx.Image(path, wx.BITMAP_TYPE_PNG)
2513        image.Rescale(SPLASH_SCREEN_WIDTH, 
2514                      SPLASH_SCREEN_HEIGHT, wx.IMAGE_QUALITY_HIGH)
2515        bm = image.ConvertToBitmap()
2516
2517        # Create and show the splash screen.  It will disappear only when the
2518        # program has entered the event loop AND either the timeout has expired
2519        # or the user has left clicked on the screen.  Thus any processing
2520        # performed in this routine (including sleeping) or processing in the
2521        # calling routine (including doing imports) will prevent the splash
2522        # screen from disappearing.
2523        #
2524        # Note that on Linux, the timeout appears to occur immediately in which
2525        # case the splash screen disappears upon entering the event loop.
2526        s_screen = wx.SplashScreen(bitmap=bm,
2527                         splashStyle=(wx.SPLASH_TIMEOUT|
2528                                              wx.SPLASH_CENTRE_ON_SCREEN),
2529                                 style=(wx.SIMPLE_BORDER|
2530                                        wx.FRAME_NO_TASKBAR|
2531                                        wx.STAY_ON_TOP),
2532                                       
2533                        milliseconds=SS_MAX_DISPLAY_TIME,
2534                        parent=parent,
2535                        id=wx.ID_ANY)
2536        from gui_statusbar import SPageStatusbar
2537        statusBar = SPageStatusbar(s_screen)
2538        s_screen.SetStatusBar(statusBar)
2539        s_screen.Bind(wx.EVT_CLOSE, self.on_close_splash_screen)
2540        s_screen.Show()
2541        return s_screen
2542       
2543       
2544    def on_close_splash_screen(self, event):
2545        """
2546        """
2547        self.frame.Show(True)
2548        event.Skip()
2549     
2550if __name__ == "__main__": 
2551    app = ViewApp(0)
2552    app.MainLoop()
2553
2554             
Note: See TracBrowser for help on using the repository browser.