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

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

working data processor grid

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