def paste(self): clipboard = QtGui.QApplication.clipboard() txt = clipboard.text() md = clipboard.mimeData() LOG.info(md) newtxt = [] for line in txt.split('\n'): line = str(line) if line.startswith('>>> ') or line.startswith('... '): line = line[4:] newtxt.append(line) txt = '\n'.join(newtxt) self.insert(txt)
def showtraceback(self): LOG.info('showtraceback') settings = QtCore.QSettings() quiet = settings.value('console/quietinterrupt', False, bool) exc_type, exc_value, exc_traceback = sys.exc_info() LOG.info(exc_type) LOG.info(exc_value) LOG.info(exc_traceback) if exc_type is KeyboardInterrupt and quiet: pass else: PyTugaConsole.showtraceback(self)
def spin(self, n, delay=0.01): '''call processEvents n times. If n is 0, continue until cmdthread is None ''' if n: for _ in range(n): time.sleep(delay) QtGui.QApplication.processEvents(QtCore.QEventLoop.AllEvents) else: self.spin(1) cs = 500 while self.cmdthread is not None: if not cs: LOG.info('spin fail') self.ctrl_c_thread_running() return False cs -= 1 time.sleep(delay) QtGui.QApplication.processEvents(QtCore.QEventLoop.AllEvents) return True
def keyPressEvent(self, ev): k = ev.key() mdf = ev.modifiers() if self.reading and self.pt is None: self.pt = self.text() Tab = QtCore.Qt.Key_Tab Backtab = QtCore.Qt.Key_Backtab Backspace = QtCore.Qt.Key_Backspace Left = QtCore.Qt.Key_Left Right = QtCore.Qt.Key_Right Return = QtCore.Qt.Key_Return Enter = QtCore.Qt.Key_Enter Up = QtCore.Qt.Key_Up PageUp = QtCore.Qt.Key_PageUp Down = QtCore.Qt.Key_Down PageDown = QtCore.Qt.Key_PageDown Control = QtCore.Qt.ControlModifier Shift = QtCore.Qt.ShiftModifier U = QtCore.Qt.Key_U C = QtCore.Qt.Key_C V = QtCore.Qt.Key_V X = QtCore.Qt.Key_X A = QtCore.Qt.Key_A Home = QtCore.Qt.Key_Home E = QtCore.Qt.Key_E D = QtCore.Qt.Key_D H = QtCore.Qt.Key_H Z = QtCore.Qt.Key_Z passthru = True scrolldown = True if k in (Return, Enter): if self.reading: self.reading = False self.movetoend() line, col = self.getCursorPosition() txt = self.text(line) txt = txt[4:].rstrip() if txt: if self.history and not self.history[-1]: # last history entry is blank line del self.history[-1] self.history.append(txt) self.historyp = -1 self.append('\n') if self.cmdthread is None: i = self.indentation(line) if txt.endswith(':'): i += 4 self._indent_level = i self.main_window.pen._mark_undo() self.cmdthread = CmdThread(self, txt) self.cmdthread.start() self.watcherthread = WatcherThread(self.cmdthread) self.watcherthread.finished.connect(self.threaddone) self.watcherthread.start() passthru = False else: passthru = True elif k in (Backspace, Tab, Backtab): line, col = self.getCursorPosition() lines = self.lines() i = self.indentation(line) if line < lines - 1: passthru = False scrolldown = True elif col <= 4 and k != Tab: passthru = False self.scroll_left() elif col <= i + 4: passthru = False spaces = col % 4 if not spaces: spaces = 4 if k != Tab: self.setSelection(line, 4, line, 4 + spaces) self.replaceSelectedText('') self.setCursorPosition(line, col - spaces) else: self.insert(' ' * spaces) self.setCursorPosition(line, 4 + i + spaces) elif line == lines - 1: passthru = True else: passthru = False elif mdf & Shift and k == Up: vbar = self.verticalScrollBar() vbar.setValue(vbar.value() - vbar.singleStep()) passthru = False elif mdf & Shift and k == Down: vbar = self.verticalScrollBar() vbar.setValue(vbar.value() + vbar.singleStep()) passthru = False elif mdf & Shift and k == PageUp: vbar = self.verticalScrollBar() vbar.setValue(vbar.value() - vbar.pageStep()) passthru = False elif mdf & Shift and k == PageDown: vbar = self.verticalScrollBar() vbar.setValue(vbar.value() + vbar.pageStep()) passthru = False elif k == Left: line, col = self.getCursorPosition() lines = self.lines() if line < lines - 1: passthru = False scrolldown = True elif col <= 4: passthru = False self.scroll_left() elif k == Right: line, col = self.getCursorPosition() lines = self.lines() if line < lines - 1: passthru = False scrolldown = True elif k in (Up, Down): self.scrolldown() line, col = self.getCursorPosition() txt = self.text(line)[4:].strip() if self.cmdthread is not None: pass elif not self.history: QtGui.QApplication.beep() else: changeline = True addthisline = False lenhist = len(self.history) if k == Up and self.historyp == -1: addthisline = True if k == Up and lenhist == 1: self.historyp -= 1 elif k == Up and self.historyp <= -lenhist: QtGui.QApplication.beep() changeline = False elif k == Up: self.historyp -= 1 elif k == Down and self.historyp >= -1: QtGui.QApplication.beep() changeline = False elif k == Down: self.historyp += 1 if addthisline: self.history.append(txt) if changeline: txt = self.history[self.historyp] endpos = len(self.text(line)) if self.historyp == -1: del self.history[-1] self.setSelection(line, 4, line, endpos) self.replaceSelectedText(txt) passthru = False elif mdf & Control and k == U: # erase from pen to beginning of line self.scroll_left() self.erasetostart() elif mdf & Control and k == X: # Cut # No action. Disabled. scrolldown = False passthru = False elif mdf & Control and mdf & Shift and k == X: # Cut self.cut() # No action. Disabled. scrolldown = False passthru = False elif mdf & Control and mdf & Shift and k == C: # Copy self.copy() scrolldown = False passthru = False elif mdf & Control and mdf & Shift and k == V: # Paste self.paste() scrolldown = False passthru = False elif mdf & Control and k == Z: self.main_window.pen._undo() scrolldown = True passthru = False elif mdf & Control and k == C: # send keyboard interrupt LOG.info('Ctrl-C pressed') import threading if hasattr(threading, 'threads'): for pen in threading.threads: threading.threads[pen] = 0 if self.cmdthread is not None and self.cmdthread.isAlive(): self.ctrl_c_thread_running() else: self.ctrl_c_no_thread_running() self.sync_pens_lists() elif (mdf & Control and k == A) or k == Home: self.movetostart() self.scroll_left() passthru = False scrolldown = False elif mdf & Control and k == E: self.movetoend() passthru = False elif mdf & Control and k == D: self.main_window.close() passthru = False elif mdf & Control and mdf & Shift and k == H: # Clear history self.history = [] if scrolldown and ev.text(): self.scrolldown() if passthru: super().keyPressEvent(ev)
def writefile02(self, fp, docs, backup=False): '''Write out open files (docs) to file path fp. Version 02 Knows how to deal with 3 kinds of files: EXTERNAL files start with '_@@EXTERNAL@@_' PYND files (stored in related _pynd directory) INTERNAL files Creates a zip file called *.pyn and if necessary the related directory (like fp with name modified to end with _pynd) Also saves file manifest and history in .pyn zipfile. When saving INTERNAL files, puts all files in to a folder first to make it match the EXTERNAL file saves better. ''' VERSION = b'pyn02' _, fn = os.path.split(fp) fbase, _ = os.path.splitext(fn) if not fbase.endswith('_pynd'): fbase = fbase + '_pynd' z = zipfile.ZipFile(fp, 'w') manifest = [] for n, doc in enumerate(docs): modified = doc.isModified() cline, ccol = doc.getCursorPosition() code = doc.cleancode() doc.beginUndoAction() doc.selectAll() doc.removeSelectedText() doc.insert(code) doc.setCursorPosition(cline, ccol) doc.setModified(modified) doc.endUndoAction() LOG.info('writing %s' % doc) if not backup and doc._filepath is not None: efp = doc._filepath manifest.append(efp) LOG.info('external: %s' % efp) if efp.startswith('_@@'): dirname, _ = os.path.split(fp) if dirname: efp = efp.replace('_@@', dirname) else: efp = efp[4:] self._remwatcher(efp) f = open(efp, 'w') f.write(code) f.close() self._addwatcher(efp, doc) doc.setModified(False) else: arcname = '%05d.py' % n zipi = zipfile.ZipInfo() zipi.filename = os.path.join(fbase, arcname) manifest.append(zipi.filename) zipi.compress_type = zipfile.ZIP_DEFLATED zipi.date_time = time.localtime() zipi.external_attr = 0o644 << 16 zipi.comment = VERSION z.writestr(zipi, code.encode('utf-8')) historyname = '@@history@@' history = '\n'.join(self.interpretereditor.history) zipi = zipfile.ZipInfo() zipi.filename = os.path.join(fbase, historyname) zipi.compress_type = zipfile.ZIP_DEFLATED zipi.date_time = time.localtime() zipi.external_attr = 0o644 << 16 zipi.comment = VERSION z.writestr(zipi, history) # .encode('utf-8')) manifestname = '@@manifest@@' zipi = zipfile.ZipInfo() zipi.filename = os.path.join(fbase, manifestname) zipi.compress_type = zipfile.ZIP_DEFLATED zipi.date_time = time.localtime() zipi.external_attr = 0o644 << 16 zipi.comment = VERSION manifeststr = '\n'.join(manifest) z.writestr(zipi, manifeststr.encode('utf-8')) z.close()