source: sasview/guiframe/gui_manager.py @ 44aa1ed

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

guiframe: add functionality to set an application welcome panel

  • Property mode set to 100644
File size: 32.5 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
[f9e803e]121        defaultpanel = DefaultPanel(self.parent, -1)
[7681bac]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
[f9e803e]127        return [defaultpanel]
[7681bac]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
[f9e803e]224        # Welcome panel
225        self.defaultPanel = None
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   
[f9e803e]351    def set_welcome_panel(self, panel_class):
352        """
353           Sets the default panel as the given welcome panel
354           @param panel_class: class of the welcome panel to be instantiated
355        """
356        self.defaultPanel    = panel_class(self, -1, style=wx.RAISED_BORDER)
[41d466f]357     
358    def _load_panels(self):
359        """
360            Load all panels in the panels directory
361        """
362       
363        # Look for plug-in panels
364        panels = []       
365        for item in self.plugins:
366            if hasattr(item, "get_panels"):
367                ps = item.get_panels(self)
368                panels.extend(ps)
369
370        # Show a default panel with some help information
371        # It also sets the size of the application windows
[c9454bb]372        #TODO: Use this for slpash screen
[f9e803e]373        if self.defaultPanel is None:
374            self.defaultPanel    = DefaultPanel(self, -1, style=wx.RAISED_BORDER)
375           
[41d466f]376        self.panels["default"] = self.defaultPanel
[ca88b2e]377       
[41d466f]378        self._mgr.AddPane(self.defaultPanel, wx.aui.AuiPaneInfo().
379                              Name("default").
380                              CenterPane().
[d0802c3]381                              # This is where we set the size of the application window
382                              BestSize(wx.Size(self._window_width, self._window_height)).
[c9454bb]383                              #MinSize(wx.Size(self._window_width, self._window_height)).
[41d466f]384                              Show())
[6d920cd]385     
[41d466f]386
387        # Add the panels to the AUI manager
388        for panel_class in panels:
389            p = panel_class
390            id = wx.NewId()
391           
392            # Check whether we need to put this panel
393            # in the center pane
394            if hasattr(p, "CENTER_PANE"):
395                if p.CENTER_PANE:
396                    self.panels[str(id)] = p
397                    self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
398                                          Name(p.window_name).Caption(p.window_caption).
399                                          CenterPane().
[c9454bb]400                                          #BestSize(wx.Size(550,600)).
401                                          #MinSize(wx.Size(500,500)).
[41d466f]402                                          Hide())
403            else:
404                self.panels[str(id)] = p
405                self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
406                                  Name(p.window_name).Caption(p.window_caption).
407                                  Right().
408                                  Dock().
409                                  TopDockable().
410                                  BottomDockable().
411                                  LeftDockable().
412                                  RightDockable().
413                                  MinimizeButton().
[c9454bb]414                                  Hide())
415                                  #BestSize(wx.Size(550,600)))
416                                  #MinSize(wx.Size(500,500)))                 
[41d466f]417               
418       
[2310d69]419    def get_context_menu(self, graph=None):
[41d466f]420        """
421            Get the context menu items made available
422            by the different plug-ins.
423            This function is used by the plotting module
424        """
425        menu_list = []
426        for item in self.plugins:
427            if hasattr(item, "get_context_menu"):
[2310d69]428                menu_list.extend(item.get_context_menu(graph))
[41d466f]429           
430        return menu_list
431       
432    def popup_panel(self, p):
433        """
434            Add a panel object to the AUI manager
435            @param p: panel object to add to the AUI manager
436            @return: ID of the event associated with the new panel [int]
437        """
438       
439        ID = wx.NewId()
440        self.panels[str(ID)] = p
441       
442        count = 0
443        for item in self.panels:
[383189f9]444            if self.panels[item].window_name.startswith(p.window_name): 
[41d466f]445                count += 1
[16bf519]446       
[41d466f]447        windowname = p.window_name
448        caption = p.window_caption
[16bf519]449       
[41d466f]450        if count>0:
451            windowname += str(count+1)
452            caption += (' '+str(count))
[16bf519]453         
[41d466f]454        p.window_name = windowname
455        p.window_caption = caption
456           
457        self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
458                          Name(windowname).Caption(caption).
459                          Floatable().
460                          #Float().
461                          Right().
462                          Dock().
463                          TopDockable().
464                          BottomDockable().
465                          LeftDockable().
466                          RightDockable().
467                          MinimizeButton().
468                          #Hide().
469                          #Show().
[c9454bb]470                          Resizable(True).
471                          # Use a large best size to make sure the AUI manager
472                          # takes all the available space
473                          BestSize(wx.Size(1300,1300)))
474                          #MinSize(wx.Size(500,500)))
[16bf519]475                          #BestSize(wx.Size(400,400)).
476                          #MinSize(wx.Size(350,350)))
[d0802c3]477        pane = self._mgr.GetPane(windowname)
478        self._mgr.MaximizePane(pane)
479        self._mgr.RestoreMaximizedPane()
480       
[41d466f]481       
482        # Register for showing/hiding the panel
[0d9dae8]483       
[41d466f]484        wx.EVT_MENU(self, ID, self._on_view)
485       
486        self._mgr.Update()
487        return ID
488       
489    def _setup_menus(self):
490        """
491            Set up the application menus
492        """
493        # Menu
494        menubar = wx.MenuBar()
495       
496        # File menu
[b0eee0f0]497        self.filemenu = wx.Menu()
[fc2b91a]498       
499        id = wx.NewId()
[b0eee0f0]500        self.filemenu.Append(id, '&Open', 'Open a file')
[fc2b91a]501        wx.EVT_MENU(self, id, self._on_open)
[b0eee0f0]502        #self.filemenu.AppendSeparator()
503       
[ca88b2e]504        id = wx.NewId()
[b0eee0f0]505        self.filemenu.Append(id,'&Quit', 'Exit') 
[fc2b91a]506        wx.EVT_MENU(self, id, self.Close)
[41d466f]507       
[adfcab3]508        # Add sub menus
[b0eee0f0]509        menubar.Append(self.filemenu,  '&File')
[adfcab3]510       
[41d466f]511        # Plot menu
512        # Attach a menu item for each panel in our
513        # panel list that also appears in a plug-in.
514        # TODO: clean this up. We should just identify
515        # plug-in panels and add them all.
516       
[b8d7491]517        # Only add the panel menu if there is more than two panels
[adfcab3]518        n_panels = 0
[41d466f]519        for plug in self.plugins:
520            pers = plug.get_perspective()
521            if len(pers)>0:
[adfcab3]522                n_panels += 1
[0d9dae8]523       
[b8d7491]524        if n_panels>2:
[adfcab3]525            viewmenu = wx.Menu()
526            for plug in self.plugins:
527                plugmenu = wx.Menu()
528                pers = plug.get_perspective()
529                if len(pers)>0:
530                    for item in self.panels:
531                        if item == 'default':
532                            continue
533                        panel = self.panels[item]
534                        if panel.window_name in pers:
535                            plugmenu.Append(int(item), panel.window_caption, "Show %s window" % panel.window_caption)
[0d9dae8]536                           
537                           
538                           
[adfcab3]539                            wx.EVT_MENU(self, int(item), self._on_view)
540                   
541                    viewmenu.AppendMenu(wx.NewId(), plug.sub_menu, plugmenu, plug.sub_menu)
542            menubar.Append(viewmenu, '&Panel')
543
[41d466f]544        # Perspective
545        # Attach a menu item for each defined perspective.
[adfcab3]546        # Only add the perspective menu if there are more than one perspectves
547        n_perspectives = 0
[41d466f]548        for plug in self.plugins:
549            if len(plug.get_perspective()) > 0:
[adfcab3]550                n_perspectives += 1
551       
552        if n_perspectives>1:
553            p_menu = wx.Menu()
554            for plug in self.plugins:
555                if len(plug.get_perspective()) > 0:
556                    id = wx.NewId()
557                    p_menu.Append(id, plug.sub_menu, "Switch to %s perspective" % plug.sub_menu)
558                    wx.EVT_MENU(self, id, plug.on_perspective)
559            menubar.Append(p_menu,   '&Perspective')
[41d466f]560 
561        # Help menu
562        helpmenu = wx.Menu()
[fa452e4]563
564        # Look for help item in plug-ins
565        for item in self.plugins:
566            if hasattr(item, "help"):
567                id = wx.NewId()
568                helpmenu.Append(id,'&%s help' % item.sub_menu, '')
569                wx.EVT_MENU(self, id, item.help)
570       
[41d466f]571        if config._do_aboutbox:
572            id = wx.NewId()
573            helpmenu.Append(id,'&About', 'Software information')
574            wx.EVT_MENU(self, id, self._onAbout)
575        id = wx.NewId()
576        helpmenu.Append(id,'&Check for update', 'Check for the latest version of %s' % config.__appname__)
577        wx.EVT_MENU(self, id, self._check_update)
578       
579       
[adfcab3]580       
[41d466f]581       
582        # Look for plug-in menus
583        # Add available plug-in sub-menus.
584        for item in self.plugins:
585            if hasattr(item, "populate_menu"):
586                for (self.next_id, menu, name) in item.populate_menu(self.next_id, self):
587                    menubar.Append(menu, name)
[0d9dae8]588                   
[41d466f]589
590        menubar.Append(helpmenu, '&Help')
591         
592        self.SetMenuBar(menubar)
593       
[fc2b91a]594       
[41d466f]595       
596    def _on_status_event(self, evt):
597        """
598            Display status message
599        """
[f706f393]600        #self.sb.clear_gauge( msg="")
[dd66fbd]601        mythread=None
602        mytype= None
603        if hasattr(evt, "curr_thread"):
604            mythread= evt.curr_thread
605        if hasattr(evt, "type"):
606            mytype= evt.type
607        self.sb.set_status( type=mytype,msg=str(evt.status),thread=mythread)
608       
[41d466f]609
610       
611    def _on_view(self, evt):
612        """
613            A panel was selected to be shown. If it's not already
614            shown, display it.
615            @param evt: menu event
616        """
617        self.show_panel(evt.GetId())
618
619    def show_panel(self, uid):
620        """
621            Shows the panel with the given id
622            @param uid: unique ID number of the panel to show
623        """
624        ID = str(uid)
625        config.printEVT("show_panel: %s" % ID)
626        if ID in self.panels.keys():
627            if not self._mgr.GetPane(self.panels[ID].window_name).IsShown():
628                self._mgr.GetPane(self.panels[ID].window_name).Show()
[383189f9]629                # Hide default panel
630                self._mgr.GetPane(self.panels["default"].window_name).Hide()
[353041d]631           
[383189f9]632               
[41d466f]633            self._mgr.Update()
[6d920cd]634   
[fc2b91a]635    def _on_open(self, event):
[4102709]636   
[fc2b91a]637        from data_loader import plot_data
638        path = self.choose_file()
[b8d7491]639
[700f9b4]640        if path ==None:
641            return
[fc2b91a]642        if path and os.path.isfile(path):
643            plot_data(self, path)
[4102709]644           
[fc2b91a]645       
646       
[41d466f]647    def _onClose(self, event):
[b0eee0f0]648        """
649            Store info to retrieve in xml before closing the application
650        """
651        try:
652            doc = xml.dom.minidom.Document()
653            main_node = doc.createElement("file Path")
654           
655            doc.appendChild(main_node)
656       
657            for item in self.filePathList:
658                id, menuitem_name , path, title = item
659                pt1 = doc.createElement("File")
660                pt1.setAttribute("name", menuitem_name)
661                pt2 = doc.createElement("path")
662                pt2.appendChild(doc.createTextNode(str(path)))
663                pt1.appendChild(pt2)
664                pt3 = doc.createElement("title")
665                pt3.appendChild(doc.createTextNode(str(title)))
666                pt1.appendChild(pt3)
667               
668                main_node.appendChild(pt1)
669               
670               
671            fd = open("fileOpened.xml",'w')
672            fd.write(doc.toprettyxml())
673            fd.close()
674        except:
675            pass
676       
[41d466f]677        import sys
678        wx.Exit()
679        sys.exit()
680                   
[b0eee0f0]681                   
[41d466f]682    def Close(self, event=None):
683        """
684            Quit the application
685        """
686        import sys
687        wx.Frame.Close(self)
688        wx.Exit()
689        sys.exit()
690
691 
692    def _check_update(self, event=None): 
693        """
694            Check with the deployment server whether a new version
695            of the application is available
696        """
697        import urllib
698        try: 
699            h = urllib.urlopen(config.__update_URL__)
700            lines = h.readlines()
701            line = ''
702            if len(lines)>0:
703                line = lines[0]
704               
705                toks = line.lstrip().rstrip().split('.')
706                toks_current = config.__version__.split('.')
707                update_available = False
708                for i in range(len(toks)):
[75b40ce]709                    if len(toks[i].strip())>0:
710                        if int(toks[i].strip())>int(toks_current[i]):
711                            update_available = True
[41d466f]712                if update_available:
713                    #print "Version %s is available" % line.rstrip().lstrip()
714                    self.SetStatusText("Version %s is available! See the Help menu to download it." % line.rstrip().lstrip())
715                    if event != None:
716                        import webbrowser
717                        webbrowser.open(config.__download_page__)
718                else:
[75b40ce]719                    if event != None:
720                        self.SetStatusText("You have the latest version of %s" % config.__appname__)
[41d466f]721        except:
[75b40ce]722            if event != None:
723                self.SetStatusText("You have the latest version of %s" % config.__appname__)
[41d466f]724           
725           
726    def _onAbout(self, evt):
727        """
728            Pop up the about dialog
729            @param evt: menu event
730        """
731        if config._do_aboutbox:
732            import aboutbox 
733            dialog = aboutbox.DialogAbout(None, -1, "")
734            dialog.ShowModal()
735           
[b0eee0f0]736           
737    def _saveOpenData(self):
738        """
739            Savename and path of n opened data  into as xml file
740        """
741        try:
742            fd = open("fileOpened.xml",'r')
743            from xml.dom.minidom import parse
744            dom = parse(fd)
745            ## Check the format version number
746            nodes = xpath.Evaluate('file Path\File', dom)
747            print "node",nodes
748            if nodes[0].hasAttributes():
749                print "--->"
750            fd.close()
751        except:
752            raise
753       
754       
755       
756    def _onreloaFile(self, event): 
757        """
758            load a data previously opened
759        """
760        from data_loader import plot_data
761        for item in self.filePathList:
762            id, menuitem_name , path, title = item
763            if id == event.GetId():
764                if path and os.path.isfile(path):
765                    plot_data(self, path)
766                    break
767           
768       
[41d466f]769    def set_manager(self, manager):
770        """
771            Sets the application manager for this frame
772            @param manager: frame manager
773        """
774        self.app_manager = manager
775       
776    def post_init(self):
777        """
778            This initialization method is called after the GUI
779            has been created and all plug-ins loaded. It calls
780            the post_init() method of each plug-in (if it exists)
781            so that final initialization can be done.
782        """
783        for item in self.plugins:
784            if hasattr(item, "post_init"):
785                item.post_init()
786       
787    def set_perspective(self, panels):
788        """
789            Sets the perspective of the GUI.
790            Opens all the panels in the list, and closes
791            all the others.
792           
793            @param panels: list of panels
794        """
795        for item in self.panels:
796            # Check whether this is a sticky panel
797            if hasattr(self.panels[item], "ALWAYS_ON"):
798                if self.panels[item].ALWAYS_ON:
799                    continue 
800           
801            if self.panels[item].window_name in panels:
802                if not self._mgr.GetPane(self.panels[item].window_name).IsShown():
803                    self._mgr.GetPane(self.panels[item].window_name).Show()
804            else:
805                if self._mgr.GetPane(self.panels[item].window_name).IsShown():
806                    self._mgr.GetPane(self.panels[item].window_name).Hide()
807                 
808        self._mgr.Update()
809       
[8068b52]810    def choose_file(self, path=None):
[41d466f]811        """
812            Functionality that belongs elsewhere
813            Should add a hook to specify the preferred file type/extension.
814        """
815        #TODO: clean this up
816        from data_loader import choose_data_file
[8068b52]817       
818        # Choose a file path
819        if path==None:
820            path = choose_data_file(self, self._default_save_location)
821           
[2310d69]822        if not path==None:
823            try:
824                self._default_save_location = os.path.dirname(path)
[b0eee0f0]825               
[25ccf33]826                #self.n_fileOpen += 1
[b0eee0f0]827                if self.n_fileOpen==1:
828                    pos= self.filemenu.GetMenuItemCount()-1
829                    #self.filemenu.InsertSeparator(pos )
830               
831                id = wx.NewId()
832                filename= os.path.basename(path)
833                dir= os.path.split(self._default_save_location)[1]
834                title= str(os.path.join(dir,filename )) 
835                menuitem_name = str(self.n_fileOpen)+". "+ title
836                position= self.filemenu.GetMenuItemCount()-2
837                #self.filemenu.Insert(id=id, pos= position,text=menuitem_name,help=str(path) )
838                #self.filePathList.append(( id, menuitem_name, path, title))
839                #wx.EVT_MENU(self, id, self._onreloaFile)
840               
841                ## construct menu item for open file
842                if self.n_fileOpen == self.n_maxfileopen +1:
843                    ## reach the maximun number of path to store
844                    self.n_fileOpen = 0
845                    id, menuitem_name , path, title = self.filePathList[0]
846                    self.filemenu.Delete(id)
847                    self.filePathList.pop(0)
848                    for item in self.filePathList:
849                        id, menuitem_name , path, title = item
850                        self.n_fileOpen += 1
851                        label = str(self.n_fileOpen)+". "+ title
852                        #self.filemenu.FindItemById(id).SetItemLabel(label)
853                       
854                         
[2310d69]855            except:
[b0eee0f0]856                raise
857                #pass
[2310d69]858        return path
859   
860    def load_ascii_1D(self, path):
861        from data_loader import load_ascii_1D
862        return load_ascii_1D(path)
[41d466f]863                 
864class DefaultPanel(wx.Panel):
865    """
866        Defines the API for a panels to work with
867        the GUI manager
868    """
869    ## Internal nickname for the window, used by the AUI manager
870    window_name = "default"
871    ## Name to appear on the window title bar
872    window_caption = "Welcome panel"
873    ## Flag to tell the AUI manager to put this panel in the center pane
874    CENTER_PANE = True
875
876 
877# Toy application to test this Frame
878class ViewApp(wx.App):
879    def OnInit(self):
880        #from gui_manager import ViewerFrame
881        self.frame = ViewerFrame(None, -1, config.__appname__)   
882        self.frame.Show(True)
883
884        if hasattr(self.frame, 'special'):
885            self.frame.special.SetCurrent()
886        self.SetTopWindow(self.frame)
887        return True
888   
889    def set_manager(self, manager):
890        """
891            Sets a reference to the application manager
892            of the GUI manager (Frame)
893        """
894        self.frame.set_manager(manager)
895       
[278cc25]896    def build_gui(self):
897        """
898            Build the GUI
899        """
900        self.frame.build_gui()
901        self.frame.post_init()
902       
[f9e803e]903    def set_welcome_panel(self, panel_class):
904        """
905            Set the welcome panel
906            @param panel_class: class of the welcome panel to be instantiated
907        """
908        self.frame.set_welcome_panel(panel_class)
909       
[278cc25]910    def add_perspective(self, perspective):
911        """
912            Manually add a perspective to the application GUI
913        """
914        self.frame.add_perspective(perspective)
915       
[41d466f]916
917if __name__ == "__main__": 
918    app = ViewApp(0)
919    app.MainLoop()             
Note: See TracBrowser for help on using the repository browser.