2
# -*- coding: UTF-8 -*-
5
This module contains the code to manage the diff window which shows
6
the changes made between two revisions on a branch.
9
__copyright__ = "Copyright © 2005 Canonical Ltd."
10
__author__ = "Scott James Remnant <scott@ubuntu.com>"
13
from cStringIO import StringIO
21
have_gtksourceview = True
23
have_gtksourceview = False
27
from bzrlib.diff import show_diff_trees
28
from bzrlib.errors import NoSuchFile
31
class DiffWindow(gtk.Window):
34
This object represents and manages a single window containing the
35
differences between two revisions on a branch.
39
gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
40
self.set_border_width(0)
41
self.set_title("bzrk diff")
43
# Use two thirds of the screen by default
44
screen = self.get_screen()
45
monitor = screen.get_monitor_geometry(0)
46
width = int(monitor.width * 0.66)
47
height = int(monitor.height * 0.66)
48
self.set_default_size(width, height)
53
"""Construct the window contents."""
54
# The window consists of a pane containing: the
55
# hierarchical list of files on the left, and the diff
56
# for the currently selected file on the right.
61
# The file hierarchy: a scrollable treeview
62
scrollwin = gtk.ScrolledWindow()
63
scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
64
scrollwin.set_shadow_type(gtk.SHADOW_IN)
68
self.model = gtk.TreeStore(str, str)
69
self.treeview = gtk.TreeView(self.model)
70
self.treeview.set_headers_visible(False)
71
self.treeview.set_search_column(1)
72
self.treeview.connect("cursor-changed", self._treeview_cursor_cb)
73
scrollwin.add(self.treeview)
76
cell = gtk.CellRendererText()
77
cell.set_property("width-chars", 20)
78
column = gtk.TreeViewColumn()
79
column.pack_start(cell, expand=True)
80
column.add_attribute(cell, "text", 0)
81
self.treeview.append_column(column)
83
# The diffs of the selected file: a scrollable source or
85
scrollwin = gtk.ScrolledWindow()
86
scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
87
scrollwin.set_shadow_type(gtk.SHADOW_IN)
91
if have_gtksourceview:
92
self.buffer = gtksourceview.SourceBuffer()
93
slm = gtksourceview.SourceLanguagesManager()
94
gsl = slm.get_language_from_mime_type("text/x-patch")
95
self.buffer.set_language(gsl)
96
self.buffer.set_highlight(True)
98
sourceview = gtksourceview.SourceView(self.buffer)
100
self.buffer = gtk.TextBuffer()
101
sourceview = gtk.TextView(self.buffer)
103
sourceview.set_editable(False)
104
sourceview.modify_font(pango.FontDescription("Monospace"))
105
scrollwin.add(sourceview)
108
def set_diff(self, description, rev_tree, parent_tree):
109
"""Set the differences showed by this window.
111
Compares the two trees and populates the window with the
114
self.rev_tree = rev_tree
115
self.parent_tree = parent_tree
118
delta = self.rev_tree.changes_from(self.parent_tree)
120
self.model.append(None, [ "Complete Diff", "" ])
123
titer = self.model.append(None, [ "Added", None ])
124
for path, id, kind in delta.added:
125
self.model.append(titer, [ path, path ])
127
if len(delta.removed):
128
titer = self.model.append(None, [ "Removed", None ])
129
for path, id, kind in delta.removed:
130
self.model.append(titer, [ path, path ])
132
if len(delta.renamed):
133
titer = self.model.append(None, [ "Renamed", None ])
134
for oldpath, newpath, id, kind, text_modified, meta_modified \
136
self.model.append(titer, [ oldpath, newpath ])
138
if len(delta.modified):
139
titer = self.model.append(None, [ "Modified", None ])
140
for path, id, kind, text_modified, meta_modified in delta.modified:
141
self.model.append(titer, [ path, path ])
143
self.treeview.expand_all()
144
self.set_title(description + " - bzrk diff")
146
def set_file(self, file_path):
148
for data in self.model:
149
for child in data.iterchildren():
150
if child[0] == file_path or child[1] == file_path:
154
raise NoSuchFile(file_path)
155
self.treeview.set_cursor(tv_path)
156
self.treeview.scroll_to_cell(tv_path)
158
def _treeview_cursor_cb(self, *args):
159
"""Callback for when the treeview cursor changes."""
160
(path, col) = self.treeview.get_cursor()
161
specific_files = [ self.model[path][1] ]
162
if specific_files == [ None ]:
164
elif specific_files == [ "" ]:
168
show_diff_trees(self.parent_tree, self.rev_tree, s, specific_files)
169
self.buffer.set_text(s.getvalue().decode(sys.getdefaultencoding(), 'replace'))