def find_multiline_pattern(self, regexp, cursor, findflag): """Reimplement QTextDocument's find method Add support for *multiline* regular expressions""" pattern = to_text_string(regexp.pattern()) text = to_text_string(self.toPlainText()) try: regobj = re.compile(pattern) except sre_constants.error: return if findflag & QTextDocument.FindBackward: # Find backward offset = min([cursor.selectionEnd(), cursor.selectionStart()]) text = text[:offset] matches = [_m for _m in regobj.finditer(text, 0, offset)] if matches: match = matches[-1] else: return else: # Find forward offset = max([cursor.selectionEnd(), cursor.selectionStart()]) match = regobj.search(text, offset) if match: pos1, pos2 = match.span() fcursor = self.textCursor() fcursor.setPosition(pos1) fcursor.setPosition(pos2, QTextCursor.KeepAnchor) return fcursor
def replace(self, text, pattern=None): """Replace selected text by *text* If *pattern* is not None, replacing selected text using regular expression text substitution""" cursor = self.textCursor() cursor.beginEditBlock() if pattern is not None: seltxt = to_text_string(cursor.selectedText()) cursor.removeSelectedText() if pattern is not None: text = re.sub(to_text_string(pattern), to_text_string(text), to_text_string(seltxt)) cursor.insertText(text) cursor.endEditBlock()
def get_current_word(self): """Return current word, i.e. word at cursor position""" cursor = self.textCursor() if cursor.hasSelection(): # Removes the selection and moves the cursor to the left side # of the selection: this is required to be able to properly # select the whole word under cursor (otherwise, the same word is # not selected when the cursor is at the right side of it): cursor.setPosition(min([cursor.selectionStart(), cursor.selectionEnd()])) else: # Checks if the first character to the right is a white space # and if not, moves the cursor one word to the left (otherwise, # if the character to the left do not match the "word regexp" # (see below), the word to the left of the cursor won't be # selected), but only if the first character to the left is not a # white space too. def is_space(move): curs = self.textCursor() curs.movePosition(move, QTextCursor.KeepAnchor) return not to_text_string(curs.selectedText()).strip() if is_space(QTextCursor.NextCharacter): if is_space(QTextCursor.PreviousCharacter): return cursor.movePosition(QTextCursor.WordLeft) cursor.select(QTextCursor.WordUnderCursor) text = to_text_string(cursor.selectedText()) # find a valid python variable name match = re.findall(r'([^\d\W]\w*)', text, re.UNICODE) if match: return match[0]
def show(self, dialog): """Generic method to show a non-modal dialog and keep reference to the Qt C++ object""" for dlg in list(self.dialogs.values()): if to_text_string(dlg.windowTitle()) \ == to_text_string(dialog.windowTitle()): dlg.show() dlg.raise_() break else: dialog.show() self.dialogs[id(dialog)] = dialog dialog.accepted.connect( lambda eid=id(dialog): self.dialog_finished(eid)) dialog.rejected.connect( lambda eid=id(dialog): self.dialog_finished(eid))
def get_selected_text(self): """ Return text selected by current text cursor, converted in unicode Replace the unicode line separator character \u2029 by the line separator characters returned by get_line_separator """ return to_text_string(self.textCursor().selectedText()).replace(u"\u2029", self.get_line_separator())
def get_text_line(self, line_nb): """Return text line at line number *line_nb*""" # Taking into account the case when a file ends in an empty line, # since splitlines doesn't return that line as the last element # TODO: Make this function more efficient try: return to_text_string(self.toPlainText()).splitlines()[line_nb] except IndexError: return self.get_line_separator()
def mimedata2url(source, extlist=None): """ Extract url list from MIME data extlist: for example ('.py', '.pyw') """ pathlist = [] if source.hasUrls(): for url in source.urls(): path = _process_mime_path(to_text_string(url.toString()), extlist) if path is not None: pathlist.append(path) elif source.hasText(): for rawpath in to_text_string(source.text()).splitlines(): path = _process_mime_path(rawpath, extlist) if path is not None: pathlist.append(path) if pathlist: return pathlist
def get_text_with_eol(self): """Same as 'toPlainText', replace '\n' by correct end-of-line characters""" utext = to_text_string(self.toPlainText()) lines = utext.splitlines() linesep = self.get_line_separator() txt = linesep.join(lines) if utext.endswith('\n'): txt += linesep return txt
def set_eol_chars(self, text): """Set widget end-of-line (EOL) characters from text (analyzes text)""" if not is_text_string(text): # testing for QString (PyQt API#1) text = to_text_string(text) eol_chars = get_eol_chars(text) is_document_modified = eol_chars is not None and self.eol_chars is not None self.eol_chars = eol_chars if is_document_modified: self.document().setModified(True) if self.sig_eol_chars_changed is not None: self.sig_eol_chars_changed.emit(eol_chars)
def get_character(self, position, offset=0): """Return character at *position* with the given offset.""" position = self.get_position(position) + offset cursor = self.textCursor() cursor.movePosition(QTextCursor.End) if position < cursor.position(): cursor.setPosition(position) cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor) return to_text_string(cursor.selectedText()) else: return ''
def _get_encoding(self): """Return the encoding/codepage to use.""" enco = 'utf-8' # Currently only cp1252 is allowed? if WIN: import ctypes codepage = to_text_string(ctypes.cdll.kernel32.GetACP()) # import locale # locale.getpreferredencoding() # Differences? enco = 'cp' + codepage return enco
def get_text(self, position_from, position_to): """ Return text between *position_from* and *position_to* Positions may be positions or 'sol', 'eol', 'sof', 'eof' or 'cursor' """ cursor = self.__select_text(position_from, position_to) text = to_text_string(cursor.selectedText()) all_text = position_from == 'sof' and position_to == 'eof' if text and not all_text: while text.endswith("\n"): text = text[:-1] while text.endswith(u"\u2029"): text = text[:-1] return text
def has_selected_text(self): """Returns True if some text is selected""" return bool(to_text_string(self.textCursor().selectedText()))
def get_block_indentation(self, block_nb): """Return line indentation (character number)""" text = to_text_string(self.document().findBlockByNumber(block_nb).text()) text = text.replace("\t", " "*self.tab_stop_width_spaces) return len(text)-len(text.lstrip())
def get_word_at(self, coordinates): """Return word at *coordinates* (QPoint)""" cursor = self.cursorForPosition(coordinates) cursor.select(QTextCursor.WordUnderCursor) return to_text_string(cursor.selectedText())
def get_line_at(self, coordinates): """Return line at *coordinates* (QPoint)""" cursor = self.cursorForPosition(coordinates) cursor.select(QTextCursor.BlockUnderCursor) return to_text_string(cursor.selectedText()).replace(u'\u2029', '')
def get_current_line(self): """Return current line's text""" cursor = self.textCursor() cursor.select(QTextCursor.BlockUnderCursor) return to_text_string(cursor.selectedText())
return fcursor def find_text(self, text, changed=True, forward=True, case=False, words=False, regexp=False): """Find text""" cursor = self.textCursor() findflag = QTextDocument.FindFlag() if not forward: findflag = findflag | QTextDocument.FindBackward if case: findflag = findflag | QTextDocument.FindCaseSensitively moves = [QTextCursor.NoMove] if forward: moves += [QTextCursor.NextWord, QTextCursor.Start] if changed: if to_text_string(cursor.selectedText()): new_position = min([cursor.selectionStart(), cursor.selectionEnd()]) cursor.setPosition(new_position) else: cursor.movePosition(QTextCursor.PreviousWord) else: moves += [QTextCursor.End] if not regexp: text = re.escape(to_text_string(text)) # if QT55_VERSION: pattern = QRegularExpression(r"\b{}\b".format(text) if words else text) if case: pattern.setPatternOptions( QRegularExpression.CaseInsensitiveOption)
def is_space(move): curs = self.textCursor() curs.movePosition(move, QTextCursor.KeepAnchor) return not to_text_string(curs.selectedText()).strip()
def handle_qbytearray(obj, encoding): """Qt/Python2/3 compatibility helper.""" if isinstance(obj, QByteArray): obj = obj.data() return to_text_string(obj, encoding=encoding)