~ddaa/bzrk/dev

10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
1
#!/usr/bin/python
2
# -*- coding: UTF-8 -*-
3
"""Difference window.
4
5
This module contains the code to manage the diff window which shows
6
the changes made between two revisions on a branch.
7
"""
8
9
__copyright__ = "Copyright © 2005 Canonical Ltd."
10
__author__    = "Scott James Remnant <scott@ubuntu.com>"
11
12
13
from cStringIO import StringIO
14
15
import gtk
16
import pango
17
18
try:
19
    import gtksourceview
20
    have_gtksourceview = True
21
except ImportError:
22
    have_gtksourceview = False
23
24
from bzrlib.delta import compare_trees
25
from bzrlib.diff import show_diff_trees
26
27
28
class DiffWindow(gtk.Window):
29
    """Diff window.
30
31
    This object represents and manages a single window containing the
32
    differences between two revisions on a branch.
33
    """
34
35
    def __init__(self, app=None):
36
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
37
        self.set_border_width(0)
38
        self.set_title("bzrk diff")
39
40
        self.app = app
41
42
        # Use two thirds of the screen by default
43
        screen = self.get_screen()
44
        monitor = screen.get_monitor_geometry(0)
45
        width = int(monitor.width * 0.66)
46
        height = int(monitor.height * 0.66)
47
        self.set_default_size(width, height)
48
49
        self.construct()
50
51
    def construct(self):
52
        """Construct the window contents."""
53
        hbox = gtk.HBox(spacing=6)
54
        hbox.set_border_width(12)
55
        self.add(hbox)
56
        hbox.show()
57
58
        scrollwin = gtk.ScrolledWindow()
59
        scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
60
        scrollwin.set_shadow_type(gtk.SHADOW_IN)
61
        hbox.pack_start(scrollwin, expand=False, fill=True)
62
        scrollwin.show()
63
64
        self.model = gtk.TreeStore(str, str)
65
        self.treeview = gtk.TreeView(self.model)
66
        self.treeview.set_headers_visible(False)
67
        self.treeview.set_search_column(1)
68
        self.treeview.connect("cursor-changed", self._treeview_cursor_cb)
69
        scrollwin.add(self.treeview)
70
        self.treeview.show()
71
72
        cell = gtk.CellRendererText()
73
        cell.set_property("width-chars", 20)
74
        column = gtk.TreeViewColumn()
75
        column.pack_start(cell, expand=True)
76
        column.add_attribute(cell, "text", 0)
77
        self.treeview.append_column(column)
78
79
80
        scrollwin = gtk.ScrolledWindow()
81
        scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
82
        scrollwin.set_shadow_type(gtk.SHADOW_IN)
83
        hbox.pack_start(scrollwin, expand=True, fill=True)
84
        scrollwin.show()
85
86
        if have_gtksourceview:
87
            self.buffer = gtksourceview.SourceBuffer()
88
            slm = gtksourceview.SourceLanguagesManager()
89
            gsl = slm.get_language_from_mime_type("text/x-patch")
90
            self.buffer.set_language(gsl)
91
            self.buffer.set_highlight(True)
92
93
            sourceview = gtksourceview.SourceView(self.buffer)
94
        else:
95
            self.buffer = gtk.TextBuffer()
96
            sourceview = gtk.TextView(self.buffer)
97
98
        sourceview.set_editable(False)
99
        sourceview.modify_font(pango.FontDescription("Monospace"))
100
        scrollwin.add(sourceview)
101
        sourceview.show()
102
103
    def set_diff(self, branch, revid, parentid):
104
        """Set the differences showed by this window.
105
106
        Compares the two trees and populates the window with the
107
        differences.
108
        """
19.2.1 by Jelmer Vernooij
Update to use post-repository API
109
        self.rev_tree = branch.repository.revision_tree(revid)
110
        self.parent_tree = branch.repository.revision_tree(parentid)
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
111
112
        self.model.clear()
113
        delta = compare_trees(self.parent_tree, self.rev_tree)
114
11 by Scott James Remnant
Add a default "Complete Diff" option to the top of the diff window
115
        self.model.append(None, [ "Complete Diff", "" ])
116
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
117
        if len(delta.added):
118
            titer = self.model.append(None, [ "Added", None ])
119
            for path, id, kind in delta.added:
120
                self.model.append(titer, [ path, path ])
121
122
        if len(delta.removed):
123
            titer = self.model.append(None, [ "Removed", None ])
124
            for path, id, kind in delta.removed:
125
                self.model.append(titer, [ path, path ])
126
127
        if len(delta.renamed):
128
            titer = self.model.append(None, [ "Renamed", None ])
129
            for oldpath, newpath, id, kind, text_modified, meta_modified \
130
                    in delta.renamed:
131
                self.model.append(titer, [ oldpath, oldpath ])
132
133
        if len(delta.modified):
134
            titer = self.model.append(None, [ "Modified", None ])
135
            for path, id, kind, text_modified, meta_modified in delta.modified:
136
                self.model.append(titer, [ path, path ])
137
138
        self.treeview.expand_all()
36.1.3 by Jamie Wilkinson
put the revid and branch nick in the diff window title
139
        self.set_title(revid + " - " + branch.nick + " - bzrk diff")
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
140
141
    def _treeview_cursor_cb(self, *args):
142
        """Callback for when the treeview cursor changes."""
143
        (path, col) = self.treeview.get_cursor()
11 by Scott James Remnant
Add a default "Complete Diff" option to the top of the diff window
144
        specific_files = [ self.model[path][1] ]
145
        if specific_files == [ None ]:
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
146
            return
11 by Scott James Remnant
Add a default "Complete Diff" option to the top of the diff window
147
        elif specific_files == [ "" ]:
148
            specific_files = []
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
149
150
        s = StringIO()
11 by Scott James Remnant
Add a default "Complete Diff" option to the top of the diff window
151
        show_diff_trees(self.parent_tree, self.rev_tree, s, specific_files)
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
152
        self.buffer.set_text(s.getvalue())