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

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 caf3a08f was caf3a08f, checked in by Gervaise Alina <gervyh@…>, 13 years ago

add functon to output result to excel

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