source: sasview/guiframe/gui_manager.py @ 4ea3600

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 4ea3600 was b28278e, checked in by Gervaise Alina <gervyh@…>, 15 years ago

adding another method set_default_perspective for plugin

  • Property mode set to 100644
File size: 33.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    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"):
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        # Plot menu
490        # Attach a menu item for each panel in our
491        # panel list that also appears in a plug-in.
492        # TODO: clean this up. We should just identify
493        # plug-in panels and add them all.
494       
495        # Only add the panel menu if there is more than two panels
496        n_panels = 0
497        for plug in self.plugins:
498            pers = plug.get_perspective()
499            if len(pers)>0:
500                n_panels += 1
501       
502        if n_panels>2:
503            viewmenu = wx.Menu()
504            for plug in self.plugins:
505                plugmenu = wx.Menu()
506                pers = plug.get_perspective()
507                if len(pers)>0:
508                    for item in self.panels:
509                        if item == 'default':
510                            continue
511                        panel = self.panels[item]
512                        if panel.window_name in pers:
513                            plugmenu.Append(int(item), panel.window_caption, "Show %s window" % panel.window_caption)
514                           
515                            wx.EVT_MENU(self, int(item), self._on_view)
516                   
517                    viewmenu.AppendMenu(wx.NewId(), plug.sub_menu, plugmenu, plug.sub_menu)
518            menubar.Append(viewmenu, '&Panel')
519
520        # Perspective
521        # Attach a menu item for each defined perspective.
522        # Only add the perspective menu if there are more than one perspectives
523        n_perspectives = 0
524        for plug in self.plugins:
525            if len(plug.get_perspective()) > 0:
526                n_perspectives += 1
527       
528        if n_perspectives>1:
529            p_menu = wx.Menu()
530            for plug in self.plugins:
531                if len(plug.get_perspective()) > 0:
532                    id = wx.NewId()
533                    p_menu.Append(id, plug.sub_menu, "Switch to %s perspective" % plug.sub_menu)
534                    wx.EVT_MENU(self, id, plug.on_perspective)
535            menubar.Append(p_menu,   '&Perspective')
536 
537        # Tools menu
538        # Go through plug-ins and find tools to populate the tools menu
539        toolsmenu = None
540        for item in self.plugins:
541            if hasattr(item, "get_tools"):
542                for tool in item.get_tools():
543                    # Only create a menu if we have at least one tool
544                    if toolsmenu is None:
545                        toolsmenu = wx.Menu()
546                    id = wx.NewId()
547                   
548                    toolsmenu.Append(id, tool[0], tool[1])
549                    wx.EVT_MENU(self, id, tool[2])
550        if toolsmenu is not None:
551            menubar.Append(toolsmenu, '&Tools')
552 
553        # Help menu
554        helpmenu = wx.Menu()
555        # add the welcome panel menu item
556        if self.defaultPanel is not None:
557            id = wx.NewId()
558            helpmenu.Append(id,'&Welcome', '')
559            helpmenu.AppendSeparator()
560            wx.EVT_MENU(self, id, self.show_welcome_panel)
561       
562        # Look for help item in plug-ins
563        for item in self.plugins:
564            if hasattr(item, "help"):
565                id = wx.NewId()
566                helpmenu.Append(id,'&%s help' % item.sub_menu, '')
567                wx.EVT_MENU(self, id, item.help)
568       
569        if config._do_aboutbox:
570            id = wx.NewId()
571            helpmenu.Append(id,'&About', 'Software information')
572            wx.EVT_MENU(self, id, self._onAbout)
573        id = wx.NewId()
574        helpmenu.Append(id,'&Check for update', 'Check for the latest version of %s' % config.__appname__)
575        wx.EVT_MENU(self, id, self._check_update)
576       
577       
578       
579       
580        # Look for plug-in menus
581        # Add available plug-in sub-menus.
582        for item in self.plugins:
583            if hasattr(item, "populate_menu"):
584                for (self.next_id, menu, name) in item.populate_menu(self.next_id, self):
585                    menubar.Append(menu, name)
586                   
587
588        menubar.Append(helpmenu, '&Help')
589         
590        self.SetMenuBar(menubar)
591       
592       
593       
594    def _on_status_event(self, evt):
595        """
596            Display status message
597        """
598        #self.sb.clear_gauge( msg="")
599        mythread=None
600        mytype= None
601        if hasattr(evt, "curr_thread"):
602            mythread= evt.curr_thread
603        if hasattr(evt, "type"):
604            mytype= evt.type
605        self.sb.set_status( type=mytype,msg=str(evt.status),thread=mythread)
606       
607
608       
609    def _on_view(self, evt):
610        """
611            A panel was selected to be shown. If it's not already
612            shown, display it.
613            @param evt: menu event
614        """
615        self.show_panel(evt.GetId())
616       
617    def on_close_welcome_panel(self):
618        """
619            Close the welcome panel
620        """
621        if self.defaultPanel is None:
622            return 
623        self._mgr.GetPane(self.panels["default"].window_name).Hide()
624        self._mgr.Update()
625        # set a default perspective
626        self.set_default_perspective()
627       
628    def show_welcome_panel(self, event):
629        """   
630            Display the welcome panel
631        """
632        if self.defaultPanel is None:
633            return 
634        for id in self.panels.keys():
635            if self._mgr.GetPane(self.panels[id].window_name).IsShown():
636                self._mgr.GetPane(self.panels[id].window_name).Hide()
637        # Show default panel
638        if not self._mgr.GetPane(self.panels["default"].window_name).IsShown():
639            self._mgr.GetPane(self.panels["default"].window_name).Show()
640       
641        self._mgr.Update()
642       
643    def show_panel(self, uid):
644        """
645            Shows the panel with the given id
646            @param uid: unique ID number of the panel to show
647        """
648        ID = str(uid)
649        config.printEVT("show_panel: %s" % ID)
650        if ID in self.panels.keys():
651            if not self._mgr.GetPane(self.panels[ID].window_name).IsShown():
652                self._mgr.GetPane(self.panels[ID].window_name).Show()
653                # Hide default panel
654                self._mgr.GetPane(self.panels["default"].window_name).Hide()
655           
656               
657            self._mgr.Update()
658   
659    def _on_open(self, event):
660   
661        from data_loader import plot_data
662        path = self.choose_file()
663
664        if path ==None:
665            return
666        if path and os.path.isfile(path):
667            plot_data(self, path)
668           
669       
670       
671    def _onClose(self, event):
672        """
673            Store info to retrieve in xml before closing the application
674        """
675        try:
676            doc = xml.dom.minidom.Document()
677            main_node = doc.createElement("file Path")
678           
679            doc.appendChild(main_node)
680       
681            for item in self.filePathList:
682                id, menuitem_name , path, title = item
683                pt1 = doc.createElement("File")
684                pt1.setAttribute("name", menuitem_name)
685                pt2 = doc.createElement("path")
686                pt2.appendChild(doc.createTextNode(str(path)))
687                pt1.appendChild(pt2)
688                pt3 = doc.createElement("title")
689                pt3.appendChild(doc.createTextNode(str(title)))
690                pt1.appendChild(pt3)
691               
692                main_node.appendChild(pt1)
693               
694               
695            fd = open("fileOpened.xml",'w')
696            fd.write(doc.toprettyxml())
697            fd.close()
698        except:
699            pass
700       
701        import sys
702        wx.Exit()
703        sys.exit()
704                   
705                   
706    def Close(self, event=None):
707        """
708            Quit the application
709        """
710        import sys
711        wx.Frame.Close(self)
712        wx.Exit()
713        sys.exit()
714
715 
716    def _check_update(self, event=None): 
717        """
718            Check with the deployment server whether a new version
719            of the application is available.
720            A thread is started for the connecting with the server. The thread calls
721            a call-back method when the current version number has been obtained.
722        """
723        if hasattr(config, "__update_URL__"):
724            import version
725            checker = version.VersionThread(config.__update_URL__, self._process_version, baggage=event==None)
726            checker.start() 
727   
728    def _process_version(self, version, standalone=True):
729        """
730            Call-back method for the process of checking for updates.
731            This methods is called by a VersionThread object once the current
732            version number has been obtained. If the check is being done in the
733            background, the user will not be notified unless there's an update.
734           
735            @param version: version string
736            @param standalone: True of the update is being checked in the background, False otherwise.
737        """
738        try:
739            if cmp(version, config.__version__)>0:
740                self.SetStatusText("Version %s is available! See the Help menu to download it." % version)
741                if not standalone:
742                    import webbrowser
743                    webbrowser.open(config.__download_page__)
744            else:
745                if not standalone:
746                    self.SetStatusText("You have the latest version of %s" % config.__appname__)
747        except:
748            logging.error("guiframe: could not get latest application version number\n  %s" % sys.exc_value)
749            if not standalone:
750                self.SetStatusText("Could not connect to the application server. Please try again later.")
751                   
752       
753    def _onAbout(self, evt):
754        """
755            Pop up the about dialog
756            @param evt: menu event
757        """
758        if config._do_aboutbox:
759            import aboutbox 
760            dialog = aboutbox.DialogAbout(None, -1, "")
761            dialog.ShowModal()           
762           
763    def _onreloaFile(self, event): 
764        """
765            load a data previously opened
766        """
767        from data_loader import plot_data
768        for item in self.filePathList:
769            id, menuitem_name , path, title = item
770            if id == event.GetId():
771                if path and os.path.isfile(path):
772                    plot_data(self, path)
773                    break
774           
775       
776    def set_manager(self, manager):
777        """
778            Sets the application manager for this frame
779            @param manager: frame manager
780        """
781        self.app_manager = manager
782       
783    def post_init(self):
784        """
785            This initialization method is called after the GUI
786            has been created and all plug-ins loaded. It calls
787            the post_init() method of each plug-in (if it exists)
788            so that final initialization can be done.
789        """
790        for item in self.plugins:
791            if hasattr(item, "post_init"):
792                item.post_init()
793       
794    def set_default_perspective(self):
795        """
796            Choose among the plugin the first plug-in that has
797            "set_default_perspective" method and its return value is True will be
798            as a default perspective when the welcome page is closed
799        """
800        for item in self.plugins:
801            if hasattr(item, "set_default_perspective"):
802                if item.set_default_perspective():
803                    item.on_perspective(event=None)
804                    return 
805           
806    def set_perspective(self, panels):
807        """
808            Sets the perspective of the GUI.
809            Opens all the panels in the list, and closes
810            all the others.
811           
812            @param panels: list of panels
813        """
814        for item in self.panels:
815            # Check whether this is a sticky panel
816            if hasattr(self.panels[item], "ALWAYS_ON"):
817                if self.panels[item].ALWAYS_ON:
818                    continue 
819           
820            if self.panels[item].window_name in panels:
821                if not self._mgr.GetPane(self.panels[item].window_name).IsShown():
822                    self._mgr.GetPane(self.panels[item].window_name).Show()
823            else:
824                if self._mgr.GetPane(self.panels[item].window_name).IsShown():
825                    self._mgr.GetPane(self.panels[item].window_name).Hide()
826   
827        self._mgr.Update()
828       
829    def choose_file(self, path=None):
830        """
831            Functionality that belongs elsewhere
832            Should add a hook to specify the preferred file type/extension.
833        """
834        #TODO: clean this up
835        from data_loader import choose_data_file
836       
837        # Choose a file path
838        if path==None:
839            path = choose_data_file(self, self._default_save_location)
840           
841        if not path==None:
842            try:
843                self._default_save_location = os.path.dirname(path)
844               
845                #self.n_fileOpen += 1
846                if self.n_fileOpen==1:
847                    pos= self.filemenu.GetMenuItemCount()-1
848                    #self.filemenu.InsertSeparator(pos )
849               
850                id = wx.NewId()
851                filename= os.path.basename(path)
852                dir= os.path.split(self._default_save_location)[1]
853                title= str(os.path.join(dir,filename )) 
854                menuitem_name = str(self.n_fileOpen)+". "+ title
855                position= self.filemenu.GetMenuItemCount()-2
856                #self.filemenu.Insert(id=id, pos= position,text=menuitem_name,help=str(path) )
857                #self.filePathList.append(( id, menuitem_name, path, title))
858                #wx.EVT_MENU(self, id, self._onreloaFile)
859               
860                ## construct menu item for open file
861                if self.n_fileOpen == self.n_maxfileopen +1:
862                    ## reach the maximun number of path to store
863                    self.n_fileOpen = 0
864                    id, menuitem_name , path, title = self.filePathList[0]
865                    self.filemenu.Delete(id)
866                    self.filePathList.pop(0)
867                    for item in self.filePathList:
868                        id, menuitem_name , path, title = item
869                        self.n_fileOpen += 1
870                        label = str(self.n_fileOpen)+". "+ title
871                        #self.filemenu.FindItemById(id).SetItemLabel(label)
872                       
873                         
874            except:
875                raise
876                #pass
877        return path
878   
879    def load_ascii_1D(self, path):
880        from data_loader import load_ascii_1D
881        return load_ascii_1D(path)
882                 
883class DefaultPanel(wx.Panel):
884    """
885        Defines the API for a panels to work with
886        the GUI manager
887    """
888    ## Internal nickname for the window, used by the AUI manager
889    window_name = "default"
890    ## Name to appear on the window title bar
891    window_caption = "Welcome panel"
892    ## Flag to tell the AUI manager to put this panel in the center pane
893    CENTER_PANE = True
894
895 
896# Toy application to test this Frame
897class ViewApp(wx.App):
898    def OnInit(self):
899        #from gui_manager import ViewerFrame
900        self.frame = ViewerFrame(None, -1, config.__appname__)   
901        self.frame.Show(True)
902
903        if hasattr(self.frame, 'special'):
904            self.frame.special.SetCurrent()
905        self.SetTopWindow(self.frame)
906        return True
907   
908    def set_manager(self, manager):
909        """
910            Sets a reference to the application manager
911            of the GUI manager (Frame)
912        """
913        self.frame.set_manager(manager)
914       
915    def build_gui(self):
916        """
917            Build the GUI
918        """
919        self.frame.build_gui()
920        self.frame.post_init()
921       
922    def set_welcome_panel(self, panel_class):
923        """
924            Set the welcome panel
925            @param panel_class: class of the welcome panel to be instantiated
926        """
927        self.frame.set_welcome_panel(panel_class)
928       
929    def add_perspective(self, perspective):
930        """
931            Manually add a perspective to the application GUI
932        """
933        self.frame.add_perspective(perspective)
934       
935
936if __name__ == "__main__": 
937    app = ViewApp(0)
938    app.MainLoop()             
Note: See TracBrowser for help on using the repository browser.