def load(self, keepUndo=False): """Loads the current url. Returns True if loading succeeded, False if an error occurred, and None when the current url is empty or non-local. Currently only local files are supported. If keepUndo is True, the loading can be undone (with Ctrl-Z). """ fileName = self.url().toLocalFile() if fileName: try: with open(fileName) as f: data = f.read() except (IOError, OSError): return False # errors are caught in MainWindow.openUrl() text = util.decode(data) if keepUndo: c = QTextCursor(self) c.select(QTextCursor.Document) c.insertText(text) else: self.setPlainText(text) self.setModified(False) self.loaded() app.documentLoaded(self) return True
def load(self, url=None, encoding=None, keepUndo=False): """Load the specified or current url (if None was specified). Currently only local files are supported. An IOError is raised when trying to load a nonlocal URL. If loading succeeds and an url was specified, the url is make the current url (by calling setUrl() internally). If keepUndo is True, the loading can be undone (with Ctrl-Z). """ if url is None: url = QUrl() u = url if not url.isEmpty() else self.url() text = self.load_data(u, encoding or self._encoding) if keepUndo: c = QTextCursor(self) c.select(QTextCursor.Document) c.insertText(text) else: self.setPlainText(text) self.setModified(False) if not url.isEmpty(): self.setUrl(url) self.loaded() app.documentLoaded(self)
def actionTriggered(self, name): # convert arpeggio_normal to arpeggioNormal, etc. name = _arpeggioTypes[name] cursor = self.mainwindow().textCursor() # which arpeggio type is last used? lastused = '\\arpeggioNormal' types = set(_arpeggioTypes.values()) block = cursor.block() while block.isValid(): s = types.intersection(tokeniter.tokens(block)) if s: lastused = s.pop() break block = block.previous() # where to insert c = lydocument.cursor(cursor) c.select_end_of_block() with cursortools.compress_undo(cursor): for item in ly.rhythm.music_items(c, partial=ly.document.OUTSIDE): c = QTextCursor(cursor.document()) c.setPosition(item.end) c.insertText('\\arpeggio') if name != lastused: cursortools.strip_indent(c) indent = c.block().text()[:c.position()-c.block().position()] c.insertText(name + '\n' + indent) # just pick the first place return
def append(self, text): """Append line to the end """ cursor = QTextCursor(self._doc) cursor.movePosition(QTextCursor.End) cursor.insertBlock() cursor.insertText(text)
def actionTriggered(self, name): # convert arpeggio_normal to arpeggioNormal, etc. name = _arpeggioTypes[name] cursor = self.mainwindow().textCursor() # which arpeggio type is last used? lastused = '\\arpeggioNormal' types = set(_arpeggioTypes.values()) block = cursor.block() while block.isValid(): s = types.intersection(tokeniter.tokens(block)) if s: lastused = s.pop() break block = block.previous() # where to insert c = lydocument.cursor(cursor) c.select_end_of_block() with cursortools.compress_undo(cursor): for item in ly.rhythm.music_items(c, partial=ly.document.OUTSIDE): c = QTextCursor(cursor.document()) c.setPosition(item.end) c.insertText('\\arpeggio') if name != lastused: cursortools.strip_indent(c) indent = c.block().text()[:c.position() - c.block().position()] c.insertText(name + '\n' + indent) # just pick the first place return
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 insert_snippet(text, cursor, variables): """Inserts a normal text snippet. After the insert, the cursor points to the end of the inserted snippet. If this function returns a cursor it must be set as the cursor for the view after the snippet has been inserted. """ exp_base = expand.Expander(cursor) evs = [] # make a list of events, either text or a constant for text, key in snippets.expand(text): if text: evs.append(text) if key == '$': evs.append('$') elif key: # basic variables func = getattr(exp_base, key, None) if func: evs.append(func()) selectionUsed = expand.SELECTION in evs # do the padding if 'selection: strip;' is used if selectionUsed and 'strip' in variables.get('selection', ''): space = '\n' if '\n' in cursor.selection().toPlainText() else ' ' # change whitespace in previous and next piece of text i = evs.index(expand.SELECTION) for j in range(i-1, -i, -1): if evs[j] not in expand.constants: evs[j] = evs[j].rstrip() + space break for j in range(i+1, len(evs)): if evs[j] not in expand.constants: evs[j] = space + evs[j].lstrip() break # now insert the text ins = QTextCursor(cursor) selectionUsed and ins.setPosition(cursor.selectionStart()) a, c = -1, -1 for e in evs: if e == expand.ANCHOR: a = ins.position() elif e == expand.CURSOR: c = ins.position() elif e == expand.SELECTION: ins.setPosition(cursor.selectionEnd()) else: ins.insertText(e) cursor.setPosition(ins.position()) # return a new cursor if requested if (a, c) != (-1, -1): new = QTextCursor(cursor) if a != -1: new.setPosition(a) if c != -1: new.setPosition(c, QTextCursor.KeepAnchor if a != -1 else QTextCursor.MoveAnchor) return new
def cut_assign(cursor): """Cuts selected text and assigns it to a LilyPond variable.""" # ask the variable name name = inputdialog.getText(None, _("Cut and Assign"), _( "Please enter the name for the variable to assign the selected " "text to:"), regexp="[A-Za-z]+") if not name: return cursortools.strip(cursor) # determine state at cursor block = cursortools.block(cursor) state = tokeniter.state(block) for t in tokeniter.partition(cursor).left: state.follow(t) mode = "" for p in state.parsers(): if isinstance(p, ly.lex.lilypond.ParseInputMode): if isinstance(p, ly.lex.lilypond.ParseLyricMode): mode = " \\lyricmode" elif isinstance(p, ly.lex.lilypond.ParseChordMode): mode = " \\chordmode" elif isinstance(p, ly.lex.lilypond.ParseFigureMode): mode = " \\figuremode" elif isinstance(p, ly.lex.lilypond.ParseDrumMode): mode = " \\drummode" break # find insertion place: found = False while block.previous().isValid(): block = block.previous() state = tokeniter.state(block) if isinstance(state.parser(), ly.lex.lilypond.ParseGlobal): found = True break tokens = tokeniter.tokens(block) for t in tokens: if isinstance(t, ly.lex.lilypond.Name): found = True break elif not isinstance(t, (ly.lex.Space, ly.lex.Comment)): break if found: break insert = QTextCursor(block) text = cursor.selection().toPlainText() space = '\n' if '\n' in text else ' ' text = ''.join((name, ' =', mode, ' {', space, text, space, '}\n\n')) with cursortools.editBlock(cursor): cursor.insertText('\\' + name) if metainfo.info(cursor.document()).autoindent: indent.insertText(insert, text) else: insert.insertText(text)
def put_some_text_in(self): c = QTextCursor(self.text.document()) c.insertText("sat") c.insertBlock() c.insertImage(self.load_an_image(), 'image') c.insertBlock() c.insertText("unsat") # Move back to head of document self.text.setTextCursor(QTextCursor(self.text.document()))
def _decorate(self, decoration): c = QTextCursor(self.block) spos = c.positionInBlock() if decoration.count(" ") == len(decoration): c.insertText(decoration) else: c.insertHtml(decoration) self.decorated = True self.decoration_len = c.positionInBlock()-spos self.active_area_start = self.decoration_len
def updateDesc(self): # get the selected dataset: serv = self.getSelectedService() desc = serv.desc name = serv.name # update the description: self.dlg.textEdit.clear() cursor = QTextCursor(self.dlg.textEdit.document()) cursor.insertText(name + "\n\n" + desc) self.dlg.textEdit.setReadOnly(True)
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 actionTriggered(self, name): cursor = self.mainwindow().textCursor() style = _glissandoStyles[name] c = lydocument.cursor(cursor) c.select_end_of_block() for item in ly.rhythm.music_items(c, partial=ly.document.OUTSIDE): c = QTextCursor(cursor.document()) c.setPosition(item.end) if style: text = "-\\tweak #'style #'{0} \\glissando".format(style) else: text = '\\glissando' c.insertText(text) return
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 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 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 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 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 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 hyphenate(self): """Hyphenates selected Lyrics text.""" view = self.mainwindow().currentView() cursor = view.textCursor() found = [] # find text to hyphenate if cursor.hasSelection(): source = tokeniter.Source.selection(cursor) else: source = tokeniter.Source.document(cursor) for token in source: if isinstance(token, ly.lex.lilypond.LyricText): # a word found for m in _word_re.finditer(token): found.append((source.cursor(token, m.start(), m.end()), m.group())) if not found and cursor.hasSelection(): # no tokens were found, then tokenize the text again as if in lyricmode start = cursor.selectionStart() state = ly.lex.State(ly.lex.lilypond.ParseLyricMode) for token in state.tokens(cursor.selection().toPlainText()): if isinstance(token, ly.lex.lilypond.LyricText): # a word found for m in _word_re.finditer(token): cur = QTextCursor(cursor) cur.setPosition(start + token.pos + m.start()) cur.setPosition(start + token.pos + m.end(), QTextCursor.KeepAnchor) found.append((cur, m.group())) if not found and cursor.hasSelection(): # still not succeeded, then try flat text for m in _word_re.finditer(cursor.selection().toPlainText()): cur = QTextCursor(cursor) cur.setPosition(start + m.start()) cur.setPosition(start + m.end(), QTextCursor.KeepAnchor) found.append((cur, m.group())) if found: import hyphendialog h = hyphendialog.HyphenDialog(self.mainwindow()).hyphenator() if h: with cursortools.editBlock(cursor): for cur, word in found: hyph_word = h.inserted(word, ' -- ') if word != hyph_word: cur.insertText(hyph_word)
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 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 toLowerCase(self): global reWord # the regex \b\w+\b tc = QTextCursor(self.textCursor()) if not tc.hasSelection() : return # no selection, nothing to do startpos = tc.selectionStart() endpos = tc.selectionEnd() qs = QString(tc.selectedText()) # copy of selected text i = reWord.indexIn(qs,0) # index of first word if any if i < 0 : return # no words in selection, exit while i >= 0: w = reWord.cap(0) # found word as QString n = w.size() # its length qs.replace(i,n,w.toLower()) # replace it with UC version i = reWord.indexIn(qs,i+n) # find next word if any # we have changed at least one word, replace selection with altered text tc.insertText(qs) # that wiped the selection, so restore it by "dragging" left to right tc.setPosition(startpos,QTextCursor.MoveAnchor) # click tc.setPosition(endpos,QTextCursor.KeepAnchor) # drag self.setTextCursor(tc)
def replaceText(self, pos, length, text): """Replace length symbols from ``pos`` with new text. If ``pos`` is an integer, it is interpreted as absolute position, if a tuple - as ``(line, column)`` """ if isinstance(pos, tuple): pos = self.mapToAbsPosition(*pos) endPos = pos + length if not self.document().findBlock(pos).isValid(): raise IndexError('Invalid start position %d' % pos) if not self.document().findBlock(endPos).isValid(): raise IndexError('Invalid end position %d' % endPos) cursor = QTextCursor(self.document()) cursor.setPosition(pos) cursor.setPosition(endPos, QTextCursor.KeepAnchor) cursor.insertText(text)
def set_indent(block, indent): """Sets the indent of block to tabs/spaces of length indent. Does not change the document if the indent does not need a change. Returns True if the indent was changed. """ # get some variables from the document indent_vars = indent_variables(block.document()) space = make_indent(indent, indent_vars['tab-width'], indent_vars['indent-tabs']) tokens = tokeniter.tokens(block) if tokens and isinstance(tokens[0], ly.lex.Space): changed = tokens[0] != space cursor = tokeniter.cursor(block, tokens[0]) else: changed = indent != 0 cursor = QTextCursor(block) if changed: cursor.insertText(space) return changed
def toLowerCase(self): global reWord # the regex \b\w+\b tc = QTextCursor(self.textCursor()) if not tc.hasSelection(): return # no selection, nothing to do startpos = tc.selectionStart() endpos = tc.selectionEnd() qs = QString(tc.selectedText()) # copy of selected text i = reWord.indexIn(qs, 0) # index of first word if any if i < 0: return # no words in selection, exit while i >= 0: w = reWord.cap(0) # found word as QString n = w.size() # its length qs.replace(i, n, w.toLower()) # replace it with UC version i = reWord.indexIn(qs, i + n) # find next word if any # we have changed at least one word, replace selection with altered text tc.insertText(qs) # that wiped the selection, so restore it by "dragging" left to right tc.setPosition(startpos, QTextCursor.MoveAnchor) # click tc.setPosition(endpos, QTextCursor.KeepAnchor) # drag self.setTextCursor(tc)
def __duplicate_line_or_selection(self, after_current_line=True): """Duplicate current line or selected text""" cursor = self.textCursor() cursor.beginEditBlock() start_pos, end_pos = self.__save_selection() if to_text_string(cursor.selectedText()): cursor.setPosition(end_pos) # Check if end_pos is at the start of a block: if so, starting # changes from the previous block cursor.movePosition(QTextCursor.StartOfBlock, QTextCursor.KeepAnchor) if not to_text_string(cursor.selectedText()): cursor.movePosition(QTextCursor.PreviousBlock) end_pos = cursor.position() cursor.setPosition(start_pos) cursor.movePosition(QTextCursor.StartOfBlock) while cursor.position() <= end_pos: cursor.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor) if cursor.atEnd(): cursor_temp = QTextCursor(cursor) cursor_temp.clearSelection() cursor_temp.insertText(self.get_line_separator()) break cursor.movePosition(QTextCursor.NextBlock, QTextCursor.KeepAnchor) text = cursor.selectedText() cursor.clearSelection() if not after_current_line: # Moving cursor before current line/selected text cursor.setPosition(start_pos) cursor.movePosition(QTextCursor.StartOfBlock) start_pos += len(text) end_pos += len(text) cursor.insertText(text) cursor.endEditBlock() self.setTextCursor(cursor) self.__restore_selection(start_pos, end_pos)
def insertMarkers(self): # Copy the text and if it is empty, complain and exit. qi = QString(self.insertText.text()) if qi.isEmpty() : pqMsgs.warningMsg("No insert text specified") return # See how many pages are involved: all the ones that aren't marked skip n = 0 for i in range(IMC.pageTable.size()): if IMC.pageTable.getAction(i) != IMC.FolioRuleSkip : n += 1 if n == 0 : # page table empty or all rows marked skip pqMsgs.warningMsg("No pages to give folios to") return m = "Insert this string at the top of {0} pages?".format(n) b = pqMsgs.okCancelMsg(QString(m),pqMsgs.trunc(qi,35)) if b : # Convert any '\n' in the text to the QT line delimiter char # we do this in the copy so the lineEdit text doesn't change qi.replace(QString(u'\\n'),QString(IMC.QtLineDelim)) # get a cursor on the edit document tc = QTextCursor(IMC.editWidget.textCursor()) tc.beginEditBlock() # start single undoable operation # Working from the end of the document backward, go to the # top of each page and insert the string for i in reversed( range( IMC.pageTable.size() ) ) : if IMC.pageTable.getAction(i) != IMC.FolioRuleSkip : # Note the page's start position and set our work cursor to it pos = IMC.pageTable.getCursor(i).position() tc.setPosition(pos) # Make a copy of the insert string replacing %f with this folio f = IMC.pageTable.getDisplay(i) qf = QString(qi) qf.replace(QString(u'%f'),f,Qt.CaseInsensitive) tc.insertText(qf) # The insertion goes in ahead of the saved cursor position so now # it points after the inserted string. Put it back where it was. IMC.pageTable.setPosition(i, pos) tc.endEditBlock() # wrap up the undo op
def insertMarkers(self): # Copy the text and if it is empty, complain and exit. qi = QString(self.insertText.text()) if qi.isEmpty(): pqMsgs.warningMsg("No insert text specified") return # See how many pages are involved: all the ones that aren't marked skip n = 0 for i in range(IMC.pageTable.size()): if IMC.pageTable.getAction(i) != IMC.FolioRuleSkip: n += 1 if n == 0: # page table empty or all rows marked skip pqMsgs.warningMsg("No pages to give folios to") return m = "Insert this string at the top of {0} pages?".format(n) b = pqMsgs.okCancelMsg(QString(m), pqMsgs.trunc(qi, 35)) if b: # Convert any '\n' in the text to the QT line delimiter char # we do this in the copy so the lineEdit text doesn't change qi.replace(QString(u'\\n'), QString(IMC.QtLineDelim)) # get a cursor on the edit document tc = QTextCursor(IMC.editWidget.textCursor()) tc.beginEditBlock() # start single undoable operation # Working from the end of the document backward, go to the # top of each page and insert the string for i in reversed(range(IMC.pageTable.size())): if IMC.pageTable.getAction(i) != IMC.FolioRuleSkip: # Note the page's start position and set our work cursor to it pos = IMC.pageTable.getCursor(i).position() tc.setPosition(pos) # Make a copy of the insert string replacing %f with this folio f = IMC.pageTable.getDisplay(i) qf = QString(qi) qf.replace(QString(u'%f'), f, Qt.CaseInsensitive) tc.insertText(qf) # The insertion goes in ahead of the saved cursor position so now # it points after the inserted string. Put it back where it was. IMC.pageTable.setPosition(i, pos) tc.endEditBlock() # wrap up the undo op
def setAppChangeLog(self, log): self._appChangeLog.clear() document = self._appChangeLog.document() document.setIndentWidth(20) cursor = QTextCursor(document) cursor.insertText("Changes:\n") listFormat = QTextListFormat() listFormat.setStyle(QTextListFormat.ListDisc) listFormat2 = QTextListFormat() listFormat2.setStyle(QTextListFormat.ListDisc) listFormat2.setIndent(2) for line in log: if line.startswith("*"): cursor.insertList(listFormat2) line = line[1:] else: cursor.insertList(listFormat) cursor.insertText(line) self.setChangelogVisible(True)
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 __replaceWithinDocument(self, document, occurrences, replacementPattern): """ Replaces given pattern occurrences in given document using given settings. :param document: Document. :type document: QTextDocument :param replacementPattern: Replacement pattern. :type replacementPattern: unicode :return: Replaced occurrences count. :rtype: int """ cursor = QTextCursor(document) cursor.beginEditBlock() offset = count = 0 for occurence in sorted(occurrences, key=lambda x: x.position): cursor.setPosition(offset + occurence.position, QTextCursor.MoveAnchor) cursor.setPosition(offset + occurence.position + occurence.length, QTextCursor.KeepAnchor) cursor.insertText(replacementPattern) offset += len(replacementPattern) - occurence.length count += 1 cursor.endEditBlock() return count
class LogWidget(QTextBrowser): def __init__(self, parent=None): QTextBrowser.__init__(self, parent) self.setFocusPolicy(Qt.NoFocus) self.setOpenLinks(False) self.setOpenExternalLinks(False) self.insertCursor = QTextCursor(self.document()) self.formats = textFormats() def checkScroll(self, func): """ Checks if we were scrolled to the bottom, calls func and then again makes sure to scroll to the bottom, if we were. """ sb = self.verticalScrollBar() # were we scrolled to the bottom? bottom = sb.value() == sb.maximum() func() # if yes, keep it that way. if bottom: sb.setValue(sb.maximum()) def write(self, text, format='log'): self.checkScroll(lambda: self.insertCursor.insertText(text, self.formats[format])) def writeMsg(self, text, format='msg'): # start on a new line if necessary if self.insertCursor.columnNumber() > 0: self.write('\n', format) self.write(text, format) def writeLine(self, text, format='msg'): self.writeMsg(text + '\n', format) def writeFileRef(self, text, path, line, column, tooltip=None, format='log'): self.write(text, format)
def printDocument2(self): dialog = QPrintDialog() if not dialog.exec_(): return self.printer = dialog.printer() headFormat = QTextBlockFormat() headFormat.setAlignment(Qt.AlignLeft) headFormat.setTextIndent(self.printer.pageRect().width() - 216) bodyFormat = QTextBlockFormat() bodyFormat.setAlignment(Qt.AlignJustify) lastParaBodyFormat = QTextBlockFormat(bodyFormat) lastParaBodyFormat.setPageBreakPolicy( QTextFormat.PageBreak_AlwaysAfter) rightBodyFormat = QTextBlockFormat() rightBodyFormat.setAlignment(Qt.AlignRight) headCharFormat = QTextCharFormat() headCharFormat.setFont(QFont("Helvetica", 10)) bodyCharFormat = QTextCharFormat() bodyCharFormat.setFont(QFont("Times", 11)) redBodyCharFormat = QTextCharFormat(bodyCharFormat) redBodyCharFormat.setForeground(Qt.red) tableFormat = QTextTableFormat() tableFormat.setBorder(1) tableFormat.setCellPadding(2) document = QTextDocument() cursor = QTextCursor(document) mainFrame = cursor.currentFrame() page = 1 cursor.insertBlock(headFormat, headCharFormat) for text in ("Greasy Hands Ltd.", "New Lombard Street", "London", "WC13", QDate.currentDate().toString(self.DATE_FORMAT)): cursor.insertBlock(headFormat, headCharFormat) cursor.insertText(text) cursor.insertBlock(bodyFormat, bodyCharFormat) cursor.insertText("Barrio Francisco Meza") cursor.insertBlock(bodyFormat) cursor.insertBlock(bodyFormat, bodyCharFormat) cursor.insertText("Dear Lyuis") cursor.insertBlock(bodyFormat) cursor.insertBlock(bodyFormat, bodyCharFormat) cursor.insertText( QString("The balance of your account is $ %L1.").arg( float(500.987), 0, "f", 2)) cursor.insertBlock(bodyFormat, redBodyCharFormat) cursor.insertText("Please remit the amount") cursor.insertBlock(bodyFormat, bodyCharFormat) cursor.insertText("Transaction") transactions = [(QDate.currentDate(), 500), (QDate.currentDate(), 500), (QDate.currentDate(), -500), (QDate.currentDate(), 500)] table = cursor.insertTable(len(transactions), 3, tableFormat) row = 0 for date, amount in transactions: cellCursor = table.cellAt(row, 0).firstCursorPosition() cellCursor.setBlockFormat(rightBodyFormat) cellCursor.insertText(date.toString(self.DATE_FORMAT), bodyCharFormat) cellCursor = table.cellAt(row, 1).firstCursorPosition() cellCursor.insertText("Credit", bodyCharFormat) cellCursor = table.cellAt(row, 2).firstCursorPosition() cellCursor.setBlockFormat(rightBodyFormat) cellCursor.insertText( QString("The balance of your account is $ %L1.").arg( float(amount), 0, "f", 2), redBodyCharFormat) row += 1 cursor.setPosition(mainFrame.lastPosition()) cursor.insertBlock(bodyFormat, bodyCharFormat) cursor.insertText("We hope") document.print_(self.printer)
def write(self, data): cursor = QTextCursor(self.document()) cursor.movePosition(QTextCursor.End, QTextCursor.MoveAnchor) cursor.insertText(data) self.setTextCursor(cursor) self.ensureCursorVisible()
def printDocument2(self): dialog = QPrintDialog() if not dialog.exec_(): return self.printer = dialog.printer() headFormat = QTextBlockFormat() headFormat.setAlignment(Qt.AlignLeft) headFormat.setTextIndent( self.printer.pageRect().width()-216) bodyFormat = QTextBlockFormat() bodyFormat.setAlignment(Qt.AlignJustify) lastParaBodyFormat = QTextBlockFormat(bodyFormat) lastParaBodyFormat.setPageBreakPolicy(QTextFormat.PageBreak_AlwaysAfter) rightBodyFormat = QTextBlockFormat() rightBodyFormat.setAlignment(Qt.AlignRight) headCharFormat = QTextCharFormat() headCharFormat.setFont(QFont("Helvetica",10)) bodyCharFormat = QTextCharFormat() bodyCharFormat.setFont(QFont("Times",11)) redBodyCharFormat = QTextCharFormat(bodyCharFormat) redBodyCharFormat.setForeground(Qt.red) tableFormat = QTextTableFormat() tableFormat.setBorder(1) tableFormat.setCellPadding(2) document = QTextDocument() cursor = QTextCursor(document) mainFrame = cursor.currentFrame() page = 1 cursor.insertBlock(headFormat, headCharFormat) for text in ("Greasy Hands Ltd.", "New Lombard Street","London" , "WC13", QDate.currentDate().toString(self.DATE_FORMAT)): cursor.insertBlock(headFormat,headCharFormat) cursor.insertText(text) cursor.insertBlock(bodyFormat,bodyCharFormat) cursor.insertText("Barrio Francisco Meza") cursor.insertBlock(bodyFormat) cursor.insertBlock(bodyFormat,bodyCharFormat) cursor.insertText("Dear Lyuis") cursor.insertBlock(bodyFormat) cursor.insertBlock(bodyFormat,bodyCharFormat) cursor.insertText(QString("The balance of your account is $ %L1.").arg(float(500.987),0,"f",2)) cursor.insertBlock(bodyFormat,redBodyCharFormat) cursor.insertText("Please remit the amount") cursor.insertBlock(bodyFormat,bodyCharFormat) cursor.insertText("Transaction") transactions = [ (QDate.currentDate(),500), (QDate.currentDate(),500), (QDate.currentDate(),-500), (QDate.currentDate(),500) ] table = cursor.insertTable(len(transactions), 3, tableFormat) row = 0 for date, amount in transactions: cellCursor = table.cellAt(row,0).firstCursorPosition() cellCursor.setBlockFormat(rightBodyFormat) cellCursor.insertText(date.toString(self.DATE_FORMAT),bodyCharFormat) cellCursor = table.cellAt(row,1).firstCursorPosition() cellCursor.insertText("Credit",bodyCharFormat) cellCursor = table.cellAt(row,2).firstCursorPosition() cellCursor.setBlockFormat(rightBodyFormat) cellCursor.insertText(QString("The balance of your account is $ %L1.").arg(float(amount),0,"f",2),redBodyCharFormat) row += 1 cursor.setPosition(mainFrame.lastPosition()) cursor.insertBlock(bodyFormat,bodyCharFormat) cursor.insertText("We hope") document.print_(self.printer)
def cut_assign(cursor): """Cuts selected text and assigns it to a LilyPond variable.""" # ask the variable name name = inputdialog.getText( None, _("Cut and Assign"), _("Please enter the name for the variable to assign the selected " "text to:"), regexp="[A-Za-z]+") if not name: return cursortools.strip_selection(cursor) # determine state at cursor block = cursortools.block(cursor) state = tokeniter.state(block) for t in tokeniter.partition(cursor).left: state.follow(t) mode = "" for p in state.parsers(): if isinstance(p, ly.lex.lilypond.ParseInputMode): if isinstance(p, ly.lex.lilypond.ParseLyricMode): mode = " \\lyricmode" elif isinstance(p, ly.lex.lilypond.ParseChordMode): mode = " \\chordmode" elif isinstance(p, ly.lex.lilypond.ParseFigureMode): mode = " \\figuremode" elif isinstance(p, ly.lex.lilypond.ParseDrumMode): mode = " \\drummode" break # find insertion place: found = False while block.previous().isValid(): block = block.previous() state = tokeniter.state(block) if isinstance(state.parser(), ly.lex.lilypond.ParseGlobal): found = True break tokens = tokeniter.tokens(block) for t in tokens: if isinstance(t, ly.lex.lilypond.Name): found = True break elif not isinstance(t, (ly.lex.Space, ly.lex.Comment)): break if found: break insert = QTextCursor(block) text = cursor.selection().toPlainText() space = '\n' if '\n' in text else ' ' text = ''.join((name, ' =', mode, ' {', space, text, space, '}\n\n')) with cursortools.compress_undo(cursor): cursor.insertText('\\' + name) pos = insert.selectionStart() insert.insertText(text) if metainfo.info(cursor.document()).auto_indent: insert.setPosition(pos, QTextCursor.KeepAnchor) with cursortools.compress_undo(insert, True): indent.re_indent(insert)
def _setBlockText(blockIndex, text): cursor = QTextCursor(self._doc.findBlockByNumber(blockIndex)) cursor.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor) cursor.insertText(text)
class Log(QTextBrowser): """Widget displaying output from a Job.""" def __init__(self, parent=None): super(Log, self).__init__(parent) self.setOpenLinks(False) self.cursor = QTextCursor(self.document()) self._types = job.ALL self._lasttype = None self._formats = self.logformats() def setMessageTypes(self, types): """Set the types of Job output to display. types is a constant bitmask from job, like job.STDOUT etc. By default job.ALL is used. """ self._types = types def messageTypes(self): """Return the set message types (job.ALL by default).""" return self._types def connectJob(self, job): """Gives us the output from the Job (past and upcoming).""" for msg, type in job.history(): self.write(msg, type) job.output.connect(self.write) def textFormat(self, type): """Returns a QTextFormat() for the given type.""" return self._formats[type] def write(self, message, type): """Writes the given message with the given type to the log. The keepScrolledDown context manager is used to scroll the log further down if it was scrolled down at that moment. If two messages of a different type are written after each other a newline is inserted if otherwise the message would continue on the same line. """ if type & self._types: with self.keepScrolledDown(): changed = type != self._lasttype self._lasttype = type if changed and self.cursor.block().text() and not message.startswith('\n'): self.cursor.insertText('\n') self.writeMessage(message, type) def writeMessage(self, message, type): """Inserts the given message in the text with the textformat belonging to type.""" self.cursor.insertText(message, self.textFormat(type)) @contextlib.contextmanager def keepScrolledDown(self): """Performs a function, ensuring the log stays scrolled down if it was scrolled down on start.""" vbar = self.verticalScrollBar() scrolleddown = vbar.value() == vbar.maximum() try: yield finally: if scrolleddown: vbar.setValue(vbar.maximum()) def logformats(self): """Returns a dictionary with QTextCharFormats for the different types of messages. Besides the STDOUT, STDERR, NEUTRAL, FAILURE and SUCCESS formats there is also a "link" format, that looks basically the same as the output formats, but blueish and underlined, to make parts of the output (e.g. filenames) look clickable. """ textColor = QApplication.palette().color(QPalette.WindowText) successColor = qutil.addcolor(textColor, 0, 128, 0) # more green failureColor = qutil.addcolor(textColor, 128, 0, 0) # more red linkColor = qutil.addcolor(textColor, 0, 0, 128) # more blue stdoutColor = qutil.addcolor(textColor, 64, 64, 0) # more purple s = QSettings() s.beginGroup("log") outputFont = QFont(s.value("fontfamily", "monospace", type(""))) outputFont.setPointSizeF(s.value("fontsize", 9.0, float)) output = QTextCharFormat() output.setFont(outputFont) # enable zooming the log font size output.setProperty(QTextFormat.FontSizeAdjustment, 0) stdout = QTextCharFormat(output) stdout.setForeground(stdoutColor) stderr = QTextCharFormat(output) link = QTextCharFormat(output) link.setForeground(linkColor) link.setFontUnderline(True) status = QTextCharFormat() status.setFontWeight(QFont.Bold) neutral = QTextCharFormat(status) success = QTextCharFormat(status) success.setForeground(successColor) failure = QTextCharFormat(status) failure.setForeground(failureColor) return { job.STDOUT: stdout, job.STDERR: stderr, job.NEUTRAL: neutral, job.SUCCESS: success, job.FAILURE: failure, 'link': link, }