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

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

correction: default folder for inv and pr

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