source: sasview/guiframe/gui_manager.py @ 784e2fa

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 784e2fa was 1f811dd, checked in by Gervaise Alina <gervyh@…>, 15 years ago

remove unused print statement

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