source: sasview/guiframe/gui_manager.py @ 977a965

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

minor fixes including paste info

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