source: sasview/guiframe/gui_manager.py @ 1702180

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 1702180 was d68c655, checked in by Mathieu Doucet <doucetm@…>, 15 years ago

guiframe: added API to add Tools to a plugin.

  • Property mode set to 100644
File size: 31.7 KB
Line 
1"""
2This software was developed by the University of Tennessee as part of the
3Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
4project funded by the US National Science Foundation.
5
6See the license text in license.txt
7
8copyright 2008, University of Tennessee
9
10How-to build an application using guiframe:
11
12 1- Write a main application script along the lines of dummyapp.py
13 2- Write a config script along the lines of config.py, and name it local_config.py
14 3- Write your plug-ins and place them in a directory called "perspectives".
15     - Look at local_perspectives/plotting for an example of a plug-in.
16     - A plug-in should define a class called Plugin. See abstract class below.
17
18"""
19#TODO: rewrite the status bar monstrosity
20
21import wx
22import wx.aui
23import os, sys
24import xml
25try:
26    # Try to find a local config
27    import imp
28    path = os.getcwd()
29    if(os.path.isfile("%s/%s.py" % (path, 'local_config'))) or \
30      (os.path.isfile("%s/%s.pyc" % (path, 'local_config'))):
31            fObj, path, descr = imp.find_module('local_config', [path])
32            config = imp.load_module('local_config', fObj, path, descr) 
33    else:
34        # Try simply importing local_config
35        import local_config as config
36except:
37    # Didn't find local config, load the default
38    import config
39   
40from sans.guicomm.events import EVT_STATUS
41from sans.guicomm.events import EVT_NEW_PLOT,EVT_SLICER_PARS_UPDATE
42
43import warnings
44warnings.simplefilter("ignore")
45
46import logging
47
48class Plugin:
49    """
50        This class defines the interface for a Plugin class
51        that can be used by the gui_manager.
52       
53        Plug-ins should be placed in a sub-directory called "perspectives".
54        For example, a plug-in called Foo should be place in "perspectives/Foo".
55        That directory contains at least two files:
56            perspectives/Foo/__init.py contains two lines:
57           
58                PLUGIN_ID = "Foo plug-in 1.0"
59                from Foo import *
60               
61            perspectives/Foo/Foo.py contains the definition of the Plugin
62            class for the Foo plug-in. The interface of that Plugin class
63            should follow the interface of the class you are looking at.
64           
65        See dummyapp.py for a plugin example.
66    """
67   
68    def __init__(self, name="Test_plugin"):
69        """
70            Abstract class for gui_manager Plugins.
71        """
72        ## Plug-in name. It will appear on the application menu.
73        self.sub_menu = name     
74       
75        ## Reference to the parent window. Filled by get_panels() below.
76        self.parent = None
77       
78        ## List of panels that you would like to open in AUI windows
79        #  for your plug-in. This defines your plug-in "perspective"
80        self.perspective = []
81       
82       
83    def populate_menu(self, id, parent):
84        """
85            Create and return the list of application menu
86            items for the plug-in.
87           
88            @param id: deprecated. Un-used.
89            @param parent: parent window
90            @return: plug-in menu
91        """
92        return []
93   
94    def get_panels(self, parent):
95        """
96            Create and return the list of wx.Panels for your plug-in.
97            Define the plug-in perspective.
98           
99            Panels should inherit from DefaultPanel defined below,
100            or should present the same interface. They must define
101            "window_caption" and "window_name".
102           
103            @param parent: parent window
104            @return: list of panels
105        """
106        ## Save a reference to the parent
107        self.parent = parent
108       
109        # Return the list of panels
110        return []
111   
112    def get_tools(self):
113        """
114            Returns a set of menu entries for tools
115        """
116        return []
117       
118   
119    def get_context_menu(self, graph=None):
120        """
121            This method is optional.
122       
123            When the context menu of a plot is rendered, the
124            get_context_menu method will be called to give you a
125            chance to add a menu item to the context menu.
126           
127            A ref to a Graph object is passed so that you can
128            investigate the plot content and decide whether you
129            need to add items to the context menu. 
130           
131            This method returns a list of menu items.
132            Each item is itself a list defining the text to
133            appear in the menu, a tool-tip help text, and a
134            call-back method.
135           
136            @param graph: the Graph object to which we attach the context menu
137            @return: a list of menu items with call-back function
138        """
139        return []
140   
141    def get_perspective(self):
142        """
143            Get the list of panel names for this perspective
144        """
145        return self.perspective
146   
147    def on_perspective(self, event):
148        """
149            Call back function for the perspective menu item.
150            We notify the parent window that the perspective
151            has changed.
152            @param event: menu event
153        """
154        self.parent.set_perspective(self.perspective)
155   
156    def post_init(self):
157        """
158            Post initialization call back to close the loose ends
159        """
160        pass
161
162
163class ViewerFrame(wx.Frame):
164    """
165        Main application frame
166    """
167    def __init__(self, parent, id, title, window_height=300, window_width=300):
168        """
169            Initialize the Frame object
170        """
171        from local_perspectives.plotting import plotting
172        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, size=(window_width, window_height))
173        # Preferred window size
174        self._window_height = window_height
175        self._window_width  = window_width
176       
177        # Logging info
178        logging.basicConfig(level=logging.DEBUG,
179                    format='%(asctime)s %(levelname)s %(message)s',
180                    filename='sans_app.log',
181                    filemode='w')       
182        path = os.path.dirname(__file__)
183        temp_path= os.path.join(path,'images')
184        ico_file = os.path.join(temp_path,'ball.ico')
185        if os.path.isfile(ico_file):
186            self.SetIcon(wx.Icon(ico_file, wx.BITMAP_TYPE_ICO))
187        else:
188            temp_path= os.path.join(os.getcwd(),'images')
189            ico_file = os.path.join(temp_path,'ball.ico')
190            if os.path.isfile(ico_file):
191                self.SetIcon(wx.Icon(ico_file, wx.BITMAP_TYPE_ICO))
192       
193        ## Application manager
194        self.app_manager = None
195       
196        ## Find plug-ins
197        # Modify this so that we can specify the directory to look into
198        self.plugins =[]
199        self.plugins.append(plotting.Plugin())
200        self.plugins += self._find_plugins()
201     
202        ## List of panels
203        self.panels = {}
204
205        ## Next available ID for wx gui events
206        #TODO:  No longer used - remove all calls to this
207        self.next_id = 20000
208
209        # Default locations
210        self._default_save_location = os.getcwd()       
211
212        # Welcome panel
213        self.defaultPanel = None
214
215        # Check for update
216        self._check_update(None)
217        ## maximum number of opened files' paths to store
218        self.n_maxfileopen =  2
219        ## number of file open
220        self.n_fileOpen=0
221        ## list of path of open files
222        self.filePathList=[]
223        ## list of open file with name form menu
224        #self._saveOpenData()
225        ## Dictionary of open file where keys are filename  and values are number of copy of data plotted
226        ## using the same loaded file
227        self.indice_load_data={}
228        # Register the close event so it calls our own method
229        wx.EVT_CLOSE(self, self._onClose)
230        # Register to status events
231        self.Bind(EVT_STATUS, self._on_status_event)
232   
233       
234    def build_gui(self):
235        # Set up the layout
236        self._setup_layout()
237       
238        # Set up the menu
239        self._setup_menus()
240       
241        #self.Fit()
242       
243        self._check_update(None)
244             
245    def _setup_layout(self):
246        """
247            Set up the layout
248        """
249        # Status bar
250        from statusbar import MyStatusBar
251        self.sb = MyStatusBar(self,wx.ID_ANY)
252        self.SetStatusBar(self.sb)
253
254        # Add panel
255        self._mgr = wx.aui.AuiManager(self)
256        self._mgr.SetDockSizeConstraint(0.5, 0.5) 
257       
258        # Load panels
259        self._load_panels()
260       
261        self._mgr.Update()
262
263    def add_perspective(self, plugin):
264        """
265            Add a perspective if it doesn't already
266            exist.
267        """
268        is_loaded = False
269        for item in self.plugins:
270             if plugin.__class__==item.__class__:
271                 print "Plugin %s already loaded" % plugin.__class__.__name__
272                 is_loaded = True
273                 
274        if not is_loaded:
275            self.plugins.append(plugin)
276     
277    def _find_plugins(self, dir="perspectives"):
278        """
279            Find available perspective plug-ins
280            @param dir: directory in which to look for plug-ins
281            @return: list of plug-ins
282        """
283        import imp
284       
285        plugins = []
286        # Go through files in panels directory
287        try:
288            list = os.listdir(dir)
289            ## the default panel is the panel is the last plugin added
290            for item in list:
291                toks = os.path.splitext(os.path.basename(item))
292                name = None
293                if not toks[0] == '__init__':
294                   
295                    if toks[1]=='.py' or toks[1]=='':
296                        name = toks[0]
297               
298                    path = [os.path.abspath(dir)]
299                    file = None
300                    try:
301                        if toks[1]=='':
302                            mod_path = '.'.join([dir, name])
303                            module = __import__(mod_path, globals(), locals(), [name])
304                        else:
305                            (file, path, info) = imp.find_module(name, path)
306                            module = imp.load_module( name, file, item, info )
307                        if hasattr(module, "PLUGIN_ID"):
308                            try:
309                                plugins.append(module.Plugin())
310                                logging.info("Found plug-in: %s" % module.PLUGIN_ID)
311                            except:
312                                config.printEVT("Error accessing PluginPanel in %s\n  %s" % (name, sys.exc_value))
313                       
314                    except:
315                        print sys.exc_value
316                        logging.error("ViewerFrame._find_plugins: %s" % sys.exc_value)
317                    finally:
318                        if not file==None:
319                            file.close()
320        except:
321            # Should raise and catch at a higher level and display error on status bar
322            pass   
323        return plugins
324   
325    def set_welcome_panel(self, panel_class):
326        """
327           Sets the default panel as the given welcome panel
328           @param panel_class: class of the welcome panel to be instantiated
329        """
330        self.defaultPanel    = panel_class(self, -1, style=wx.RAISED_BORDER)
331     
332    def _load_panels(self):
333        """
334            Load all panels in the panels directory
335        """
336       
337        # Look for plug-in panels
338        panels = []       
339        for item in self.plugins:
340            if hasattr(item, "get_panels"):
341                ps = item.get_panels(self)
342                panels.extend(ps)
343
344        # Show a default panel with some help information
345        # It also sets the size of the application windows
346        #TODO: Use this for slpash screen
347        if self.defaultPanel is None:
348            self.defaultPanel    = DefaultPanel(self, -1, style=wx.RAISED_BORDER)
349           
350        self.panels["default"] = self.defaultPanel
351       
352        self._mgr.AddPane(self.defaultPanel, wx.aui.AuiPaneInfo().
353                              Name("default").
354                              CenterPane().
355                              # This is where we set the size of the application window
356                              BestSize(wx.Size(self._window_width, self._window_height)).
357                              #MinSize(wx.Size(self._window_width, self._window_height)).
358                              Show())
359     
360
361        # Add the panels to the AUI manager
362        for panel_class in panels:
363            p = panel_class
364            id = wx.NewId()
365           
366            # Check whether we need to put this panel
367            # in the center pane
368            if hasattr(p, "CENTER_PANE"):
369                if p.CENTER_PANE:
370                    self.panels[str(id)] = p
371                    self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
372                                          Name(p.window_name).Caption(p.window_caption).
373                                          CenterPane().
374                                          #BestSize(wx.Size(550,600)).
375                                          #MinSize(wx.Size(500,500)).
376                                          Hide())
377            else:
378                self.panels[str(id)] = p
379                self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
380                                  Name(p.window_name).Caption(p.window_caption).
381                                  Right().
382                                  Dock().
383                                  TopDockable().
384                                  BottomDockable().
385                                  LeftDockable().
386                                  RightDockable().
387                                  MinimizeButton().
388                                  Hide())
389                                  #BestSize(wx.Size(550,600)))
390                                  #MinSize(wx.Size(500,500)))                 
391               
392       
393    def get_context_menu(self, graph=None):
394        """
395            Get the context menu items made available
396            by the different plug-ins.
397            This function is used by the plotting module
398        """
399        menu_list = []
400        for item in self.plugins:
401            if hasattr(item, "get_context_menu"):
402                menu_list.extend(item.get_context_menu(graph))
403           
404        return menu_list
405       
406    def popup_panel(self, p):
407        """
408            Add a panel object to the AUI manager
409            @param p: panel object to add to the AUI manager
410            @return: ID of the event associated with the new panel [int]
411        """
412       
413        ID = wx.NewId()
414        self.panels[str(ID)] = p
415       
416        count = 0
417        for item in self.panels:
418            if self.panels[item].window_name.startswith(p.window_name): 
419                count += 1
420       
421        windowname = p.window_name
422        caption = p.window_caption
423       
424        if count>0:
425            windowname += str(count+1)
426            caption += (' '+str(count))
427         
428        p.window_name = windowname
429        p.window_caption = caption
430           
431        self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
432                          Name(windowname).Caption(caption).
433                          Floatable().
434                          #Float().
435                          Right().
436                          Dock().
437                          TopDockable().
438                          BottomDockable().
439                          LeftDockable().
440                          RightDockable().
441                          MinimizeButton().
442                          #Hide().
443                          #Show().
444                          Resizable(True).
445                          # Use a large best size to make sure the AUI manager
446                          # takes all the available space
447                          BestSize(wx.Size(400,400)))
448        pane = self._mgr.GetPane(windowname)
449        self._mgr.MaximizePane(pane)
450        self._mgr.RestoreMaximizedPane()
451       
452       
453        # Register for showing/hiding the panel
454       
455        wx.EVT_MENU(self, ID, self._on_view)
456       
457        self._mgr.Update()
458        return ID
459       
460    def _setup_menus(self):
461        """
462            Set up the application menus
463        """
464        # Menu
465        menubar = wx.MenuBar()
466       
467        # File menu
468        self.filemenu = wx.Menu()
469       
470        id = wx.NewId()
471        self.filemenu.Append(id, '&Open', 'Open a file')
472        wx.EVT_MENU(self, id, self._on_open)
473        #self.filemenu.AppendSeparator()
474       
475        id = wx.NewId()
476        self.filemenu.Append(id,'&Quit', 'Exit') 
477        wx.EVT_MENU(self, id, self.Close)
478       
479        # Add sub menus
480        menubar.Append(self.filemenu,  '&File')
481       
482        # Plot menu
483        # Attach a menu item for each panel in our
484        # panel list that also appears in a plug-in.
485        # TODO: clean this up. We should just identify
486        # plug-in panels and add them all.
487       
488        # Only add the panel menu if there is more than two panels
489        n_panels = 0
490        for plug in self.plugins:
491            pers = plug.get_perspective()
492            if len(pers)>0:
493                n_panels += 1
494       
495        if n_panels>2:
496            viewmenu = wx.Menu()
497            for plug in self.plugins:
498                plugmenu = wx.Menu()
499                pers = plug.get_perspective()
500                if len(pers)>0:
501                    for item in self.panels:
502                        if item == 'default':
503                            continue
504                        panel = self.panels[item]
505                        if panel.window_name in pers:
506                            plugmenu.Append(int(item), panel.window_caption, "Show %s window" % panel.window_caption)
507                           
508                           
509                           
510                            wx.EVT_MENU(self, int(item), self._on_view)
511                   
512                    viewmenu.AppendMenu(wx.NewId(), plug.sub_menu, plugmenu, plug.sub_menu)
513            menubar.Append(viewmenu, '&Panel')
514
515        # Perspective
516        # Attach a menu item for each defined perspective.
517        # Only add the perspective menu if there are more than one perspectives
518        n_perspectives = 0
519        for plug in self.plugins:
520            if len(plug.get_perspective()) > 0:
521                n_perspectives += 1
522       
523        if n_perspectives>1:
524            p_menu = wx.Menu()
525            for plug in self.plugins:
526                if len(plug.get_perspective()) > 0:
527                    id = wx.NewId()
528                    p_menu.Append(id, plug.sub_menu, "Switch to %s perspective" % plug.sub_menu)
529                    wx.EVT_MENU(self, id, plug.on_perspective)
530            menubar.Append(p_menu,   '&Perspective')
531 
532        # Tools menu
533        # Go through plug-ins and find tools to populate the tools menu
534        toolsmenu = None
535        for item in self.plugins:
536            if hasattr(item, "get_tools"):
537                for tool in item.get_tools():
538                    # Only create a menu if we have at least one tool
539                    if toolsmenu is None:
540                        toolsmenu = wx.Menu()
541                    id = wx.NewId()
542                    toolsmenu.Append(id, tool[0], tool[1])
543                    wx.EVT_MENU(self, id, tool[2])
544        if toolsmenu is not None:
545            menubar.Append(toolsmenu, '&Tools')
546 
547        # Help menu
548        helpmenu = wx.Menu()
549
550        # Look for help item in plug-ins
551        for item in self.plugins:
552            if hasattr(item, "help"):
553                id = wx.NewId()
554                helpmenu.Append(id,'&%s help' % item.sub_menu, '')
555                wx.EVT_MENU(self, id, item.help)
556       
557        if config._do_aboutbox:
558            id = wx.NewId()
559            helpmenu.Append(id,'&About', 'Software information')
560            wx.EVT_MENU(self, id, self._onAbout)
561        id = wx.NewId()
562        helpmenu.Append(id,'&Check for update', 'Check for the latest version of %s' % config.__appname__)
563        wx.EVT_MENU(self, id, self._check_update)
564       
565       
566       
567       
568        # Look for plug-in menus
569        # Add available plug-in sub-menus.
570        for item in self.plugins:
571            if hasattr(item, "populate_menu"):
572                for (self.next_id, menu, name) in item.populate_menu(self.next_id, self):
573                    menubar.Append(menu, name)
574                   
575
576        menubar.Append(helpmenu, '&Help')
577         
578        self.SetMenuBar(menubar)
579       
580       
581       
582    def _on_status_event(self, evt):
583        """
584            Display status message
585        """
586        #self.sb.clear_gauge( msg="")
587        mythread=None
588        mytype= None
589        if hasattr(evt, "curr_thread"):
590            mythread= evt.curr_thread
591        if hasattr(evt, "type"):
592            mytype= evt.type
593        self.sb.set_status( type=mytype,msg=str(evt.status),thread=mythread)
594       
595
596       
597    def _on_view(self, evt):
598        """
599            A panel was selected to be shown. If it's not already
600            shown, display it.
601            @param evt: menu event
602        """
603        self.show_panel(evt.GetId())
604
605    def show_panel(self, uid):
606        """
607            Shows the panel with the given id
608            @param uid: unique ID number of the panel to show
609        """
610        ID = str(uid)
611        config.printEVT("show_panel: %s" % ID)
612        if ID in self.panels.keys():
613            if not self._mgr.GetPane(self.panels[ID].window_name).IsShown():
614                self._mgr.GetPane(self.panels[ID].window_name).Show()
615                # Hide default panel
616                self._mgr.GetPane(self.panels["default"].window_name).Hide()
617           
618               
619            self._mgr.Update()
620   
621    def _on_open(self, event):
622   
623        from data_loader import plot_data
624        path = self.choose_file()
625
626        if path ==None:
627            return
628        if path and os.path.isfile(path):
629            plot_data(self, path)
630           
631       
632       
633    def _onClose(self, event):
634        """
635            Store info to retrieve in xml before closing the application
636        """
637        try:
638            doc = xml.dom.minidom.Document()
639            main_node = doc.createElement("file Path")
640           
641            doc.appendChild(main_node)
642       
643            for item in self.filePathList:
644                id, menuitem_name , path, title = item
645                pt1 = doc.createElement("File")
646                pt1.setAttribute("name", menuitem_name)
647                pt2 = doc.createElement("path")
648                pt2.appendChild(doc.createTextNode(str(path)))
649                pt1.appendChild(pt2)
650                pt3 = doc.createElement("title")
651                pt3.appendChild(doc.createTextNode(str(title)))
652                pt1.appendChild(pt3)
653               
654                main_node.appendChild(pt1)
655               
656               
657            fd = open("fileOpened.xml",'w')
658            fd.write(doc.toprettyxml())
659            fd.close()
660        except:
661            pass
662       
663        import sys
664        wx.Exit()
665        sys.exit()
666                   
667                   
668    def Close(self, event=None):
669        """
670            Quit the application
671        """
672        import sys
673        wx.Frame.Close(self)
674        wx.Exit()
675        sys.exit()
676
677 
678    def _check_update(self, event=None): 
679        """
680            Check with the deployment server whether a new version
681            of the application is available.
682            A thread is started for the connecting with the server. The thread calls
683            a call-back method when the current version number has been obtained.
684        """
685        if hasattr(config, "__update_URL__"):
686            import version
687            checker = version.VersionThread(config.__update_URL__, self._process_version, baggage=event==None)
688            checker.start() 
689   
690    def _process_version(self, version, standalone=True):
691        """
692            Call-back method for the process of checking for updates.
693            This methods is called by a VersionThread object once the current
694            version number has been obtained. If the check is being done in the
695            background, the user will not be notified unless there's an update.
696           
697            @param version: version string
698            @param standalone: True of the update is being checked in the background, False otherwise.
699        """
700        try:
701            if cmp(version, config.__version__)>0:
702                self.SetStatusText("Version %s is available! See the Help menu to download it." % version)
703                if not standalone:
704                    import webbrowser
705                    webbrowser.open(config.__download_page__)
706            else:
707                if not standalone:
708                    self.SetStatusText("You have the latest version of %s" % config.__appname__)
709        except:
710            logging.error("guiframe: could not get latest application version number\n  %s" % sys.exc_value)
711            if not standalone:
712                self.SetStatusText("Could not connect to the application server. Please try again later.")
713                   
714       
715    def _onAbout(self, evt):
716        """
717            Pop up the about dialog
718            @param evt: menu event
719        """
720        if config._do_aboutbox:
721            import aboutbox 
722            dialog = aboutbox.DialogAbout(None, -1, "")
723            dialog.ShowModal()           
724           
725    def _onreloaFile(self, event): 
726        """
727            load a data previously opened
728        """
729        from data_loader import plot_data
730        for item in self.filePathList:
731            id, menuitem_name , path, title = item
732            if id == event.GetId():
733                if path and os.path.isfile(path):
734                    plot_data(self, path)
735                    break
736           
737       
738    def set_manager(self, manager):
739        """
740            Sets the application manager for this frame
741            @param manager: frame manager
742        """
743        self.app_manager = manager
744       
745    def post_init(self):
746        """
747            This initialization method is called after the GUI
748            has been created and all plug-ins loaded. It calls
749            the post_init() method of each plug-in (if it exists)
750            so that final initialization can be done.
751        """
752        for item in self.plugins:
753            if hasattr(item, "post_init"):
754                item.post_init()
755       
756    def set_perspective(self, panels):
757        """
758            Sets the perspective of the GUI.
759            Opens all the panels in the list, and closes
760            all the others.
761           
762            @param panels: list of panels
763        """
764        for item in self.panels:
765            # Check whether this is a sticky panel
766            if hasattr(self.panels[item], "ALWAYS_ON"):
767                if self.panels[item].ALWAYS_ON:
768                    continue 
769           
770            if self.panels[item].window_name in panels:
771                if not self._mgr.GetPane(self.panels[item].window_name).IsShown():
772                    self._mgr.GetPane(self.panels[item].window_name).Show()
773            else:
774                if self._mgr.GetPane(self.panels[item].window_name).IsShown():
775                    self._mgr.GetPane(self.panels[item].window_name).Hide()
776                 
777        self._mgr.Update()
778       
779    def choose_file(self, path=None):
780        """
781            Functionality that belongs elsewhere
782            Should add a hook to specify the preferred file type/extension.
783        """
784        #TODO: clean this up
785        from data_loader import choose_data_file
786       
787        # Choose a file path
788        if path==None:
789            path = choose_data_file(self, self._default_save_location)
790           
791        if not path==None:
792            try:
793                self._default_save_location = os.path.dirname(path)
794               
795                #self.n_fileOpen += 1
796                if self.n_fileOpen==1:
797                    pos= self.filemenu.GetMenuItemCount()-1
798                    #self.filemenu.InsertSeparator(pos )
799               
800                id = wx.NewId()
801                filename= os.path.basename(path)
802                dir= os.path.split(self._default_save_location)[1]
803                title= str(os.path.join(dir,filename )) 
804                menuitem_name = str(self.n_fileOpen)+". "+ title
805                position= self.filemenu.GetMenuItemCount()-2
806                #self.filemenu.Insert(id=id, pos= position,text=menuitem_name,help=str(path) )
807                #self.filePathList.append(( id, menuitem_name, path, title))
808                #wx.EVT_MENU(self, id, self._onreloaFile)
809               
810                ## construct menu item for open file
811                if self.n_fileOpen == self.n_maxfileopen +1:
812                    ## reach the maximun number of path to store
813                    self.n_fileOpen = 0
814                    id, menuitem_name , path, title = self.filePathList[0]
815                    self.filemenu.Delete(id)
816                    self.filePathList.pop(0)
817                    for item in self.filePathList:
818                        id, menuitem_name , path, title = item
819                        self.n_fileOpen += 1
820                        label = str(self.n_fileOpen)+". "+ title
821                        #self.filemenu.FindItemById(id).SetItemLabel(label)
822                       
823                         
824            except:
825                raise
826                #pass
827        return path
828   
829    def load_ascii_1D(self, path):
830        from data_loader import load_ascii_1D
831        return load_ascii_1D(path)
832                 
833class DefaultPanel(wx.Panel):
834    """
835        Defines the API for a panels to work with
836        the GUI manager
837    """
838    ## Internal nickname for the window, used by the AUI manager
839    window_name = "default"
840    ## Name to appear on the window title bar
841    window_caption = "Welcome panel"
842    ## Flag to tell the AUI manager to put this panel in the center pane
843    CENTER_PANE = True
844
845 
846# Toy application to test this Frame
847class ViewApp(wx.App):
848    def OnInit(self):
849        #from gui_manager import ViewerFrame
850        self.frame = ViewerFrame(None, -1, config.__appname__)   
851        self.frame.Show(True)
852
853        if hasattr(self.frame, 'special'):
854            self.frame.special.SetCurrent()
855        self.SetTopWindow(self.frame)
856        return True
857   
858    def set_manager(self, manager):
859        """
860            Sets a reference to the application manager
861            of the GUI manager (Frame)
862        """
863        self.frame.set_manager(manager)
864       
865    def build_gui(self):
866        """
867            Build the GUI
868        """
869        self.frame.build_gui()
870        self.frame.post_init()
871       
872    def set_welcome_panel(self, panel_class):
873        """
874            Set the welcome panel
875            @param panel_class: class of the welcome panel to be instantiated
876        """
877        self.frame.set_welcome_panel(panel_class)
878       
879    def add_perspective(self, perspective):
880        """
881            Manually add a perspective to the application GUI
882        """
883        self.frame.add_perspective(perspective)
884       
885
886if __name__ == "__main__": 
887    app = ViewApp(0)
888    app.MainLoop()             
Note: See TracBrowser for help on using the repository browser.