casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables
customgui_tkagg.py
Go to the documentation of this file.
00001 import os
00002 import matplotlib, numpy
00003 from asap.logging import asaplog, asaplog_post_dec
00004 from matplotlib.patches import Rectangle
00005 from asap.parameters import rcParams
00006 from asap._asap import stmath
00007 from asap.customgui_base import *
00008 
00009 import Tkinter as Tk
00010 import tkMessageBox
00011 
00012 ######################################
00013 ##    Add CASA custom toolbar       ##
00014 ######################################
00015 class CustomToolbarTkAgg(CustomToolbarCommon, Tk.Frame):
00016     def __init__(self,parent):
00017         from asap.asapplotter import asapplotter
00018         if not isinstance(parent,asapplotter):
00019             return False
00020         if not parent._plotter:
00021             return False
00022         self._p = parent._plotter
00023         self.figmgr = self._p.figmgr
00024         self.canvas = self.figmgr.canvas
00025         self.mode = ''
00026         self.button = True
00027         self.pagecount = None
00028         CustomToolbarCommon.__init__(self,parent)
00029         self.notewin = NotationWindowTkAgg(master=self.canvas)
00030         self._add_custom_toolbar()
00031 
00032     def _add_custom_toolbar(self):
00033         Tk.Frame.__init__(self,master=self.figmgr.window)
00034         #self.bSpec = self._NewButton(master=self,
00035         #                             text='spec value',
00036         #                             command=self.spec_show)
00037         self.bNote = self._NewButton(master=self,
00038                                      text='notation',
00039                                      command=self.modify_note)
00040 
00041         self.bStat = self._NewButton(master=self,
00042                                      text='statistics',
00043                                      command=self.stat_cal)
00044         self.bQuit = self._NewButton(master=self,
00045                                      text='Quit',
00046                                      command=self.quit,
00047                                      side=Tk.RIGHT)
00048 
00049         # page change oparations
00050         frPage = Tk.Frame(master=self,borderwidth=2,relief=Tk.GROOVE)
00051         frPage.pack(ipadx=2,padx=10,side=Tk.RIGHT)
00052         self.lPagetitle = Tk.Label(master=frPage,text='Page:',padx=5)
00053         self.lPagetitle.pack(side=Tk.LEFT)
00054         self.pagecount = Tk.StringVar(master=frPage)
00055         self.lPagecount = Tk.Label(master=frPage,
00056                                    textvariable=self.pagecount,
00057                                    padx=5,bg='white')
00058         self.lPagecount.pack(side=Tk.LEFT,padx=3)
00059         
00060         self.bNext = self._NewButton(master=frPage,
00061                                      text=' + ',
00062                                      command=self.next_page)
00063         self.bPrev = self._NewButton(master=frPage,
00064                                      text=' - ',
00065                                      command=self.prev_page)
00066 
00067         if os.uname()[0] != 'Darwin':
00068             self.bPrev.config(padx=5)
00069             self.bNext.config(padx=5)
00070 
00071         self.pack(side=Tk.BOTTOM,fill=Tk.BOTH)
00072         self.pagecount.set(' '*4)
00073 
00074         self.disable_button()
00075         return #self
00076 
00077     def _NewButton(self, master, text, command, side=Tk.LEFT):
00078         if os.uname()[0] == 'Darwin':
00079             b = Tk.Button(master=master, text=text, command=command)
00080         else:
00081             b = Tk.Button(master=master, text=text, padx=2, pady=2,
00082                           command=command)
00083         b.pack(side=side)
00084         return b
00085 
00086     def show_pagenum(self,pagenum,formatstr):
00087         self.pagecount.set(formatstr % (pagenum))
00088 
00089     def spec_show(self):
00090         if not self.figmgr.toolbar.mode == '' or not self.button: return
00091         self.figmgr.toolbar.set_message('spec value: drag on a spec')
00092         if self.mode == 'spec': return
00093         #self.bStat.config(relief='raised')
00094         #self.bSpec.config(relief='sunken')
00095         #self.bNote.config(relief='raised')
00096         self.mode = 'spec'
00097         self.notewin.close_widgets()
00098         self.__disconnect_event()
00099         self._p.register('button_press',self._select_spectrum)
00100 
00101     def stat_cal(self):
00102         if not self.figmgr.toolbar.mode == '' or not self.button: return
00103         self.figmgr.toolbar.set_message('statistics: select a region')
00104         if self.mode == 'stat':
00105             # go back to spec mode
00106             self.bStat.config(relief='raised')
00107             self.spec_show()
00108             return
00109         #self.bSpec.config(relief='raised')
00110         self.bStat.config(relief='sunken')
00111         self.bNote.config(relief='raised')
00112         self.mode = 'stat'
00113         self.notewin.close_widgets()
00114         self.__disconnect_event()
00115         self._p.register('button_press',self._single_mask)
00116 
00117     def modify_note(self):
00118         if not self.figmgr.toolbar.mode == '': return
00119         if self.mode == 'note':
00120             self.bNote.config(relief='raised')
00121             self.mode = 'none'
00122             self.spec_show()
00123             if not self.button:
00124                 self.notewin.close_widgets()
00125                 self.__disconnect_event()
00126             return
00127         self.figmgr.toolbar.set_message('text: select a position/text')
00128         #self.bSpec.config(relief='raised')
00129         self.bStat.config(relief='raised')
00130         self.bNote.config(relief='sunken')
00131         self.mode = 'note'
00132         self.__disconnect_event()
00133         self._p.register('button_press',self._mod_note)
00134 
00135     def quit(self):
00136         self.__disconnect_event()
00137         #self.delete_bar()
00138         self.disable_button()
00139         self.figmgr.window.wm_withdraw()
00140         self._p.quit()
00141 
00142     def enable_button(self):
00143         if self.button: return
00144         #self.bSpec.config(state=Tk.NORMAL)
00145         self.bStat.config(state=Tk.NORMAL)
00146         self.button = True
00147         self.spec_show()
00148 
00149     def disable_button(self):
00150         if not self.button: return
00151         #self.bSpec.config(relief='raised', state=Tk.DISABLED)
00152         self.bStat.config(relief='raised', state=Tk.DISABLED)
00153         self.bNext.config(state=Tk.DISABLED)
00154         self.bPrev.config(state=Tk.DISABLED)
00155         self.button = False
00156         self.mode = ''
00157         self.__disconnect_event()
00158 
00159     def enable_next(self):
00160         self.bNext.config(state=Tk.NORMAL)
00161 
00162     def disable_next(self):
00163         self.bNext.config(state=Tk.DISABLED)
00164 
00165     def enable_prev(self):
00166         self.bPrev.config(state=Tk.NORMAL)
00167 
00168     def disable_prev(self):
00169         self.bPrev.config(state=Tk.DISABLED)
00170 
00171     # pause buttons for slow operations
00172     def _pause_buttons(self,operation="end",msg=""):
00173         buttons = ["bStat","bNote","bQuit"]
00174         if operation == "start":
00175             state = Tk.DISABLED
00176         else:
00177             state = Tk.NORMAL
00178         for btn in buttons:
00179             getattr(self,btn).config(state=state)
00180         self.figmgr.toolbar.set_message(msg)
00181 
00182     def delete_bar(self):
00183         self.__disconnect_event()
00184         self.destroy()
00185 
00186     def __disconnect_event(self):
00187         self._p.register('button_press',None)
00188         self._p.register('button_release',None)
00189 
00190     def _draw_span(self,axes,x0,x1,**kwargs):
00191         height = self._p.figure.bbox.height
00192         y0 = height - axes.bbox.y0
00193         y1 = height - axes.bbox.y1
00194         return self._p.canvas._tkcanvas.create_rectangle(x0,y0,x1,y1,**kwargs)
00195 
00196     def _remove_span(self,span):
00197         self._p.canvas._tkcanvas.delete(span)
00198 
00199 
00200 
00201 ######################################
00202 ##    Notation box window           ##
00203 ######################################
00204 class NotationWindowTkAgg(NotationWindowCommon):
00205     """
00206     Backend based class to create widgets to add, modify, or delete
00207     note on the plot.
00208 
00209     Note:
00210     Press LEFT-mouse button on the plot to ADD a note on the canvas.
00211     A notation window will be loaded for specifying note string and
00212     anchor. The note will be anchored on a position in whether figure-
00213     (0-1 relative in a figure), panel- (0-1 relative in a plot axes),
00214     or data-coordinate (data value in a plot axes).
00215     Press RIGHT-mouse button on a note to MODIFY/DELETE it. A cascade
00216     menu will be displayed and you can select an operation.
00217     """
00218     def __init__(self,master=None):
00219         self.parent = master._tkcanvas
00220         NotationWindowCommon.__init__(self,master=master)
00221         self.anchval = None
00222         self.textwin = self._create_textwindow(master=None)
00223         self.menu = self._create_modmenu(master=self.parent)
00224 
00225     ### Notation window widget
00226     def _create_textwindow(self,master=None):
00227         """Create notation window widget and iconfy it"""
00228         twin = Tk.Toplevel(padx=3,pady=3)
00229         twin.title("Notation")
00230         twin.resizable(width=True,height=True)
00231         self.textbox = self._NotationBox(parent=twin)
00232         self.radio = self._AnchorRadio(parent=twin)
00233         self.actionbs = self._ActionButtons(parent=twin)
00234         
00235         self.textbox.pack(side=Tk.TOP,fill=Tk.BOTH,expand=True)
00236         self.actionbs.pack(side=Tk.BOTTOM)
00237         self.radio.pack(side=Tk.BOTTOM)
00238         #twin.deiconify()
00239         #twin.minsize(width=twin.winfo_width(),height=twin.winfo_height())
00240         #twin.lift()
00241         twin.withdraw()
00242         return twin
00243 
00244     def _NotationBox(self,parent=None):
00245         textbox = Tk.Text(master=parent,background='white',
00246                           height=2,width=20,cursor="xterm",
00247                           padx=2,pady=2,undo=True,maxundo=10,
00248                           relief='sunken',borderwidth=3,
00249                           state=Tk.NORMAL,takefocus=1)
00250         return textbox
00251 
00252     def _AnchorRadio(self,parent=None):
00253         radio = Tk.LabelFrame(master=parent,text="anchor",
00254                             labelanchor="nw",padx=5,pady=3)
00255         self.anchval = Tk.IntVar(master=radio,value=0)
00256         self.rFig = self._NewRadioButton(radio,"figure",state=Tk.NORMAL,
00257                                          variable=self.anchval,value=0,
00258                                          side=Tk.LEFT)
00259         self.rAxis = self._NewRadioButton(radio,"panel",state=Tk.DISABLED,
00260                                           variable=self.anchval,value=1,
00261                                           side=Tk.LEFT)
00262         self.rData = self._NewRadioButton(radio,"data",state=Tk.DISABLED,
00263                                           variable=self.anchval,value=2,
00264                                           side=Tk.LEFT)
00265         # set initial selection "figure"
00266         self.anchval.set(0)
00267         return radio
00268 
00269     def _NewRadioButton(self,parent,text,state=Tk.NORMAL,variable=None,value=None,side=Tk.LEFT):
00270         rb = Tk.Radiobutton(master=parent,text=text,state=state,
00271                           variable=variable,value=value)
00272         rb.pack(side=side)
00273         return rb
00274 
00275     def _enable_radio(self):
00276         """Enable 'panel' and 'data' radio button"""
00277         self.rAxis.config(state=Tk.NORMAL)
00278         self.rData.config(state=Tk.NORMAL)
00279         #self.rFig.config(state=Tk.NORMAL)
00280         self.rFig.select()
00281 
00282     def _reset_radio(self):
00283         """Disable 'panel' and 'data' radio button"""
00284         self.rAxis.config(state=Tk.DISABLED)
00285         self.rData.config(state=Tk.DISABLED)
00286         self.rFig.config(state=Tk.NORMAL)
00287         self.rFig.select()
00288 
00289     def _select_radio(self,selection):
00290         """Select a specified radio button"""
00291         if not selection in self.anchors:
00292             return
00293         if selection == "data":
00294             self.rData.select()
00295         elif selection == "axes":
00296             self.rAxis.select()
00297         else:
00298             self.rFig.select()
00299 
00300     def _get_anchval(self):
00301         """Returns a integer of a selected radio button"""
00302         return self.anchval.get()
00303 
00304     def _get_note(self):
00305         """Returns a note string specified in the text box"""
00306         # A WORKAROUND for OSX 10.7 (Tk.Text returns unicode but asaplog doesn't accept it)
00307         #return self.textbox.get("1.0",Tk.END)
00308         return str(self.textbox.get("1.0",Tk.END))
00309 
00310     def _clear_textbox(self):
00311         """Clear the text box"""
00312         self.textbox.delete("1.0",Tk.END)
00313 
00314     def _set_note(self,note=None):
00315         """Set a note string to the text box"""
00316         self._clear_textbox()
00317         if len(note) >0:
00318             self.textbox.insert("1.0",note)
00319 
00320     def _ActionButtons(self,parent=None):
00321         actbuts = Tk.Frame(master=parent)
00322         bCancel = self._NewButton(actbuts,"cancel",self._cancel_text,side=Tk.LEFT)
00323         bPrint = self._NewButton(actbuts,"print", self._print_text,side=Tk.LEFT)
00324         return actbuts
00325 
00326     def _NewButton(self, parent, text, command, side=Tk.LEFT):
00327         if(os.uname()[0] == 'Darwin'):
00328             b = Tk.Button(master=parent, text=text, command=command)
00329         else:
00330             b = Tk.Button(master=parent, text=text, padx=2, pady=2, command=command)
00331         b.pack(side=side)
00332         return b
00333 
00334     def _cancel_text(self):
00335         """
00336         Cancel adding/modifying a note and close notaion window.
00337         called when 'cancel' is selected.
00338         """
00339         self.close_textwindow()
00340 
00341     def _print_text(self):
00342         """
00343         Add/Modify a note. Called when 'print' is selected on the
00344         notation window.
00345         """
00346         self.print_text()
00347         self.close_textwindow()
00348 
00349     def load_textwindow(self,event):
00350         """
00351         Load text window at a event position to add a note on a plot.
00352         Parameter:
00353             event:   an even object to specify the position to load
00354                      text window. 
00355         """
00356         self.close_modmenu()
00357         if event.canvas._tkcanvas != self.parent:
00358             raise RuntimeError, "Got invalid event!"
00359         
00360         self.event = event
00361         is_ax = (event.inaxes != None)
00362         (xpix, ypix) = self._disppix2screen(event.x, event.y)
00363         offset = 5
00364         self.show_textwindow(xpix+offset,ypix+offset,enableaxes=is_ax)
00365         
00366     def show_textwindow(self,xpix,ypix,basetext=None,enableaxes=False):
00367         """
00368         Load text window at a position of screen to add a note on a plot.
00369         Parameters:
00370             xpix, ypix:   a pixel position from Upper-left corner
00371                           of the screen.
00372             basetext:     None (default) or any string.
00373                           A string to be printed on text box when loaded. 
00374             enable axes:  False (default) or True.
00375                           If True, 'panel' & 'data' radio button is enabled. 
00376         """
00377         if not self.textwin: return
00378         self._reset_radio()
00379         if enableaxes: 
00380             self._enable_radio()
00381         self.textwin.deiconify()
00382         (w,h) = self.textwin.minsize()
00383         # WORKAROUND for too small default minsize on OSX 10.7
00384         #if w*h <= 1:
00385         if w*h <= 1500:
00386             self.textwin.minsize(width=self.textwin.winfo_width(),
00387                                  height=self.textwin.winfo_height())
00388             (w,h) = self.textwin.minsize()
00389         self.textwin.geometry("%sx%s+%s+%s"%(w,h,xpix,ypix))
00390         self.textwin.lift()
00391 
00392     def close_textwindow(self):
00393         """Close text window."""
00394         self.seltext = {}
00395         self._reset_radio()
00396         self._clear_textbox()
00397         self.textwin.withdraw()
00398 
00399 
00400     ### Modify/Delete menu widget
00401     def _create_modmenu(self,master=None):
00402         """Create modify/delete menu widget"""
00403         if master:
00404             self.parent = master
00405         if not self.parent:
00406             return False
00407         menu = Tk.Menu(master=self.parent,tearoff=False)
00408         menu.add_command(label="Modify",command=self._modify_note)
00409         menu.add_command(label="Delete",command=self._delnote_dialog)
00410         return menu
00411 
00412     def load_modmenu(self,event):
00413         """
00414         Load cascade menu at a event position to modify or delete
00415         selected text.
00416         Parameter:
00417             event:  an even object to specify the position to load
00418                     text window. 
00419         """
00420         self.close_textwindow()
00421         self.seltext = self._get_selected_text(event)
00422         if len(self.seltext) == 3:
00423             tkcanvas = event.canvas._tkcanvas
00424             xpos = tkcanvas.winfo_rootx() + int(event.x)
00425             ypos = tkcanvas.winfo_rooty() \
00426                    + tkcanvas.winfo_height() - int(event.y)
00427             self.menu.post(xpos,ypos)
00428 
00429     def close_modmenu(self):
00430         """Close cascade menu."""
00431         self.seltext = {}
00432         self.menu.unpost()
00433 
00434     ### load text window for modification 
00435     def _modify_note(self):
00436         """helper function to load text window to modify selected note"""
00437         #print "Modify selected!!"
00438         textobj = self.seltext['textobj']
00439         (xtx, ytx) = textobj._get_xy_display()
00440         is_ax = (self.seltext['anchor'] != 'figure')
00441         if not is_ax:
00442             # previous anchor is figure
00443             pos = textobj.get_position()
00444             is_ax = (self._get_axes_from_pos(pos,self.canvas) != None)
00445 
00446         (xpix, ypix) = self._disppix2screen(xtx,ytx)
00447         offset = int(textobj.get_size())*2
00448         self.show_textwindow(xpix,ypix+offset,basetext=textobj.get_text(),\
00449                              enableaxes=is_ax)
00450         self._select_radio(self.seltext['anchor'])
00451         self._set_note(textobj.get_text())
00452 
00453     ### close all widgets
00454     def close_widgets(self):
00455         """Close note window and menu"""
00456         self.close_textwindow()
00457         self.close_modmenu()
00458 
00459     ### dialog to confirm deleting note 
00460     def _delnote_dialog(self):
00461         """Load dialog to confirm deletion of the text"""
00462         remind = "Delete text?\n '"+self.seltext['textobj'].get_text()+"'"
00463         answer = tkMessageBox.askokcancel(parent=self.parent,title="Delete?",
00464                                           message=remind,
00465                                           default=tkMessageBox.CANCEL)
00466         if answer:
00467             self.delete_note()
00468         else:
00469             self.cancel_delete()
00470 
00471     ### helper functions
00472     def _disppix2screen(self,xpixd,ypixd):
00473         """
00474         helper function to calculate a pixel position form Upper-left
00475         corner of the SCREEN from a pixel position (xpixd, ypixd)
00476         from Lower-left of the CANVAS (which, e.g., event.x/y returns)
00477 
00478         Returns:
00479             (x, y):  pixel position from Upper-left corner of the SCREEN.
00480         """
00481         xpixs = self.parent.winfo_rootx() + xpixd
00482         ypixs = self.parent.winfo_rooty() + self.parent.winfo_height() \
00483                - ypixd
00484         return (int(xpixs), int(ypixs))
00485         
00486 
00487 
00488 
00489 
00490 
00491 ###########################################
00492 ##    Add CASA custom Flag toolbar       ##
00493 ###########################################
00494 class CustomFlagToolbarTkAgg(CustomFlagToolbarCommon, Tk.Frame):
00495     def __init__(self,parent):
00496         from asap.asapplotter import asapplotter
00497         if not isinstance(parent,asapplotter):
00498             return False
00499         if not parent._plotter:
00500             return False
00501         self._p = parent._plotter
00502         self.figmgr = self._p.figmgr
00503         self.canvas = self.figmgr.canvas
00504         self.mode = ''
00505         self.button = True
00506         self.pagecount = None
00507         CustomFlagToolbarCommon.__init__(self,parent)
00508         self.notewin=NotationWindowTkAgg(master=self.canvas)
00509         self._add_custom_toolbar()
00510 
00511     def _add_custom_toolbar(self):
00512         Tk.Frame.__init__(self,master=self.figmgr.window)
00513         #self.bSpec = self._NewButton(master=self,
00514         #                             text='spec value',
00515         #                             command=self.spec_show)
00516 
00517         self.bRegion = self._NewButton(master=self,
00518                                        text='region',
00519                                        command=self.select_region)
00520         self.bPanel = self._NewButton(master=self,
00521                                       text='panel',
00522                                       command=self.select_panel)
00523         self.bClear = self._NewButton(master=self,
00524                                       text='clear',
00525                                       command=self.cancel_select)
00526         self.bFlag = self._NewButton(master=self,
00527                                      text='flag',
00528                                      command=self.flag)
00529         self.bUnflag = self._NewButton(master=self,
00530                                        text='unflag',
00531                                        command=self.unflag)
00532         
00533         self.bStat = self._NewButton(master=self,
00534                                      text='statistics',
00535                                      command=self.stat_cal)
00536 
00537         self.bNote = self._NewButton(master=self,
00538                                      text='notation',
00539                                      command=self.modify_note)
00540 
00541         self.bQuit = self._NewButton(master=self,
00542                                      text='Quit',
00543                                      #file="stock_close.ppm",
00544                                      command=self.quit,
00545                                      side=Tk.RIGHT)
00546 
00547         # page change oparations
00548         frPage = Tk.Frame(master=self,borderwidth=2,relief=Tk.GROOVE)
00549         frPage.pack(ipadx=2,padx=10,side=Tk.RIGHT)
00550         self.lPagetitle = Tk.Label(master=frPage,text='Page:',padx=5)
00551                                    #width=8,anchor=Tk.E,padx=5)
00552         self.lPagetitle.pack(side=Tk.LEFT)
00553         self.pagecount = Tk.StringVar(master=frPage)
00554         self.lPagecount = Tk.Label(master=frPage,
00555                                    textvariable=self.pagecount,
00556                                    padx=5,bg='white')
00557         self.lPagecount.pack(side=Tk.LEFT,padx=3)
00558 
00559         self.bNext=self._NewButton(master=frPage,
00560                                    text=' + ',
00561                                    #file="hand.ppm",
00562                                    command=self.next_page)
00563         self.bPrev=self._NewButton(master=frPage,
00564                                    text=' - ',
00565                                    command=self.prev_page)
00566 
00567         if os.uname()[0] != 'Darwin':
00568             self.bPrev.config(padx=5)
00569             self.bNext.config(padx=5)
00570 
00571         self.pack(side=Tk.BOTTOM,fill=Tk.BOTH)
00572         self.pagecount.set(' '*4)
00573 
00574         self.disable_button()
00575         return #self
00576 
00577     def _NewButton(self, master, text, command, side=Tk.LEFT,file=None):
00578         img = None
00579         if file:
00580             file = os.path.join(matplotlib.rcParams['datapath'], 'images', file)
00581             img = Tk.PhotoImage(master=master, file=file)
00582 
00583         if os.uname()[0] == 'Darwin':
00584             b = Tk.Button(master=master, text=text, image=img,
00585                           command=command)
00586             if img: b.image = img
00587         else:
00588             b = Tk.Button(master=master, text=text, image=img, padx=2, pady=2,
00589                           command=command)
00590             if img: b.image = img
00591         b.pack(side=side)
00592         return b
00593 
00594     def show_pagenum(self,pagenum,formatstr):
00595         self.pagecount.set(formatstr % (pagenum))
00596 
00597     def spec_show(self):
00598         if not self.figmgr.toolbar.mode == '' or not self.button: return
00599         self.figmgr.toolbar.set_message('spec value: drag on a spec')
00600         if self.mode == 'spec': return
00601         self.mode = 'spec'
00602         self.notewin.close_widgets()
00603         self.__disconnect_event()
00604         self._p.register('button_press',self._select_spectrum)
00605 
00606     def modify_note(self):
00607         if not self.figmgr.toolbar.mode == '': return
00608         if self.mode == 'note':
00609             self.bNote.config(relief='raised')
00610             self.mode = 'none'
00611             self.spec_show()
00612             if not self.button:
00613                 self.notewin.close_widgets()
00614                 self.__disconnect_event()
00615             return
00616         self.figmgr.toolbar.set_message('text: select a position/text')
00617         self.bNote.config(relief='sunken')
00618         self.bRegion.config(relief='raised')
00619         self.bPanel.config(relief='raised')
00620         self.mode = 'note'
00621         self.__disconnect_event()
00622         self._p.register('button_press',self._mod_note)
00623 
00624     def select_region(self):
00625         if not self.figmgr.toolbar.mode == '' or not self.button: return
00626         if self.mode == 'region':
00627             self.bRegion.config(relief='raised')
00628             self.mode = 'none'
00629             self.spec_show()
00630             return
00631         self.figmgr.toolbar.set_message('select regions: click at start and end channels')
00632         self.bNote.config(relief='raised')
00633         self.bRegion.config(relief='sunken')
00634         self.bPanel.config(relief='raised')
00635         self.mode = 'region'
00636         self.notewin.close_widgets()
00637         self.__disconnect_event()
00638         self._p.register('button_press',self._add_region)
00639 
00640     def select_panel(self):
00641         if not self.figmgr.toolbar.mode == '' or not self.button: return
00642         if self.mode == 'panel':
00643             self.bPanel.config(relief='raised')
00644             self.mode = 'none'
00645             self.spec_show()
00646             return
00647         self.figmgr.toolbar.set_message('select spectra: click on subplots')
00648         self.bNote.config(relief='raised')
00649         self.bRegion.config(relief='raised')
00650         self.bPanel.config(relief='sunken')
00651         self.mode = 'panel'
00652         self.notewin.close_widgets()
00653         self.__disconnect_event()
00654         self._p.register('button_press',self._add_panel)
00655 
00656     def quit(self):
00657         self.__disconnect_event()
00658         self.disable_button()
00659         self.figmgr.window.wm_withdraw()
00660         self._p.quit()
00661 
00662     def enable_button(self):
00663         if self.button: return
00664         self.bRegion.config(state=Tk.NORMAL)
00665         self.bPanel.config(state=Tk.NORMAL)
00666         self.bClear.config(state=Tk.NORMAL)
00667         self.bFlag.config(state=Tk.NORMAL)
00668         self.bUnflag.config(state=Tk.NORMAL)
00669         self.bStat.config(state=Tk.NORMAL)
00670         self.button = True
00671         self.spec_show()
00672 
00673     def disable_button(self):
00674         ## disable buttons which don't work for plottp
00675         if not self.button: return
00676         self.bRegion.config(relief='raised')
00677         self.bPanel.config(relief='raised')
00678         self.bRegion.config(state=Tk.DISABLED)
00679         self.bPanel.config(state=Tk.DISABLED)
00680         self.bClear.config(state=Tk.DISABLED)
00681         self.bFlag.config(state=Tk.DISABLED)
00682         self.bUnflag.config(state=Tk.DISABLED)
00683         self.bStat.config(state=Tk.DISABLED)
00684         self.bNext.config(state=Tk.DISABLED)
00685         self.bPrev.config(state=Tk.DISABLED)
00686         self.button = False
00687         self.mode = ''
00688         self.notewin.close_widgets()
00689         self.__disconnect_event()
00690 
00691     def enable_next(self):
00692         self.bNext.config(state=Tk.NORMAL)
00693 
00694     def disable_next(self):
00695         self.bNext.config(state=Tk.DISABLED)
00696 
00697     def enable_prev(self):
00698         self.bPrev.config(state=Tk.NORMAL)
00699 
00700     def disable_prev(self):
00701         self.bPrev.config(state=Tk.DISABLED)
00702 
00703     # pause buttons for slow operations
00704     def _pause_buttons(self,operation="end",msg=""):
00705         buttons = ["bRegion","bPanel","bClear","bFlag","bUnflag","bStat",
00706                    "bNote","bQuit"]
00707         if operation == "start":
00708             state=Tk.DISABLED
00709         else:
00710             state=Tk.NORMAL
00711         for btn in buttons:
00712             getattr(self,btn).config(state=state)
00713         self.figmgr.toolbar.set_message(msg)
00714 
00715     def delete_bar(self):
00716         self.__disconnect_event()
00717         self.destroy()
00718 
00719     def __disconnect_event(self):
00720         self._p.register('button_press',None)
00721         self._p.register('button_release',None)
00722 
00723     def _draw_span(self,axes,x0,x1,**kwargs):
00724         height = self._p.figure.bbox.height
00725         y0 = height - axes.bbox.y0
00726         y1 = height - axes.bbox.y1
00727         return self._p.canvas._tkcanvas.create_rectangle(x0,y0,x1,y1,**kwargs)
00728 
00729     def _remove_span(self,span):
00730         self._p.canvas._tkcanvas.delete(span)