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

📄 dirdiff.py

📁 LINUX下的文件比较工具
💻 PY
📖 第 1 页 / 共 3 页
字号:
            files = [ m.value_path( m.get_iter(p), pane ) for p in self._get_selected_paths(pane) ]            self._edit_files( [f for f in files if os.path.isfile(f)] )    def on_button_ignore_case_toggled(self, button):        self.refresh()    def _update_state_filter(self, state, active):        assert state in (tree.STATE_NEW, tree.STATE_MODIFIED, tree.STATE_NORMAL)        try:            self.state_filters.remove( state )        except ValueError:            pass        if active:            self.state_filters.append( state )        self.refresh()    def on_filter_state_normal_toggled(self, button):        self._update_state_filter( tree.STATE_NORMAL, button.get_active() )    def on_filter_state_new_toggled(self, button):        self._update_state_filter( tree.STATE_NEW, button.get_active() )    def on_filter_state_modified_toggled(self, button):        self._update_state_filter( tree.STATE_MODIFIED, button.get_active() )    def _update_name_filter(self, button, idx):        for i in range(len(self.name_filters)):            if self.name_filters[i] == self.name_filters_available[idx]:                self.name_filters.pop(i)                break        if button.get_active():            self.name_filters.append( self.name_filters_available[idx] )        self.refresh()    def on_filter_hide_current_clicked(self, button):        pane = self._get_focused_pane()        if pane != None:            paths = self._get_selected_paths(pane)            paths.reverse()            for p in paths:                self.model.remove( self.model.get_iter(p) )        #        # Selection        #    def _get_selected_paths(self, pane):        assert pane != None        selected_paths = []        self.treeview[pane].get_selection().selected_foreach(            lambda store, path, it: selected_paths.append( path ) )        return selected_paths        #        # Filtering        #    def _filter_on_state(self, roots, fileslist):        """Get state of 'files' for filtering purposes.           Returns STATE_NORMAL, STATE_NEW or STATE_MODIFIED               roots - array of root directories               fileslist - array of filename tuples of length len(roots)        """        assert len(roots) == self.model.ntree        ret = []        for files in fileslist:            curfiles = [ os.path.join( r, f ) for r,f in zip(roots,files) ]            is_present = [ os.path.exists( f ) for f in curfiles ]            all_present = 0 not in is_present            if all_present:                if _files_same( curfiles, self.regexes ):                    state = tree.STATE_NORMAL                else:                    state = tree.STATE_MODIFIED            else:                state = tree.STATE_NEW            if state in self.state_filters:                ret.append( files )        return ret    def _update_item_state(self, it):        """Update the state of the item at 'it'        """        files = self.model.value_paths(it)        def mtime(f):            try:                return os.stat(f).st_mtime            except OSError:                return 0        # find the newest file, checking also that they differ        mod_times = [ mtime(f) for f in files[:self.num_panes] ]        newest_index = mod_times.index( max(mod_times) )        if mod_times.count( max(mod_times) ) == len(mod_times):            newest_index = -1 # all same        all_present = 0 not in mod_times        if all_present:            all_same = _files_same( files, self.regexes )            all_present_same = all_same        else:            lof = []            for j in range(len(mod_times)):                if mod_times[j]:                    lof.append( files[j] )            all_same = 0            all_present_same = _files_same( lof, self.regexes )        different = 1        for j in range(self.model.ntree):            if mod_times[j]:                isdir = os.path.isdir( files[j] )                if all_same == 1:                    self.model.set_state(it, j,  tree.STATE_NORMAL, isdir)                    different = 0                elif all_same == 2:                    self.model.set_state(it, j,  tree.STATE_NOCHANGE, isdir)                    different = 0                elif all_present_same:                    self.model.set_state(it, j,  tree.STATE_NEW, isdir)                else:                    self.model.set_state(it, j,  tree.STATE_MODIFIED, isdir)                self.model.set_value(it,                    self.model.column_index(COL_EMBLEM, j),                    j == newest_index and pixbuf_newer or None)            else:                self.model.set_state(it, j,  tree.STATE_MISSING)        return different    def on_treeview_button_press_event(self, treeview, event):        # unselect other panes        for t in filter(lambda x:x!=treeview, self.treeview[:self.num_panes]):            t.get_selection().unselect_all()        if event.button == 3:            try:                path, col, cellx, celly = treeview.get_path_at_pos( int(event.x), int(event.y) )            except TypeError:                pass # clicked outside tree            else:                treeview.grab_focus()                selected = self._get_selected_paths( self.treeview.index(treeview) )                if len(selected) <= 1 and event.state == 0:                    treeview.set_cursor( path, col, 0)                self.popup_menu.popup_in_pane( self.treeview.index(treeview) )            return event.state==0        return 0    def set_num_panes(self, n):        if n != self.num_panes and n in (1,2,3):            self.model = DirDiffTreeStore(n)            for i in range(n):                self.treeview[i].set_model(self.model)            toshow =  self.scrolledwindow[:n] + self.fileentry[:n]            toshow += self.linkmap[:n-1] + self.diffmap[:n]            map( lambda x: x.show(), toshow )            tohide =  self.scrolledwindow[n:] + self.fileentry[n:]            tohide += self.linkmap[n-1:] + self.diffmap[n:]            map( lambda x: x.hide(), tohide )            if self.num_panes != 0: # not first time through                self.num_panes = n                self.on_fileentry_activate(None)            else:                self.num_panes = n    def refresh(self):        root = self.model.get_iter_root()        if root:            roots = self.model.value_paths(root)            self.set_locations( roots )    def recompute_label(self):        root = self.model.get_iter_root()        filenames = self.model.value_paths(root)        shortnames = misc.shorten_names(*filenames)        self.label_text = " : ".join(shortnames)        self.label_changed()    def _update_diffmaps(self):        self.diffmap[0].queue_draw()        self.diffmap[1].queue_draw()    def on_diffmap_expose_event(self, area, event):        diffmapindex = self.diffmap.index(area)        treeindex = (0, self.num_panes-1)[diffmapindex]        treeview = self.treeview[treeindex]        def traverse_states(root):            todo = [root]            model = self.model            while len(todo):                it = todo.pop(0)                #print model.value_path(it, treeindex), model.get_state(it, treeindex)                yield model.get_state(it, treeindex)                path = model.get_path(it)                if treeview.row_expanded(path):                    children = []                    child = model.iter_children(it)                    while child:                        children.append(child)                        child = model.iter_next(child)                    todo = children + todo            yield None # end marker        chunks = []        laststate = None        lastlines = 0        numlines = -1        for state in traverse_states( self.model.get_iter_root() ):            if state != laststate:                chunks.append( (lastlines, laststate) )                laststate = state                lastlines = 1            else:                lastlines += 1            numlines += 1        if not hasattr(area, "meldgc"):            assert area.window            gcd = area.window.new_gc()            gcd.set_rgb_fg_color( gdk.color_parse(self.prefs.color_delete_bg) )            gcc = area.window.new_gc()            gcc.set_rgb_fg_color( gdk.color_parse(self.prefs.color_replace_bg) )            gce = area.window.new_gc()            gce.set_rgb_fg_color( gdk.color_parse("yellow") )            gcm = area.window.new_gc()            gcm.set_rgb_fg_color( gdk.color_parse("white") )            gcb = area.window.new_gc()            gcb.set_rgb_fg_color( gdk.color_parse("black") )            area.meldgc = [None, # ignore                           None, # none                           None, # normal                           None, # nochange                           gce,  # error                           None, # empty                           gcd,  # new                           gcc,  # modified                           gcc,  # conflict                           gcc,  # removed                           gcm,  # missing                           gcb ] # border            assert len(area.meldgc) - 1 == tree.STATE_MAX        #TODO need gutter of scrollbar - how do we get that?        size_of_arrow = 14        hperline = float( area.get_allocation().height - 3*size_of_arrow) / numlines        scaleit = lambda x,s=hperline,o=size_of_arrow: x*s+o        x0 = 4        x1 = area.get_allocation().width - 2*x0        window = area.window        window.clear()        start = 0        for c in chunks[1:]:            end = start + c[0]            s,e = [int(x) for x in (math.floor(scaleit(start)), math.ceil(scaleit(end))) ]            gc = area.meldgc[ int(c[1]) ]            if gc:                window.draw_rectangle( gc, 1, x0, s, x1, e-s)                window.draw_rectangle( area.meldgc[-1], 0, x0, s, x1, e-s)            start = end    def on_diffmap_button_press_event(self, area, event):        #TODO need gutter of scrollbar - how do we get that?        if event.button == 1:            size_of_arrow = 14            diffmapindex = self.diffmap.index(area)            index = (0, self.num_panes-1)[diffmapindex]            height = area.get_allocation().height            fraction = (event.y - size_of_arrow) / (height - 3.75*size_of_arrow)            adj = self.scrolledwindow[index].get_vadjustment()            val = fraction * adj.upper - adj.page_size/2            upper = adj.upper - adj.page_size            adj.set_value( max( min(upper, val), 0) )            return 1        return 0    def on_file_changed(self, changed_filename):        """When a file has changed, try to find it in our tree           and update its status if necessary        """        model = self.model        changed_paths = []        # search each panes tree for changed_filename        for pane in range(self.num_panes):            it = model.get_iter_root()            current = model.value_path(it, pane).split(os.sep)            changed = changed_filename.split(os.sep)            # early exit. does filename begin with root?            try:                if changed[:len(current)] != current:                    continue            except IndexError:                continue            changed = changed[len(current):]            # search the tree component at a time            for component in changed:                child = model.iter_children( it )                while child:                    leading, name = os.path.split( model.value_path(child, pane) )                    if component == name : # found it                        it = child                        break                    else:                        child = self.model.iter_next( child ) # next                if not it:                    break            # save if found and unique            if it:                path = model.get_path(it)                if path not in changed_paths:                    changed_paths.append(path)        # do the update        for path in changed_paths:            self._update_item_state( model.get_iter(path) )    def next_diff(self, direction):        if self.treeview_focussed:            pane = self.treeview.index( self.treeview_focussed )        else:            pane = 0        start_iter = self.model.get_iter( (self._get_selected_paths(pane) or [(0,)])[-1] )        def goto_iter(it):            curpath = self.model.get_path(it)            for i in range(len(curpath)-1):                self.treeview[pane].expand_row( curpath[:i+1], 0)            self.treeview[pane].set_cursor(curpath)        search = {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, pane ))            if state not in (tree.STATE_NORMAL, tree.STATE_EMPTY):                goto_iter(it)                return    def on_reload_activate(self, *extra):        self.on_fileentry_activate(None)if gobject.pygtk_version < (2,8,0):    gobject.type_register(DirDiff)

⌨️ 快捷键说明

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