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

📄 filediff.py

📁 一份linux上的比较工具meld的源代码
💻 PY
📖 第 1 页 / 共 5 页
字号:
    def set_buffer_writable(self, buf, yesno):        pane = self.textview.index(buf.textview)        self.bufferdata[pane].writable = yesno        self.recompute_label()    def set_buffer_modified(self, buf, yesno):        pane = self.textview.index(buf.textview)        self.bufferdata[pane].modified = yesno        self.recompute_label()    def save(self):        pane = self._get_focused_pane()        if pane >= 0:            self.save_file(pane)    def save_all(self):        for i in range(self.num_panes):            if self.bufferdata[i].modified:                self.save_file(i)    def on_fileentry_activate(self, entry):        if self.on_delete_event() != gtk.RESPONSE_CANCEL:            files = [ e.get_full_path(0) for e in self.fileentry[:self.num_panes] ]            self.set_files(files)        return 1    def _get_focused_pane(self):        for i in range(self.num_panes):            if self.textview[i].is_focus():                return i        return -1    def copy_selected(self, direction):        assert direction in (-1,1)        src_pane = self._get_focused_pane()        dst_pane = src_pane + direction        assert dst_pane in range(self.num_panes)        buffers = [t.get_buffer() for t in self.textview]        text = buffers[src_pane].get_text( buffers[src_pane].get_start_iter(), buffers[src_pane].get_end_iter() )        self.on_text_begin_user_action()        buffers[dst_pane].set_text( text )        self.on_text_end_user_action()        self.scheduler.add_task( lambda : self._sync_vscroll( self.scrolledwindow[src_pane].get_vadjustment() ) and None )        #        # refresh and reload        #    def on_reload_activate(self, *extra):        modified = [os.path.basename(b.label) for b in self.bufferdata if b.modified]        if len(modified):            message = _("Reloading will discard changes in:\n%s\n\nYou cannot undo this operation.") % "\n".join(modified)            response = misc.run_dialog( message, parent=self, messagetype=gtk.MESSAGE_WARNING, buttonstype=gtk.BUTTONS_OK_CANCEL)            if response != gtk.RESPONSE_OK:                return        files = [b.filename for b in self.bufferdata[:self.num_panes] ]        self.set_files(files)    def on_refresh_activate(self, *extra):        files = [None for b in self.bufferdata[:self.num_panes] ]        self.set_files(files)    def queue_draw(self, junk=None):        for i in range(self.num_panes-1):            self.linkmap[i].queue_draw()        self.diffmap0.queue_draw()        self.diffmap1.queue_draw()        #        # scrollbars        #    def _sync_hscroll(self, adjustment):        if not hasattr(self,"_sync_hscroll_lock"):            self._sync_hscroll_lock = 0        if not self._sync_hscroll_lock:            self._sync_hscroll_lock = 1            adjs = map( lambda x: x.get_hadjustment(), self.scrolledwindow)            adjs.remove(adjustment)            val = adjustment.get_value()            for a in adjs:                a.set_value(val)            self._sync_hscroll_lock = 0    def _sync_vscroll(self, adjustment):        # only allow one scrollbar to be here at a time        if not hasattr(self,"_sync_vscroll_lock"):            self._sync_vscroll_lock = 0        if (self.keymask & MASK_SHIFT)==0 and not self._sync_vscroll_lock:            self._sync_vscroll_lock = 1            syncpoint = 0.5            adjustments = map( lambda x: x.get_vadjustment(), self.scrolledwindow)            adjustments = adjustments[:self.num_panes]            master = adjustments.index(adjustment)            # scrollbar influence 0->1->2 or 0<-1<-2 or 0<-1->2            others = zip( range(self.num_panes), adjustments)            del others[master]            if master == 2:                others.reverse()            # the line to search for in the 'master' text            master_y = adjustment.value + adjustment.page_size * syncpoint            it = self.textview[master].get_line_at_y(master_y)[0]            line_y, height = self.textview[master].get_line_yrange(it)            line = it.get_line() + ((master_y-line_y)/height)            for (i,adj) in others:                mbegin,mend, obegin,oend = 0, self._get_line_count(master), 0, self._get_line_count(i)                # look for the chunk containing 'line'                for c in self.linediffer.pair_changes(master, i, self._get_texts()):                    c = c[1:]                    if c[0] >= line:                        mend = c[0]                        oend = c[2]                        break                    elif c[1] >= line:                        mbegin,mend = c[0],c[1]                        obegin,oend = c[2],c[3]                        break                    else:                        mbegin = c[1]                        obegin = c[3]                fraction = (line - mbegin) / ((mend - mbegin) or 1)                other_line = (obegin + fraction * (oend - obegin))                it = self.textview[i].get_buffer().get_iter_at_line(other_line)                val, height = self.textview[i].get_line_yrange(it)                val -= (adj.page_size) * syncpoint                val += (other_line-int(other_line)) * height                val = misc.clamp(val, 0, adj.upper - adj.page_size)                adj.set_value( val )                # scrollbar influence 0->1->2 or 0<-1<-2 or 0<-1->2                if master != 1:                    line = other_line                    master = 1            self.on_linkmap_expose_event(self.linkmap0, None)            self.on_linkmap_expose_event(self.linkmap1, None)            self._sync_vscroll_lock = 0        #        # diffmap drawing        #    def on_diffmap_expose_event(self, area, event):        diffmapindex = self.diffmap.index(area)        textindex = (0, self.num_panes-1)[diffmapindex]        #TODO need height of arrow button on scrollbar - how do we get that?        size_of_arrow = 14        hperline = float( self.scrolledwindow[textindex].get_allocation().height - 4*size_of_arrow) / self._get_line_count(textindex)        if hperline > self.pixels_per_line:            hperline = self.pixels_per_line        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()        gctext = area.get_style().text_gc[0]        if not hasattr(area, "meldgc"):            self._setup_gcs(area)        gc = area.meldgc.get_gc        for c in self.linediffer.single_changes(textindex, self._get_texts()):            assert c[0] != "equal"            outline = True            if self.prefs.ignore_blank_lines:                c1,c2 = self._consume_blank_lines( self._get_texts()[textindex][c[1]:c[2]] )                if (c1 or c2) and (c[1]+c1 == c[2]-c2):                    outline = False            s,e = [int(x) for x in ( math.floor(scaleit(c[1])), math.ceil(scaleit(c[2]+(c[1]==c[2]))) ) ]            window.draw_rectangle( gc(c[0]), 1, x0, s, x1, e-s)            if outline: window.draw_rectangle( gctext, 0, x0, s, x1, e-s)    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 _get_line_count(self, index):        """Return the number of lines in the buffer of textview 'text'"""        return self.textview[index].get_buffer().get_line_count()    def set_num_panes(self, n):        if n != self.num_panes and n in (1,2,3):            self.num_panes = n            toshow =  self.scrolledwindow[:n] + self.fileentry[:n]            toshow += self.linkmap[:n-1] + self.diffmap[:n]            map( lambda x: x.show(), toshow )            tohide =  self.statusimage + self.scrolledwindow[n:] + self.fileentry[n:]            tohide += self.linkmap[n-1:] + self.diffmap[n:]            map( lambda x: x.hide(), tohide )            for i in range(self.num_panes):                if self.bufferdata[i].modified:                    self.statusimage[i].show()            self.queue_draw()            self.recompute_label()    def _line_to_pixel(self, pane, line ):        it = self.textview[pane].get_buffer().get_iter_at_line(line)        return self.textview[pane].get_iter_location( it ).y    def _pixel_to_line(self, pane, pixel ):        return self.textview[pane].get_line_at_y( pixel )[0].get_line()    def next_diff(self, direction):        adjs = map( lambda x: x.get_vadjustment(), self.scrolledwindow)        curline = self._pixel_to_line( 1, int(adjs[1].value + adjs[1].page_size/2) )        c = None        if direction == gdk.SCROLL_DOWN:            for c in self.linediffer.single_changes(1, self._get_texts()):                assert c[0] != "equal"                c1,c2 = self._consume_blank_lines( self._get_texts()[1][c[1]:c[2]] )                if c[1]+c1 == c[2]-c2:                    continue                if c[1] > curline + 1:                    break        else: #direction == gdk.SCROLL_UP            for chunk in self.linediffer.single_changes(1, self._get_texts()):                c1,c2 = self._consume_blank_lines( self._get_texts()[1][chunk[1]:chunk[2]] )                if chunk[1]+c1 == chunk[2]-c2:                    continue                if chunk[2] < curline:                    c = chunk                elif c:                    break        if c:            if c[2] - c[1]: # no range, use other side                l0,l1 = c[1],c[2]                aidx = 1                a = adjs[aidx]            else:                l0,l1 = c[3],c[4]                aidx = c[5]                a = adjs[aidx]            want = 0.5 * ( self._line_to_pixel(aidx, l0) + self._line_to_pixel(aidx,l1) - a.page_size )            want = misc.clamp(want, 0, a.upper-a.page_size)            a.set_value( want )    def _setup_gcs(self, area):        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(self.prefs.color_edited_bg) )        gcx = area.window.new_gc()        gcx.set_rgb_fg_color( gdk.color_parse(self.prefs.color_conflict_bg) )        area.meldgc = misc.struct(gc_delete=gcd, gc_insert=gcd, gc_replace=gcc, gc_conflict=gcx)        area.meldgc.get_gc = lambda p: getattr(area.meldgc, "gc_"+p)    def _consume_blank_lines(self, txt):        lo, hi = 0, 0        for l in txt:            if len(l)==0:                lo += 1            else:                break        for l in txt[lo:]:            if len(l)==0:                hi += 1            else:                break        return lo,hi        #        # linkmap drawing        #    def on_linkmap_expose_event(self, area, event):        window = area.window        # not mapped?        if not window: return        if not hasattr(area, "meldgc"):            self._setup_gcs(area)        gctext = area.get_style().bg_gc[gtk.STATE_ACTIVE]

⌨️ 快捷键说明

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