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
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'))
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
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)
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
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)
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()