source: sasview/guiframe/gui_manager.py @ 64e44c1

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

revert some code

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