source: sasview/guiframe/gui_manager.py @ 1c95d15

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

check if the toolbar is created before trying to update it

  • Property mode set to 100644
File size: 81.0 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
[db10f97]18
[41d466f]19try:
20    # Try to find a local config
21    import imp
22    path = os.getcwd()
[cbb2e40]23    if(os.path.isfile("%s/%s.py" % (path, 'local_config'))) or \
[32c0841]24        (os.path.isfile("%s/%s.pyc" % (path, 'local_config'))):
25        fObj, path, descr = imp.find_module('local_config', [path])
26        config = imp.load_module('local_config', fObj, path, descr) 
[278cc25]27    else:
[cbb2e40]28        # Try simply importing local_config
29        import local_config as config
[41d466f]30except:
31    # Didn't find local config, load the default
32    import config
[4e9583c]33   
34import warnings
35warnings.simplefilter("ignore")
[3c44c66]36
[4e9583c]37import logging
[32c0841]38
[f444b20]39from sans.guiframe.events import EVT_STATUS
[4e4d3bb]40from sans.guiframe.events import EVT_APPEND_BOOKMARK
[a45037aa]41from sans.guiframe.events import EVT_PANEL_ON_FOCUS
[f444b20]42from sans.guiframe.events import StatusEvent
43from sans.guiframe.events import NewPlotEvent
[f036c692]44from sans.guiframe.gui_style import GUIFRAME
45from sans.guiframe.gui_style import GUIFRAME_ID
[52b8b74]46from sans.guiframe.events import NewLoadedDataEvent
[3feed3e]47from sans.guiframe.data_panel import DataPanel
[d828481]48from sans.guiframe.panel_base import PanelBase
[f036c692]49from sans.guiframe.gui_toolbar import GUIToolBar
[75fbd17]50from DataLoader.loader import Loader
51
[b5ca223]52
[957723f]53#read some constants from config
54APPLICATION_STATE_EXTENSION = config.APPLICATION_STATE_EXTENSION
55APPLICATION_NAME = config.__appname__
56SPLASH_SCREEN_PATH = config.SPLASH_SCREEN_PATH
57DEFAULT_STYLE = config.DEFAULT_STYLE
58SPLASH_SCREEN_WIDTH = config.SPLASH_SCREEN_WIDTH
59SPLASH_SCREEN_HEIGHT = config.SPLASH_SCREEN_HEIGHT
60SS_MAX_DISPLAY_TIME = config.SS_MAX_DISPLAY_TIME
61PLOPANEL_WIDTH = config.PLOPANEL_WIDTH
62PLOPANEL_HEIGTH = config.PLOPANEL_HEIGTH
63GUIFRAME_WIDTH = config.GUIFRAME_WIDTH
64GUIFRAME_HEIGHT = config.GUIFRAME_HEIGHT
65PLUGIN_STATE_EXTENSIONS =  config.PLUGIN_STATE_EXTENSIONS
66extension_list = []
67if APPLICATION_STATE_EXTENSION is not None:
68    extension_list.append(APPLICATION_STATE_EXTENSION)
69EXTENSIONS = PLUGIN_STATE_EXTENSIONS + extension_list
70try:
[4c01978]71    PLUGINS_WLIST = '|'.join(config.PLUGINS_WLIST)
[957723f]72except:
[4c01978]73    PLUGINS_WLIST = ''
74APPLICATION_WLIST = config.APPLICATION_WLIST
[7681bac]75
[41d466f]76class ViewerFrame(wx.Frame):
77    """
[d955bf19]78    Main application frame
[41d466f]79    """
[f444b20]80   
[3385795]81    def __init__(self, parent, title, 
[4753fc2]82                 size=(GUIFRAME_WIDTH, GUIFRAME_HEIGHT),
[3385795]83                 gui_style=GUIFRAME.DEFAULT_STYLE, 
84                 pos=wx.DefaultPosition):
[41d466f]85        """
[d955bf19]86        Initialize the Frame object
[41d466f]87        """
[b7c7a1c]88       
[3385795]89        wx.Frame.__init__(self, parent=parent, title=title, pos=pos,size=size)
[d0802c3]90        # Preferred window size
[3385795]91        self._window_width, self._window_height = size
[52b8b74]92        self.__gui_style = gui_style
[41d466f]93       
[fc2b91a]94        # Logging info
95        logging.basicConfig(level=logging.DEBUG,
96                    format='%(asctime)s %(levelname)s %(message)s',
97                    filename='sans_app.log',
98                    filemode='w')       
[c44e7cc]99        path = os.path.dirname(__file__)
[32c0841]100        temp_path = os.path.join(path,'images')
[c44e7cc]101        ico_file = os.path.join(temp_path,'ball.ico')
[278cc25]102        if os.path.isfile(ico_file):
103            self.SetIcon(wx.Icon(ico_file, wx.BITMAP_TYPE_ICO))
[cbb2e40]104        else:
[32c0841]105            temp_path = os.path.join(os.getcwd(),'images')
[c44e7cc]106            ico_file = os.path.join(temp_path,'ball.ico')
[cbb2e40]107            if os.path.isfile(ico_file):
108                self.SetIcon(wx.Icon(ico_file, wx.BITMAP_TYPE_ICO))
[41d466f]109       
110        ## Application manager
[29ef718]111        self._input_file = None
[41d466f]112        self.app_manager = None
[32c0841]113        self._mgr = None
[f444b20]114        #add current perpsective
115        self._current_perspective = None
[52b8b74]116        self._plotting_plugin = None
117        self._data_plugin = None
118        #Menu bar and item
119        self._menubar = None
120        self._file_menu = None
121        self._data_menu = None
122        self._window_menu = None
[e75b5fa]123        self._data_panel_menu = None
[c5e84fb]124        self._help_menu = None
125        self._tool_menu = None
[95f9cc4]126        self._applications_menu_pos = -1
[4c0572f]127        self._applications_menu_name = None
[95f9cc4]128        self._applications_menu = None
[d828481]129        self._edit_menu = None
[a45037aa]130        self._toolbar_menu = None
[73b3ae2]131        self._save_appl_menu = None
[f036c692]132        #tool bar
133        self._toolbar = None
[41d466f]134        ## Find plug-ins
135        # Modify this so that we can specify the directory to look into
[32c0841]136        self.plugins = []
[b7c7a1c]137        #add local plugin
[52b8b74]138        self.plugins += self._get_local_plugins()
[a88ac04]139        self.plugins += self._find_plugins()
[41d466f]140        ## List of panels
141        self.panels = {}
142
[2310d69]143        # Default locations
144        self._default_save_location = os.getcwd()       
[f444b20]145       
[f9e803e]146        # Welcome panel
147        self.defaultPanel = None
[b91c736]148        #panel on focus
149        self.panel_on_focus = None
[75fbd17]150        self.loader = Loader()   
[6d727ae]151        #data manager
[213892bc]152        from data_manager import DataManager
153        self._data_manager = DataManager()
154        self._data_panel = DataPanel(parent=self)
155        if self.panel_on_focus is not None:
[6db811e]156            self._data_panel.set_panel_on_focus(self.panel_on_focus.window_caption)
[6d727ae]157        # list of plot panels in schedule to full redraw
158        self.schedule = False
159        #self.callback = True
160        self._idle_count = 0
161        self.schedule_full_draw_list = []
162        self.idletimer = wx.CallLater(1, self._onDrawIdle)
163
[a0d56d5]164        # Check for update
[af20f6b]165        #self._check_update(None)
[278cc25]166        # Register the close event so it calls our own method
[52725d6]167        wx.EVT_CLOSE(self, self.Close)
[278cc25]168        # Register to status events
169        self.Bind(EVT_STATUS, self._on_status_event)
[b91c736]170        #Register add extra data on the same panel event on load
[a45037aa]171        self.Bind(EVT_PANEL_ON_FOCUS, self.set_panel_on_focus)
[4e4d3bb]172        self.Bind(EVT_APPEND_BOOKMARK, self.append_bookmark)
[03314e7]173   
[29ef718]174    def set_input_file(self, input_file):
175        """
176        :param input_file: file to read
177        """
178        self._input_file = input_file
179       
[4c0572f]180    def get_data_manager(self):
181        """
182        """
183        return self._data_manager
184   
[03314e7]185    def get_toolbar(self):
186        """
187        """
188        return self._toolbar
189   
[b91c736]190    def set_panel_on_focus(self, event):
191        """
[d955bf19]192        Store reference to the last panel on focus
[f036c692]193        update the toolbar if available
194        update edit menu if available
[b91c736]195        """
196        self.panel_on_focus = event.panel
[a45037aa]197        panel_name = 'No panel on focus'
198        application_name = 'No Selected Application'
[213892bc]199        if self.panel_on_focus is not None and self._data_panel is not None:
[a45037aa]200            panel_name = self.panel_on_focus.window_caption
201            self._data_panel.set_panel_on_focus(panel_name)
[03314e7]202            #update toolbar
203            self._update_toolbar_helper()
204            #update edit menu
205            self.enable_edit_menu()
[73b3ae2]206       
[278cc25]207    def build_gui(self):
[d955bf19]208        """
209        """
[41d466f]210        # Set up the layout
211        self._setup_layout()
212        # Set up the menu
213        self._setup_menus()
[f036c692]214        # set tool bar
215        self._setup_tool_bar()
[29ef718]216        try:
217            self.load_from_cmd(self._input_file)
218        except:
[1c95d15]219            raise
220            msg = "%s Cannot load file %s\n" %(str(APPLICATION_NAME), 
221                                             str(self._input_file))
222            msg += str(sys.exc_value) + '\n'
223            print msg
[29ef718]224        self.post_init()
225        self.Show(True)
[af20f6b]226        #self._check_update(None)
[41d466f]227             
228    def _setup_layout(self):
229        """
[d955bf19]230        Set up the layout
[41d466f]231        """
232        # Status bar
[010c251]233        from gui_statusbar import StatusBar
[db10f97]234        self.sb = StatusBar(self, wx.ID_ANY)
[dd66fbd]235        self.SetStatusBar(self.sb)
[41d466f]236        # Add panel
[4c0572f]237        default_flag = wx.aui.AUI_MGR_DEFAULT| wx.aui.AUI_MGR_ALLOW_ACTIVE_PANE
[52b8b74]238        self._mgr = wx.aui.AuiManager(self, flags=default_flag)
[7a67e075]239   
[41d466f]240        # Load panels
241        self._load_panels()
[c5e84fb]242        self.set_default_perspective()
[41d466f]243        self._mgr.Update()
[db10f97]244       
245    def SetStatusText(self, *args, **kwds):
[d955bf19]246        """
247        """
[db10f97]248        number = self.sb.get_msg_position()
249        wx.Frame.SetStatusText(number=number, *args, **kwds)
250       
251    def PopStatusText(self, *args, **kwds):
[d955bf19]252        """
253        """
[db10f97]254        field = self.sb.get_msg_position()
255        wx.Frame.PopStatusText(field=field)
256       
257    def PushStatusText(self, *args, **kwds):
[d955bf19]258        """
259        """
[db10f97]260        field = self.sb.get_msg_position()
[32c0841]261        wx.Frame.PushStatusText(self, field=field, string=string)
[278cc25]262
263    def add_perspective(self, plugin):
264        """
[d955bf19]265        Add a perspective if it doesn't already
266        exist.
[278cc25]267        """
268        is_loaded = False
269        for item in self.plugins:
[32c0841]270            if plugin.__class__ == item.__class__:
[56681bd]271                msg = "Plugin %s already loaded" % plugin.sub_menu
[f444b20]272                logging.info(msg)
[32c0841]273                is_loaded = True   
[278cc25]274        if not is_loaded:
275            self.plugins.append(plugin)
[41d466f]276     
[52b8b74]277    def _get_local_plugins(self):
278        """
279        get plugins local to guiframe and others
280        """
281        plugins = []
282        #import guiframe local plugins
[7a67e075]283        #check if the style contain guiframe.dataloader
284        style1 = self.__gui_style & GUIFRAME.DATALOADER_ON
[3feed3e]285        style2 = self.__gui_style & GUIFRAME.PLOTTING_ON
[7a67e075]286        if style1 == GUIFRAME.DATALOADER_ON:
[52b8b74]287            try:
288                from sans.guiframe.local_perspectives.data_loader import data_loader
[3feed3e]289                self._data_plugin = data_loader.Plugin()
[52b8b74]290                plugins.append(self._data_plugin)
291            except:
[3feed3e]292                msg = "ViewerFrame._get_local_plugins:"
[52b8b74]293                msg += "cannot import dataloader plugin.\n %s" % sys.exc_value
294                logging.error(msg)
[3feed3e]295        if style2 == GUIFRAME.PLOTTING_ON:
[52b8b74]296            try:
297                from sans.guiframe.local_perspectives.plotting import plotting
298                self._plotting_plugin = plotting.Plugin()
299                plugins.append(self._plotting_plugin)
300            except:
[3feed3e]301                msg = "ViewerFrame._get_local_plugins:"
[52b8b74]302                msg += "cannot import plotting plugin.\n %s" % sys.exc_value
303                logging.error(msg)
[3feed3e]304     
[52b8b74]305        return plugins
306   
[41d466f]307    def _find_plugins(self, dir="perspectives"):
308        """
[d955bf19]309        Find available perspective plug-ins
310       
311        :param dir: directory in which to look for plug-ins
312       
313        :return: list of plug-ins
314       
[41d466f]315        """
316        import imp
317        plugins = []
318        # Go through files in panels directory
319        try:
320            list = os.listdir(dir)
[a88ac04]321            ## the default panel is the panel is the last plugin added
322            for item in list:
[41d466f]323                toks = os.path.splitext(os.path.basename(item))
[c3f697e]324                name = ''
[41d466f]325                if not toks[0] == '__init__':
[32c0841]326                    if toks[1] == '.py' or toks[1] == '':
[41d466f]327                        name = toks[0]
[56681bd]328                    #check the validity of the module name parsed
329                    #before trying to import it
330                    if name is None or name.strip() == '':
331                        continue
[41d466f]332                    path = [os.path.abspath(dir)]
[c3f697e]333                    file = ''
[41d466f]334                    try:
[32c0841]335                        if toks[1] == '':
[41d466f]336                            mod_path = '.'.join([dir, name])
[32c0841]337                            module = __import__(mod_path, globals(),
338                                                locals(), [name])
[41d466f]339                        else:
340                            (file, path, info) = imp.find_module(name, path)
[32c0841]341                            module = imp.load_module( name, file, item, info)
[41d466f]342                        if hasattr(module, "PLUGIN_ID"):
[f444b20]343                            try: 
344                                plug = module.Plugin()
345                                if plug.set_default_perspective():
346                                    self._current_perspective = plug
347                                plugins.append(plug)
[32c0841]348                                msg = "Found plug-in: %s" % module.PLUGIN_ID
349                                logging.info(msg)
[41d466f]350                            except:
[32c0841]351                                msg = "Error accessing PluginPanel"
352                                msg += " in %s\n  %s" % (name, sys.exc_value)
353                                config.printEVT(msg)
[41d466f]354                    except:
[32c0841]355                        msg = "ViewerFrame._find_plugins: %s" % sys.exc_value
[56681bd]356                        #print msg
[32c0841]357                        logging.error(msg)
[41d466f]358                    finally:
[32c0841]359                        if not file == None:
[41d466f]360                            file.close()
361        except:
[32c0841]362            # Should raise and catch at a higher level and
363            # display error on status bar
[41d466f]364            pass   
365        return plugins
366   
[f9e803e]367    def set_welcome_panel(self, panel_class):
368        """
[d955bf19]369        Sets the default panel as the given welcome panel
370       
371        :param panel_class: class of the welcome panel to be instantiated
372       
[f9e803e]373        """
[d955bf19]374        self.defaultPanel = panel_class(self, -1, style=wx.RAISED_BORDER)
[b28278e]375       
[3feed3e]376    def _get_panels_size(self, p):
377        """
378        find the proper size of the current panel
379        get the proper panel width and height
380        """
381        panel_height_min = self._window_height
382        panel_width_min = self._window_width
383        style = self.__gui_style & (GUIFRAME.MANAGER_ON)
384        if self._data_panel is not None  and (p == self._data_panel):
[18ec684]385            panel_width_min = self._window_width * 5/25 
[3feed3e]386            return panel_width_min, panel_height_min
387        if hasattr(p, "CENTER_PANE") and p.CENTER_PANE:
388            style = self.__gui_style & (GUIFRAME.PLOTTING_ON|GUIFRAME.MANAGER_ON)
389            if style == (GUIFRAME.PLOTTING_ON|GUIFRAME.MANAGER_ON):
[18ec684]390                panel_width_min = self._window_width * 15/25 
[3feed3e]391            return panel_width_min, panel_height_min
392        return panel_width_min, panel_height_min
393   
[41d466f]394    def _load_panels(self):
395        """
[d955bf19]396        Load all panels in the panels directory
[41d466f]397        """
398       
399        # Look for plug-in panels
[c1469ebe]400        panels = []   
[41d466f]401        for item in self.plugins:
402            if hasattr(item, "get_panels"):
403                ps = item.get_panels(self)
404                panels.extend(ps)
[3feed3e]405       
[41d466f]406        # Show a default panel with some help information
407        # It also sets the size of the application windows
[c9454bb]408        #TODO: Use this for slpash screen
[f9e803e]409        if self.defaultPanel is None:
[32c0841]410            self.defaultPanel = DefaultPanel(self, -1, style=wx.RAISED_BORDER)
[3feed3e]411        # add a blank default panel always present
[41d466f]412        self.panels["default"] = self.defaultPanel
413        self._mgr.AddPane(self.defaultPanel, wx.aui.AuiPaneInfo().
414                              Name("default").
[3feed3e]415                              Center().
[a45037aa]416                              CloseButton(False).
417                              MinimizeButton(False).
[32c0841]418                              # This is where we set the size of
419                              # the application window
420                              BestSize(wx.Size(self._window_width, 
421                                               self._window_height)).
[41d466f]422                              Show())
[3feed3e]423        #add data panel
424        self.panels["data_panel"] = self._data_panel
425        w, h = self._get_panels_size(self._data_panel)
426        self._mgr.AddPane(self._data_panel, wx.aui.AuiPaneInfo().
427                              Name(self._data_panel.window_name).
428                              Left().
429                              MinimizeButton().
[e75b5fa]430                              CloseButton(False).
[18ec684]431                              TopDockable(False).
432                              BottomDockable(False).
433                              LeftDockable(True).
434                              RightDockable(False).
435                              BestSize(wx.Size(w, h)).
[d828481]436                              Hide())
[3feed3e]437        style = self.__gui_style & GUIFRAME.MANAGER_ON
438        if style != GUIFRAME.MANAGER_ON:
439            self._mgr.GetPane(self.panels["data_panel"].window_name).Hide()
[d828481]440        else:
441            self._mgr.GetPane(self.panels["data_panel"].window_name).Show()
[3feed3e]442           
[41d466f]443        # Add the panels to the AUI manager
444        for panel_class in panels:
445            p = panel_class
446            id = wx.NewId()
[3feed3e]447            w, h = self._get_panels_size(p)
[41d466f]448            # Check whether we need to put this panel
449            # in the center pane
[6f59a98]450            if hasattr(p, "CENTER_PANE") and p.CENTER_PANE:
[41d466f]451                if p.CENTER_PANE:
452                    self.panels[str(id)] = p
453                    self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
454                                          Name(p.window_name).Caption(p.window_caption).
[a45037aa]455                                           #CenterPane().
456                                            Center().
457                                            CloseButton(False).
458                                            MinimizeButton(False).
[3feed3e]459                                           MinSize(wx.Size(w, h)).
460                                           Hide())
[41d466f]461            else:
462                self.panels[str(id)] = p
463                self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
464                                  Name(p.window_name).Caption(p.window_caption).
465                                  Right().
466                                  Dock().
467                                  TopDockable().
468                                  BottomDockable().
469                                  LeftDockable().
470                                  RightDockable().
471                                  MinimizeButton().
[3feed3e]472                                  Hide())       
[b28278e]473     
[c70eb7c]474    def update_data(self, prev_data, new_data):
475        """
476        """
477        prev_id, data_state = self._data_manager.update_data(prev_data=prev_data, 
478                                       new_data=new_data)
[e88ebfd]479       
[c70eb7c]480        self._data_panel.remove_by_id(prev_id)
481        self._data_panel.load_data_list(data_state)
[e88ebfd]482       
483    def update_theory(self, data_id, theory, state=None):
484        """
485        """ 
486        data_state = self._data_manager.update_theory(data_id=data_id, 
487                                         theory=theory,
488                                         state=state) 
489        self._data_panel.load_data_list(data_state)
[c70eb7c]490       
[e6a93df]491    def onfreeze(self, theory_id):
492        """
493        """
494        data_state_list = self._data_manager.freeze(theory_id)
495        self._data_panel.load_data_list(list=data_state_list)
496        for data_state in data_state_list.values():
497            new_plot = data_state.get_data()
[df22224]498           
[e6a93df]499            wx.PostEvent(self, NewPlotEvent(plot=new_plot,
500                                             title=new_plot.title))
501       
[c70eb7c]502    def freeze(self, data_id, theory_id):
503        """
504        """
505        data_state_list = self._data_manager.freeze_theory(data_id=data_id, 
506                                                theory_id=theory_id)
507        self._data_panel.load_data_list(list=data_state_list)
[ee2b492]508        for data_state in data_state_list.values():
509            new_plot = data_state.get_data()
510            wx.PostEvent(self, NewPlotEvent(plot=new_plot,
[c70eb7c]511                                             title=new_plot.title))
512       
513    def delete_data(self, data):
514        """
515        """
516        self._current_perspective.delete_data(data)
517       
518   
[a07e72f]519    def get_context_menu(self, plotpanel=None):
[41d466f]520        """
[d955bf19]521        Get the context menu items made available
522        by the different plug-ins.
523        This function is used by the plotting module
[41d466f]524        """
[a07e72f]525        if plotpanel is None:
526            return
[41d466f]527        menu_list = []
528        for item in self.plugins:
[a07e72f]529            menu_list.extend(item.get_context_menu(plotpanel=plotpanel))
[41d466f]530        return menu_list
531       
532    def popup_panel(self, p):
533        """
[d955bf19]534        Add a panel object to the AUI manager
535       
536        :param p: panel object to add to the AUI manager
[41d466f]537       
[d955bf19]538        :return: ID of the event associated with the new panel [int]
539       
540        """
[41d466f]541        ID = wx.NewId()
542        self.panels[str(ID)] = p
543        count = 0
544        for item in self.panels:
[383189f9]545            if self.panels[item].window_name.startswith(p.window_name): 
[41d466f]546                count += 1
547        windowname = p.window_name
548        caption = p.window_caption
[32c0841]549        if count > 0:
[41d466f]550            windowname += str(count+1)
551            caption += (' '+str(count))
552        p.window_name = windowname
553        p.window_caption = caption
554           
[7a67e075]555        style1 = self.__gui_style & GUIFRAME.FIXED_PANEL
556        style2 = self.__gui_style & GUIFRAME.FLOATING_PANEL
557        if style1 == GUIFRAME.FIXED_PANEL:
558            self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
559                              Name(windowname).Caption(caption).
560                              MinimizeButton().
561                              Resizable(True).
[c5e84fb]562                              # Use a large best size to make sure the AUI
563                              # manager takes all the available space
[6d727ae]564                              BestSize(wx.Size(PLOPANEL_WIDTH, PLOPANEL_HEIGTH)).
565                              MinSize(wx.Size(PLOPANEL_WIDTH*0.9, PLOPANEL_HEIGTH)))
[3feed3e]566            self._popup_fixed_panel(p)
[213892bc]567   
[0663dfb1]568        elif style2 == GUIFRAME.FLOATING_PANEL:
[7a67e075]569            self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
570                              Name(windowname).Caption(caption).
571                              MinimizeButton().
572                              Resizable(True).
[c5e84fb]573                              # Use a large best size to make sure the AUI
574                              #  manager takes all the available space
[3feed3e]575                              BestSize(wx.Size(PLOPANEL_WIDTH, PLOPANEL_HEIGTH)))
576            self._popup_floating_panel(p)
[7a67e075]577           
[d0802c3]578        pane = self._mgr.GetPane(windowname)
579        self._mgr.MaximizePane(pane)
580        self._mgr.RestoreMaximizedPane()
[41d466f]581        # Register for showing/hiding the panel
582        wx.EVT_MENU(self, ID, self._on_view)
583       
584        self._mgr.Update()
585        return ID
586       
587    def _setup_menus(self):
588        """
[d955bf19]589        Set up the application menus
[41d466f]590        """
591        # Menu
[b7c7a1c]592        self._menubar = wx.MenuBar()
[52b8b74]593        self._add_menu_file()
594        self._add_menu_data()
595        self._add_menu_application()
[f036c692]596        self._add_menu_edit()
[c5e84fb]597        self._add_menu_tool()
[7bc88bf]598        self._add_current_plugin_menu()
[52b8b74]599        self._add_menu_window()
[c5e84fb]600        self._add_help_menu()
601        self.SetMenuBar(self._menubar)
602       
[f036c692]603    def _setup_tool_bar(self):
604        """
605        add toolbar to the frame
606        """
607        #set toolbar
608        self._toolbar = GUIToolBar(self, -1)
609        self.SetToolBar(self._toolbar)
[a45037aa]610        self._update_toolbar_helper()
611        #self._on_hide_toolbar(event=None)
612   
613    def _update_toolbar_helper(self):
614        """
615        """
616        application_name = 'No Selected Application'
617        panel_name = 'No Panel on Focus'
[1c95d15]618        if self._toolbar is not None:
619            self._toolbar.update_toolbar(self.panel_on_focus)
[f036c692]620        if self._current_perspective is not None:
[a45037aa]621            application_name = self._current_perspective.sub_menu
622        if self.panel_on_focus is not None:
623            panel_name = self.panel_on_focus.window_caption
624        self._toolbar.update_button(application_name=application_name, 
625                                        panel_name=panel_name)
626        self._toolbar.Realize()
627       
[c5e84fb]628    def _add_menu_tool(self):
629        """
630        Tools menu
631        Go through plug-ins and find tools to populate the tools menu
632        """
633        style = self.__gui_style & GUIFRAME.TOOL_ON
634        if style == GUIFRAME.TOOL_ON:
635            self._tool_menu = None
636            for item in self.plugins:
637                if hasattr(item, "get_tools"):
638                    for tool in item.get_tools():
639                        # Only create a menu if we have at least one tool
640                        if self._tool_menu is None:
641                            self._tool_menu = wx.Menu()
642                        id = wx.NewId()
643                        self._tool_menu.Append(id, tool[0], tool[1])
644                        wx.EVT_MENU(self, id, tool[2])
645            if self._tool_menu is not None:
646                self._menubar.Append(self._tool_menu, '&Tools')
647               
648    def _add_current_plugin_menu(self):
649        """
650        add current plugin menu
[cbf22e5]651        Look for plug-in menus
652        Add available plug-in sub-menus.
[c5e84fb]653        """
[7bc88bf]654        if (self._menubar is None) or (self._current_perspective is None):
[cbf22e5]655            return
[7bc88bf]656        #replace or add a new menu for the current plugin
[4c0572f]657       
658        pos = self._menubar.FindMenu(str(self._applications_menu_name))
[7bc88bf]659        if pos != -1:
660            menu_list = self._current_perspective.populate_menu(self)
661            if menu_list:
[4c0572f]662                for (menu, name) in menu_list:
663                    hidden_menu = self._menubar.Replace(pos, menu, name) 
664                    self._applications_menu_name = name
665                #self._applications_menu_pos = pos
[7bc88bf]666            else:
667                hidden_menu = self._menubar.Remove(pos)
[4c0572f]668                self._applications_menu_name = None
[7bc88bf]669            #get the position of the menu when it first added
[4c0572f]670            self._applications_menu_pos = pos
671           
[7bc88bf]672        else:
673            menu_list = self._current_perspective.populate_menu(self)
674            if menu_list:
[4c0572f]675                for (menu,name) in menu_list:
[95f9cc4]676                    if self._applications_menu_pos == -1:
[7bc88bf]677                        self._menubar.Append(menu, name)
678                    else:
[95f9cc4]679                        self._menubar.Insert(self._applications_menu_pos, menu, name)
[4c0572f]680                    self._applications_menu_name = name
[7bc88bf]681                 
[c5e84fb]682    def _add_help_menu(self):
683        """
684        add help menu
685        """
[41d466f]686        # Help menu
[c5e84fb]687        self._help_menu = wx.Menu()
[d828481]688        style = self.__gui_style & GUIFRAME.WELCOME_PANEL_ON
689        if style == GUIFRAME.WELCOME_PANEL_ON:
690            # add the welcome panel menu item
691            if self.defaultPanel is not None:
692                id = wx.NewId()
693                self._help_menu.Append(id, '&Welcome', '')
694                self._help_menu.AppendSeparator()
695                wx.EVT_MENU(self, id, self.show_welcome_panel)
[fa452e4]696        # Look for help item in plug-ins
697        for item in self.plugins:
698            if hasattr(item, "help"):
699                id = wx.NewId()
[c5e84fb]700                self._help_menu.Append(id,'&%s help' % item.sub_menu, '')
[fa452e4]701                wx.EVT_MENU(self, id, item.help)
[41d466f]702        if config._do_aboutbox:
703            id = wx.NewId()
[c5e84fb]704            self._help_menu.Append(id,'&About', 'Software information')
[41d466f]705            wx.EVT_MENU(self, id, self._onAbout)
[c5e84fb]706       
[af20f6b]707        # Checking for updates needs major refactoring to work with py2exe
708        # We need to make sure it doesn't hang the application if the server
709        # is not up. We also need to make sure there's a proper executable to
710        # run if we spawn a new background process.
711        #id = wx.NewId()
[c5e84fb]712        #self._help_menu.Append(id,'&Check for update',
[32c0841]713        #'Check for the latest version of %s' % config.__appname__)
[af20f6b]714        #wx.EVT_MENU(self, id, self._check_update)
[c5e84fb]715        self._menubar.Append(self._help_menu, '&Help')
716           
[52b8b74]717    def _add_menu_window(self):
718        """
719        add a menu window to the menu bar
720        Window menu
721        Attach a menu item for each panel in our
722        panel list that also appears in a plug-in.
723       
724        Only add the panel menu if there is only one perspective and
725        it has more than two panels.
726        Note: the first plug-in is always the plotting plug-in.
727        The first application
728        #plug-in is always the second one in the list.
729        """
730        self._window_menu = wx.Menu()
731        if self._plotting_plugin is not None:
[bf4402c3]732            for (menu, name) in self._plotting_plugin.populate_menu(self):
[52b8b74]733                self._window_menu.AppendSubMenu(menu, name)
734        self._menubar.Append(self._window_menu, '&Window')
[c5e84fb]735     
[7a67e075]736        style = self.__gui_style & GUIFRAME.MANAGER_ON
[e75b5fa]737        id = wx.NewId()
738        self._data_panel_menu = self._window_menu.Append(id,
739                                                '&Data Explorer ON', '')
740        wx.EVT_MENU(self, id, self.show_data_panel)
[7a67e075]741        if style == GUIFRAME.MANAGER_ON:
[e75b5fa]742            self._data_panel_menu.SetText('Data Explorer OFF')
743        else:
744            self._data_panel_menu.SetText('Data Explorer ON')
[52b8b74]745           
[4753fc2]746        style = self.__gui_style & GUIFRAME.PLOTTING_ON
747        if style == GUIFRAME.PLOTTING_ON:
748            self._window_menu.AppendSeparator()
749            id = wx.NewId()
750            preferences_menu = wx.Menu()
751            hint = "Plot panels will floating"
752            preferences_menu.Append(id, '&Floating Plot Panel', hint)
753            wx.EVT_MENU(self, id, self.set_plotpanel_floating)
754            id = wx.NewId()
755            hint = "Plot panels will displayed within the frame"
756            preferences_menu.Append(id, '&Fixed Plot Panel', hint)
757            wx.EVT_MENU(self, id, self.set_plotpanel_fixed)
758            id = wx.NewId()
[a45037aa]759            style1 = self.__gui_style & GUIFRAME.MULTIPLE_APPLICATIONS
760            if style1 == GUIFRAME.MULTIPLE_APPLICATIONS:
761                id = wx.NewId()
762                self._toolbar_menu = preferences_menu.Append(id,'&Hide Toolbar', '')
763                wx.EVT_MENU(self, id, self._on_hide_toolbar)
[4753fc2]764            self._window_menu.AppendSubMenu(preferences_menu,'&Preferences')
[d828481]765        if self._window_menu.GetMenuItemCount() == 0:
766            pos = self._menubar.FindMenu('Window')
767            self._menubar.Remove(pos)
[7a67e075]768        #wx.EVT_MENU(self, id, self.show_preferences_panel)   
[52b8b74]769        """
770        if len(self.plugins) == 2:
771            plug = self.plugins[1]
772            pers = plug.get_perspective()
773       
774            if len(pers) > 1:
775                self._window_menu = wx.Menu()
776                for item in self.panels:
777                    if item == 'default':
778                        continue
779                    panel = self.panels[item]
780                    if panel.window_name in pers:
781                        self._window_menu.Append(int(item),
782                                                  panel.window_caption,
783                                        "Show %s window" % panel.window_caption)
784                        wx.EVT_MENU(self, int(item), self._on_view)
785                self._menubar.Append(self._window_menu, '&Window')
786                """
787               
788    def _add_menu_application(self):
789        """
790       
791        # Attach a menu item for each defined perspective or application.
792        # Only add the perspective menu if there are more than one perspectives
793        add menu application
794        """
[7a67e075]795        style = self.__gui_style & GUIFRAME.MULTIPLE_APPLICATIONS
796        if style == GUIFRAME.MULTIPLE_APPLICATIONS:
[95f9cc4]797            plug_data_count = False
798            plug_no_data_count = False
799            self._applications_menu = wx.Menu()
[788ff23]800            pos = 0
[95f9cc4]801            separator = self._applications_menu.AppendSeparator()
[52b8b74]802            for plug in self.plugins:
803                if len(plug.get_perspective()) > 0:
804                    id = wx.NewId()
[95f9cc4]805                    if plug.use_data():
[788ff23]806                       
807                        self._applications_menu.InsertCheckItem(pos, id, plug.sub_menu,
[95f9cc4]808                                      "Switch to application: %s" % plug.sub_menu)
809                        plug_data_count = True
[788ff23]810                        pos += 1
[95f9cc4]811                    else:
812                        plug_no_data_count = True
813                        self._applications_menu.AppendCheckItem(id, plug.sub_menu,
814                                      "Switch to application: %s" % plug.sub_menu)
[52b8b74]815                    wx.EVT_MENU(self, id, plug.on_perspective)
[788ff23]816            #self._applications_menu.
817            if (not plug_data_count or not plug_no_data_count):
[95f9cc4]818                self._applications_menu.RemoveItem(separator)
819            self._menubar.Append(self._applications_menu, '&Applications')
820            self._check_applications_menu()
[52b8b74]821           
822    def _add_menu_file(self):
823        """
824        add menu file
825        """
[d828481]826       
[52b8b74]827         # File menu
[52725d6]828        self._file_menu = wx.Menu()
[d828481]829        style = self.__gui_style & GUIFRAME.DATALOADER_ON
[4c01978]830        style1 = self.__gui_style & GUIFRAME.MULTIPLE_APPLICATIONS
[d828481]831        if style == GUIFRAME.DATALOADER_ON:
[4c01978]832            if style1 == GUIFRAME.MULTIPLE_APPLICATIONS:
833                # some menu of plugin to be seen under file menu
834                hint_load_file = "Read state's files and load"
835                hint_load_file += " them into the application"
836                id = wx.NewId()
837                self._save_appl_menu = self._file_menu.Append(id, 
838                                        '&Load Application', hint_load_file)
839                wx.EVT_MENU(self, id, self._on_open_state_application)
840               
[d828481]841            id = wx.NewId()
[4c01978]842            hint_load_file = "read all applications states save previously"
[73b3ae2]843            self._save_appl_menu = self._file_menu.Append(id, 
[4c01978]844                                    '&Load Project', hint_load_file)
845            wx.EVT_MENU(self, id, self._on_open_state_project)
846           
847            if style1 == GUIFRAME.MULTIPLE_APPLICATIONS:
848                self._file_menu.AppendSeparator()
849                id = wx.NewId()
850                self._save_appl_menu = self._file_menu.Append(id, 
[73b3ae2]851                                                          '&Save Application',
[d828481]852                                 'Save state of the current active application')
[4c01978]853                wx.EVT_MENU(self, id, self._on_save_application)
[d828481]854            id = wx.NewId()
855            self._file_menu.Append(id, '&Save Project',
856                                 'Save the state of the whole application')
857            wx.EVT_MENU(self, id, self._on_save_project)
858            self._file_menu.AppendSeparator()
[52725d6]859       
860        id = wx.NewId()
861        self._file_menu.Append(id, '&Quit', 'Exit') 
[52b8b74]862        wx.EVT_MENU(self, id, self.Close)
863        # Add sub menus
[52725d6]864        self._menubar.Append(self._file_menu, '&File')
[52b8b74]865       
[d828481]866    def _add_menu_edit(self):
867        """
868        add menu edit
869        """
870        # Edit Menu
871        self._edit_menu = wx.Menu()
[f036c692]872        self._edit_menu.Append(GUIFRAME_ID.UNDO_ID, '&Undo', 
873                               'Undo the previous action')
874        wx.EVT_MENU(self, GUIFRAME_ID.UNDO_ID, self.on_undo_panel)
875        self._edit_menu.Append(GUIFRAME_ID.REDO_ID, '&Redo', 
876                               'Redo the previous action')
877        wx.EVT_MENU(self, GUIFRAME_ID.REDO_ID, self.on_redo_panel)
[d828481]878        self._edit_menu.AppendSeparator()
[783940c]879        self._edit_menu.Append(GUIFRAME_ID.PREVIEW_ID, '&Report',
[f036c692]880                               'Preview current panel')
881        wx.EVT_MENU(self, GUIFRAME_ID.PREVIEW_ID, self.on_preview_panel)
882        self._edit_menu.Append(GUIFRAME_ID.PRINT_ID, '&Print',
883                               'Print current panel')
884        wx.EVT_MENU(self, GUIFRAME_ID.PRINT_ID, self.on_print_panel)
885        self._edit_menu.Append(GUIFRAME_ID.RESET_ID, '&Reset', 
886                               'Reset current panel')
887        wx.EVT_MENU(self, GUIFRAME_ID.RESET_ID, self.on_reset_panel)
888        self._menubar.Append(self._edit_menu,  '&Edit')
889        self.enable_edit_menu()
[d828481]890       
[75fbd17]891    def get_style(self):
[52b8b74]892        """
893        """
[75fbd17]894        return  self.__gui_style
895   
896    def _add_menu_data(self):
[52b8b74]897        """
[75fbd17]898        Add menu item item data to menu bar
[52b8b74]899        """
[75fbd17]900        if self._data_plugin is not None:
901            menu_list = self._data_plugin.populate_menu(self)
902            if menu_list:
903                for (menu, name) in menu_list:
904                    self._menubar.Append(menu, name)
905           
[a45037aa]906    def _on_hide_toolbar(self, event=None):
907        """
908        hide or show toolbar
909        """
910        if self._toolbar is None:
911            return
912        if self._toolbar.IsShown():
913            if self._toolbar_menu is not None:
914                self._toolbar_menu.SetItemLabel('Show Toolbar')
915            self._toolbar.Hide()
916        else:
917            if self._toolbar_menu is not None:
918                self._toolbar_menu.SetItemLabel('Hide Toolbar')
919            self._toolbar.Show()
920        self._toolbar.Realize()
921       
[41d466f]922    def _on_status_event(self, evt):
923        """
[d955bf19]924        Display status message
[41d466f]925        """
[db10f97]926        self.sb.set_status(event=evt)
[dd66fbd]927       
[41d466f]928    def _on_view(self, evt):
929        """
[d955bf19]930        A panel was selected to be shown. If it's not already
931        shown, display it.
932       
933        :param evt: menu event
934       
[41d466f]935        """
[6d727ae]936        self.show_panel(evt.GetId(), 'on')
937        wx.CallLater(5, self.set_schedule(True))
[c1469ebe]938       
[b28278e]939    def on_close_welcome_panel(self):
[c1469ebe]940        """
[d955bf19]941        Close the welcome panel
[c1469ebe]942        """
[629e8b9]943        if self.defaultPanel is None:
944            return 
[c1469ebe]945        self._mgr.GetPane(self.panels["default"].window_name).Hide()
946        self._mgr.Update()
[b28278e]947        # set a default perspective
948        self.set_default_perspective()
[c1469ebe]949       
950    def show_welcome_panel(self, event):
951        """   
[d955bf19]952        Display the welcome panel
[c1469ebe]953        """
[629e8b9]954        if self.defaultPanel is None:
955            return 
[c1469ebe]956        for id in self.panels.keys():
[c5e84fb]957            if id  ==  'default':
958                # Show default panel
959                if not self._mgr.GetPane(self.panels["default"].window_name).IsShown():
960                    self._mgr.GetPane(self.panels["default"].window_name).Show(True)
961            elif id == "data_panel":
962                flag = self._mgr.GetPane(self.panels["data_panel"].window_name).IsShown()
963                self._mgr.GetPane(self.panels["data_panel"].window_name).Show(flag)
964            else:
965                self._mgr.GetPane(self.panels[id].window_name).IsShown()
[c1469ebe]966                self._mgr.GetPane(self.panels[id].window_name).Hide()
967        self._mgr.Update()
[c5e84fb]968       
[6d727ae]969    def show_panel(self, uid, show=None):
[41d466f]970        """
[d955bf19]971        Shows the panel with the given id
972       
973        :param uid: unique ID number of the panel to show
974       
[41d466f]975        """
976        ID = str(uid)
977        config.printEVT("show_panel: %s" % ID)
978        if ID in self.panels.keys():
[6d727ae]979            if not self._mgr.GetPane(self.panels[ID].window_name).IsShown(): 
980                if show == 'on':
981                    self._mgr.GetPane(self.panels[ID].window_name).Show()   
982                elif self.panels[ID].window_name.split(" ")[0] == "Residuals":
983                    self._mgr.GetPane(self.panels[ID].window_name).Hide()
984                else:
985                    self._mgr.GetPane(self.panels[ID].window_name).Show()
[383189f9]986                # Hide default panel
987                self._mgr.GetPane(self.panels["default"].window_name).Hide()
[6d727ae]988        self._mgr.Update()     
989        self._redraw_idle()
990                   
[ae83ad3]991    def hide_panel(self, uid):
992        """
993        hide panel
994        """
995        ID = str(uid)
996        config.printEVT("hide_panel: %s" % ID)
997        if ID in self.panels.keys():
998            if self._mgr.GetPane(self.panels[ID].window_name).IsShown():
999                self._mgr.GetPane(self.panels[ID].window_name).Hide()
1000                # Hide default panel
1001                self._mgr.GetPane(self.panels["default"].window_name).Hide()
1002            self._mgr.Update()
1003           
[c9937c0]1004    def delete_panel(self, uid):
1005        """
1006        delete panel given uid
1007        """
1008        ID = str(uid)
1009        config.printEVT("delete_panel: %s" % ID)
[df22224]1010       
[c9937c0]1011        if ID in self.panels.keys():
[df22224]1012            panel = self.panels[ID]
1013            self._plotting_plugin.delete_panel(panel.group_id)
1014            self._mgr.DetachPane(panel)
1015            panel.Destroy()
[c9937c0]1016            del self.panels[ID]
1017            self._mgr.Update()
1018     
[75fbd17]1019    def clear_panel(self):
[b3644f3]1020        """
1021        """
[75fbd17]1022        for item in self.panels:
1023            try:
1024                self.panels[item].clear_panel()
1025            except:
1026                pass
1027           
1028    def create_gui_data(self, data, path=None):
1029        """
[0348245]1030        """
1031        return self._data_manager.create_gui_data(data, path)
1032   
[03314e7]1033    def get_data(self, path):
[75fbd17]1034        """
1035        """
1036        message = ""
1037        log_msg = ''
1038        output = []
1039        error_message = ""
1040        basename  = os.path.basename(path)
1041        root, extension = os.path.splitext(basename)
1042        if extension.lower() not in EXTENSIONS:
1043            log_msg = "File Loader cannot "
1044            log_msg += "load: %s\n" % str(basename)
1045            log_msg += "Try Data opening...."
1046            logging.info(log_msg)
1047            self.load_complete(output=output, error_message=error_message,
1048                   message=log_msg, path=path)   
[700f9b4]1049            return
[75fbd17]1050       
1051        #reading a state file
1052        for plug in self.plugins:
[03314e7]1053            reader, ext = plug.get_extensions()
1054            if reader is not None:
1055                #read the state of the single plugin
1056                if extension == ext:
1057                    reader.read(path)
1058                    return
[957723f]1059                elif extension == APPLICATION_STATE_EXTENSION:
[03314e7]1060                    reader.read(path)
1061       
[75fbd17]1062        style = self.__gui_style & GUIFRAME.MANAGER_ON
1063        if style == GUIFRAME.MANAGER_ON:
1064            if self._data_panel is not None:
1065                data_state = self._data_manager.get_selected_data()
1066                self._data_panel.load_data_list(data_state)
1067                self._mgr.GetPane(self._data_panel.window_name).Show(True)
[976604d]1068     
1069    def load_from_cmd(self,  path):   
1070        """
[c3f697e]1071        load data from cmd or application
[976604d]1072        """ 
[c3f697e]1073        if path is None:
[976604d]1074            return
1075        else:
1076            path = os.path.abspath(path)
1077            if not os.path.isfile(path):
1078               return
1079        basename  = os.path.basename(path)
1080        root, extension = os.path.splitext(basename)
1081        if extension.lower() not in EXTENSIONS:
1082            self.load_data(path)
1083        else:
1084            self.load_state(path)
[c3f697e]1085         
[957723f]1086    def load_state(self, path):   
1087        """
[c3f697e]1088        load data from command line or application
[957723f]1089        """
[976604d]1090        if path and (path is not None) and os.path.isfile(path):
[957723f]1091            basename  = os.path.basename(path)
1092            if APPLICATION_STATE_EXTENSION is not None \
1093                and basename.endswith(APPLICATION_STATE_EXTENSION):
1094                #remove panels for new states
1095                for plug in self.plugins:
1096                    reader, ext = plug.get_extensions()
1097                    if ext is not None and ext.strip() != ''\
1098                        and ext.lower() not in EXTENSIONS:
1099                        plug.clear_panel() 
1100            self.panel_on_focus = None   
1101            self.get_data(path)
1102        if self.defaultPanel is not None and \
1103            self._mgr.GetPane(self.panels["default"].window_name).IsShown():
1104            self.on_close_welcome_panel()
1105           
1106    def load_data(self, path):
1107        """
[c3f697e]1108        load data from command line
[957723f]1109        """
1110        if not os.path.isfile(path):
1111            return
1112        basename  = os.path.basename(path)
1113        root, extension = os.path.splitext(basename)
1114        if extension.lower() in EXTENSIONS:
1115            log_msg = "Data Loader cannot "
1116            log_msg += "load: %s\n" % str(path)
1117            log_msg += "Try File opening ...."
1118            print log_msg
1119            return
[c3f697e]1120        message = ""
1121        log_msg = ''
1122        output = {}
1123        error_message = ""
[957723f]1124        try:
[c3f697e]1125            print "Loading Data...:\n" + str(path) + "\n"
[957723f]1126            temp =  self.loader.load(path)
1127            if temp.__class__.__name__ == "list":
1128                for item in temp:
[c3f697e]1129                    data = self.create_gui_data(item, path)
[957723f]1130                    output[data.id] = data
1131            else:
[c3f697e]1132                data = self.create_gui_data(temp, path)
[957723f]1133                output[data.id] = data
1134           
1135            self.add_data(data_list=output)
1136        except:
[c3f697e]1137            error_message = "Error while loading"
1138            error_message += " Data from cmd:\n %s\n" % str(path)
[957723f]1139            error_message += str(sys.exc_value) + "\n"
1140            print error_message
1141           
[4c01978]1142     
1143    def _on_open_state_application(self, event):
1144        """
1145        """
1146        path = None
1147        if self._default_save_location == None:
1148            self._default_save_location = os.getcwd()
1149 
1150        dlg = wx.FileDialog(self, 
1151                            "Choose a file", 
1152                            self._default_save_location, "",
1153                             PLUGINS_WLIST)
1154        if dlg.ShowModal() == wx.ID_OK:
1155            path = dlg.GetPath()
1156            if path is not None:
1157                self._default_save_location = os.path.dirname(path)
1158        dlg.Destroy()
1159        self.load_state(path=path) 
[957723f]1160           
[4c01978]1161    def _on_open_state_project(self, event):
[75fbd17]1162        """
1163        """
1164        path = None
1165        if self._default_save_location == None:
1166            self._default_save_location = os.getcwd()
1167 
1168        dlg = wx.FileDialog(self, 
1169                            "Choose a file", 
1170                            self._default_save_location, "",
[4c01978]1171                             APPLICATION_WLIST)
[75fbd17]1172        if dlg.ShowModal() == wx.ID_OK:
1173            path = dlg.GetPath()
1174            if path is not None:
1175                self._default_save_location = os.path.dirname(path)
1176        dlg.Destroy()
[957723f]1177        self.load_state(path=path)
[75fbd17]1178   
[52725d6]1179    def _on_save_application(self, event):
[b35d3d1]1180        """
[52725d6]1181        save the state of the current active application
[b35d3d1]1182        """
[73b3ae2]1183        if self.panel_on_focus is not None:
1184            self.panel_on_focus.on_save(event)
[52725d6]1185           
1186    def _on_save_project(self, event):
1187        """
1188        save the state of the current active application
1189        """
1190        ## Default file location for save
1191        self._default_save_location = os.getcwd()
1192        if self._current_perspective is  None:
1193            return
1194        reader, ext = self._current_perspective.get_extensions()
1195        path = None
[75fbd17]1196        dlg = wx.FileDialog(self, "Save Project file",
[957723f]1197                            self._default_save_location, "",
1198                             APPLICATION_STATE_EXTENSION, 
1199                             wx.SAVE)
[52725d6]1200        if dlg.ShowModal() == wx.ID_OK:
1201            path = dlg.GetPath()
1202            self._default_save_location = os.path.dirname(path)
1203        else:
1204            return None
1205        dlg.Destroy()
1206        if path is None:
1207            return
1208        # default cansas xml doc
1209        doc = None
1210        for panel in self.panels.values():
1211            doc = self.on_save_helper(doc, reader, panel, path)
1212       
1213           
1214    def on_save_helper(self, doc, reader, panel, path):
1215        """
1216        Save state into a file
1217        """
1218        try:
1219            data = panel.get_data()
1220            state = panel.get_state()
1221            if reader is not None:
1222                if data is not None:
1223                    new_doc = reader.write_toXML(data, state)
1224                    if hasattr(doc, "firstChild"):
1225                        child = new_doc.firstChild.firstChild
1226                        doc.firstChild.appendChild(child) 
1227                    else:
1228                        doc = new_doc
1229        except: 
1230            raise
1231            #pass
[b35d3d1]1232        # Write the XML document
1233        if doc != None:
1234            fd = open(path, 'w')
1235            fd.write(doc.toprettyxml())
1236            fd.close()
1237        else:
[957723f]1238            msg = "%s cannot read %s\n" % (str(APPLICATION_NAME), str(path))
1239            raise RuntimeError, msg
[52725d6]1240        return doc
[b35d3d1]1241
[b5ca223]1242    def quit_guiframe(self):
1243        """
1244        Pop up message to make sure the user wants to quit the application
1245        """
1246        message = "Do you really want to quit \n"
1247        message += "this application?"
1248        dial = wx.MessageDialog(self, message, 'Question',
1249                           wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
1250        if dial.ShowModal() == wx.ID_YES:
1251            return True
1252        else:
1253            return False   
1254       
[41d466f]1255    def Close(self, event=None):
1256        """
[d955bf19]1257        Quit the application
[41d466f]1258        """
[52725d6]1259        #flag = self.quit_guiframe()
1260        if True:
[ba535a6]1261            wx.Exit()
1262            sys.exit()
[41d466f]1263
1264    def _check_update(self, event=None): 
1265        """
[d955bf19]1266        Check with the deployment server whether a new version
1267        of the application is available.
1268        A thread is started for the connecting with the server. The thread calls
1269        a call-back method when the current version number has been obtained.
[52070a1]1270        """
[d68c655]1271        if hasattr(config, "__update_URL__"):
1272            import version
[32c0841]1273            checker = version.VersionThread(config.__update_URL__,
1274                                            self._process_version,
1275                                            baggage=event==None)
[d68c655]1276            checker.start() 
[52070a1]1277   
1278    def _process_version(self, version, standalone=True):
1279        """
[d955bf19]1280        Call-back method for the process of checking for updates.
1281        This methods is called by a VersionThread object once the current
1282        version number has been obtained. If the check is being done in the
1283        background, the user will not be notified unless there's an update.
1284       
1285        :param version: version string
1286        :param standalone: True of the update is being checked in
1287           the background, False otherwise.
1288           
[52070a1]1289        """
1290        try:
[32c0841]1291            if cmp(version, config.__version__) > 0:
1292                msg = "Version %s is available! See the Help "
1293                msg += "menu to download it." % version
1294                self.SetStatusText(msg)
[52070a1]1295                if not standalone:
1296                    import webbrowser
1297                    webbrowser.open(config.__download_page__)
1298            else:
1299                if not standalone:
[32c0841]1300                    msg = "You have the latest version"
1301                    msg += " of %s" % config.__appname__
1302                    self.SetStatusText(msg)
[41d466f]1303        except:
[32c0841]1304            msg = "guiframe: could not get latest application"
1305            msg += " version number\n  %s" % sys.exc_value
1306            logging.error(msg)
[52070a1]1307            if not standalone:
[32c0841]1308                msg = "Could not connect to the application server."
1309                msg += " Please try again later."
1310                self.SetStatusText(msg)
[52070a1]1311                   
[41d466f]1312    def _onAbout(self, evt):
1313        """
[d955bf19]1314        Pop up the about dialog
1315       
1316        :param evt: menu event
1317       
[41d466f]1318        """
1319        if config._do_aboutbox:
1320            import aboutbox 
1321            dialog = aboutbox.DialogAbout(None, -1, "")
[6ab0ad1]1322            dialog.ShowModal()           
[4e9583c]1323           
[41d466f]1324    def set_manager(self, manager):
1325        """
[d955bf19]1326        Sets the application manager for this frame
1327       
1328        :param manager: frame manager
[41d466f]1329        """
1330        self.app_manager = manager
1331       
1332    def post_init(self):
1333        """
[d955bf19]1334        This initialization method is called after the GUI
1335        has been created and all plug-ins loaded. It calls
1336        the post_init() method of each plug-in (if it exists)
1337        so that final initialization can be done.
[41d466f]1338        """
1339        for item in self.plugins:
1340            if hasattr(item, "post_init"):
1341                item.post_init()
1342       
[b28278e]1343    def set_default_perspective(self):
1344        """
[d955bf19]1345        Choose among the plugin the first plug-in that has
1346        "set_default_perspective" method and its return value is True will be
1347        as a default perspective when the welcome page is closed
[b28278e]1348        """
1349        for item in self.plugins:
1350            if hasattr(item, "set_default_perspective"):
1351                if item.set_default_perspective():
[749eb8a]1352                    item.on_perspective(event=None)
[b28278e]1353                    return 
[f444b20]1354       
[41d466f]1355    def set_perspective(self, panels):
1356        """
[d955bf19]1357        Sets the perspective of the GUI.
1358        Opens all the panels in the list, and closes
1359        all the others.
1360       
1361        :param panels: list of panels
[41d466f]1362        """
1363        for item in self.panels:
1364            # Check whether this is a sticky panel
1365            if hasattr(self.panels[item], "ALWAYS_ON"):
1366                if self.panels[item].ALWAYS_ON:
1367                    continue 
1368            if self.panels[item].window_name in panels:
1369                if not self._mgr.GetPane(self.panels[item].window_name).IsShown():
1370                    self._mgr.GetPane(self.panels[item].window_name).Show()
1371            else:
[3feed3e]1372                # always show the data panel if enable
1373                style = self.__gui_style & GUIFRAME.MANAGER_ON
1374                if (style == GUIFRAME.MANAGER_ON) and self.panels[item] == self._data_panel:
1375                    if 'data_panel' in self.panels.keys():
1376                        flag = self._mgr.GetPane(self.panels['data_panel'].window_name).IsShown()
1377                        self._mgr.GetPane(self.panels['data_panel'].window_name).Show(flag)
1378                else:
1379                    if self._mgr.GetPane(self.panels[item].window_name).IsShown():
1380                        self._mgr.GetPane(self.panels[item].window_name).Hide()
[41d466f]1381        self._mgr.Update()
[4e9583c]1382       
[213892bc]1383    def show_data_panel(self, event=None):
[52b8b74]1384        """
[3feed3e]1385        show the data panel
[52b8b74]1386        """
[e75b5fa]1387        label = self._data_panel_menu.GetText()
1388        if label == 'Data Explorer ON':
[75fbd17]1389            pane = self._mgr.GetPane(self.panels["data_panel"].window_name)
1390            #if not pane.IsShown():
1391            pane.Show(True)
1392            self._mgr.Update()
[e75b5fa]1393            self.__gui_style = self.__gui_style | GUIFRAME.MANAGER_ON
1394           
1395            self._data_panel_menu.SetText('Data Explorer OFF')
1396        else:
1397            pane = self._mgr.GetPane(self.panels["data_panel"].window_name)
1398            #if not pane.IsShown():
1399            pane.Show(False)
1400            self._mgr.Update()
1401            self.__gui_style = self.__gui_style & (~GUIFRAME.MANAGER_ON)
1402            self._data_panel_menu.SetText('Data Explorer ON')
[c70eb7c]1403   
1404    def add_data_helper(self, data_list):
1405        """
1406        """
[e88ebfd]1407        if self._data_manager is not None:
1408            self._data_manager.add_data(data_list)
[c70eb7c]1409       
[75fbd17]1410    def add_data(self, data_list):
[f444b20]1411        """
[e88ebfd]1412        receive a dictionary of data from loader
1413        store them its data manager if possible
1414        send to data the current active perspective if the data panel
1415        is not active.
1416        :param data_list: dictionary of data's ID and value Data
[f444b20]1417        """
[e88ebfd]1418        #Store data into manager
1419        self.add_data_helper(data_list)
1420        # set data in the data panel
1421        if self._data_panel is not None:
1422            data_state = self._data_manager.get_data_state(data_list.keys())
1423            self._data_panel.load_data_list(data_state)
1424        #if the data panel is shown wait for the user to press a button
1425        #to send data to the current perspective. if the panel is not
1426        #show  automatically send the data to the current perspective
[3feed3e]1427        style = self.__gui_style & GUIFRAME.MANAGER_ON
1428        if style == GUIFRAME.MANAGER_ON:
[9c169f4]1429            #wait for button press from the data panel to set_data
[3feed3e]1430            if self._data_panel is not None:
1431                self._mgr.GetPane(self._data_panel.window_name).Show(True)
[9c169f4]1432                self._mgr.Update() 
[3feed3e]1433        else:
1434            #automatically send that to the current perspective
[e88ebfd]1435            self.set_data(data_id=data_list.keys())
[c70eb7c]1436       
[e88ebfd]1437    def set_data(self, data_id): 
[c5e84fb]1438        """
[e88ebfd]1439        set data to current perspective
[c5e84fb]1440        """
[e88ebfd]1441        list_data, _ = self._data_manager.get_by_id(data_id)
1442        if self._current_perspective is not None:
[df22224]1443            self._current_perspective.set_data(list_data.values())
[584c4c4]1444        else:
[e88ebfd]1445            msg = "Guiframe does not have a current perspective"
1446            logging.info(msg)
1447           
1448    def set_theory(self, state_id, theory_id=None):
[c5e84fb]1449        """
1450        """
[df22224]1451        _, list_theory = self._data_manager.get_by_id(theory_id)
[c5e84fb]1452        if self._current_perspective is not None:
1453            try:
[df22224]1454                self._current_perspective.set_theory(list_theory.values())
[c5e84fb]1455            except:
[e88ebfd]1456                msg = "Guiframe set_theory: \n" + str(sys.exc_value)
1457                logging.info(msg)
[c5e84fb]1458                wx.PostEvent(self, StatusEvent(status=msg, info="error"))
1459        else:
1460            msg = "Guiframe does not have a current perspective"
1461            logging.info(msg)
[3feed3e]1462           
[e88ebfd]1463    def plot_data(self,  state_id, data_id=None,
1464                  theory_id=None, append=False):
[f444b20]1465        """
1466        send a list of data to plot
1467        """
[d7f727d]1468        total_plot_list = []
[e88ebfd]1469        data_list, _ = self._data_manager.get_by_id(data_id)
[df22224]1470        _, temp_list_theory = self._data_manager.get_by_id(theory_id)
[d7f727d]1471        total_plot_list = data_list.values()
[df22224]1472        for item in temp_list_theory.values():
[e88ebfd]1473            theory_data, theory_state = item
[d7f727d]1474            total_plot_list.append(theory_data)
[e88ebfd]1475        GROUP_ID = wx.NewId()
[d7f727d]1476        for new_plot in total_plot_list:
[213892bc]1477            if append:
[ee2b492]1478                if self.panel_on_focus is None:
[213892bc]1479                    message = "cannot append plot. No plot panel on focus!"
1480                    message += "please click on any available plot to set focus"
1481                    wx.PostEvent(self, StatusEvent(status=message, 
1482                                                   info='warning'))
1483                    return 
1484                else:
[e88ebfd]1485                    if self.enable_add_data(new_plot):
1486                        new_plot.group_id = self.panel_on_focus.group_id
1487                    else:
1488                        message = "Only 1D Data can be append to plot panel\n"
1489                        message += "%s will be plot separetly\n" %str(new_plot.name)
1490                        wx.PostEvent(self, StatusEvent(status=message, 
1491                                                   info='warning'))
[4c0572f]1492            else:
1493                #if not append then new plot
[e88ebfd]1494                new_plot.group_id = GROUP_ID
1495            title = "PLOT " + str(new_plot.title)
[f444b20]1496            wx.PostEvent(self, NewPlotEvent(plot=new_plot,
[e88ebfd]1497                                                  title=title))
[f444b20]1498           
[665c083]1499    def remove_data(self, data_id, theory_id=None):
[213892bc]1500        """
1501        Delete data state if data_id is provide
1502        delete theory created with data of id data_id if theory_id is provide
1503        if delete all true: delete the all state
1504        else delete theory
1505        """
[6db811e]1506        for plug in self.plugins:
1507            plug.delete_data(data_id)
[3658717e]1508        total_plot_list = []
1509        data_list, _ = self._data_manager.get_by_id(data_id)
1510        _, temp_list_theory = self._data_manager.get_by_id(theory_id)
1511        total_plot_list = data_list.values()
1512        for item in temp_list_theory.values():
1513            theory_data, theory_state = item
1514            total_plot_list.append(theory_data)
1515        for new_plot in total_plot_list:
1516            id = new_plot.id
1517            for group_id in new_plot.list_group_id:
1518                wx.PostEvent(self, NewPlotEvent(id=id,
1519                                                   group_id=group_id,
1520                                                   action='remove'))
1521        self._data_manager.delete_data(data_id=data_id, 
1522                                       theory_id=theory_id)
[6db811e]1523           
[213892bc]1524       
[f444b20]1525    def set_current_perspective(self, perspective):
1526        """
1527        set the current active perspective
1528        """
1529        self._current_perspective = perspective
[c5e84fb]1530        name = "No current Application selected"
[cbf22e5]1531        if self._current_perspective is not None:
1532            self._add_current_plugin_menu()
[a45037aa]1533            for panel in self.panels.values():
1534                if hasattr(panel, 'CENTER_PANE') and panel.CENTER_PANE:
1535                    for name in self._current_perspective.get_perspective():
1536                        if name == panel.window_name:
1537                            panel.on_set_focus(event=None)
1538                            break
1539                           
[f036c692]1540            name = self._current_perspective.sub_menu
[cbf22e5]1541            if self._data_panel is not None:
1542                self._data_panel.set_active_perspective(name)
[95f9cc4]1543                self._check_applications_menu()
[568658b]1544 
[95f9cc4]1545    def _check_applications_menu(self):
1546        """
1547        check the menu of the current application
1548        """
1549        if self._applications_menu is not None:
1550            for menu in self._applications_menu.GetMenuItems():
1551                if self._current_perspective is not None:
1552                    name = self._current_perspective.sub_menu
1553                    if menu.IsCheckable():
1554                        if menu.GetLabel() == name:
1555                            menu.Check(True)
1556                        else:
1557                             menu.Check(False) 
[c5e84fb]1558           
[213892bc]1559    def set_plotpanel_floating(self, event=None):
[7a67e075]1560        """
1561        make the plot panel floatable
1562        """
[0663dfb1]1563        self.__gui_style &= (~GUIFRAME.FIXED_PANEL)
[3feed3e]1564        self.__gui_style |= GUIFRAME.FLOATING_PANEL
1565        for p in self.panels.values():
[ae83ad3]1566            plot_panel = self._plotting_plugin.plot_panels.values()
[3feed3e]1567            for p in self.panels.values():
1568                if p in plot_panel:
1569                    self._popup_floating_panel(p)
1570       
[213892bc]1571    def set_plotpanel_fixed(self, event=None):
[7a67e075]1572        """
1573        make the plot panel fixed
1574        """
[0663dfb1]1575        self.__gui_style &= (~GUIFRAME.FLOATING_PANEL)
[3feed3e]1576        self.__gui_style |= GUIFRAME.FIXED_PANEL
1577        plot_panel = []
1578        if self._plotting_plugin is not None:
[ae83ad3]1579            plot_panel = self._plotting_plugin.plot_panels.values()
[3feed3e]1580            for p in self.panels.values():
1581                if p in plot_panel:
1582                    self._popup_fixed_panel(p)
1583                   
1584    def _popup_fixed_panel(self, p):
1585        """
1586        """
1587        style = self.__gui_style & GUIFRAME.FIXED_PANEL
1588        if style == GUIFRAME.FIXED_PANEL:
1589            self._mgr.GetPane(p.window_name).Floatable()
1590            self._mgr.GetPane(p.window_name).Right()
1591            self._mgr.GetPane(p.window_name).TopDockable(False)
1592            self._mgr.GetPane(p.window_name).BottomDockable(False)
1593            self._mgr.GetPane(p.window_name).LeftDockable(False)
1594            self._mgr.GetPane(p.window_name).RightDockable(True)
1595            flag = self._mgr.GetPane(p.window_name).IsShown()
1596            self._mgr.GetPane(p.window_name).Show(flag)
1597            self._mgr.Update()
1598           
1599    def _popup_floating_panel(self, p):
1600        """
1601        """
1602        style = self.__gui_style &  GUIFRAME.FLOATING_PANEL
1603        if style == GUIFRAME.FLOATING_PANEL: 
1604            self._mgr.GetPane(p.window_name).Floatable(True)
1605            self._mgr.GetPane(p.window_name).Float()
1606            self._mgr.GetPane(p.window_name).Dockable(False)
1607            flag = self._mgr.GetPane(p.window_name).IsShown()
1608            self._mgr.GetPane(p.window_name).Show(flag)
1609            self._mgr.Update()
[213892bc]1610           
1611    def enable_add_data(self, new_plot):
1612        """
1613        Enable append data on a plot panel
1614        """
[ee2b492]1615        if self.panel_on_focus not in self._plotting_plugin.plot_panels.values():
1616            return
[213892bc]1617        is_theory = len(self.panel_on_focus.plots) <= 1 and \
1618            self.panel_on_focus.plots.values()[0].__class__.__name__ == "Theory1D"
1619           
1620        is_data2d = hasattr(new_plot, 'data')
1621        is_data1d = self.panel_on_focus.__class__.__name__ == "ModelPanel1D"\
1622            and self.panel_on_focus.group_id is not None
1623        has_meta_data = hasattr(new_plot, 'meta_data')
1624       
1625        #disable_add_data if the data is being recovered from  a saved state file.
1626        is_state_data = False
1627        if has_meta_data:
1628            if 'invstate' in new_plot.meta_data: is_state_data = True
1629            if  'prstate' in new_plot.meta_data: is_state_data = True
1630            if  'fitstate' in new_plot.meta_data: is_state_data = True
1631   
1632        return is_data1d and not is_data2d and not is_theory and not is_state_data
[d828481]1633   
[f036c692]1634    def enable_edit_menu(self):
1635        """
1636        enable menu item under edit menu depending on the panel on focus
1637        """
1638        if self.panel_on_focus is not None and self._edit_menu is not None:
[a45037aa]1639            flag = self.panel_on_focus.get_undo_flag()
[f036c692]1640            self._edit_menu.Enable(GUIFRAME_ID.UNDO_ID, flag)
[a45037aa]1641            flag = self.panel_on_focus.get_redo_flag()
[f036c692]1642            self._edit_menu.Enable(GUIFRAME_ID.REDO_ID, flag)
[a45037aa]1643            flag = self.panel_on_focus.get_print_flag()
[f036c692]1644            self._edit_menu.Enable(GUIFRAME_ID.PRINT_ID, flag)
[a45037aa]1645            flag = self.panel_on_focus.get_preview_flag()
[f036c692]1646            self._edit_menu.Enable(GUIFRAME_ID.PREVIEW_ID, flag)
[a45037aa]1647            flag = self.panel_on_focus.get_reset_flag()
[f036c692]1648            self._edit_menu.Enable(GUIFRAME_ID.RESET_ID, flag)
1649        else:
1650            flag = False
1651            self._edit_menu.Enable(GUIFRAME_ID.UNDO_ID, flag)
1652            self._edit_menu.Enable(GUIFRAME_ID.REDO_ID, flag)
1653            self._edit_menu.Enable(GUIFRAME_ID.PRINT_ID, flag)
1654            self._edit_menu.Enable(GUIFRAME_ID.PREVIEW_ID, flag)
1655            self._edit_menu.Enable(GUIFRAME_ID.RESET_ID, flag)
1656           
[d828481]1657    def on_undo_panel(self, event=None):
1658        """
1659        undo previous action of the last panel on focus if possible
1660        """
[f036c692]1661        if self.panel_on_focus is not None:
1662            self.panel_on_focus.on_undo(event)
1663           
[d828481]1664    def on_redo_panel(self, event=None):
1665        """
1666        redo the last cancel action done on the last panel on focus
1667        """
[f036c692]1668        if self.panel_on_focus is not None:
1669            self.panel_on_focus.on_redo(event)
1670           
[d828481]1671    def on_bookmark_panel(self, event=None):
1672        """
[4e4d3bb]1673        bookmark panel
[d828481]1674        """
[f036c692]1675        if self.panel_on_focus is not None:
1676            self.panel_on_focus.on_bookmark(event)
1677           
[4e4d3bb]1678    def append_bookmark(self, event=None):
1679        """
1680        Bookmark available information of the panel on focus
1681        """
1682        self._toolbar.append_bookmark(event)
1683           
[d828481]1684    def on_save_panel(self, event=None):
1685        """
1686        save possible information on the current panel
1687        """
[f036c692]1688        if self.panel_on_focus is not None:
1689            self.panel_on_focus.on_save(event)
1690           
[d828481]1691    def on_preview_panel(self, event=None):
1692        """
1693        preview information on the panel on focus
1694        """
[f036c692]1695        if self.panel_on_focus is not None:
1696            self.panel_on_focus.on_preview(event)
1697           
[d828481]1698    def on_print_panel(self, event=None):
1699        """
1700        print available information on the last panel on focus
1701        """
[f036c692]1702        if self.panel_on_focus is not None:
1703            self.panel_on_focus.on_print(event)
1704           
[d828481]1705    def on_zoom_panel(self, event=None):
1706        """
1707        zoom on the current panel if possible
1708        """
[f036c692]1709        if self.panel_on_focus is not None:
1710            self.panel_on_focus.on_zoom(event)
1711           
[d828481]1712    def on_zoom_in_panel(self, event=None):
1713        """
1714        zoom in of the panel on focus
1715        """
[f036c692]1716        if self.panel_on_focus is not None:
1717            self.panel_on_focus.on_zoom_in(event)
1718           
[d828481]1719    def on_zoom_out_panel(self, event=None):
1720        """
1721        zoom out on the panel on focus
1722        """
[f036c692]1723        if self.panel_on_focus is not None:
1724            self.panel_on_focus.on_zoom_out(event)
1725           
[d828481]1726    def on_drag_panel(self, event=None):
1727        """
1728        drag apply to the panel on focus
1729        """
[f036c692]1730        if self.panel_on_focus is not None:
1731            self.panel_on_focus.on_drag(event)
1732           
[d828481]1733    def on_reset_panel(self, event=None):
1734        """
1735        reset the current panel
1736        """
[f036c692]1737        if self.panel_on_focus is not None:
1738            self.panel_on_focus.on_reset(event)
[03314e7]1739           
1740    def enable_undo(self):
1741        """
1742        enable undo related control
1743        """
1744        if self.panel_on_focus is not None:
1745            self._toolbar.enable_undo(self.panel_on_focus)
1746           
1747    def enable_redo(self):
1748        """
1749        enable redo
1750        """
1751        if self.panel_on_focus is not None:
1752            self._toolbar.enable_redo(self.panel_on_focus)
1753           
1754    def enable_bookmark(self):
1755        """
1756        Bookmark
1757        """
1758        if self.panel_on_focus is not None:
1759            self._toolbar.enable_bookmark(self.panel_on_focus)
1760           
1761    def enable_save(self):
1762        """
1763        save
1764        """
1765        if self.panel_on_focus is not None:
1766            self._toolbar.enable_save(self.panel_on_focus)
1767           
1768    def enable_preview(self):
1769        """
1770        preview
1771        """
1772        if self.panel_on_focus is not None:
1773            self._toolbar.enable_preview(self.panel_on_focus)
1774           
1775    def enable_print(self):
1776        """
1777        print
1778        """
1779        if self.panel_on_focus is not None:
1780            self._toolbar.enable_print(self.panel_on_focus)
1781           
1782    def enable_zoom(self):
1783        """
1784        zoom
1785        """
1786        if self.panel_on_focus is not None:
1787            self._toolbar.enable_zoom(self.panel_on_focus)
1788           
1789    def enable_zoom_in(self):
1790        """
1791        zoom in
1792        """
1793        if self.panel_on_focus is not None:
1794            self._toolbar.enable_zoom_in(self.panel_on_focus)
1795           
1796    def enable_zoom_out(self):
1797        """
1798        zoom out
1799        """
1800        if self.panel_on_focus is not None:
1801            self._toolbar.enable_zoom_out(self.panel_on_focus)
1802           
1803    def enable_drag(self, event=None):
1804        """
1805        drag
1806        """
1807        if self.panel_on_focus is not None:
1808            self._toolbar.enable_drag(self.panel_on_focus)
1809           
1810    def enable_reset(self):
1811        """
1812        reset the current panel
1813        """
1814        if self.panel_on_focus is not None:
1815            self._toolbar.enable_reset(self.panel_on_focus)
[6d727ae]1816
1817    def set_schedule_full_draw(self, panel=None, func='del'):
1818        """
1819        Add/subtract the schedule full draw list with the panel given
1820       
1821        :param panel: plot panel
1822        :param func: append or del [string]
1823        """
1824
1825        # append this panel in the schedule list if not in yet
1826        if func == 'append':
1827            if not panel in self.schedule_full_draw_list:
1828                self.schedule_full_draw_list.append(panel) 
1829        # remove this panel from schedule list
1830        elif func == 'del':
1831            if len(self.schedule_full_draw_list) > 0:
1832                if panel in self.schedule_full_draw_list:
1833                    self.schedule_full_draw_list.remove(panel)
1834
1835        # reset the schdule
1836        if len(self.schedule_full_draw_list) == 0:
1837            self.schedule = False
1838        else:
1839            self.schedule = True   
1840       
1841    def full_draw(self):
1842        """
1843        Draw the panels with axes in the schedule to full dwar list
1844        """
1845        count = len(self.schedule_full_draw_list)
1846        #if not self.schedule:
1847        if count < 1:
1848            self.set_schedule(False)
1849            return
1850        else:
1851            ind = 0
1852            # if any of the panel is shown do full_draw
1853            for panel in self.schedule_full_draw_list:
1854                ind += 1
1855                if self._mgr.GetPane(panel.window_name).IsShown():
1856                    break
1857                # otherwise, return
1858                if ind == count:
1859                    return
1860
1861        #Simple redraw only for a panel shown
1862        def f_draw(panel):
1863            """
1864            Draw A panel in the full dwar list
1865            """
1866            # Check if the panel is shown
1867            if self._mgr.GetPane(panel.window_name).IsShown():
1868                try:
1869                    # This checking of GetCapture is to stop redrawing
1870                    # while any panel is capture.
1871                    if self.GetCapture() == None:
1872                        # draw if possible
1873                        panel.set_resizing(False)
1874                        panel.draw_plot()
1875                except:
1876                    pass
1877        #print self.callback,self.schedule,self.schedule_full_draw_list
1878       
1879        # Draw all panels       
1880        map(f_draw, self.schedule_full_draw_list)
1881       
1882        # Reset the attr 
1883        if len(self.schedule_full_draw_list) == 0:
1884            self.set_schedule(False)
1885        else:
1886            self.set_schedule(True)
1887        # update mgr
1888        self._mgr.Update()
1889       
1890    def set_schedule(self, schedule=False): 
1891        """
1892        Set schedule
1893        """
1894        self.schedule = schedule
1895               
1896    def get_schedule(self): 
1897        """
1898        Get schedule
1899        """
1900        return self.schedule
1901   
1902       
1903    def _onDrawIdle(self, *args, **kwargs):
1904        """
1905        ReDraw with axes
1906        """
1907        # check if it is time to redraw
1908        if self.GetCapture() == None:
1909            # Draw plot, changes resizing too
1910            self.full_draw()
1911           
1912        # restart idle       
1913        self._redraw_idle(*args, **kwargs)
1914
1915           
1916    def _redraw_idle(self, *args, **kwargs):
1917        """
1918        Restart Idle
1919        """
1920        # restart idle   
1921        self.idletimer.Restart(55, *args, **kwargs)
1922
[3feed3e]1923       
[d828481]1924class DefaultPanel(wx.Panel, PanelBase):
[41d466f]1925    """
[d955bf19]1926    Defines the API for a panels to work with
1927    the GUI manager
[41d466f]1928    """
1929    ## Internal nickname for the window, used by the AUI manager
1930    window_name = "default"
1931    ## Name to appear on the window title bar
1932    window_caption = "Welcome panel"
1933    ## Flag to tell the AUI manager to put this panel in the center pane
1934    CENTER_PANE = True
[1b3a5a9]1935    def __init__(self, parent, *args, **kwds):
1936        wx.Panel.__init__(self, parent, *args, **kwds)
1937        PanelBase.__init__(self, parent)
[d828481]1938   
[41d466f]1939
[4753fc2]1940
[41d466f]1941# Toy application to test this Frame
1942class ViewApp(wx.App):
[d955bf19]1943    """
1944    """
[41d466f]1945    def OnInit(self):
[d955bf19]1946        """
1947        """
[957723f]1948        pos, size = self.window_placement((GUIFRAME_WIDTH, GUIFRAME_HEIGHT))
[3385795]1949        self.frame = ViewerFrame(parent=None, 
[957723f]1950                                 title=APPLICATION_NAME, 
[3385795]1951                                 pos=pos, 
[957723f]1952                                 gui_style = DEFAULT_STYLE,
[3385795]1953                                 size=size) 
[957723f]1954        self.s_screen = None
1955        # Display a splash screen on top of the frame.
[3385795]1956        if len(sys.argv) > 1 and '--time' in sys.argv[1:]:
1957            log_time("Starting to display the splash screen")
[957723f]1958       
1959        try:
1960            if os.path.isfile(SPLASH_SCREEN_PATH):
1961                self.s_screen = self.display_splash_screen(parent=self.frame, 
1962                                        path=SPLASH_SCREEN_PATH)
1963            else:
1964                self.frame.Show()   
1965        except:
[cc835cd8]1966           msg = "Cannot display splash screen\n"
1967           msg += str (sys.exc_value)
1968           logging.error(msg)
1969           self.frame.Show()
1970           
[41d466f]1971        if hasattr(self.frame, 'special'):
1972            self.frame.special.SetCurrent()
1973        self.SetTopWindow(self.frame)
[c3f697e]1974        try:
1975            self.open_file()
1976        except:
1977            msg = "%s Could not load " % str(APPLICATION_NAME)
1978            msg += "input file from command line.\n"
1979            logging.error(msg)
[41d466f]1980        return True
[976604d]1981
[957723f]1982    def open_file(self):
1983        """
1984        open a state file at the start of the application
1985        """
[c3f697e]1986        input_file = None
1987        if len(sys.argv) >= 2:
1988            cmd = sys.argv[0].lower()
1989            if os.path.isfile(cmd):
1990                basename  = os.path.basename(cmd)
1991                if basename in ['sansview.py', 'sansview.exe']:
1992                    input_file = sys.argv[1]
1993        if input_file is None:
1994            return
[976604d]1995        if self.frame is not None:
[29ef718]1996            self.frame.set_input_file(input_file=input_file)
[976604d]1997         
[957723f]1998           
[41d466f]1999    def set_manager(self, manager):
2000        """
[d955bf19]2001        Sets a reference to the application manager
2002        of the GUI manager (Frame)
[41d466f]2003        """
2004        self.frame.set_manager(manager)
2005       
[278cc25]2006    def build_gui(self):
2007        """
[d955bf19]2008        Build the GUI
[278cc25]2009        """
[976604d]2010        #try to load file at the start
2011        try:
2012            self.open_file()
2013        except:
2014            raise
[29ef718]2015        self.frame.build_gui()
[d18e208]2016        if self.s_screen is not None and self.s_screen.IsShown():
[957723f]2017            self.s_screen.Close()
[278cc25]2018       
[f9e803e]2019    def set_welcome_panel(self, panel_class):
2020        """
[d955bf19]2021        Set the welcome panel
2022       
2023        :param panel_class: class of the welcome panel to be instantiated
2024       
[f9e803e]2025        """
2026        self.frame.set_welcome_panel(panel_class)
2027       
[278cc25]2028    def add_perspective(self, perspective):
2029        """
[d955bf19]2030        Manually add a perspective to the application GUI
[278cc25]2031        """
2032        self.frame.add_perspective(perspective)
[3385795]2033   
2034    def window_placement(self, size):
2035        """
2036        Determines the position and size of the application frame such that it
2037        fits on the user's screen without obstructing (or being obstructed by)
2038        the Windows task bar.  The maximum initial size in pixels is bounded by
2039        WIDTH x HEIGHT.  For most monitors, the application
2040        will be centered on the screen; for very large monitors it will be
2041        placed on the left side of the screen.
2042        """
2043        window_width, window_height = size
2044        screen_size = wx.GetDisplaySize()
2045        window_height = window_height if screen_size[1]>window_height else screen_size[1]-50
2046        window_width  = window_width if screen_size[0]> window_width else screen_size[0]-50
2047        xpos = ypos = 0
2048
2049        # Note that when running Linux and using an Xming (X11) server on a PC
2050        # with a dual  monitor configuration, the reported display size may be
2051        # that of both monitors combined with an incorrect display count of 1.
2052        # To avoid displaying this app across both monitors, we check for
2053        # screen 'too big'.  If so, we assume a smaller width which means the
2054        # application will be placed towards the left hand side of the screen.
2055
2056        _, _, x, y = wx.Display().GetClientArea() # size excludes task bar
2057        if len(sys.argv) > 1 and '--platform' in sys.argv[1:]:
2058            w, h = wx.DisplaySize()  # size includes task bar area
2059        if x > 1920: x = 1280  # display on left side, not centered on screen
2060        if x > window_width:  xpos = (x - window_width)/2
2061        if y > window_height: ypos = (y - window_height)/2
2062
2063        # Return the suggested position and size for the application frame.
2064        return (xpos, ypos), (min(x, window_width), min(y, window_height))
2065   
[783940c]2066    def display_splash_screen(self, parent, 
[957723f]2067                              path=SPLASH_SCREEN_PATH):
[3385795]2068        """Displays the splash screen.  It will exactly cover the main frame."""
[957723f]2069       
[3385795]2070        # Prepare the picture.  On a 2GHz intel cpu, this takes about a second.
2071        x, y = parent.GetSizeTuple()
2072        image = wx.Image(path, wx.BITMAP_TYPE_PNG)
[957723f]2073        image.Rescale(SPLASH_SCREEN_WIDTH, 
2074                      SPLASH_SCREEN_HEIGHT, wx.IMAGE_QUALITY_HIGH)
[3385795]2075        bm = image.ConvertToBitmap()
2076
2077        # Create and show the splash screen.  It will disappear only when the
2078        # program has entered the event loop AND either the timeout has expired
2079        # or the user has left clicked on the screen.  Thus any processing
2080        # performed in this routine (including sleeping) or processing in the
2081        # calling routine (including doing imports) will prevent the splash
2082        # screen from disappearing.
2083        #
2084        # Note that on Linux, the timeout appears to occur immediately in which
2085        # case the splash screen disappears upon entering the event loop.
[783940c]2086        s_screen = wx.SplashScreen(bitmap=bm,
2087                         splashStyle=(wx.SPLASH_TIMEOUT|
2088                                              wx.SPLASH_CENTRE_ON_SCREEN),
2089                                 style=(wx.SIMPLE_BORDER|
2090                                        wx.FRAME_NO_TASKBAR|
2091                                        wx.STAY_ON_TOP),
2092                                       
[957723f]2093                        milliseconds=SS_MAX_DISPLAY_TIME,
[3385795]2094                        parent=parent,
2095                        id=wx.ID_ANY)
2096
[783940c]2097        s_screen.Bind(wx.EVT_CLOSE, self.on_close_splash_screen)
2098        s_screen.Show()
2099        return s_screen
2100       
2101       
2102    def on_close_splash_screen(self, event):
2103        """
2104        """
2105        self.frame.Show(True)
2106        event.Skip()
2107     
[41d466f]2108if __name__ == "__main__": 
2109    app = ViewApp(0)
[32c0841]2110    app.MainLoop()
2111
2112             
Note: See TracBrowser for help on using the repository browser.