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

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

control menu differently on app

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