source: sasview/guiframe/gui_manager.py @ 91128648

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

guiframe: repair a breaking change with bad assumptions about Data1D. Allow to specify a file when using the choose_file method in order to re-use the code elsewhere.

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