예제 #1
0
def apply_smart_comment(editor, opening='/*', closing='*/', line_comment=None):
    doc = editor.document()
    c = QTextCursor(editor.textCursor())
    c.clearSelection()
    before_opening = doc.find(
        opening, c, QTextDocument.FindFlag.FindBackward
        | QTextDocument.FindFlag.FindCaseSensitively)
    before_closing = doc.find(
        closing, c, QTextDocument.FindFlag.FindBackward
        | QTextDocument.FindFlag.FindCaseSensitively)
    after_opening = doc.find(opening, c,
                             QTextDocument.FindFlag.FindCaseSensitively)
    after_closing = doc.find(closing, c,
                             QTextDocument.FindFlag.FindCaseSensitively)
    in_block_comment = (not before_opening.isNull() and (before_closing.isNull() or before_opening.position() >= before_closing.position())) and \
        (not after_closing.isNull() and (after_opening.isNull() or after_closing.position() <= after_opening.position()))
    if in_block_comment:
        before_opening.removeSelectedText(), after_closing.removeSelectedText()
        return
    c = QTextCursor(editor.textCursor())
    left, right = min(c.position(), c.anchor()), max(c.position(), c.anchor())
    c.beginEditBlock()
    c.setPosition(right), c.insertText(closing)
    c.setPosition(left), c.insertText(opening)
    c.endEditBlock()
예제 #2
0
 def search(self, query, reverse=False):
     ''' Search for query, also searching the headers. Matches in headers
     are not highlighted as managing the highlight is too much of a pain.'''
     if not query.strip():
         return
     c = self.textCursor()
     lnum = c.block().blockNumber()
     cpos = c.positionInBlock()
     headers = dict(self.headers)
     if lnum in headers:
         cpos = self.search_header_pos
     lines = unicode_type(self.toPlainText()).splitlines()
     for hn, text in self.headers:
         lines[hn] = text
     prefix, postfix = lines[lnum][:cpos], lines[lnum][cpos:]
     before, after = enumerate(lines[0:lnum]), ((lnum+1+i, x) for i, x in enumerate(lines[lnum+1:]))
     if reverse:
         sl = chain([(lnum, prefix)], reversed(tuple(before)), reversed(tuple(after)), [(lnum, postfix)])
     else:
         sl = chain([(lnum, postfix)], after, before, [(lnum, prefix)])
     flags = regex.REVERSE if reverse else 0
     pat = regex.compile(regex.escape(query, special_only=True), flags=regex.UNICODE|regex.IGNORECASE|flags)
     for num, text in sl:
         try:
             m = next(pat.finditer(text))
         except StopIteration:
             continue
         start, end = m.span()
         length = end - start
         if text is postfix:
             start += cpos
         c = QTextCursor(self.document().findBlockByNumber(num))
         c.setPosition(c.position() + start)
         if num in headers:
             self.search_header_pos = start + length
         else:
             c.setPosition(c.position() + length, QTextCursor.MoveMode.KeepAnchor)
             self.search_header_pos = 0
         if reverse:
             pos, anchor = c.position(), c.anchor()
             c.setPosition(pos), c.setPosition(anchor, QTextCursor.MoveMode.KeepAnchor)
         self.setTextCursor(c)
         self.centerCursor()
         self.scrolled.emit()
         break
     else:
         info_dialog(self, _('No matches found'), _(
             'No matches found for query: %s' % query), show=True)
예제 #3
0
    def find_text(self, pat, cursor, reverse):
        from calibre.gui2.tweak_book.text_search import find_text_in_chunks
        chunks = []

        cstart = min(cursor.position(), cursor.anchor())
        cend = max(cursor.position(), cursor.anchor())
        if reverse:
            cend -= 1
        c = QTextCursor(cursor)
        c.setPosition(cstart)
        block = c.block()
        in_text = find_tag_definition(block, 0)[0] is None
        if in_text:
            # Check if we are in comment/PI/etc.
            pb = block.previous()
            while pb.isValid():
                boundaries = pb.userData().non_tag_structures
                if boundaries:
                    if boundaries[-1].is_start:
                        in_text = False
                    break
                pb = pb.previous()

        def append(text, start):
            text = text.replace(PARAGRAPH_SEPARATOR, '\n')
            after = start + len(text)
            if start <= cend and cstart < after:
                extra = after - (cend + 1)
                if extra > 0:
                    text = text[:-extra]
                extra = cstart - start
                if extra > 0:
                    text = text[extra:]
                chunks.append((text, start + max(extra, 0)))

        while block.isValid() and block.position() <= cend:
            ud = block.userData()
            boundaries = sorted(chain(ud.tags, ud.non_tag_structures),
                                key=get_offset)
            if not boundaries:
                # Add the whole line
                if in_text:
                    text = block.text() + '\n'
                    append(text, block.position())
            else:
                start = block.position()
                c.setPosition(start)
                for b in boundaries:
                    if in_text:
                        c.setPosition(start + b.offset,
                                      QTextCursor.MoveMode.KeepAnchor)
                        if c.hasSelection():
                            append(c.selectedText(), c.anchor())
                    in_text = not b.is_start
                    c.setPosition(start + b.offset + 1)
                if in_text:
                    # Add remaining text in block
                    c.setPosition(block.position() + boundaries[-1].offset + 1)
                    c.movePosition(QTextCursor.MoveOperation.EndOfBlock,
                                   QTextCursor.MoveMode.KeepAnchor)
                    if c.hasSelection():
                        append(c.selectedText() + '\n', c.anchor())
            block = block.next()
        s, e = find_text_in_chunks(pat, chunks)
        return s != -1 and e != -1, s, e