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

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

modify batch dialog to frame window

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