source: sasview/guiframe/gui_manager.py @ c8570c3

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

Fixed issue with "Panel" menu. Moved to Window menu if app has 1 and only 1 perspective and it has >1 panels.

  • Property mode set to 100644
File size: 33.4 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    def set_default_perspective(self):
163        """
164           Call back method that True to notify the parent that the current plug-in
165           can be set as default  perspective.
166           when returning False, the plug-in is not candidate for an automatic
167           default perspective setting
168        """
169        return False
170
171class ViewerFrame(wx.Frame):
172    """
173        Main application frame
174    """
175    def __init__(self, parent, id, title, window_height=300, window_width=300):
176        """
177            Initialize the Frame object
178        """
179        from local_perspectives.plotting import plotting
180        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, size=(window_width, window_height))
181        # Preferred window size
182        self._window_height = window_height
183        self._window_width  = window_width
184       
185        # Logging info
186        logging.basicConfig(level=logging.DEBUG,
187                    format='%(asctime)s %(levelname)s %(message)s',
188                    filename='sans_app.log',
189                    filemode='w')       
190        path = os.path.dirname(__file__)
191        temp_path= os.path.join(path,'images')
192        ico_file = os.path.join(temp_path,'ball.ico')
193        if os.path.isfile(ico_file):
194            self.SetIcon(wx.Icon(ico_file, wx.BITMAP_TYPE_ICO))
195        else:
196            temp_path= os.path.join(os.getcwd(),'images')
197            ico_file = os.path.join(temp_path,'ball.ico')
198            if os.path.isfile(ico_file):
199                self.SetIcon(wx.Icon(ico_file, wx.BITMAP_TYPE_ICO))
200       
201        ## Application manager
202        self.app_manager = None
203       
204        ## Find plug-ins
205        # Modify this so that we can specify the directory to look into
206        self.plugins =[]
207        self.plugins.append(plotting.Plugin())
208        self.plugins += self._find_plugins()
209     
210        ## List of panels
211        self.panels = {}
212
213        ## Next available ID for wx gui events
214        #TODO:  No longer used - remove all calls to this
215        self.next_id = 20000
216
217        # Default locations
218        self._default_save_location = os.getcwd()       
219
220        # Welcome panel
221        self.defaultPanel = None
222
223        # Check for update
224        self._check_update(None)
225        ## maximum number of opened files' paths to store
226        self.n_maxfileopen =  2
227        ## number of file open
228        self.n_fileOpen=0
229        ## list of path of open files
230        self.filePathList=[]
231        ## list of open file with name form menu
232        #self._saveOpenData()
233        ## Dictionary of open file where keys are filename  and values are number of copy of data plotted
234        ## using the same loaded file
235        self.indice_load_data={}
236        # Register the close event so it calls our own method
237        wx.EVT_CLOSE(self, self._onClose)
238        # Register to status events
239        self.Bind(EVT_STATUS, self._on_status_event)
240   
241       
242    def build_gui(self):
243        # Set up the layout
244        self._setup_layout()
245       
246        # Set up the menu
247        self._setup_menus()
248       
249        #self.Fit()
250       
251        self._check_update(None)
252             
253    def _setup_layout(self):
254        """
255            Set up the layout
256        """
257        # Status bar
258        from statusbar import MyStatusBar
259        self.sb = MyStatusBar(self,wx.ID_ANY)
260        self.SetStatusBar(self.sb)
261
262        # Add panel
263        self._mgr = wx.aui.AuiManager(self)
264        self._mgr.SetDockSizeConstraint(0.5, 0.5) 
265       
266        # Load panels
267        self._load_panels()
268       
269        self._mgr.Update()
270
271    def add_perspective(self, plugin):
272        """
273            Add a perspective if it doesn't already
274            exist.
275        """
276        is_loaded = False
277        for item in self.plugins:
278             if plugin.__class__==item.__class__:
279                 print "Plugin %s already loaded" % plugin.__class__.__name__
280                 is_loaded = True
281                 
282        if not is_loaded:
283            self.plugins.append(plugin)
284     
285    def _find_plugins(self, dir="perspectives"):
286        """
287            Find available perspective plug-ins
288            @param dir: directory in which to look for plug-ins
289            @return: list of plug-ins
290        """
291        import imp
292       
293        plugins = []
294        # Go through files in panels directory
295        try:
296            list = os.listdir(dir)
297            ## the default panel is the panel is the last plugin added
298            for item in list:
299                toks = os.path.splitext(os.path.basename(item))
300                name = None
301                if not toks[0] == '__init__':
302                   
303                    if toks[1]=='.py' or toks[1]=='':
304                        name = toks[0]
305               
306                    path = [os.path.abspath(dir)]
307                    file = None
308                    try:
309                        if toks[1]=='':
310                            mod_path = '.'.join([dir, name])
311                            module = __import__(mod_path, globals(), locals(), [name])
312                        else:
313                            (file, path, info) = imp.find_module(name, path)
314                            module = imp.load_module( name, file, item, info )
315                        if hasattr(module, "PLUGIN_ID"):
316                            try:
317                                plugins.append(module.Plugin())
318                                logging.info("Found plug-in: %s" % module.PLUGIN_ID)
319                            except:
320                                config.printEVT("Error accessing PluginPanel in %s\n  %s" % (name, sys.exc_value))
321                       
322                    except:
323                        print sys.exc_value
324                        logging.error("ViewerFrame._find_plugins: %s" % sys.exc_value)
325                    finally:
326                        if not file==None:
327                            file.close()
328        except:
329            # Should raise and catch at a higher level and display error on status bar
330            pass   
331        return plugins
332   
333    def set_welcome_panel(self, panel_class):
334        """
335           Sets the default panel as the given welcome panel
336           @param panel_class: class of the welcome panel to be instantiated
337        """
338        self.defaultPanel    = panel_class(self, -1, style=wx.RAISED_BORDER)
339       
340    def _load_panels(self):
341        """
342            Load all panels in the panels directory
343        """
344       
345        # Look for plug-in panels
346        panels = []   
347        for item in self.plugins:
348            if hasattr(item, "get_panels"):
349                ps = item.get_panels(self)
350                panels.extend(ps)
351
352        # Show a default panel with some help information
353        # It also sets the size of the application windows
354        #TODO: Use this for slpash screen
355        if self.defaultPanel is None:
356            self.defaultPanel    = DefaultPanel(self, -1, style=wx.RAISED_BORDER)
357           
358        self.panels["default"] = self.defaultPanel
359       
360        self._mgr.AddPane(self.defaultPanel, wx.aui.AuiPaneInfo().
361                              Name("default").
362                              CenterPane().
363                              # This is where we set the size of the application window
364                              BestSize(wx.Size(self._window_width, self._window_height)).
365                              #MinSize(wx.Size(self._window_width, self._window_height)).
366                              Show())
367     
368
369        # Add the panels to the AUI manager
370        for panel_class in panels:
371            p = panel_class
372            id = wx.NewId()
373           
374            # Check whether we need to put this panel
375            # in the center pane
376            if hasattr(p, "CENTER_PANE") and p.CENTER_PANE:
377                if p.CENTER_PANE:
378                    self.panels[str(id)] = p
379                    self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
380                                          Name(p.window_name).Caption(p.window_caption).
381                                          CenterPane().
382                                          #BestSize(wx.Size(550,600)).
383                                          #MinSize(wx.Size(500,500)).
384                                          Hide())
385            else:
386                self.panels[str(id)] = p
387                self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
388                                  Name(p.window_name).Caption(p.window_caption).
389                                  Right().
390                                  Dock().
391                                  TopDockable().
392                                  BottomDockable().
393                                  LeftDockable().
394                                  RightDockable().
395                                  MinimizeButton().
396                                  Hide())
397                                  #BestSize(wx.Size(550,600)))
398                                  #MinSize(wx.Size(500,500)))                 
399     
400    def get_context_menu(self, graph=None):
401        """
402            Get the context menu items made available
403            by the different plug-ins.
404            This function is used by the plotting module
405        """
406        menu_list = []
407        for item in self.plugins:
408            if hasattr(item, "get_context_menu"):
409                menu_list.extend(item.get_context_menu(graph))
410           
411        return menu_list
412       
413    def popup_panel(self, p):
414        """
415            Add a panel object to the AUI manager
416            @param p: panel object to add to the AUI manager
417            @return: ID of the event associated with the new panel [int]
418        """
419       
420        ID = wx.NewId()
421        self.panels[str(ID)] = p
422       
423        count = 0
424        for item in self.panels:
425            if self.panels[item].window_name.startswith(p.window_name): 
426                count += 1
427       
428        windowname = p.window_name
429        caption = p.window_caption
430       
431        if count>0:
432            windowname += str(count+1)
433            caption += (' '+str(count))
434         
435        p.window_name = windowname
436        p.window_caption = caption
437           
438        self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
439                          Name(windowname).Caption(caption).
440                          Floatable().
441                          #Float().
442                          Right().
443                          Dock().
444                          TopDockable().
445                          BottomDockable().
446                          LeftDockable().
447                          RightDockable().
448                          MinimizeButton().
449                          #Hide().
450                          #Show().
451                          Resizable(True).
452                          # Use a large best size to make sure the AUI manager
453                          # takes all the available space
454                          BestSize(wx.Size(400,400)))
455        pane = self._mgr.GetPane(windowname)
456        self._mgr.MaximizePane(pane)
457        self._mgr.RestoreMaximizedPane()
458       
459       
460        # Register for showing/hiding the panel
461       
462        wx.EVT_MENU(self, ID, self._on_view)
463       
464        self._mgr.Update()
465        return ID
466       
467    def _setup_menus(self):
468        """
469            Set up the application menus
470        """
471        # Menu
472        menubar = wx.MenuBar()
473       
474        # File menu
475        self.filemenu = wx.Menu()
476       
477        id = wx.NewId()
478        self.filemenu.Append(id, '&Open', 'Open a file')
479        wx.EVT_MENU(self, id, self._on_open)
480        #self.filemenu.AppendSeparator()
481       
482        id = wx.NewId()
483        self.filemenu.Append(id,'&Quit', 'Exit') 
484        wx.EVT_MENU(self, id, self.Close)
485       
486        # Add sub menus
487        menubar.Append(self.filemenu,  '&File')
488       
489        # Window menu
490        # Attach a menu item for each panel in our
491        # panel list that also appears in a plug-in.
492       
493        # Only add the panel menu if there is only one perspective and
494        # it has more than two panels.
495        # Note: the first plug-in is always the plotting plug-in. The first application
496        # plug-in is always the second one in the list.
497        if len(self.plugins)==2:
498            plug = self.plugins[1]
499            pers = plug.get_perspective()
500       
501            if len(pers)>1:
502                viewmenu = wx.Menu()
503                for item in self.panels:
504                    if item == 'default':
505                        continue
506                    panel = self.panels[item]
507                    if panel.window_name in pers:
508                        viewmenu.Append(int(item), panel.window_caption, "Show %s window" % panel.window_caption)
509                        wx.EVT_MENU(self, int(item), self._on_view)
510                menubar.Append(viewmenu, '&Window')
511
512        # Perspective
513        # Attach a menu item for each defined perspective.
514        # Only add the perspective menu if there are more than one perspectives
515        n_perspectives = 0
516        for plug in self.plugins:
517            if len(plug.get_perspective()) > 0:
518                n_perspectives += 1
519       
520        if n_perspectives>1:
521            p_menu = wx.Menu()
522            for plug in self.plugins:
523                if len(plug.get_perspective()) > 0:
524                    id = wx.NewId()
525                    p_menu.Append(id, plug.sub_menu, "Switch to %s perspective" % plug.sub_menu)
526                    wx.EVT_MENU(self, id, plug.on_perspective)
527            menubar.Append(p_menu,   '&Perspective')
528 
529        # Tools menu
530        # Go through plug-ins and find tools to populate the tools menu
531        toolsmenu = None
532        for item in self.plugins:
533            if hasattr(item, "get_tools"):
534                for tool in item.get_tools():
535                    # Only create a menu if we have at least one tool
536                    if toolsmenu is None:
537                        toolsmenu = wx.Menu()
538                    id = wx.NewId()
539                   
540                    toolsmenu.Append(id, tool[0], tool[1])
541                    wx.EVT_MENU(self, id, tool[2])
542        if toolsmenu is not None:
543            menubar.Append(toolsmenu, '&Tools')
544 
545        # Help menu
546        helpmenu = wx.Menu()
547        # add the welcome panel menu item
548        if self.defaultPanel is not None:
549            id = wx.NewId()
550            helpmenu.Append(id,'&Welcome', '')
551            helpmenu.AppendSeparator()
552            wx.EVT_MENU(self, id, self.show_welcome_panel)
553       
554        # Look for help item in plug-ins
555        for item in self.plugins:
556            if hasattr(item, "help"):
557                id = wx.NewId()
558                helpmenu.Append(id,'&%s help' % item.sub_menu, '')
559                wx.EVT_MENU(self, id, item.help)
560       
561        if config._do_aboutbox:
562            id = wx.NewId()
563            helpmenu.Append(id,'&About', 'Software information')
564            wx.EVT_MENU(self, id, self._onAbout)
565        id = wx.NewId()
566        helpmenu.Append(id,'&Check for update', 'Check for the latest version of %s' % config.__appname__)
567        wx.EVT_MENU(self, id, self._check_update)
568       
569       
570       
571       
572        # Look for plug-in menus
573        # Add available plug-in sub-menus.
574        for item in self.plugins:
575            if hasattr(item, "populate_menu"):
576                for (self.next_id, menu, name) in item.populate_menu(self.next_id, self):
577                    menubar.Append(menu, name)
578                   
579
580        menubar.Append(helpmenu, '&Help')
581         
582        self.SetMenuBar(menubar)
583       
584       
585       
586    def _on_status_event(self, evt):
587        """
588            Display status message
589        """
590        #self.sb.clear_gauge( msg="")
591        mythread=None
592        mytype= None
593        if hasattr(evt, "curr_thread"):
594            mythread= evt.curr_thread
595        if hasattr(evt, "type"):
596            mytype= evt.type
597        self.sb.set_status( type=mytype,msg=str(evt.status),thread=mythread)
598       
599
600       
601    def _on_view(self, evt):
602        """
603            A panel was selected to be shown. If it's not already
604            shown, display it.
605            @param evt: menu event
606        """
607        self.show_panel(evt.GetId())
608       
609    def on_close_welcome_panel(self):
610        """
611            Close the welcome panel
612        """
613        if self.defaultPanel is None:
614            return 
615        self._mgr.GetPane(self.panels["default"].window_name).Hide()
616        self._mgr.Update()
617        # set a default perspective
618        self.set_default_perspective()
619       
620    def show_welcome_panel(self, event):
621        """   
622            Display the welcome panel
623        """
624        if self.defaultPanel is None:
625            return 
626        for id in self.panels.keys():
627            if self._mgr.GetPane(self.panels[id].window_name).IsShown():
628                self._mgr.GetPane(self.panels[id].window_name).Hide()
629        # Show default panel
630        if not self._mgr.GetPane(self.panels["default"].window_name).IsShown():
631            self._mgr.GetPane(self.panels["default"].window_name).Show()
632       
633        self._mgr.Update()
634       
635    def show_panel(self, uid):
636        """
637            Shows the panel with the given id
638            @param uid: unique ID number of the panel to show
639        """
640        ID = str(uid)
641        config.printEVT("show_panel: %s" % ID)
642        if ID in self.panels.keys():
643            if not self._mgr.GetPane(self.panels[ID].window_name).IsShown():
644                self._mgr.GetPane(self.panels[ID].window_name).Show()
645                # Hide default panel
646                self._mgr.GetPane(self.panels["default"].window_name).Hide()
647           
648               
649            self._mgr.Update()
650   
651    def _on_open(self, event):
652   
653        from data_loader import plot_data
654        path = self.choose_file()
655
656        if path ==None:
657            return
658        if path and os.path.isfile(path):
659            plot_data(self, path)
660           
661       
662       
663    def _onClose(self, event):
664        """
665            Store info to retrieve in xml before closing the application
666        """
667        try:
668            doc = xml.dom.minidom.Document()
669            main_node = doc.createElement("file Path")
670           
671            doc.appendChild(main_node)
672       
673            for item in self.filePathList:
674                id, menuitem_name , path, title = item
675                pt1 = doc.createElement("File")
676                pt1.setAttribute("name", menuitem_name)
677                pt2 = doc.createElement("path")
678                pt2.appendChild(doc.createTextNode(str(path)))
679                pt1.appendChild(pt2)
680                pt3 = doc.createElement("title")
681                pt3.appendChild(doc.createTextNode(str(title)))
682                pt1.appendChild(pt3)
683               
684                main_node.appendChild(pt1)
685               
686               
687            fd = open("fileOpened.xml",'w')
688            fd.write(doc.toprettyxml())
689            fd.close()
690        except:
691            pass
692       
693        import sys
694        wx.Exit()
695        sys.exit()
696                   
697                   
698    def Close(self, event=None):
699        """
700            Quit the application
701        """
702        import sys
703        wx.Frame.Close(self)
704        wx.Exit()
705        sys.exit()
706
707 
708    def _check_update(self, event=None): 
709        """
710            Check with the deployment server whether a new version
711            of the application is available.
712            A thread is started for the connecting with the server. The thread calls
713            a call-back method when the current version number has been obtained.
714        """
715        if hasattr(config, "__update_URL__"):
716            import version
717            checker = version.VersionThread(config.__update_URL__, self._process_version, baggage=event==None)
718            checker.start() 
719   
720    def _process_version(self, version, standalone=True):
721        """
722            Call-back method for the process of checking for updates.
723            This methods is called by a VersionThread object once the current
724            version number has been obtained. If the check is being done in the
725            background, the user will not be notified unless there's an update.
726           
727            @param version: version string
728            @param standalone: True of the update is being checked in the background, False otherwise.
729        """
730        try:
731            if cmp(version, config.__version__)>0:
732                self.SetStatusText("Version %s is available! See the Help menu to download it." % version)
733                if not standalone:
734                    import webbrowser
735                    webbrowser.open(config.__download_page__)
736            else:
737                if not standalone:
738                    self.SetStatusText("You have the latest version of %s" % config.__appname__)
739        except:
740            logging.error("guiframe: could not get latest application version number\n  %s" % sys.exc_value)
741            if not standalone:
742                self.SetStatusText("Could not connect to the application server. Please try again later.")
743                   
744       
745    def _onAbout(self, evt):
746        """
747            Pop up the about dialog
748            @param evt: menu event
749        """
750        if config._do_aboutbox:
751            import aboutbox 
752            dialog = aboutbox.DialogAbout(None, -1, "")
753            dialog.ShowModal()           
754           
755    def _onreloaFile(self, event): 
756        """
757            load a data previously opened
758        """
759        from data_loader import plot_data
760        for item in self.filePathList:
761            id, menuitem_name , path, title = item
762            if id == event.GetId():
763                if path and os.path.isfile(path):
764                    plot_data(self, path)
765                    break
766           
767       
768    def set_manager(self, manager):
769        """
770            Sets the application manager for this frame
771            @param manager: frame manager
772        """
773        self.app_manager = manager
774       
775    def post_init(self):
776        """
777            This initialization method is called after the GUI
778            has been created and all plug-ins loaded. It calls
779            the post_init() method of each plug-in (if it exists)
780            so that final initialization can be done.
781        """
782        for item in self.plugins:
783            if hasattr(item, "post_init"):
784                item.post_init()
785       
786    def set_default_perspective(self):
787        """
788            Choose among the plugin the first plug-in that has
789            "set_default_perspective" method and its return value is True will be
790            as a default perspective when the welcome page is closed
791        """
792        for item in self.plugins:
793            if hasattr(item, "set_default_perspective"):
794                if item.set_default_perspective():
795                    item.on_perspective(event=None)
796                    return 
797           
798    def set_perspective(self, panels):
799        """
800            Sets the perspective of the GUI.
801            Opens all the panels in the list, and closes
802            all the others.
803           
804            @param panels: list of panels
805        """
806        for item in self.panels:
807            # Check whether this is a sticky panel
808            if hasattr(self.panels[item], "ALWAYS_ON"):
809                if self.panels[item].ALWAYS_ON:
810                    continue 
811           
812            if self.panels[item].window_name in panels:
813                if not self._mgr.GetPane(self.panels[item].window_name).IsShown():
814                    self._mgr.GetPane(self.panels[item].window_name).Show()
815            else:
816                if self._mgr.GetPane(self.panels[item].window_name).IsShown():
817                    self._mgr.GetPane(self.panels[item].window_name).Hide()
818   
819        self._mgr.Update()
820       
821    def choose_file(self, path=None):
822        """
823            Functionality that belongs elsewhere
824            Should add a hook to specify the preferred file type/extension.
825        """
826        #TODO: clean this up
827        from data_loader import choose_data_file
828       
829        # Choose a file path
830        if path==None:
831            path = choose_data_file(self, self._default_save_location)
832           
833        if not path==None:
834            try:
835                self._default_save_location = os.path.dirname(path)
836               
837                #self.n_fileOpen += 1
838                if self.n_fileOpen==1:
839                    pos= self.filemenu.GetMenuItemCount()-1
840                    #self.filemenu.InsertSeparator(pos )
841               
842                id = wx.NewId()
843                filename= os.path.basename(path)
844                dir= os.path.split(self._default_save_location)[1]
845                title= str(os.path.join(dir,filename )) 
846                menuitem_name = str(self.n_fileOpen)+". "+ title
847                position= self.filemenu.GetMenuItemCount()-2
848                #self.filemenu.Insert(id=id, pos= position,text=menuitem_name,help=str(path) )
849                #self.filePathList.append(( id, menuitem_name, path, title))
850                #wx.EVT_MENU(self, id, self._onreloaFile)
851               
852                ## construct menu item for open file
853                if self.n_fileOpen == self.n_maxfileopen +1:
854                    ## reach the maximun number of path to store
855                    self.n_fileOpen = 0
856                    id, menuitem_name , path, title = self.filePathList[0]
857                    self.filemenu.Delete(id)
858                    self.filePathList.pop(0)
859                    for item in self.filePathList:
860                        id, menuitem_name , path, title = item
861                        self.n_fileOpen += 1
862                        label = str(self.n_fileOpen)+". "+ title
863                        #self.filemenu.FindItemById(id).SetItemLabel(label)
864                       
865                         
866            except:
867                raise
868                #pass
869        return path
870   
871    def load_ascii_1D(self, path):
872        from data_loader import load_ascii_1D
873        return load_ascii_1D(path)
874                 
875class DefaultPanel(wx.Panel):
876    """
877        Defines the API for a panels to work with
878        the GUI manager
879    """
880    ## Internal nickname for the window, used by the AUI manager
881    window_name = "default"
882    ## Name to appear on the window title bar
883    window_caption = "Welcome panel"
884    ## Flag to tell the AUI manager to put this panel in the center pane
885    CENTER_PANE = True
886
887 
888# Toy application to test this Frame
889class ViewApp(wx.App):
890    def OnInit(self):
891        #from gui_manager import ViewerFrame
892        self.frame = ViewerFrame(None, -1, config.__appname__)   
893        self.frame.Show(True)
894
895        if hasattr(self.frame, 'special'):
896            self.frame.special.SetCurrent()
897        self.SetTopWindow(self.frame)
898        return True
899   
900    def set_manager(self, manager):
901        """
902            Sets a reference to the application manager
903            of the GUI manager (Frame)
904        """
905        self.frame.set_manager(manager)
906       
907    def build_gui(self):
908        """
909            Build the GUI
910        """
911        self.frame.build_gui()
912        self.frame.post_init()
913       
914    def set_welcome_panel(self, panel_class):
915        """
916            Set the welcome panel
917            @param panel_class: class of the welcome panel to be instantiated
918        """
919        self.frame.set_welcome_panel(panel_class)
920       
921    def add_perspective(self, perspective):
922        """
923            Manually add a perspective to the application GUI
924        """
925        self.frame.add_perspective(perspective)
926       
927
928if __name__ == "__main__": 
929    app = ViewApp(0)
930    app.MainLoop()             
Note: See TracBrowser for help on using the repository browser.