00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 __facility__ = "Online"
00011 __abstract__ = "Comment panel for the ScriptEngine"
00012 __author__ = "S. Tuvi <stuvi@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00013 __date__ = "2005/07/23 00:08:27"
00014 __updated__ = "$Date: 2005/09/22 00:29:30 $"
00015 __version__ = "$Revision: 1.6 $"
00016 __release__ = "$Name: HEAD $"
00017 __credits__ = "SLAC"
00018
00019 import LICOS.copyright_SLAC
00020
00021 from qt import *
00022 import os
00023 import time
00024
00025 class rcCommentPanel(QWidget):
00026 """!\brief ScriptEngine comment panel class.
00027
00028 """
00029 def __init__(self,parent = None,name = None,fl = 0):
00030 """!\brief rcCommentPanel constructor.
00031
00032 \param parent Parent GUI
00033 \param name GUI name
00034 \param fl GUI flags
00035 """
00036 QWidget.__init__(self,parent,name,fl)
00037
00038 if not name:
00039 self.setName("rcComments")
00040
00041
00042 Form2Layout = QGridLayout(self,1,1,0,6,"Form2Layout")
00043
00044 self.__teComments = CommentEntryWidget(self)
00045
00046 Form2Layout.addWidget(self.__teComments,0,0)
00047
00048 self.languageChange()
00049
00050 self.resize(QSize(291,219).expandedTo(self.minimumSizeHint()))
00051
00052 def getWidget(self):
00053 """!\brief Retrieve the comment panel widget
00054
00055 \return CommentEntryWidget instance
00056 """
00057 return self.__teComments
00058
00059 def languageChange(self):
00060 """!\brief languageChange
00061
00062 """
00063 self.setCaption(self.tr("rcComments"))
00064
00065 class CommentEntryWidget(QTextEdit):
00066 """!\brief Comment entry widget
00067
00068 This widget is based on the QTextEdit widget and allows
00069 the entry and storage of comments entered by an operator.
00070 """
00071 def __init__(self, parent=None):
00072 """!\brief CommentEntryWidget constructor
00073
00074 \param parent Parent GUI
00075 """
00076 QTextEdit.__init__(self, parent)
00077
00078 self.__prompt = "--> "
00079
00080
00081 self.line = QString()
00082 self.lines = []
00083
00084 self.point = 0
00085
00086 self.reading = 0
00087
00088 self.__history = []
00089 self.__timeStamps = []
00090 self.pointer = 0
00091 self.xLast = 0
00092 self.yLast = 0
00093 self.__xLastBP = 0
00094 self.__yLastBP = 0
00095 self.clip = QApplication.clipboard()
00096
00097
00098 self.setTextFormat(QTextEdit.PlainText)
00099 self.setWrapPolicy(QTextEdit.Anywhere)
00100
00101 if os.name == 'posix':
00102 font = QFont("Fixed", 12)
00103 elif os.name == 'nt' or os.name == 'dos':
00104 font = QFont("Courier New", 8)
00105 else:
00106 raise SystemExit, "FIXME for 'os2', 'mac', 'ce' or 'riscos'"
00107 font.setFixedPitch(1)
00108 self.setFont(font)
00109 self.connect(self, SIGNAL("clicked(int,int)"), self.handleClicked)
00110
00111
00112 height = 40*QFontMetrics(font).lineSpacing()
00113 request = QSize(600, height)
00114 if parent is not None:
00115 request = request.boundedTo(parent.size())
00116 self.resize(request)
00117 self.setReadOnly(1)
00118 self.clearDisplay()
00119
00120 def getHistory(self):
00121 return self.__history
00122
00123 def getTimestamps(self):
00124 """!\brief Return the timestamps of the comments entered so far.
00125
00126 \return A list of timestamps.
00127 """
00128 return self.__timeStamps
00129
00130 def clearHistory(self):
00131 """!\brief Clear the comment history.
00132
00133 """
00134 self.__history = []
00135 self.__timeStamps = []
00136
00137 def clearDisplay(self):
00138 """!\brief Clear the display buffer.
00139
00140 """
00141 self.clear()
00142 self.write(self.__prompt)
00143
00144
00145
00146
00147
00148 def setPrompt(self, prompt):
00149 """!\brief Set the prompt for comment entry.
00150
00151 \param prompt Prompt string
00152 """
00153 self.__prompt = prompt
00154
00155 def getPrompt(self):
00156 """!\brief Retrieve the current prompt.
00157
00158 \return Prompt string
00159 """
00160 return self.__prompt
00161
00162 def flush(self):
00163 """!\brief Simulate stdin, stdout, and stderr.
00164
00165 """
00166 pass
00167
00168 def isatty(self):
00169 """!\brief Simulate stdin, stdout, and stderr.
00170
00171 """
00172 return 1
00173
00174 def readline(self):
00175 """!\brief Simulate stdin, stdout, and stderr.
00176
00177 """
00178 self.reading = 1
00179 self.__clearLine()
00180 self.moveCursor(QTextEdit.MoveEnd, 0)
00181 while self.reading:
00182 qApp.processOneEvent()
00183 if self.line.length() == 0:
00184 return '\n'
00185 else:
00186 return str(self.line)
00187
00188 def write(self, text):
00189 """!\brief Simulate stdin, stdout, and stderr.
00190
00191 """
00192
00193
00194 hack = self.text()
00195 hack.append(text)
00196 self.setText(hack)
00197
00198 self.moveCursor(QTextEdit.MoveEnd, 0)
00199 self.yLast, self.xLast = self.getCursorPosition()
00200
00201 def writelines(self, text):
00202 """!\brief Simulate stdin, stdout, and stderr.
00203
00204 """
00205 map(self.write, text)
00206 print "DO WE EVER GET HERE? IF YES, OPTIMIZATION POSSIBLE"
00207
00208 def enterComment(self, comment, addToHistory=0, source='system'):
00209 """!\brief Enter a comment programmatically.
00210
00211 This can be called from a user script to add to comments.
00212 The text is prepended with \a source to indicate that it is a
00213 machine generated comment.
00214
00215 \param comment The text of the comment to be entered
00216 \param addtoHistory Whether this comment will be persistent or not
00217 \param source The text to be prepended before the comment
00218
00219 """
00220 self.line = comment.rstrip()
00221 if source != "":
00222 self.line = '[' + source + '] ' + self.line
00223 self.line = QString(self.line)
00224 self.write(self.line)
00225 self.__xLastBP, self.__yLastBP = self.xLast, self.yLast
00226 self.__xLastBP += 11
00227 self.write('\n')
00228 self.__run(addToHistory)
00229
00230 def flushComment(self):
00231 """!\brief Force comment entry if the user hasn't pressed the Enter key yet.
00232
00233 """
00234 if self.line.length() > 0:
00235 self.write('\n')
00236 self.__run()
00237
00238 def __run(self, addToHistory=1):
00239 """!\brief Display/store the comment.
00240
00241 Display the comment in the textedit window and based on
00242 \a addHistory value store it in the history.
00243
00244 \param addToHistory If 1, store the comment in the history (default).
00245 If 0, do not store the comment in the history.
00246 """
00247 self.pointer = 0
00248 y, x = self.getCursorPosition()
00249 yFirst = y - len(self.lines) - 1
00250 self.setSelection(yFirst, 0, yFirst, 4)
00251 self.removeSelectedText()
00252 tStamp = time.gmtime()
00253 self.insertAt(time.strftime('[%H:%M:%S] ', tStamp), y - len(self.lines) - 1, 0)
00254 if addToHistory:
00255 self.__history.append(str(self.line))
00256 self.__timeStamps.append(tStamp)
00257 self.lines.append(str(self.line))
00258 self.write(self.__prompt)
00259 self.lines = []
00260 self.__clearLine()
00261
00262 def __clearLine(self):
00263 """!\brief Clear input line buffer
00264
00265 """
00266 self.line.truncate(0)
00267 self.point = 0
00268
00269 def insertText(self, text, offsetY=0, absX=0, overwrite=0):
00270 """!\brief Insert text at a given position.
00271
00272 \param text Text to be inserted
00273 \param offsetY The position of the comment text relative to the current position
00274 \param absX The absolute position of the comment text
00275 \param overwrite Overwrite flag
00276 """
00277 posy = self.__yLastBP + offsetY
00278 posx = absX + 11
00279 self.setCursorPosition(posy, posx)
00280 if overwrite:
00281 self.setSelection(posy, posx, posy, posx+len(text), 0)
00282 self.removeSelectedText()
00283 self.__insertText(QString(text), posy, posx)
00284
00285 def __insertText(self, text, posY=0, posX=0):
00286 """!\brief Insert text at the current cursor position.
00287
00288 \param text Text to be inserted
00289 \param posY Relative Y position
00290 \param posX Relative X position
00291 """
00292 y, x = self.getCursorPosition()
00293 if posX != 0: x = posX
00294 if posY != 0: y = posY
00295 self.insertAt(text, y, x)
00296 self.line.insert(self.point, text)
00297 self.point += text.length()
00298 self.setCursorPosition(y, x + text.length())
00299
00300 def keyPressEvent(self, e):
00301 """!\brief Handle user input a key at a time.
00302
00303 \param e Key event
00304 """
00305 if self.isReadOnly() or not self.isEnabled():
00306 e.ignore()
00307 return
00308 text = e.text()
00309 key = e.key()
00310 ascii = e.ascii()
00311
00312 if text.length() and ascii>=32 and ascii<127:
00313 self.__insertText(text)
00314 return
00315
00316 if e.state() & Qt.ControlButton or e.state() & Qt.ShiftButton:
00317 e.ignore()
00318 return
00319
00320 if key == Qt.Key_Backspace:
00321 if self.point:
00322 self.doKeyboardAction(QTextEdit.ActionBackspace)
00323 self.point -= 1
00324 self.line.remove(self.point, 1)
00325 elif key == Qt.Key_Delete:
00326 self.doKeyboardAction(QTextEdit.ActionDelete)
00327 self.line.remove(self.point, 1)
00328 elif key == Qt.Key_Return or key == Qt.Key_Enter:
00329 self.write('\n')
00330 if self.reading:
00331 self.reading = 0
00332 else:
00333 self.__run()
00334 elif key == Qt.Key_Tab:
00335 self.__insertText(text)
00336 elif key == Qt.Key_Left:
00337 if self.point:
00338 self.moveCursor(QTextEdit.MoveBackward,0)
00339 self.point -= 1
00340 elif key == Qt.Key_Right:
00341 if self.point < self.line.length():
00342 self.moveCursor(QTextEdit.MoveForward,0)
00343 self.point += 1
00344 elif key == Qt.Key_Home:
00345 self.setCursorPosition(self.yLast, self.xLast)
00346 self.point = 0
00347 elif key == Qt.Key_End:
00348 self.moveCursor(QTextEdit.MoveLineEnd,0)
00349 self.point = self.line.length()
00350 elif key == Qt.Key_Up:
00351 if len(self.__history):
00352 if self.pointer == 0:
00353 self.pointer = len(self.__history)
00354 self.pointer -= 1
00355 self.__recall()
00356 elif key == Qt.Key_Down:
00357 if len(self.__history):
00358 self.pointer += 1
00359 if self.pointer == len(self.__history):
00360 self.pointer = 0
00361 self.__recall()
00362 elif key == Qt.Key_Escape:
00363 self.__deleteLine()
00364 else:
00365 e.ignore()
00366
00367 def __deleteLine(self):
00368 """!\brief Delete a line.
00369
00370 """
00371 self.setCursorPosition(self.yLast, self.xLast)
00372 self.setSelection(self.yLast, self.xLast,
00373 self.yLast, self.paragraphLength(self.yLast))
00374 self.removeSelectedText()
00375 self.__clearLine()
00376
00377 def __recall(self):
00378 """!\brief Display the current item from the command history.
00379
00380 """
00381 self.__deleteLine()
00382 self.__insertText(QString(self.__history[self.pointer]))
00383
00384
00385 def focusNextPrevChild(self, next):
00386 """!\brief Suppress tabbing to the next window in multi-line commands.
00387
00388 """
00389 return QTextEdit.focusNextPrevChild(self, next)
00390
00391 def handleClicked(self, para, pos):
00392 """!\brief Save the selected text to the clipboard.
00393
00394 """
00395 if self.hasSelectedText():
00396 if len(self.selectedText()) > 0:
00397 self.clip.setText(self.selectedText())
00398 self.moveCursor(QTextEdit.MoveEnd, 0)
00399 return
00400
00401 def contentsContextMenuEvent(self,ev):
00402 """!\brief Paste the contents of the clipboard to the cursor position.
00403
00404 """
00405 if not self.isReadOnly():
00406 self.__insertText(self.clip.text())
00407 ev.accept()
00408 return
00409