source: sasview/guiframe/gui_manager.py @ 8dcfb2e

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 8dcfb2e was b3644f3, checked in by Gervaise Alina <gervyh@…>, 15 years ago

working on loading large data

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