casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables
customgui_qt4agg.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 PyQt4 as qt
00010 
00011 ######################################
00012 ##    Add CASA custom toolbar       ##
00013 ######################################
00014 class CustomToolbarQT4Agg(CustomToolbarCommon,  qt.QtGui.QToolBar):
00015     def __init__(self,parent):
00016         from asap.asapplotter import asapplotter
00017         if not isinstance(parent,asapplotter):
00018             return False
00019         if not parent._plotter:
00020             return False
00021         self._p = parent._plotter
00022         self.figmgr = self._p.figmgr
00023         self.canvas = self.figmgr.canvas
00024         self.mode = ''
00025         self.button = True
00026         self.pagecount = None
00027         CustomToolbarCommon.__init__(self,parent)
00028         self.notewin = NotationWindowQT4Agg(master=self.canvas)
00029         self._add_custom_toolbar()
00030 
00031     def _add_custom_toolbar(self):
00032         qt.QtGui.QToolBar.__init__(self,parent=self.figmgr.window)
00033         self.figmgr.window.addToolBar(qt.QtCore.Qt.BottomToolBarArea,self)
00034         self.bNote = self._NewButton(master=self,
00035                                      text='notation',
00036                                      command=self.modify_note,
00037                                      balloon="add note on plot")
00038         self.bNote.setCheckable(True)
00039 
00040         self.bStat = self._NewButton(master=self,
00041                                      text='statistics',
00042                                      command=self.stat_cal,
00043                                      balloon="calculate statistics")
00044         self.bStat.setCheckable(True)
00045 
00046         # page change oparations
00047         frPage = qt.QtGui.QWidget(parent=self,flags=qt.QtCore.Qt.Tool)
00048         loPage = qt.QtGui.QHBoxLayout(self)
00049         loPage.addStretch(1)
00050         self.lPagetitle = qt.QtGui.QLabel('Page:',parent=frPage)
00051         self.lPagetitle.setMargin(5)
00052         loPage.addWidget(self.lPagetitle)
00053         self.pagecount = qt.QtGui.QLabel(parent=frPage)
00054         self.pagecount.setStyleSheet("background-color: white")
00055         self.pagecount.setMargin(3)
00056         self.pagecount.setText('   1')
00057         loPage.addWidget(self.pagecount)
00058         
00059         self.bNext = self._NewButton(master=frPage,
00060                                      text=' + ',
00061                                      command=self.next_page,
00062                                      addit=False,
00063                                      balloon="plot next page")
00064         loPage.addWidget(self.bNext)
00065         self.bPrev = self._NewButton(master=frPage,
00066                                      text=' - ',
00067                                      command=self.prev_page,addit=False,
00068                                      balloon="plot previous page")
00069         loPage.addWidget(self.bPrev)
00070         frPage.setLayout(loPage)
00071         self.addWidget(frPage)
00072 
00073         self.bQuit = self._NewButton(master=self,
00074                                      text='Quit',
00075                                      command=self.quit,
00076                                      balloon="Close window")
00077 
00078         self.pagecount.setText(' '*4)
00079 
00080         self.disable_button()
00081         return
00082 
00083     def _NewButton(self, master, text, command, balloon=None,addit=True):
00084         b = qt.QtGui.QPushButton(text,parent=master)
00085         if balloon: b.setToolTip(balloon)
00086         if addit: master.addWidget(b)
00087         master.connect(b,qt.QtCore.SIGNAL('clicked()'),command)
00088         return b
00089 
00090     def show_pagenum(self,pagenum,formatstr):
00091         self.pagecount.setText(formatstr % (pagenum))
00092 
00093     def spec_show(self):
00094         if not self.figmgr.toolbar.mode == '' or not self.button: return
00095         self.figmgr.toolbar.set_message("spec value: drag on a spec")
00096         if self.mode == 'spec': return
00097         self.mode = 'spec'
00098         self.notewin.close_widgets()
00099         self.__disconnect_event()
00100         self._p.register('button_press',self._select_spectrum)
00101 
00102     def stat_cal(self):
00103         if not self.figmgr.toolbar.mode == '' or not self.button:
00104             # Get back button status BEFORE clicked
00105             self.bStat.setChecked(not self.bStat.isChecked())
00106             return
00107         if self.mode == 'stat':
00108             # go back to spec mode
00109             self.bStat.setChecked(False)
00110             self.bStat.setToolTip("calculate statistics")
00111             self.spec_show()
00112             return
00113         self.figmgr.toolbar.set_message("statistics: click at start and end channels")
00114         self.bStat.setChecked(True)
00115         self.bStat.setToolTip("Back to spec value mode")
00116         self.bNote.setChecked(False)
00117         self.bNote.setToolTip("add note on plot")
00118         self.mode = 'stat'
00119         self.notewin.close_widgets()
00120         self.__disconnect_event()
00121         self._p.register('button_press',self._single_mask)
00122 
00123     def modify_note(self):
00124         if not self.figmgr.toolbar.mode == '':
00125             # Get back button status BEFORE clicked
00126             self.bNote.setChecked(not self.bNote.isChecked())
00127             return
00128         if self.mode == 'note':
00129             self.bNote.setChecked(False)
00130             self.bNote.setToolTip("add note on plot")
00131             self.mode = 'none'
00132             self.spec_show()
00133             if not self.button:
00134                 self.notewin.close_widgets()
00135                 self.__disconnect_event()
00136             return
00137         self.figmgr.toolbar.set_message("text: select a position/text")
00138         self.bStat.setChecked(False)
00139         self.bStat.setToolTip("calculate statistics")
00140         self.bNote.setChecked(True)
00141         self.bNote.setToolTip("Back to spec value mode")
00142         self.mode = 'note'
00143         self.__disconnect_event()
00144         self._p.register('button_press',self._mod_note)
00145 
00146     def quit(self):
00147         self.__disconnect_event()
00148         self.disable_button()
00149         self._p.quit()
00150 
00151     def enable_button(self):
00152         if self.button: return
00153         self.bStat.setEnabled(True)
00154         self.button = True
00155         self.spec_show()
00156 
00157     def disable_button(self):
00158         if not self.button: return
00159         self.bStat.setChecked(False)
00160         self.bStat.setDisabled(True)
00161         self.button = False
00162         self.mode = ''
00163         self.__disconnect_event()
00164 
00165     def enable_next(self):
00166         self.bNext.setEnabled(True)
00167 
00168     def disable_next(self):
00169         self.bNext.setDisabled(True)
00170 
00171     def enable_prev(self):
00172         self.bPrev.setEnabled(True)
00173 
00174     def disable_prev(self):
00175         self.bPrev.setDisabled(True)
00176 
00177     # pause buttons for slow operations
00178     def _pause_buttons(self,operation="end",msg=""):
00179         buttons = ["bStat","bNote","bQuit"]
00180         if operation == "start":
00181             enable = False
00182         else:
00183             enable = True
00184         for btn in buttons:
00185             getattr(self,btn).setEnabled(enable)
00186         self.figmgr.toolbar.set_message(msg)
00187 
00188     def delete_bar(self):
00189         self.__disconnect_event()
00190         self.destroy()
00191 
00192     def __disconnect_event(self):
00193         self._p.register('button_press',None)
00194         self._p.register('button_release',None)
00195 
00196     def _draw_span(self,axes,x0,x1,**kwargs):
00197         height = self._p.figure.bbox.height
00198         y1 = height - axes.bbox.y1
00199         h = axes.bbox.height
00200         w = abs(x1 - x0)
00201         rect = [ int(val) for val in min(x0,x1), y1, w, h ]
00202         self._p.canvas.drawRectangle( rect )
00203         # nothing is returned by drawRectangle
00204         return None
00205 
00206     def _remove_span(self,span):
00207         # Nothing to do with remove. just refresh (call only once)
00208         self.canvas.draw()
00209 
00210 
00211 
00212 ######################################
00213 ##    Notation box window           ##
00214 ######################################
00215 class NotationWindowQT4Agg(NotationWindowCommon):
00216     """
00217     Backend based class to create widgets to add, modify, or delete
00218     note on the plot.
00219 
00220     Note:
00221     Press LEFT-mouse button on the plot to ADD a note on the canvas.
00222     A notation window will be loaded for specifying note string and
00223     anchor. The note will be anchored on a position in whether figure-
00224     (0-1 relative in a figure), panel- (0-1 relative in a plot axes),
00225     or data-coordinate (data value in a plot axes).
00226     Press RIGHT-mouse button on a note to MODIFY/DELETE it. A cascade
00227     menu will be displayed and you can select an operation.
00228     """
00229     def __init__(self,master=None):
00230         self.parent = master
00231         NotationWindowCommon.__init__(self,master=master)
00232         self.anchval = None
00233         self.textwin = self._create_textwindow(master=None)
00234         self.menu = self._create_modmenu(master=self.parent)
00235 
00236     ### Notation window widget
00237     def _create_textwindow(self,master=None):
00238         """Create notation window widget and iconfy it"""
00239         #twin = qt.QtGui.QWidget(parent=master, flags=qt.QtCore.Qt.Popup)
00240         twin = qt.QtGui.QWidget(parent=master, flags=qt.QtCore.Qt.Dialog)
00241         twin.setWindowTitle("Notation")
00242         self.textbox = self._NotationBox(parent=twin)
00243         radiobox = self._AnchorRadio(parent=twin)
00244         self.actionbs = self._ActionButtons(parent=twin)
00245         vbox = qt.QtGui.QVBoxLayout(twin)
00246         vbox.addWidget(self.textbox)
00247         vbox.addWidget(radiobox)
00248         vbox.addLayout(self.actionbs)
00249         twin.setLayout(vbox)
00250         #twin.setCentralWidget(self.textbox)
00251         twin.hide()
00252         return twin
00253 
00254     def _NotationBox(self,parent=None):
00255         textbox = qt.QtGui.QPlainTextEdit(parent=parent)
00256         textbox.setStyleSheet("background-color: white")
00257         fmetric = qt.QtGui.QFontMetrics(textbox.currentCharFormat().font())
00258         textbox.resize(fmetric.width("A")*20+fmetric.leading()*2,
00259                        fmetric.height()*2+fmetric.ascent()+fmetric.descent())
00260         del fmetric
00261         textbox.setMinimumSize(textbox.size())
00262         textbox.setUndoRedoEnabled(True)
00263         textbox.setMidLineWidth(3)
00264         textbox.setFrameShadow(qt.QtGui.QFrame.Sunken)
00265         textbox.setCursor(qt.QtCore.Qt.IBeamCursor)
00266         textbox.setFocus()
00267         return textbox
00268 
00269     def _AnchorRadio(self,parent=None):
00270         # Returns a QGoupBox object which includes radio butons to
00271         # select an anchor
00272         anchbox = qt.QtGui.QGroupBox("anchor",parent=parent)
00273         self.radio = qt.QtGui.QButtonGroup(parent=anchbox)
00274         self.rFig = self._NewRadioButton(anchbox,"figure",\
00275                                          bgr=self.radio,value=0,\
00276                                          balloon="a fixed position in figure")
00277         self.rAxis = self._NewRadioButton(anchbox,"panel",\
00278                                           bgr=self.radio,value=1,\
00279                                           balloon="a fixed realtive position in subplot")
00280         self.rData = self._NewRadioButton(anchbox,"data",\
00281                                           bgr=self.radio,value=2,\
00282                                           balloon="a fixed data position in subplot")
00283         hbox = qt.QtGui.QHBoxLayout(anchbox)
00284         hbox.addWidget(self.rFig)
00285         hbox.addWidget(self.rAxis)
00286         hbox.addWidget(self.rData)
00287         anchbox.setLayout(hbox)
00288         # set initial selection "figure"
00289         self.rFig.setChecked(True)
00290         self.radio.setExclusive(True)
00291         self.anchval = self.radio.checkedId()
00292         return anchbox
00293 
00294     def _NewRadioButton(self,parent,text,balloon=None,bgr=None,value=None):
00295         rb= qt.QtGui.QRadioButton(text,parent=parent)
00296         if bgr:
00297             if value is not None:
00298                 bgr.addButton(rb,value)
00299             else:
00300                 bgr.addButton(rb)
00301         if balloon: rb.setToolTip(balloon)
00302         return rb
00303 
00304     def _enable_radio(self):
00305         """Enable 'panel' and 'data' radio button"""
00306         self.rAxis.setEnabled(True)
00307         self.rData.setEnabled(True)
00308         # select Figure as the default value
00309         self.rFig.setChecked(True)
00310         self.anchval = self.radio.checkedId()
00311 
00312     def _reset_radio(self):
00313         """Disable 'panel' and 'data' radio button"""
00314         self.rAxis.setDisabled(True)
00315         self.rData.setDisabled(True)
00316         self.rFig.setEnabled(True)
00317         # select Figure as the default value
00318         self.rFig.setChecked(True)
00319         self.anchval = self.radio.checkedId()
00320 
00321     def _select_radio(self,selection):
00322         """Select a specified radio button"""
00323         if not selection in self.anchors:
00324             return
00325         if selection == "data":
00326             self.rData.setChecked(True)
00327         elif selection == "axes":
00328             self.rAxis.setChecked(True)
00329         else:
00330             self.rFig.setChecked(True)
00331         self.anchval = self.radio.checkedId()
00332 
00333     def _get_anchval(self):
00334         """Returns a integer of a selected radio button"""
00335         self.anchval = self.radio.checkedId()
00336         return self.anchval
00337 
00338     def _get_note(self):
00339         """Returns a note string specified in the text box"""
00340         return str(self.textbox.toPlainText())
00341 
00342     def _clear_textbox(self):
00343         """Clear the text box"""
00344         self.textbox.clear()
00345 
00346     def _set_note(self,note=None):
00347         """Set a note string to the text box"""
00348         self._clear_textbox()
00349         if len(note) >0:
00350             self.textbox.setPlainText(note)
00351 
00352     def _ActionButtons(self,parent=None):
00353         # Returns a layout object which includes "cancel" and "print" buttons
00354         actbuts = qt.QtGui.QHBoxLayout()
00355         bCancel = self._NewButton(parent,"cancel",self._cancel_text,\
00356                                   addit=False,\
00357                                   balloon="cancel printing/modifying")
00358         bPrint = self._NewButton(parent,"print", self._print_text,\
00359                                  addit=False,\
00360                                  balloon="print text on plot")
00361         actbuts.addWidget(bCancel)
00362         actbuts.addWidget(bPrint)
00363         return actbuts
00364 
00365     def _NewButton(self, parent, text, command, balloon=None, addit=True):
00366         b = qt.QtGui.QPushButton(text,parent=parent)
00367         if balloon: b.setToolTip(balloon)
00368         if addit: parent.addWidget(b)
00369         parent.connect(b,qt.QtCore.SIGNAL('clicked()'),command)
00370         return b
00371 
00372     def _cancel_text(self):
00373         """
00374         Cancel adding/modifying a note and close notaion window.
00375         called when 'cancel' is selected.
00376         """
00377         self.close_textwindow()
00378 
00379     def _print_text(self):
00380         """
00381         Add/Modify a note. Called when 'print' is selected on the
00382         notation window.
00383         """
00384         self.print_text()
00385         self.close_textwindow()
00386 
00387     def load_textwindow(self,event):
00388         """
00389         Load text window at a event position to add a note on a plot.
00390         Parameter:
00391             event:   an even object to specify the position to load
00392                      text window. 
00393         """
00394         self.close_modmenu()
00395         if event.canvas != self.parent:
00396             raise RuntimeError, "Got invalid event!"
00397 
00398         self.event = event
00399         is_ax = (event.inaxes != None)
00400         (xpix, ypix) = self._disppix2screen(event.x, event.y)
00401         offset = 5
00402         self.show_textwindow(xpix+offset,ypix+offset,enableaxes=is_ax)
00403 
00404     def show_textwindow(self,xpix,ypix,basetext=None,enableaxes=False):
00405         """
00406         Load text window at a position of screen to add a note on a plot.
00407         Parameters:
00408             xpix, ypix:   a pixel position from Upper-left corner
00409                           of the screen.
00410             basetext:     None (default) or any string.
00411                           A string to be printed on text box when loaded. 
00412             enableaxes:   False (default) or True.
00413                           If True, 'panel' & 'data' radio button is enabled. 
00414         """
00415         if not self.textwin: return
00416         self._reset_radio()
00417         if enableaxes: 
00418             self._enable_radio()
00419         self.textwin.activateWindow()
00420         h = self.textwin.minimumHeight()
00421         w = self.textwin.minimumWidth()
00422         self.textwin.resize(w,h)
00423         self.textwin.move(xpix,ypix)
00424         self.textbox.setFocus()
00425         self.textwin.raise_()
00426         self.textwin.show()
00427         if w*h <= 1: # Initial load
00428             self.textwin.setMinimumSize(self.textwin.size())
00429 
00430     def close_textwindow(self):
00431         """Close text window."""
00432         self.seltext = {}
00433         self._reset_radio()
00434         self._clear_textbox()
00435         self.textwin.hide()
00436 
00437 
00438     ### Modify/Delete menu widget
00439     def _create_modmenu(self,master=None):
00440         """Create modify/delete menu widget"""
00441         if master:
00442             self.parent = master
00443         if not self.parent:
00444             return False
00445         menu = qt.QtGui.QMenu(parent=self.parent)
00446         menu.setTearOffEnabled(False)
00447         menu.addAction("Modify",self._modify_note)
00448         menu.addAction("Delete",self._delnote_dialog)
00449         return menu
00450 
00451     def load_modmenu(self,event):
00452         """
00453         Load cascade menu at a event position to modify or delete
00454         selected text.
00455         Parameter:
00456             event:  an even object to specify the position to load
00457                     text window. 
00458         """
00459         self.close_textwindow()
00460         self.seltext = self._get_selected_text(event)
00461         if len(self.seltext) == 3:
00462             canvas = event.canvas
00463             corig = canvas.mapToGlobal(qt.QtCore.QPoint(0,0))
00464             xpixs = corig.x() + int(event.x)
00465             ypixs = corig.y() + canvas.height() - int(event.y)
00466             self.menu.activateWindow()
00467             self.menu.move(xpixs,ypixs)
00468             self.menu.show()
00469 
00470     def close_modmenu(self):
00471         """Close cascade menu."""
00472         self.seltext = {}
00473         self.menu.hide()
00474 
00475     ### load text window for modification 
00476     def _modify_note(self):
00477         """helper function to load text window to modify selected note"""
00478         textobj = self.seltext['textobj']
00479         (xtx, ytx) = textobj._get_xy_display()
00480         is_ax = (self.seltext['anchor'] != 'figure')
00481         if not is_ax:
00482             # previous anchor is figure
00483             pos = textobj.get_position()
00484             is_ax = (self._get_axes_from_pos(pos,self.canvas) != None)
00485 
00486         (xpix, ypix) = self._disppix2screen(xtx,ytx)
00487         offset = int(textobj.get_size())*2
00488         self.show_textwindow(xpix,ypix+offset,basetext=textobj.get_text(),\
00489                              enableaxes=is_ax)
00490         self._select_radio(self.seltext['anchor'])
00491         self._set_note(textobj.get_text())
00492 
00493     ### close all widgets
00494     def close_widgets(self):
00495         """Close note window and menu"""
00496         self.close_textwindow()
00497         self.close_modmenu()
00498 
00499     ### dialog to confirm deleting note 
00500     def _delnote_dialog(self):
00501         """Load dialog to confirm deletion of the text"""
00502         remind = "Delete text?\n '"+self.seltext['textobj'].get_text()+"'"
00503         from PyQt4.QtGui import QMessageBox as mbox
00504         answer = mbox.question(self.parent,"Delete?",remind,
00505                                buttons = mbox.Ok | mbox.Cancel,
00506                                defaultButton=mbox.Cancel)
00507         if answer == mbox.Ok:
00508             self.delete_note()
00509         else:
00510             self.cancel_delete()
00511 
00512     ### helper functions
00513     def _disppix2screen(self,xpixd,ypixd):
00514         """
00515         helper function to calculate a pixel position form Upper-left
00516         corner of the SCREEN from a pixel position (xpixd, ypixd)
00517         from Lower-left of the CANVAS (which, e.g., event.x/y returns)
00518 
00519         Returns:
00520             (x, y):  pixel position from Upper-left corner of the SCREEN.
00521         """
00522         corig = self.parent.mapToGlobal(qt.QtCore.QPoint(0,0))
00523         xpixs = corig.x() + xpixd
00524         ypixs = corig.y() + self.parent.height() - ypixd
00525         return (int(xpixs), int(ypixs))
00526         
00527 
00528 
00529 
00530 
00531 
00532 ###########################################
00533 ##    Add CASA custom Flag toolbar       ##
00534 ###########################################
00535 class CustomFlagToolbarQT4Agg(CustomFlagToolbarCommon,  qt.QtGui.QToolBar):
00536     def __init__(self,parent):
00537         from asap.asapplotter import asapplotter
00538         if not isinstance(parent,asapplotter):
00539             return False
00540         if not parent._plotter:
00541             return False
00542         self._p = parent._plotter
00543         self.figmgr = self._p.figmgr
00544         self.canvas = self.figmgr.canvas
00545         self.mode = ''
00546         self.button = True
00547         self.pagecount = None
00548         CustomFlagToolbarCommon.__init__(self,parent)
00549         self.notewin=NotationWindowQT4Agg(master=self.canvas)
00550         self._add_custom_toolbar()
00551 
00552     def _add_custom_toolbar(self):
00553         qt.QtGui.QToolBar.__init__(self,parent=self.figmgr.window)
00554         self.figmgr.window.addToolBar(qt.QtCore.Qt.BottomToolBarArea,self)
00555         self.bRegion = self._NewButton(master=self,
00556                                        text='region',
00557                                        command=self.select_region,
00558                                        balloon="select channel regions")
00559         self.bRegion.setCheckable(True)
00560         
00561         self.bPanel = self._NewButton(master=self,
00562                                       text='panel',
00563                                       command=self.select_panel,
00564                                       balloon="select a whole spectrum")
00565         self.bPanel.setCheckable(True)
00566 
00567         self.bClear = self._NewButton(master=self,
00568                                       text='clear',
00569                                       command=self.cancel_select,
00570                                       balloon="clear selections")
00571 
00572         self.bFlag = self._NewButton(master=self,
00573                                      text='flag',
00574                                      command=self.flag,
00575                                      balloon="flag selections")
00576 
00577         self.bUnflag = self._NewButton(master=self,
00578                                        text='unflag',
00579                                        command=self.unflag,
00580                                        balloon="unflag selections")
00581 
00582         self.bStat = self._NewButton(master=self,
00583                                      text='statistics',
00584                                      command=self.stat_cal,
00585                                      balloon="print statistics of selections")
00586 
00587         self.bNote = self._NewButton(master=self,
00588                                      text='notation',
00589                                      command=self.modify_note,
00590                                      balloon="add note on plot")
00591         self.bNote.setCheckable(True)
00592 
00593         # page change oparations
00594         frPage = qt.QtGui.QWidget(parent=self,flags=qt.QtCore.Qt.Tool)
00595         loPage = qt.QtGui.QHBoxLayout(self)
00596         loPage.addStretch(1)
00597         self.lPagetitle = qt.QtGui.QLabel('Page:',parent=frPage)
00598         self.lPagetitle.setMargin(5)
00599         loPage.addWidget(self.lPagetitle)
00600         self.pagecount = qt.QtGui.QLabel(parent=frPage)
00601         self.pagecount.setStyleSheet("background-color: white")
00602         self.pagecount.setMargin(3)
00603         self.pagecount.setText('   1')
00604         loPage.addWidget(self.pagecount)
00605 
00606         self.bNext = self._NewButton(master=frPage,
00607                                      text='+',
00608                                      #imagename="hand.ppm",
00609                                      command=self.next_page,
00610                                      addit=False,
00611                                      balloon="plot next page")
00612         loPage.addWidget(self.bNext)
00613         self.bPrev = self._NewButton(master=frPage,
00614                                      text='-',
00615                                      command=self.prev_page,
00616                                      addit=False,
00617                                      balloon="plot previous page")
00618         loPage.addWidget(self.bPrev)
00619         frPage.setLayout(loPage)
00620         self.addWidget(frPage)
00621 
00622         self.bQuit = self._NewButton(master=self,
00623                                      text='Quit',
00624                                      #imagename="stock_close.ppm",
00625                                      command=self.quit,
00626                                      balloon="Close window")
00627 
00628         self.pagecount.setText(' '*4)
00629         self.disable_button()
00630         return
00631 
00632     def _NewButton(self, master, text, command, balloon=None,addit=True,imagename=None):
00633         img = None
00634         if imagename:
00635             imagename = os.path.join(matplotlib.rcParams['datapath'], 'images', imagename)
00636 #             img = Tk.PhotoImage(master=master, file=imagename)
00637 
00638         b = qt.QtGui.QPushButton(text,parent=master)
00639         if balloon: b.setToolTip(balloon)
00640         if addit: master.addWidget(b)
00641         master.connect(b,qt.QtCore.SIGNAL('clicked()'),command)
00642 #         if img: b.image = img
00643         return b
00644 
00645     def show_pagenum(self,pagenum,formatstr):
00646         self.pagecount.setText(formatstr % (pagenum))
00647 
00648     def spec_show(self):
00649         if not self.figmgr.toolbar.mode == '' or not self.button: return
00650         self.figmgr.toolbar.set_message('spec value: drag on a spec')
00651         if self.mode == 'spec': return
00652         self.mode = 'spec'
00653         self.notewin.close_widgets()
00654         self.__disconnect_event()
00655         self._p.register('button_press',self._select_spectrum)
00656 
00657     def modify_note(self):
00658         if not self.figmgr.toolbar.mode == '':
00659             # Get back button status BEFORE clicked
00660             self.bNote.setChecked(not self.bNote.isChecked())
00661             return
00662         if self.mode == 'note':
00663             self.bNote.setChecked(False)
00664             self.bNote.setToolTip("add note on plot")
00665             self.mode = 'none'
00666             self.spec_show()
00667             if not self.button:
00668                 self.notewin.close_widgets()
00669                 self.__disconnect_event()
00670             return
00671         self.figmgr.toolbar.set_message('text: select a position/text')
00672         self.bNote.setChecked(True)
00673         self.bNote.setToolTip("Back to spec value mode")
00674         self.bRegion.setChecked(False)
00675         self.bRegion.setToolTip("select channel regions")
00676         self.bPanel.setChecked(False)
00677         self.bPanel.setToolTip("select a whole spectrum")
00678         self.mode = 'note'
00679         self.__disconnect_event()
00680         self._p.register('button_press',self._mod_note)
00681 
00682     def select_region(self):
00683         if not self.figmgr.toolbar.mode == '' or not self.button:
00684             # Get back button status BEFORE clicked
00685             self.bRegion.setChecked(not self.bRegion.isChecked())
00686         if self.mode == 'region':
00687             self.bRegion.setChecked(False)
00688             self.bRegion.setToolTip("select channel regions")
00689             self.mode = 'none'
00690             self.spec_show()
00691             return
00692         self.figmgr.toolbar.set_message('select regions: click at start and end channels')
00693         self.bNote.setChecked(False)
00694         self.bNote.setToolTip("add note on plot")
00695         self.bRegion.setChecked(True)
00696         self.bRegion.setToolTip("Back to spec value mode")
00697         self.bPanel.setChecked(False)
00698         self.bPanel.setToolTip("select a whole spectrum")
00699         self.mode = 'region'
00700         self.notewin.close_widgets()
00701         self.__disconnect_event()
00702         self._p.register('button_press',self._add_region)
00703 
00704     def select_panel(self):
00705         if not self.figmgr.toolbar.mode == '' or not self.button:
00706             # Get back button status BEFORE clicked
00707             self.bPanel.setChecked(not self.bPanel.isChecked())
00708             return
00709         if self.mode == 'panel':
00710             self.bPanel.setChecked(False)
00711             self.bPanel.setToolTip("select subplots")
00712             self.mode = 'none'
00713             self.spec_show()
00714             return
00715         self.figmgr.toolbar.set_message('select spectra: click on subplots')
00716         self.bNote.setChecked(False)
00717         self.bNote.setToolTip("add note on plot")
00718         self.bRegion.setChecked(False)
00719         self.bRegion.setToolTip("select channel regions")
00720         self.bPanel.setChecked(True)
00721         self.bPanel.setToolTip("Back to spec value mode")
00722         self.mode = 'panel'
00723         self.notewin.close_widgets()
00724         self.__disconnect_event()
00725         self._p.register('button_press',self._add_panel)
00726 
00727     def quit(self):
00728         self.__disconnect_event()
00729         self.disable_button()
00730         self._p.unmap()
00731 
00732     def enable_button(self):
00733         if self.button: return
00734         self.bRegion.setEnabled(True)
00735         self.bPanel.setEnabled(True)
00736         self.bClear.setEnabled(True)
00737         self.bFlag.setEnabled(True)
00738         self.bUnflag.setEnabled(True)
00739         self.bStat.setEnabled(True)
00740         self.button = True
00741         self.spec_show()
00742 
00743     def disable_button(self):
00744         ## disable buttons which don't work for plottp
00745         if not self.button: return
00746         self.bRegion.setChecked(False)
00747         self.bRegion.setToolTip("select channel regions")
00748         self.bPanel.setChecked(False)
00749         self.bPanel.setToolTip("select subplots")
00750 
00751         self.bRegion.setDisabled(True)
00752         self.bPanel.setDisabled(True)
00753         self.bClear.setDisabled(True)
00754         self.bFlag.setDisabled(True)
00755         self.bUnflag.setDisabled(True)
00756         self.bStat.setDisabled(True)
00757         self.bNext.setDisabled(True)
00758         self.bPrev.setDisabled(True)
00759         self.button = False
00760         self.mode = ''
00761         self.notewin.close_widgets()
00762         self.__disconnect_event()
00763 
00764     def enable_next(self):
00765         self.bNext.setEnabled(True)
00766 
00767     def disable_next(self):
00768         self.bNext.setDisabled(True)
00769 
00770     def enable_prev(self):
00771         self.bPrev.setEnabled(True)
00772 
00773     def disable_prev(self):
00774         self.bPrev.setDisabled(True)
00775 
00776     # pause buttons for slow operations
00777     def _pause_buttons(self,operation="end",msg=""):
00778         buttons = ["bRegion","bPanel","bClear","bFlag","bUnflag","bStat",
00779                    "bNote","bQuit"]
00780         if operation == "start":
00781             enable = False
00782         else:
00783             enable = True
00784         for btn in buttons:
00785             getattr(self,btn).setEnabled(enable)
00786         self.figmgr.toolbar.set_message(msg)
00787 
00788     def delete_bar(self):
00789         self.__disconnect_event()
00790         self.destroy()
00791 
00792     def __disconnect_event(self):
00793         self._p.register('button_press',None)
00794         self._p.register('button_release',None)
00795 
00796     def _draw_span(self,axes,x0,x1,**kwargs):
00797         height = self._p.figure.bbox.height
00798         y1 = height - axes.bbox.y1
00799         h = axes.bbox.height
00800         w = abs(x1 - x0)
00801         rect = [ int(val) for val in min(x0,x1), y1, w, h ]
00802         self._p.canvas.drawRectangle( rect )
00803         # nothing is returned by drawRectangle
00804         return None
00805 
00806     def _remove_span(self,span):
00807         # Nothing to do with remove.
00808         pass