⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vcview.py

📁 LINUX下的文件比较工具
💻 PY
📖 第 1 页 / 共 2 页
字号:
        else:            path = self.model.value_path(it, 0)            self.run_diff( [path] )    def run_diff_iter(self, paths, empty_patch_ok):        yield _("[%s] Fetching differences") % self.label_text        difffunc = self._command_iter(self.vc.diff_command(), paths, 0).next        diff = None        while type(diff) != type(()):            diff = difffunc()            yield 1        prefix, patch = diff[0], diff[1]        yield _("[%s] Applying patch") % self.label_text        if patch:            self.show_patch(prefix, patch)        elif empty_patch_ok:            misc.run_dialog( _("No differences found."), parent=self, messagetype=gtk.MESSAGE_INFO)        else:            for path in paths:                self.emit("create-diff", [path])    def run_diff(self, paths, empty_patch_ok=0):        self.scheduler.add_task( self.run_diff_iter(paths, empty_patch_ok).next, atfront=1 )    def on_button_press_event(self, text, event):        if event.button==3:            VcMenu(self, event)            return len(self._get_selected_treepaths()) != 1        return 0    def on_button_flatten_toggled(self, button):        self.treeview_column_location.set_visible( self.button_flatten.get_active() )        self.refresh()    def on_button_filter_toggled(self, button):        self.refresh()    def _get_selected_treepaths(self):        sel = []        def gather(model, path, it):            sel.append( model.get_path(it) )        s = self.treeview.get_selection()        s.selected_foreach(gather)        return sel    def _get_selected_files(self):        sel = []        def gather(model, path, it):            sel.append( model.value_path(it,0) )        s = self.treeview.get_selection()        s.selected_foreach(gather)        # remove empty entries and remove trailing slashes        return [ x[-1]!="/" and x or x[:-1] for x in sel if x != None ]    def _command_iter(self, command, files, refresh):        """Run 'command' on 'files'. Return a tuple of the directory the           command was executed in and the output of the command.        """        msg = misc.shelljoin(command)        yield "[%s] %s" % (self.label_text, msg.replace("\n", u"\u21b2") )        def relpath(pbase, p):            assert p.startswith(pbase)            kill = len(pbase) and (len(pbase)+1) or 0            return p[kill:] or "."        if len(files) == 1 and os.path.isdir(files[0]):            workdir = self.vc.get_working_directory(files[0])        else:            workdir = self.vc.get_working_directory( _commonprefix(files) )        files = [ relpath(workdir, f) for f in files ]        r = None        self.consolestream.write( misc.shelljoin(command+files) + " (in %s)\n" % workdir)        readfunc = misc.read_pipe_iter(command + files, self.consolestream, workdir=workdir).next        try:            while r == None:                r = readfunc()                self.consolestream.write(r)                yield 1        except IOError, e:            misc.run_dialog("Error running command.\n'%s'\n\nThe error was:\n%s" % ( misc.shelljoin(command), e),                parent=self, messagetype=gtk.MESSAGE_ERROR)        if refresh:            self.refresh_partial(workdir)        yield workdir, r    def _command(self, command, files, refresh=1):        """Run 'command' on 'files'.        """        self.scheduler.add_task( self._command_iter(command, files, refresh).next )            def _command_on_selected(self, command, refresh=1):        files = self._get_selected_files()        if len(files):            self._command(command, files, refresh)        else:            misc.run_dialog( _("Select some files first."), parent=self, messagetype=gtk.MESSAGE_INFO)    def on_button_update_clicked(self, object):        self._command_on_selected( self.vc.update_command() )    def on_button_commit_clicked(self, object):        dialog = CommitDialog( self )        dialog.run()    def on_button_add_clicked(self, object):        self._command_on_selected(self.vc.add_command() )    def on_button_add_binary_clicked(self, object):        self._command_on_selected(self.vc.add_command(binary=1))    def on_button_remove_clicked(self, object):        self._command_on_selected(self.vc.remove_command())    def on_button_revert_clicked(self, object):        self._command_on_selected(self.vc.revert_command())    def on_button_delete_clicked(self, object):        files = self._get_selected_files()        for name in files:            try:                if os.path.isfile(name):                    os.remove(name)                elif os.path.isdir(name):                    if misc.run_dialog(_("'%s' is a directory.\nRemove recusively?") % os.path.basename(name),                            parent = self,                            buttonstype=gtk.BUTTONS_OK_CANCEL) == gtk.RESPONSE_OK:                        shutil.rmtree(name)            except OSError, e:                misc.run_dialog(_("Error removing %s\n\n%s.") % (name,e), parent = self)        workdir = _commonprefix(files)        self.refresh_partial(workdir)    def on_button_diff_clicked(self, object):        files = self._get_selected_files()        if len(files):            self.run_diff(files, empty_patch_ok=1)    def show_patch(self, prefix, patch):        if not patch: return        tmpdir = tempfile.mkdtemp("-meld")        self.tempdirs.append(tmpdir)        regex = re.compile(self.vc.PATCH_INDEX_RE, re.M)        files = [f.split()[-1] for f in regex.findall(patch)]        diffs = []        for fname in files:            destfile = os.path.join(tmpdir,fname)            destdir = os.path.dirname( destfile )            if not os.path.exists(destdir):                os.makedirs(destdir)            pathtofile = os.path.join(prefix, fname)            try:                shutil.copyfile( pathtofile, destfile)            except IOError: # it is missing, create empty file                open(destfile,"w").close()            diffs.append( (destfile, pathtofile) )        patchcmd = self.vc.patch_command( tmpdir )        misc.write_pipe(patchcmd, patch)        for d in diffs:            self.emit("create-diff", d)    def refresh(self):        self.set_location( self.model.value_path( self.model.get_iter_root(), 0 ) )    def refresh_partial(self, where):        if not self.button_flatten.get_active():            it = self.find_iter_by_name( where )            if it:                newiter = self.model.insert_after( None, it)                self.model.set_value(newiter, self.model.column_index( tree.COL_PATH, 0), where)                self.model.set_state(newiter, 0, tree.STATE_NORMAL, isdir=1)                self.model.remove(it)                self.scheduler.add_task( self._search_recursively_iter(newiter).next )        else: # XXX fixme            self.refresh()    def on_button_jump_press_event(self, button, event):        class MyMenu(gtk.Menu):            def __init__(self, parent, where, showup=1):                gtk.Menu.__init__(self)                self.vcview = parent                self.map_id = self.connect("map", lambda item: self.on_map(item,where,showup) )            def add_item(self, name, submenu, showup):                item = gtk.MenuItem(name)                if submenu:                    item.set_submenu( MyMenu(self.vcview, submenu, showup ) )                self.append( item )            def on_map(self, item, where, showup):                if showup:                    self.add_item("..", os.path.dirname(where), 1 )                self.populate( where, self.listdir(where) )                self.show_all()                self.disconnect(self.map_id)                del self.map_id            def listdir(self, d):                try:                    return [p for p in os.listdir(d) if os.path.isdir( os.path.join(d,p))]                except OSError:                    return []            def populate(self, where, children):                for child in children:                    cc = self.listdir( os.path.join(where, child) )                    self.add_item( child, len(cc) and os.path.join(where,child), 0 )        menu = MyMenu( self, os.path.abspath(self.location) )        menu.popup(None, None, None, event.button, event.time)    def _update_item_state(self, it, vcentry, location):        e = vcentry        self.model.set_state( it, 0, e.state, e.isdir )        def set(col, val):            self.model.set_value( it, self.model.column_index(col,0), val)        set( COL_LOCATION, location )        set( COL_STATUS, e.get_status())        set( COL_REVISION, e.rev)        set( COL_TAG, e.tag)        set( COL_OPTIONS, e.options)    def on_file_changed(self, filename):        it = self.find_iter_by_name(filename)        if it:            path = self.model.value_path(it, 0)            dirs, files = self.vc.lookup_files( [], [ (os.path.basename(path), path)] )            for e in files:                if e.path == path:                    prefixlen = 1 + len( self.model.value_path( self.model.get_iter_root(), 0 ) )                    self._update_item_state( it, e, e.parent[prefixlen:])                    return    def find_iter_by_name(self, name):        it = self.model.get_iter_root()        path = self.model.value_path(it, 0)        while it:            if name == path:                return it            elif name.startswith(path):                child = self.model.iter_children( it )                while child:                    path = self.model.value_path(child, 0)                    if name == path:                        return child                    elif name.startswith(path):                        break                    else:                        child = self.model.iter_next( child )                it = child            else:                break        return None    def on_console_view_toggle(self, box, event=None):        if box == self.console_hide_box:            self.prefs.vc_console_visible = 0            self.console_hbox.hide()            self.console_show_box.show()        else:            self.prefs.vc_console_visible = 1            self.console_hbox.show()            self.console_show_box.hide()    def on_consoleview_populate_popup(self, text, menu):        item = gtk.ImageMenuItem(gtk.STOCK_CLEAR)        def activate(*args):            buf = text.get_buffer()            buf.delete( buf.get_start_iter(), buf.get_end_iter() )        item.connect("activate", activate)        item.show()        menu.insert( item, 0 )        item = gtk.SeparatorMenuItem()        item.show()        menu.insert( item, 1 )    def next_diff(self, direction):        start_iter = self.model.get_iter( (self._get_selected_treepaths() or [(0,)])[-1] )        def goto_iter(it):            curpath = self.model.get_path(it)            for i in range(len(curpath)-1):                self.treeview.expand_row( curpath[:i+1], 0)            self.treeview.set_cursor(curpath)        search = {gtk.gdk.SCROLL_UP : self.model.inorder_search_up}.get(direction, self.model.inorder_search_down)        for it in search( start_iter ):            state = int(self.model.get_state( it, 0))            if state not in (tree.STATE_NORMAL, tree.STATE_EMPTY):                goto_iter(it)                return    def on_reload_activate(self, *extra):        self.on_fileentry_activate(self.fileentry)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -