Ejemplo n.º 1
0
    def get_words(self):
        if self._words is not None:
            return self._words, False

        # Add path
        self._words = set()
        if self.status == 'rename':
            for path in self.path:
                self._words.add(path)
                self._words.add(os.path.split(path)[-1])
        else:
            self._words.add(self.path)
            self._words.add(os.path.split(self.path)[-1])

        if self.status == 'modify text':
            ext = file_extension(self.path)
            builder = get_wordlist_builder(ext)
            if builder is not None:
                try:
                    self._words.update(
                        builder.iter_words(StringIO("".join(self.work_lines))))
                    return self._words, True
                except EnvironmentError:
                    pass

        return self._words, False
Ejemplo n.º 2
0
 def test_file_extension(self):
     self.assertEqual('', util.file_extension(''))
     self.assertEqual('', util.file_extension('/foo/bar.x/'))
     self.assertEqual('', util.file_extension('C:/foo/bar.x/'))
     self.assertEqual('', util.file_extension('.bzrignore'))
     self.assertEqual('', util.file_extension('/foo/bar.x/.bzrignore'))
     self.assertEqual('.txt', util.file_extension('foo.txt'))
     self.assertEqual('.txt', util.file_extension('/foo/bar.x/foo.txt'))
Ejemplo n.º 3
0
 def _pattern_for_action(self, filename, action):
     if action == ACTION_NONE:
         return ''
     elif action == ACTION_BY_EXT:
         ext = file_extension(filename)
         if ext:
             return '*' + ext
         else:
             return 'RE:\\.?[^.]+'
     elif action == ACTION_BY_EXT_CASE_INSENSITIVE:
         ext = file_extension(filename)
         if ext:
             return 'RE:(?i).*\\' + ext.lower()
         else:
             return 'RE:\\.?[^.]+'
     elif action == ACTION_BY_BASENAME:
         return os.path.basename(filename)
     elif action == ACTION_BY_FULLNAME:
         return './' + filename
Ejemplo n.º 4
0
 def load(self):
     self.set_title([gettext("Ignore"), self.wt.basedir])
     items = []
     for i in self.wt.unknowns():
         item = QtWidgets.QTreeWidgetItem()
         item.setText(0, i)
         item.setText(1, file_extension(i))
         item.setData(0, QtCore.Qt.UserRole, i)
         item.setData(2, QtCore.Qt.UserRole, ACTION_NONE)
         items.append(item)
         self.unknowns[i] = item
     self.unknowns_list.clear()
     self.unknowns_list.addTopLevelItems(items)
Ejemplo n.º 5
0
 def detect_content_type(self, relpath, text, kind='file'):
     """Return (file_type, viewer_factory) based on kind, text and relpath.
     Supported file types: text, image, binary
     """
     if kind == 'file':
         if not b'\0' in text:
             return 'text file', self._create_text_view
         else:
             ext = file_extension(relpath).lower()
             image_exts = [
                 '.' + str(i)
                 for i in QtGui.QImageReader.supportedImageFormats()
             ]
             if ext in image_exts:
                 return 'image file', self._create_image_view
             else:
                 return 'binary file', self._create_hexdump_view
     else:
         return kind, self._create_symlink_view
Ejemplo n.º 6
0
    def update_compleater_words(self):
        if self.is_loading:
            return

        num_files_loaded = 0

        words = set()
        for ref in self.filelist_widget.tree_model.iter_checked():
            path = ref.path
            if path not in self.file_words:
                file_words = set()
                if num_files_loaded < MAX_AUTOCOMPLETE_FILES:
                    file_words.add(path)
                    file_words.add(os.path.split(path)[-1])
                    change = self.filelist_widget.tree_model.inventory_data_by_path[
                        ref.path].change
                    if change and change.is_renamed():
                        file_words.add(change.oldpath())
                        file_words.add(os.path.split(change.oldpath())[-1])
                    #if num_versioned_files < MAX_AUTOCOMPLETE_FILES:
                    ext = file_extension(path)
                    builder = get_wordlist_builder(ext)
                    if builder is not None:
                        try:
                            abspath = os.path.join(self.tree.basedir, path)
                            file = open(abspath, 'rt')
                            file_words.update(builder.iter_words(file))
                            self.processEvents()
                        except EnvironmentError:
                            pass
                    self.file_words[path] = file_words
                    num_files_loaded += 1
            else:
                file_words = self.file_words[path]
            words.update(file_words)
        words = list(words)
        words.sort(key=lambda x: x.lower())
        self.completer_model.setStringList(words)
Ejemplo n.º 7
0
    def append_diff(self, paths, file_id, kind, status, dates,
                    present, binary, lines, groups, data, properties_changed):
        cursors = self.cursors

        guidebar_data = self.guidebar_data

        for i in range(2):
            cursor = cursors[i]
            guidebar_data[i]['title'].append((cursor.block().blockNumber(), 2))
            cursor.beginEditBlock()
            cursor.insertText(paths[i] or " ", self.titleFormat)    # None or " " => " "
            cursor.insertBlock()
            if present[i]:
                cursor.insertText(self.lastModifiedLabel, self.metadataLabelFormat)
                cursor.insertText(" %s, " % format_timestamp(dates[i]), self.metadataFormat)
                cursor.insertText(self.statusLabel, self.metadataLabelFormat)
                cursor.insertText(" %s, " % gettext(status), self.metadataFormat)
                cursor.insertText(self.kindLabel, self.metadataLabelFormat)
                cursor.insertText(" %s" % gettext(kind[i]), self.metadataFormat)
                if properties_changed:
                    cursor.insertText(", ", self.metadataFormat)
                    cursor.insertText(self.propertiesLabel, self.metadataLabelFormat)
                    cursor.insertText(" ", self.metadataFormat)
                    cursor.insertText(", ".join([p[i] for p in properties_changed]), self.metadataFormat)
            else:
                cursor.insertText(" ", self.metadataFormat)
            cursor.insertBlock()

        infoBlocks = (cursors[0].block().layout(),
                      cursors[1].block().layout())
        changes = []

        if not binary:
            for cursor in cursors:
                cursor.setCharFormat(self.monospacedFormat)
                cursor.insertBlock()

            def fix_last_line(lines):
                """Fix last line if there is no new line.

                @param  lines:  list of lines
                @return:    original lines if lastline is OK,
                            or new list with fixed last line.
                """
                if lines:
                    last = lines[-1]
                    if last and last[-1] not in ('\r', '\n'):
                        lines = lines[:-1] + [last+'\n']
                return lines

            lines = [fix_last_line(l) for l in lines]
            if have_pygments:
                use_pygments = True
                try:
                    def getTokens(p, d, path):
                        if not p:
                            return []
                        lexer = get_lexer_for_filename(path, stripnl=False)
                        tokens = []
                        for token in split_tokens_at_lines(lex(d, lexer)):
                            tokens.append(token)
                            if len(token) % 100 == 0:
                                QtCore.QCoreApplication.processEvents()
                        return tokens

                    display_lines = [getTokens(p, d, path)
                                     for p, d, path in zip(present,
                                                           data,
                                                           paths)]
                except ClassNotFound:
                    use_pygments = False
                    display_lines = lines
            else:
                use_pygments = False
                display_lines = lines

            def insertLine(cursor, line):
                if use_pygments:
                    for ttype, value in line:
                        format = self.ttype_formater.format(ttype)
                        modifyFormatForTag(format, "equal")
                        cursor.insertText(value, format)
                else:
                    cursor.insertText(line)

            def insertIxs(ixs):
                for cursor, line, ix in zip(cursors, display_lines, ixs):
                    for l in line[ix[0]:ix[1]]:
                        insertLine(cursor, l)

            def modifyFormatForTag (format, tag):
                if tag == "replace":
                    format.setBackground(interline_changes_background)
                elif tag == "equal":
                    format.setBackground(self.background)
                elif self.show_intergroup_colors:
                    format.setBackground(brushes[tag][0])
                else:
                    format.setBackground(interline_changes_background)

            split_words = re.compile(r"\w+|\n\r|\r\n|\W")
            def insertIxsWithChangesHighlighted(ixs):
                texts = ["".join(l[ix[0]:ix[1]]) for l, ix in zip(lines, ixs)]
                if use_pygments:
                    # This is what the pygments lexer does, so we need to do the
                    # same incase we have \r\n line endings.
                    texts = ["\n".join(t.splitlines()) for t in texts]

                texts = [split_words.findall(t) for t in texts]

                if use_pygments:
                    groups = ([], [])
                    for tag, i0, i1, j0, j1 in SequenceMatcher(None,
                                                                tuple(texts[0]),
                                                                tuple(texts[1]),
                                                                ).get_opcodes():
                        groups[0].append((tag, len("".join(texts[0][i0:i1]))))
                        groups[1].append((tag, len("".join(texts[1][j0:j1]))))
                    for cursor, ls, ix, g in zip(cursors, display_lines, ixs, groups):
                        tag, n = g.pop(0)
                        for l in ls[ix[0]:ix[1]]:
                            for ttype, value in l:
                                while value:
                                    format = self.ttype_formater.format(ttype)
                                    modifyFormatForTag(format, tag)
                                    t = value[0:n]
                                    cursor.insertText(t, format)
                                    value = value[len(t):]
                                    n -= len(t)
                                    if n<=0:
                                        if g:
                                            tag, n = g.pop(0)
                                        else:
                                            # why would this happen?????
                                            tag = 'equal'
                                            n = len(value)
                else:
                    for tag, i0, i1, j0, j1 in SequenceMatcher(None,
                                                               tuple(texts[0]),
                                                               tuple(texts[1]),
                                                               ).get_opcodes():
                        format = QtGui.QTextCharFormat()
                        format.setFont(self.monospacedFont)
                        modifyFormatForTag(format, tag)

                        cursors[0].insertText("".join(texts[0][i0:i1]),format)
                        cursors[1].insertText("".join(texts[1][j0:j1]),format)

                    for cursor in cursors:
                        cursor.setCharFormat (self.monospacedFormat)


            for i, group in enumerate(groups):
                if i > 0:
                    y_top = [cursor.block().layout() for cursor in self.cursors]
                    for cursor in cursors:
                        cursor.insertBlock()
                    t_bot = [cursor.block().layout() for cursor in self.cursors]
                    changes.append((y_top[0], t_bot[0], y_top[1], t_bot[1], 'blank'))
                linediff = 0
                for g in group:
                    tag = g[0]
                    # indexes
                    ixs = ((g[1], g[2]), (g[3], g[4]))
                    n = [ix[1]-ix[0] for ix in ixs]
                    if tag == "equal":
                        insertIxs(ixs)
                    else:
                        y_top = [cursor.block().layout() for cursor in self.cursors]
                        g_top = [cursor.block().blockNumber() for cursor in self.cursors]
                        if tag == "replace":
                            insertIxsWithChangesHighlighted(ixs)
                        else:
                            insertIxs(ixs)
                        linediff += n[0] - n[1]
                        y_bot = [cursor.block().layout() for cursor in self.cursors]
                        changes.append((y_top[0], y_bot[0], y_top[1], y_bot[1], tag))

                        g_bot = [cursor.block().blockNumber() for cursor in self.cursors]
                        for data, top, bot in zip(guidebar_data, g_top, g_bot):
                            data[tag].append((top, bot - top))

                if linediff == 0:
                    continue
                if not self.complete:
                    if linediff < 0:
                        i0 = group[-1][2]
                        i1 = i0 - linediff
                        exlines = display_lines[0][i0:i1]
                        linediff = -linediff - len(exlines)
                        cursor = cursors[0]
                    else:
                        j0 = group[-1][4]
                        j1 = j0 + linediff
                        exlines = display_lines[1][j0:j1]
                        linediff = linediff - len(exlines)
                        cursor = cursors[1]
                    for l in exlines:
                        insertLine(cursor, l)

                if i % 100 == 0:
                    QtCore.QCoreApplication.processEvents()
        else:
            y_top = [cursor.block().layout() for cursor in self.cursors]
            heights = [0,0]
            is_images = [False, False]
            for i in range(2):
                if present[i]:
                    ext = file_extension(paths[i]).lower()
                    if ext in self.image_exts:
                        is_images[i] = True
                        image = QtGui.QImage()
                        image.loadFromData(data[i])
                        heights[i] = image.height()
                        self.docs[i].addResource(QtGui.QTextDocument.ImageResource,
                                        QtCore.QUrl(file_id),
                                        image)

            max_height = max(heights)
            for i, cursor in enumerate(self.cursors):
                format = QtGui.QTextBlockFormat()
                format.setBottomMargin((max_height - heights[i])/2)
                format.setTopMargin((max_height - heights[i])/2)
                cursor.insertBlock(format)
                if present[i]:
                    if is_images[i]:
                        cursor.insertImage(file_id)
                    else:
                        cursor.insertText(gettext('[binary file (%d bytes)]') % len(data[i]))
                else:
                    cursor.insertText(" ")
                cursor.insertBlock(QtGui.QTextBlockFormat())
            y_bot = [cursor.block().layout() for cursor in self.cursors]
            changes.append((y_top[0], y_bot[0], y_top[1], y_bot[1], 'dummy'))

        for cursor in cursors:
            cursor.endEditBlock()
            cursor.insertText("\n")
        y_top = [cursor.block().layout() for cursor in self.cursors]
        if not self.complete:
            maxy = max([l.position().y() for l in y_top])
            for cursor in cursors:
                format = QtGui.QTextBlockFormat()
                format.setBottomMargin(maxy-cursor.block().layout().position().y())
                cursor.setBlockFormat(format)
                cursor.insertBlock(QtGui.QTextBlockFormat())

        l_block = infoBlocks[0].position().y()
        r_block = infoBlocks[1].position().y()
        self.browsers[0].infoBlocks.append(l_block)
        self.browsers[1].infoBlocks.append(r_block)
        self.handle(1).infoBlocks.append((l_block, r_block))

        for (ly_top, ly_bot, ry_top, ry_bot, kind) in changes:
            ly_top = ly_top.position().y() - 1
            ly_bot = ly_bot.position().y() + 1
            ry_top = ry_top.position().y() - 1
            ry_bot = ry_bot.position().y() + 1
            self.scrollbar.append_change(ly_top, ly_bot, ry_top, ry_bot, kind)
            self.browsers[0].changes.append((ly_top, ly_bot, kind))
            self.browsers[1].changes.append((ry_top, ry_bot, kind))
            self.handle(1).changes.append((ly_top, ly_bot, ry_top, ry_bot, kind))
        self.scrollbar.fix_document_length(cursors)

        # check horizontal scrollbars and force both if scrollbar visible only at one side
        if (self.browsers[0].horizontalScrollBar().isVisible()
            or self.browsers[1].horizontalScrollBar().isVisible()):
            self.browsers[0].setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
            self.browsers[1].setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)

        self.update_guidebar()
        self.update()