source: sasview/sansguiframe/src/sans/guiframe/gui_manager.py @ 3576dd0

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

committing print statement for debugging

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