def cursor(self): """Return a QTextCursor with the same selection.""" c = QTextCursor(self.document.document) c.movePosition(QTextCursor.End) if self.end is None else c.setPosition( self.end) c.setPosition(self.start, QTextCursor.KeepAnchor) return c
def append(self, text): """Append line to the end """ cursor = QTextCursor(self._doc) cursor.movePosition(QTextCursor.End) cursor.insertBlock() cursor.insertText(text)
def show(cursor, pos=None, num_lines=6): """Displays a tooltip showing part of the cursor's Document. If the cursor has a selection, those blocks are displayed. Otherwise, num_lines lines are displayed. If pos is not given, the global mouse position is used. """ block = cursor.document().findBlock(cursor.selectionStart()) c2 = QTextCursor(block) if cursor.hasSelection(): c2.setPosition(cursor.selectionEnd(), QTextCursor.KeepAnchor) c2.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor) else: c2.movePosition(QTextCursor.NextBlock, QTextCursor.KeepAnchor, num_lines) data = textformats.formatData('editor') doc = QTextDocument() font = QFont(data.font) font.setPointSizeF(font.pointSizeF() * .8) doc.setDefaultFont(font) doc.setPlainText(c2.selection().toPlainText()) if metainfo.info(cursor.document()).highlighting: highlighter.highlight(doc, state=tokeniter.state(block)) size = doc.size().toSize() + QSize(8, -4) pix = QPixmap(size) pix.fill(data.baseColors['background']) doc.drawContents(QPainter(pix)) label = QLabel() label.setPixmap(pix) label.setStyleSheet("QLabel { border: 1px solid #777; }") label.resize(size) widgets.customtooltip.show(label, pos)
def setLine(self, line): cursor = QTextCursor(self.document()) cursor.movePosition(QTextCursor.End) cursor.setPosition(self.newPromptPos, QTextCursor.KeepAnchor) cursor.removeSelectedText() cursor.insertText(line) self.setTextCursor(cursor)
def onMatchNumberChange(self, matchNumber): # Set default format on the whole text before highlighting the selected # match. document = self.matchText.document() cursor = QTextCursor(document) cursor.movePosition(QTextCursor.End, QTextCursor.KeepAnchor) cursor.setCharFormat(QTextCharFormat()) search = self.getSearchText() for i, match in enumerate(self.regex.finditer(search)): if i + 1 == matchNumber: break else: assert False, ("We didn't find a match?! (RE=%r, text=%r" % (self.regex.pattern, search)) self.formatMatchedText(document, match) model = self.groupsView.model() model.clear() # Create a reversed self.regex.groupindex dictionnary groupsIndexes = dict( (v, k) for (k, v) in self.regex.groupindex.iteritems()) for i in range(1, self.regex.groups + 1): groupName = groupsIndexes.get(i, "") groupValue = match.group(i) model.append((groupName, groupValue))
def cursorAt(self, position, in_active_area=True): c = QTextCursor(self.block) p = min(position, self.length-1) if in_active_area: p = max(p, self.active_area_start) c.movePosition(QTextCursor.Right, QTextCursor.MoveAnchor, p) return c
def _find(self, textEdit=None, backward=False): if textEdit is None: textEdit = self.textEdit found = False if textEdit is not None: cursor = textEdit.textCursor() text, flags = self._textAndFindFlags(backward=backward) position = cursor.position() cursor = textEdit.document().find(text, cursor, flags) if not cursor.isNull(): textEdit.setTextCursor(cursor) found = True elif self.wrapAroundCheckBox.isChecked(): cursor = QTextCursor(textEdit.textCursor()) cursor.movePosition(backward and QTextCursor.End or QTextCursor.Start) cursor = textEdit.document().find(text, cursor, flags) if not cursor.isNull(): if position == cursor.position(): pass #todo textEdit.setTextCursor(cursor) found = True self.writeSettings() if not found: QApplication.beep() self.feedbackLabel.setText(self.tr("Not found")) else: self.clearFeedback()
def onMatchNumberChange(self, matchNumber): # Set default format on the whole text before highlighting the selected # match. document = self.matchText.document() cursor = QTextCursor(document) cursor.movePosition(QTextCursor.End, QTextCursor.KeepAnchor) cursor.setCharFormat(QTextCharFormat()) search = self.getSearchText() for i, match in enumerate(self.regex.finditer(search)): if i + 1 == matchNumber: break else: assert False, ("We didn't find a match?! (RE=%r, text=%r" % (self.regex.pattern, search)) self.formatMatchedText(document, match) model = self.groupsView.model() model.clear() # Create a reversed self.regex.groupindex dictionnary groupsIndexes = dict((v, k) for (k, v) in self.regex.groupindex.iteritems()) for i in range(1, self.regex.groups + 1): groupName = groupsIndexes.get(i, "") groupValue = match.group(i) model.append((groupName, groupValue))
def formatMatchedText(self, document, match): """Format the matched text in a document""" cursor = QTextCursor(document) cursor.setPosition(match.start()) cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor, match.end() - match.start()) cursor.setCharFormat(self.matchFormat)
def isBlankAfter(cursor): """Returns True if there's no text on the current line after the cursor.""" if cursor.hasSelection(): return False if cursor.atBlockEnd(): return True c = QTextCursor(cursor) c.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor) return c.selection().toPlainText().isspace()
def isBlankBefore(cursor): """Returns True if there's no text on the current line before the cursor.""" if cursor.hasSelection(): return False if cursor.atBlockStart(): return True c = QTextCursor(cursor) c.movePosition(QTextCursor.StartOfBlock, QTextCursor.KeepAnchor) return c.selection().toPlainText().isspace()
def show_msg(self, message): """Show message in textBrowser """ self.textEdit.append(message) # Scroll to end of the last message cursor = QTextCursor(self.textEdit.textCursor()) cursor.movePosition(QTextCursor.End) self.textEdit.setTextCursor(cursor) QApplication.processEvents()
def _selectLines(self, startBlockNumber, endBlockNumber): """Select whole lines """ startBlock = self.document().findBlockByNumber(startBlockNumber) endBlock = self.document().findBlockByNumber(endBlockNumber) cursor = QTextCursor(startBlock) cursor.setPosition(endBlock.position(), QTextCursor.KeepAnchor) cursor.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor) self.setTextCursor(cursor)
def formatMatchedText(self, document, match): """Format the matched text in a document""" cursor = QTextCursor(document) cursor.setPosition(match.start()) cursor.movePosition( QTextCursor.NextCharacter, QTextCursor.KeepAnchor, match.end() - match.start()) cursor.setCharFormat(self.matchFormat)
def add_debug_message(self, message): self.text_debug.append(message) while self.text_debug.document().blockCount() > 1000: cursor = QTextCursor(self.text_debug.document().begin()) cursor.select(QTextCursor.BlockUnderCursor) cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor) cursor.removeSelectedText() if self.checkbox_debug_auto_scroll.isChecked(): self.text_debug.verticalScrollBar().setValue(self.text_debug.verticalScrollBar().maximum())
def __highlight(self, positions, color=None, cancel=False): cursor = QTextCursor(self.document()) for position in positions: if position > self.get_position('eof'): return cursor.setPosition(position) cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor) charformat = cursor.charFormat() pen = QPen(Qt.NoPen) if cancel else QPen(color) charformat.setTextOutline(pen) cursor.setCharFormat(charformat)
def setTextCursor(self, cursor): """Reimplemented to show n surrounding lines.""" numlines = QSettings().value("view_preferences/context_lines", 3, int) if numlines > 0: c = QTextCursor(cursor) c.setPosition(cursor.selectionEnd()) c.movePosition(QTextCursor.Down, QTextCursor.MoveAnchor, numlines) super(View, self).setTextCursor(c) c.setPosition(cursor.selectionStart()) c.movePosition(QTextCursor.Up, QTextCursor.MoveAnchor, numlines) super(View, self).setTextCursor(c) super(View, self).setTextCursor(cursor)
def write(self, s): if self.echo: sys.__stdout__.write(s) doc = self.document() cursor = QTextCursor(doc) cursor.clearSelection() cursor.movePosition(QTextCursor.End, QTextCursor.MoveAnchor) cursor.insertText(s) cursor.movePosition(QTextCursor.End, QTextCursor.MoveAnchor) cursor.clearSelection() self.ensureCursorVisible() qApp.processEvents()
def on_log_received(self, data): time_info = datetime.fromtimestamp((data["time"] / 1000)).isoformat() log_message = "%s: %s : %s" % (time_info, data["level"], data["message"]) message_document = self.document() cursor_to_add = QTextCursor(message_document) cursor_to_add.movePosition(cursor_to_add.End) cursor_to_add.insertText(log_message + "\n") if data["level"] in COLORS: fmt = QTextCharFormat() fmt.setForeground(COLORS[data["level"]]) cursor_to_add.movePosition(cursor_to_add.PreviousBlock) cursor_to_add_fmt = message_document.find(data["level"], cursor_to_add.position()) cursor_to_add_fmt.mergeCharFormat(fmt) self.ensureCursorVisible()
def _removeBlock(blockIndex): block = self._doc.findBlockByNumber(blockIndex) if block.next().isValid(): # not the last cursor = QTextCursor(block) cursor.movePosition(QTextCursor.NextBlock, QTextCursor.KeepAnchor) elif block.previous().isValid(): # the last, not the first cursor = QTextCursor(block.previous()) cursor.movePosition(QTextCursor.EndOfBlock) cursor.movePosition(QTextCursor.NextBlock, QTextCursor.KeepAnchor) cursor.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor) else: # only one block cursor = QTextCursor(block) cursor.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor) cursor.removeSelectedText()
def get_tooltip(self, pos): cursor_pos = self.document().documentLayout().hitTest(QtCore.QPointF(pos), Qt.Qt.ExactHit) if cursor_pos == -1: return "", QRect() cursor = QTextCursor(self.document()) cursor.setPosition(cursor_pos) col = cursor.positionInBlock() line = cursor.blockNumber() tooltip = "" rect = QRect() if line >= len(self.highlighter.matches): return "", QRect() match_start = 0 match_len = 0 matches = 0 #for word in self.highlighter.matches[line]: #if col >= word[1] and col < word[2]: for word in self.words_at_pos(line, col): keyword = word[0] # Go for the smallest region possible so we can update # as soon as the mouse falls out of range of one of the words. if word[1] > match_start: match_start = word[1] if word[2] - word[1] < match_len: match_len = word[2] - word[1] if matches > 0: tooltip += u"\n" if not keyword.section == "": tooltip += u"【%s】 " % keyword.section tooltip += u"%s ― %s" % (keyword.word, keyword.meaning) matches += 1 # Highlight our word, so we can get the rect. cursor.movePosition(QTextCursor.Start) for i in range(line): cursor.movePosition(QTextCursor.NextBlock) for i in range(match_start): cursor.movePosition(QTextCursor.NextCharacter) for i in range(match_len): cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor) rect = self.cursorRect(cursor) return tooltip, rect
def slotCursorPositionChanged(self): """Called whenever the cursor position changes. Highlights matching characters if the cursor is at one of them. """ cursor = self.edit().textCursor() block = cursor.block() text = block.text() # try both characters at the cursor col = cursor.position() - block.position() end = col + 1 col = max(0, col - 1) for c in text[col:end]: if c in self.matchPairs: break col += 1 else: self.clear() return # the cursor is at a character from matchPairs i = self.matchPairs.index(c) cursor.setPosition(block.position() + col) # find the matching character new = QTextCursor(cursor) if i & 1: # look backward match = self.matchPairs[i-1] flags = QTextDocument.FindBackward else: # look forward match = self.matchPairs[i+1] flags = QTextDocument.FindFlags() new.movePosition(QTextCursor.Right) # search, also nesting rx = QRegExp(QRegExp.escape(c) + '|' + QRegExp.escape(match)) nest = 0 while nest >= 0: new = cursor.document().find(rx, new, flags) if new.isNull(): self.clear() return nest += 1 if new.selectedText() == c else -1 cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor) self.highlight([cursor, new])
def slotCursorPositionChanged(self): """Called whenever the cursor position changes. Highlights matching characters if the cursor is at one of them. """ cursor = self.edit().textCursor() block = cursor.block() text = block.text() # try both characters at the cursor col = cursor.position() - block.position() end = col + 1 col = max(0, col - 1) for c in text[col:end]: if c in self.matchPairs: break col += 1 else: self.clear() return # the cursor is at a character from matchPairs i = self.matchPairs.index(c) cursor.setPosition(block.position() + col) # find the matching character new = QTextCursor(cursor) if i & 1: # look backward match = self.matchPairs[i - 1] flags = QTextDocument.FindBackward else: # look forward match = self.matchPairs[i + 1] flags = QTextDocument.FindFlags() new.movePosition(QTextCursor.Right) # search, also nesting rx = QRegExp(QRegExp.escape(c) + "|" + QRegExp.escape(match)) nest = 0 while nest >= 0: new = cursor.document().find(rx, new, flags) if new.isNull(): self.clear() return nest += 1 if new.selectedText() == c else -1 cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor) self.highlight([cursor, new])
def apply_changes(self): """Apply the changes and update the tokens.""" c = QTextCursor(self._d) # record a sensible position for undo c.setPosition(self._changes_list[-1][0]) c.joinPreviousEditBlock() if self.combine_undo else c.beginEditBlock() try: for start, end, text in self._changes_list: c.movePosition(QTextCursor.End) if end is None else c.setPosition(end) c.setPosition(start, QTextCursor.KeepAnchor) c.insertText(text) finally: c.endEditBlock() if self.combine_undo is None: self.combine_undo = True
def on_log_received(self, data): time_info = datetime.fromtimestamp((data['time']/1000)).isoformat() log_message = '%s: %s : %s' % ( time_info, data['level'], data['message']) message_document = self.document() cursor_to_add = QTextCursor(message_document) cursor_to_add.movePosition(cursor_to_add.End) cursor_to_add.insertText(log_message + '\n') if data['level'] in COLORS: fmt = QTextCharFormat() fmt.setForeground(COLORS[data['level']]) cursor_to_add.movePosition(cursor_to_add.PreviousBlock) cursor_to_add_fmt = message_document.find(data['level'], cursor_to_add.position()) cursor_to_add_fmt.mergeCharFormat(fmt) self.ensureCursorVisible()
def apply_changes(self): """Apply the changes and update the tokens.""" c = QTextCursor(self._d) # record a sensible position for undo c.setPosition(self._changes_list[-1][0]) c.joinPreviousEditBlock() if self.combine_undo else c.beginEditBlock() try: for start, end, text in self._changes_list: c.movePosition( QTextCursor.End) if end is None else c.setPosition(end) c.setPosition(start, QTextCursor.KeepAnchor) c.insertText(text) finally: c.endEditBlock() if self.combine_undo is None: self.combine_undo = True
def html_copy(cursor, scheme='editor', number_lines=False): """Return a new QTextDocument with highlighting set as HTML textcharformats. The cursor is a cursor of a document.Document instance. If the cursor has a selection, only the selection is put in the new document. If number_lines is True, line numbers are added. """ data = textformats.formatData(scheme) doc = QTextDocument() doc.setDefaultFont(data.font) doc.setPlainText(cursor.document().toPlainText()) if metainfo.info(cursor.document()).highlighting: highlight(doc, mapping(data), ly.lex.state(documentinfo.mode(cursor.document()))) if cursor.hasSelection(): # cut out not selected text start, end = cursor.selectionStart(), cursor.selectionEnd() cur1 = QTextCursor(doc) cur1.setPosition(start, QTextCursor.KeepAnchor) cur2 = QTextCursor(doc) cur2.setPosition(end) cur2.movePosition(QTextCursor.End, QTextCursor.KeepAnchor) cur2.removeSelectedText() cur1.removeSelectedText() if number_lines: c = QTextCursor(doc) f = QTextCharFormat() f.setBackground(QColor('#eeeeee')) if cursor.hasSelection(): num = cursor.document().findBlock( cursor.selectionStart()).blockNumber() + 1 last = cursor.document().findBlock(cursor.selectionEnd()) else: num = 1 last = cursor.document().lastBlock() lastnum = last.blockNumber() + 1 padding = len(format(lastnum)) block = doc.firstBlock() while block.isValid(): c.setPosition(block.position()) c.setCharFormat(f) c.insertText('{0:>{1}d} '.format(num, padding)) block = block.next() num += 1 return doc
def insert(self, index, text): """Insert line to the document """ if index < 0 or index > self._doc.blockCount(): raise IndexError('Invalid block index', index) if index == 0: # first cursor = QTextCursor(self._doc.firstBlock()) cursor.insertText(text) cursor.insertBlock() elif index != self._doc.blockCount(): # not the last cursor = QTextCursor(self._doc.findBlockByNumber(index).previous()) cursor.movePosition(QTextCursor.EndOfBlock) cursor.insertBlock() cursor.insertText(text) else: # last append to the end self.append(text)
def html_copy(cursor, scheme="editor", number_lines=False): """Return a new QTextDocument with highlighting set as HTML textcharformats. The cursor is a cursor of a document.Document instance. If the cursor has a selection, only the selection is put in the new document. If number_lines is True, line numbers are added. """ data = textformats.formatData(scheme) doc = QTextDocument() doc.setDefaultFont(data.font) doc.setPlainText(cursor.document().toPlainText()) if metainfo.info(cursor.document()).highlighting: highlight(doc, mapping(data), ly.lex.state(documentinfo.mode(cursor.document()))) if cursor.hasSelection(): # cut out not selected text start, end = cursor.selectionStart(), cursor.selectionEnd() cur1 = QTextCursor(doc) cur1.setPosition(start, QTextCursor.KeepAnchor) cur2 = QTextCursor(doc) cur2.setPosition(end) cur2.movePosition(QTextCursor.End, QTextCursor.KeepAnchor) cur2.removeSelectedText() cur1.removeSelectedText() if number_lines: c = QTextCursor(doc) f = QTextCharFormat() f.setBackground(QColor("#eeeeee")) if cursor.hasSelection(): num = cursor.document().findBlock(cursor.selectionStart()).blockNumber() + 1 last = cursor.document().findBlock(cursor.selectionEnd()) else: num = 1 last = cursor.document().lastBlock() lastnum = last.blockNumber() + 1 padding = len(format(lastnum)) block = doc.firstBlock() while block.isValid(): c.setPosition(block.position()) c.setCharFormat(f) c.insertText("{0:>{1}d} ".format(num, padding)) block = block.next() num += 1 return doc
def makeTableDocument(self): printer = QPrinter() document = QTextDocument() document.setDefaultStyleSheet("table {border:1px; border-color:teal}") document.setDefaultStyleSheet("h1, h2, h3 {color:teal}") document.setDocumentMargin(0.0) document.setPageSize(QSizeF(printer.pageRect().size())) header = ''' <html> <body> <div style="line-height:2.5"> <h1>Desmond International College</h1> <h2>Km4, Happiness Street, Kafanchan</h2> <h2>Kaduna, Nigeria</h2> </div> <div> <h2 style='display:block; text-align:center; word-spacing:10vw; text-transform: uppercase; margin-top:25px; margin-bottom:15px'><u>STUDENT DATA TABLE</u></h2> </div> </body> </html> ''' #print(dir(document)) cursor = QTextCursor(document) rows = self.table.rowCount() columns = self.table.columnCount() cursor.insertHtml(header) table = cursor.insertTable(rows + 1, columns) formats = table.format() formats.setHeaderRowCount(1) table.setFormat(formats) formats = cursor.blockCharFormat() formats.setFontWeight(QFont.Bold) for column in range(columns): cursor.setCharFormat(formats) cursor.insertText(self.table.horizontalHeaderItem(column).text()) cursor.movePosition(QTextCursor.NextCell) for row in range(rows): for column in range(columns): cursor.insertText(self.table.item(row, column).text()) cursor.movePosition(QTextCursor.NextCell) return document
def gotoTextCursor(self, cursor, numlines=3): """Go to the specified cursor. If possible, at least numlines (default: 3) number of surrounding lines is shown. The number of surrounding lines can also be set in the preferences, under the key "view_preferences/context_lines". This setting takes precedence. """ numlines = QSettings().value("view_preferences/context_lines", numlines, int) if numlines > 0: c = QTextCursor(cursor) c.setPosition(cursor.selectionEnd()) c.movePosition(QTextCursor.Down, QTextCursor.MoveAnchor, numlines) self.setTextCursor(c) c.setPosition(cursor.selectionStart()) c.movePosition(QTextCursor.Up, QTextCursor.MoveAnchor, numlines) self.setTextCursor(c) self.setTextCursor(cursor)
def __searchDocument(self, document, pattern, settings): """ Searches for given pattern occurrences in given document using given settings. :param document: Document. :type document: QTextDocument :param pattern: Pattern. :type pattern: unicode :param settings: Search settings. :type settings: Structure :return: Matched occurrences. :rtype: list """ pattern = settings.regularExpressions and QRegExp(pattern) or pattern flags = QTextDocument.FindFlags() if settings.caseSensitive: flags = flags | QTextDocument.FindCaseSensitively if settings.wholeWord: flags = flags | QTextDocument.FindWholeWords occurrences = [] block = document.findBlock(0) cursor = document.find(pattern, block.position(), flags) while block.isValid() and cursor.position() != -1: if self.__interrupt: return blockCursor = QTextCursor(cursor) blockCursor.movePosition(QTextCursor.StartOfLine, QTextCursor.MoveAnchor) blockCursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor) length = cursor.selectionEnd() - cursor.selectionStart() occurrences.append(Occurence(line=cursor.blockNumber(), column=cursor.columnNumber() - length, length=length, position=cursor.position() - length, text=blockCursor.selectedText())) cursor = document.find(pattern, cursor.position(), flags) block = block.next() return occurrences
def on_log_received(self, data): time_info = datetime.fromtimestamp((data['time'] / 1000)).isoformat() log_message = '%s: %s : %s' % ( time_info, data['level'], data['message']) message_document = self.document() cursor_to_add = QTextCursor(message_document) cursor_to_add.movePosition(cursor_to_add.End) cursor_to_add.insertText(log_message + '\n') if data['level'] in COLORS: fmt = QTextCharFormat() fmt.setForeground(COLORS[data['level']]) cursor_to_add.movePosition(cursor_to_add.PreviousBlock) log_lvl_data = LogLevelData(log_levels[data['level'].upper()]) cursor_to_add.block().setUserData(log_lvl_data) cursor_to_add_fmt = message_document.find(data['level'], cursor_to_add.position()) cursor_to_add_fmt.mergeCharFormat(fmt) if log_levels[data['level']] > self.log_lvl: cursor_to_add.block().setVisible(False) self.ensureCursorVisible()
def insertLanguage(document, language): """Inserts a language command in the document. The command is inserted at the top or just below the version line. If the document uses LilyPond < 2.13.38, the \\include command is used, otherwise the newer \\language command. """ version = (documentinfo.info(document).version() or lilypondinfo.preferred().version()) if version and version < (2, 13, 38): text = '\\include "{0}.ly"' else: text = '\\language "{0}"' # insert language command on top of file, but below version block = document.firstBlock() c = QTextCursor(block) if '\\version' in tokeniter.tokens(block): c.movePosition(QTextCursor.EndOfBlock) text = '\n' + text else: text += '\n' c.insertText(text.format(language))
def indent_line(self, line_no, indent_length): block = self._get_block(line_no) cursor = QTextCursor(block) cursor.joinPreviousEditBlock() cursor.movePosition(QTextCursor.StartOfBlock, QTextCursor.MoveAnchor) if indent_length < 0: for i in range(-indent_length): cursor.deleteChar() else: cursor.insertText(" " * indent_length) if indent_length: cursor.movePosition(QTextCursor.StartOfBlock, QTextCursor.MoveAnchor) line = unicode(cursor.block().text()) if len(line) and line[0] == " ": cursor.movePosition(QTextCursor.NextWord, QTextCursor.MoveAnchor) self.editview.setTextCursor(cursor) cursor.endEditBlock()
def indent_line(self, line_no, indent_length): block = self._get_block(line_no) cursor = QTextCursor(block) cursor.joinPreviousEditBlock() cursor.movePosition(QTextCursor.StartOfBlock, QTextCursor.MoveAnchor) if indent_length < 0: for i in range(-indent_length): cursor.deleteChar() else: cursor.insertText(" " * indent_length) if indent_length: cursor.movePosition( QTextCursor.StartOfBlock, QTextCursor.MoveAnchor) line = unicode(cursor.block().text()) if len(line) and line[0] == " ": cursor.movePosition( QTextCursor.NextWord, QTextCursor.MoveAnchor) self.editview.setTextCursor(cursor) cursor.endEditBlock()
def write(self, data): cursor = QTextCursor(self.document()) cursor.movePosition(QTextCursor.End, QTextCursor.MoveAnchor) cursor.insertText(data) self.setTextCursor(cursor) self.ensureCursorVisible()
def loadMetadata(self, metaStream): sectionRE = QRegExp( u"\{\{(" + '|'.join ( ['PAGETABLE','CHARCENSUS','WORDCENSUS','BOOKMARKS', 'NOTES','GOODWORDS','BADWORDS','CURSOR','VERSION', 'STALECENSUS','NEEDSPELLCHECK','ENCODING', 'DOCHASH', 'MAINDICT'] ) \ + u")(.*)\}\}", Qt.CaseSensitive) metaVersion = 0 # base version while not metaStream.atEnd(): qline = metaStream.readLine().trimmed() if qline.isEmpty(): continue # allow blank lines between sections if sectionRE.exactMatch(qline): # section start section = sectionRE.cap(1) argument = unicode(sectionRE.cap(2).trimmed()) endsec = QString(u"{{/" + section + u"}}") if section == u"VERSION": if len(argument) != 0: metaVersion = int(argument) continue # no more data after {{VERSION x }} elif section == u"STALECENSUS": if argument == u"TRUE": IMC.staleCensus = IMC.staleCensusLoaded continue # no more data after {{STALECENSUS x}} elif section == u"NEEDSPELLCHECK": if argument == u"TRUE": IMC.needSpellCheck = True continue # no more data after {{NEEDSPELLCHECK x}} elif section == u"ENCODING": IMC.bookSaveEncoding = QString(argument) continue elif section == u"MAINDICT": IMC.bookMainDict = QString(argument) continue elif section == u"DOCHASH": IMC.metaHash = argument continue elif section == u"PAGETABLE": qline = metaStream.readLine() while (not qline.startsWith(endsec)) and ( not qline.isEmpty()): IMC.pageTable.metaStringIn(qline) qline = metaStream.readLine() continue elif section == u"CHARCENSUS": qline = metaStream.readLine() while (not qline.startsWith(endsec)) and ( not qline.isEmpty()): # can't just .split the char census, the first # char is the char being counted and it can be a space. str = unicode(qline) parts = str[2:].split(' ') IMC.charCensus.append(QString(str[0]), int(parts[0]), int(parts[1])) qline = metaStream.readLine() continue elif section == u"WORDCENSUS": qline = metaStream.readLine() while (not qline.startsWith(endsec)) and ( not qline.isEmpty()): parts = unicode(qline).split(' ') IMC.wordCensus.append(QString(parts[0]), int(parts[1]), int(parts[2])) qline = metaStream.readLine() continue elif section == u"BOOKMARKS": qline = metaStream.readLine() while (not qline.startsWith(endsec)) and ( not qline.isEmpty()): parts = unicode(qline).split(' ') tc = QTextCursor(self.document()) tc.setPosition(int(parts[1])) if len(parts ) == 3: # early versions didn't save anchor tc.movePosition(int(parts[2]), QTextCursor.KeepAnchor) self.bookMarkList[int(parts[0])] = tc qline = metaStream.readLine() continue elif section == u"NOTES": e = IMC.notesEditor e.setUndoRedoEnabled(False) qline = metaStream.readLine() while (not qline.startsWith(endsec) ) and not metaStream.atEnd(): if qline.startsWith(u"\xfffd"): # escaped {{ qline.remove(0, 1) e.appendPlainText(qline) qline = metaStream.readLine() e.setUndoRedoEnabled(True) continue elif section == u"GOODWORDS": # not going to bother checking for endsec return, # if it isn't that then we will shortly fail anyway w = IMC.goodWordList.load(metaStream, endsec) continue elif section == u"BADWORDS": w = IMC.badWordList.load(metaStream, endsec) continue elif section == u"CURSOR": # restore selection as of save p1p2 = argument.split(' ') tc = QTextCursor(self.document()) tc.setPosition(int(p1p2[0]), QTextCursor.MoveAnchor) tc.setPosition(int(p1p2[1]), QTextCursor.KeepAnchor) self.setTextCursor(tc) else: # this can't happen; section is text captured by the RE # and we have accounted for all possibilities raise AssertionError, "impossible metadata" else: # Non-blank line that doesn't match sectionRE? pqMsgs.infoMsg( "Unexpected line in metadata: {0}".format( pqMsgs.trunc(qline, 20)), "Metadata may be incomplete, suggest quit") break
def startCursor(self, in_active_area=True): c = QTextCursor(self.block) if in_active_area: c.movePosition( QTextCursor.Right, QTextCursor.MoveAnchor, self.active_area_start) return c
def _setBlockText(blockIndex, text): cursor = QTextCursor(self._doc.findBlockByNumber(blockIndex)) cursor.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor) cursor.insertText(text)
def get_tooltip(self, pos): cursor_pos = self.document().documentLayout().hitTest( QtCore.QPointF(pos), Qt.Qt.ExactHit) if cursor_pos == -1: return "", QRect() cursor = QTextCursor(self.document()) cursor.setPosition(cursor_pos) col = cursor.positionInBlock() line = cursor.blockNumber() tooltip = "" rect = QRect() if line >= len(self.highlighter.matches): return "", QRect() match_start = 0 match_len = 0 matches = 0 #for word in self.highlighter.matches[line]: #if col >= word[1] and col < word[2]: for word in self.words_at_pos(line, col): keyword = word[0] # Go for the smallest region possible so we can update # as soon as the mouse falls out of range of one of the words. if word[1] > match_start: match_start = word[1] if word[2] - word[1] < match_len: match_len = word[2] - word[1] if matches > 0: tooltip += u"\n" if not keyword.section == "": tooltip += u"【%s】 " % keyword.section tooltip += u"%s ― %s" % (keyword.word, keyword.meaning) matches += 1 # Highlight our word, so we can get the rect. cursor.movePosition(QTextCursor.Start) for i in range(line): cursor.movePosition(QTextCursor.NextBlock) for i in range(match_start): cursor.movePosition(QTextCursor.NextCharacter) for i in range(match_len): cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor) rect = self.cursorRect(cursor) return tooltip, rect