/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
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
76 by Jelmer Vernooij
Replace non-UTF8 characters rather than generating an exception (fixes #44677).
17
import sys
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
18
19
try:
20
    import gtksourceview
21
    have_gtksourceview = True
22
except ImportError:
23
    have_gtksourceview = False
24
71 by Szilveszter Farkas (Phanatic)
(phanatic) compare_trees deprecated in 0.9
25
import bzrlib
26
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
27
from bzrlib.diff import show_diff_trees
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
28
from bzrlib.errors import NoSuchFile
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
29
30
31
class DiffWindow(gtk.Window):
32
    """Diff window.
33
34
    This object represents and manages a single window containing the
35
    differences between two revisions on a branch.
36
    """
37
51 by Jelmer Vernooij
Rework some of the parameters to DiffWindow.set_diff() to be
38
    def __init__(self):
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
39
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
40
        self.set_border_width(0)
41
        self.set_title("bzrk diff")
42
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)
49
50
        self.construct()
51
52
    def construct(self):
53
        """Construct the window contents."""
75 by Jelmer Vernooij
Use HPaned rather than HBox so long filenames can be viewed (fixes #56993).
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.
57
        pane = gtk.HPaned()
58
        self.add(pane)
59
        pane.show()
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
60
75 by Jelmer Vernooij
Use HPaned rather than HBox so long filenames can be viewed (fixes #56993).
61
        # The file hierarchy: a scrollable treeview
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
62
        scrollwin = gtk.ScrolledWindow()
63
        scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
64
        scrollwin.set_shadow_type(gtk.SHADOW_IN)
75 by Jelmer Vernooij
Use HPaned rather than HBox so long filenames can be viewed (fixes #56993).
65
        pane.pack1(scrollwin)
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
66
        scrollwin.show()
67
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)
74
        self.treeview.show()
75
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)
82
75 by Jelmer Vernooij
Use HPaned rather than HBox so long filenames can be viewed (fixes #56993).
83
        # The diffs of the  selected file: a scrollable source or
84
        # text view
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
85
        scrollwin = gtk.ScrolledWindow()
86
        scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
87
        scrollwin.set_shadow_type(gtk.SHADOW_IN)
75 by Jelmer Vernooij
Use HPaned rather than HBox so long filenames can be viewed (fixes #56993).
88
        pane.pack2(scrollwin)
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
89
        scrollwin.show()
90
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)
97
98
            sourceview = gtksourceview.SourceView(self.buffer)
99
        else:
100
            self.buffer = gtk.TextBuffer()
101
            sourceview = gtk.TextView(self.buffer)
102
103
        sourceview.set_editable(False)
104
        sourceview.modify_font(pango.FontDescription("Monospace"))
105
        scrollwin.add(sourceview)
106
        sourceview.show()
107
51 by Jelmer Vernooij
Rework some of the parameters to DiffWindow.set_diff() to be
108
    def set_diff(self, description, rev_tree, parent_tree):
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
109
        """Set the differences showed by this window.
110
111
        Compares the two trees and populates the window with the
112
        differences.
113
        """
51 by Jelmer Vernooij
Rework some of the parameters to DiffWindow.set_diff() to be
114
        self.rev_tree = rev_tree
115
        self.parent_tree = parent_tree
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
116
117
        self.model.clear()
77 by Jelmer Vernooij
Prepare for 0.10.0
118
        delta = self.rev_tree.changes_from(self.parent_tree)
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
119
11 by Scott James Remnant
Add a default "Complete Diff" option to the top of the diff window
120
        self.model.append(None, [ "Complete Diff", "" ])
121
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
122
        if len(delta.added):
123
            titer = self.model.append(None, [ "Added", None ])
124
            for path, id, kind in delta.added:
125
                self.model.append(titer, [ path, path ])
126
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 ])
131
132
        if len(delta.renamed):
133
            titer = self.model.append(None, [ "Renamed", None ])
134
            for oldpath, newpath, id, kind, text_modified, meta_modified \
135
                    in delta.renamed:
63 by Aaron Bentley
Accept either side of a rename for DiffWindow.set_file
136
                self.model.append(titer, [ oldpath, newpath ])
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
137
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 ])
142
143
        self.treeview.expand_all()
51 by Jelmer Vernooij
Rework some of the parameters to DiffWindow.set_diff() to be
144
        self.set_title(description + " - bzrk diff")
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
145
59.2.3 by Aaron Bentley
Gannotate-launched diffs now jump to correct file
146
    def set_file(self, file_path):
147
        tv_path = None
148
        for data in self.model:
149
            for child in data.iterchildren():
63 by Aaron Bentley
Accept either side of a rename for DiffWindow.set_file
150
                if child[0] == file_path or child[1] == file_path:
59.2.3 by Aaron Bentley
Gannotate-launched diffs now jump to correct file
151
                    tv_path = child.path
152
                    break
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
153
        if tv_path is None:
154
            raise NoSuchFile(file_path)
59.2.3 by Aaron Bentley
Gannotate-launched diffs now jump to correct file
155
        self.treeview.set_cursor(tv_path)
64 by Aaron Bentley
Scroll to the appropriate cell when file selected
156
        self.treeview.scroll_to_cell(tv_path)
59.2.3 by Aaron Bentley
Gannotate-launched diffs now jump to correct file
157
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
158
    def _treeview_cursor_cb(self, *args):
159
        """Callback for when the treeview cursor changes."""
160
        (path, col) = self.treeview.get_cursor()
11 by Scott James Remnant
Add a default "Complete Diff" option to the top of the diff window
161
        specific_files = [ self.model[path][1] ]
162
        if specific_files == [ None ]:
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
163
            return
11 by Scott James Remnant
Add a default "Complete Diff" option to the top of the diff window
164
        elif specific_files == [ "" ]:
165
            specific_files = []
10 by Scott James Remnant
Add an extra window type, clicking the little icons next to a parent
166
167
        s = StringIO()
11 by Scott James Remnant
Add a default "Complete Diff" option to the top of the diff window
168
        show_diff_trees(self.parent_tree, self.rev_tree, s, specific_files)
66.2.10 by Jelmer Vernooij
Merge some fixes from Alexander Belchenko
169
        self.buffer.set_text(s.getvalue().decode(sys.getdefaultencoding(), 'replace'))