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

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

remember the last folder opened/saved

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