source: sasview/guiframe/gui_manager.py @ a9e489c

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

finished menu re-arrange

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