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

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 3d2d54a6 was 3d2d54a6, checked in by Jessica Tumarkin <jtumarki@…>, 13 years ago

Committing changes that were made for color selection

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