source: sasview/guiframe/gui_manager.py @ 7f84e22

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 7f84e22 was b5ca223, checked in by Gervaise Alina <gervyh@…>, 14 years ago

make all plugins inheriting from pluginbase in plugin-base.py

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