source: sasview/guiframe/gui_manager.py @ f50330b7

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

guiframe: removed hard-coded window sizes from gui_manager

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