source: sasview/sansguiframe/src/sans/guiframe/gui_manager.py @ c994f8f

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

added custom path saving by view setting

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