source: sasview/guiframe/gui_manager.py @ 3b11d0d

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

revert uncheck all and remove welcome

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