source: sasview/guiframe/gui_manager.py @ f0ff8d65

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

guiframe: reduce best size for plot windows

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