source: sasview/guiframe/gui_manager.py @ 6ac1cf5

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

working on guiframe in batch mode

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