source: sasview/guiframe/gui_manager.py @ 7a8faf8

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

make sure the combobox of datapanel get the proper number of panel

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