/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz

« back to all changes in this revision

Viewing changes to xannotate.py

  • Committer: Dan Loda
  • Date: 2005-10-24 07:32:48 UTC
  • mto: (0.1.4)
  • mto: This revision was merged to the branch mainline in revision 49.
  • Revision ID: danloda@gmail.com-20051024073248-2695df551fd01dbc
First working version of xannotate.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005 Dan Loda <danloda@gmail.com>
 
2
 
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
 
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
 
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
import pygtk
 
18
pygtk.require("2.0")
 
19
import gtk
 
20
import pango
 
21
 
 
22
from bzrlib.branch import Branch
 
23
from bzrlib.errors import NoSuchRevision
 
24
 
 
25
from logview import LogView
 
26
 
 
27
 
 
28
(
 
29
    REVISION_ID_COL,
 
30
    LINE_NUM_COL,
 
31
    COMMITTER_COL,
 
32
    REVNO_COL,
 
33
    TEXT_LINE_COL
 
34
) = range(5)
 
35
 
 
36
 
 
37
class XAnnotateWindow(gtk.Window):
 
38
    """Annotate window."""
 
39
 
 
40
    def __init__(self):
 
41
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
 
42
        self.set_default_size(640, 480)
 
43
        self.set_icon(self.render_icon(gtk.STOCK_FIND, gtk.ICON_SIZE_BUTTON))
 
44
 
 
45
        self._create()
 
46
 
 
47
    def annotate(self, branch, file_id, all=False):
 
48
        self.revisions = {}
 
49
        
 
50
        # [revision id, line number, committer, revno, line]
 
51
        self.model = gtk.ListStore(str, str, str, str, str)
 
52
        
 
53
        last_seen = None
 
54
        for line_no, (revision, revno, line)\
 
55
                in enumerate(self._annotate(branch, file_id)):
 
56
            if revision.revision_id == last_seen and not all:
 
57
                revno = committer = ""
 
58
            else:
 
59
                last_seen = revision.revision_id
 
60
                committer = revision.committer
 
61
                self.revisions[revision.revision_id] = revision
 
62
 
 
63
            self.model.append([revision.revision_id,
 
64
                               line_no + 1,
 
65
                               committer,
 
66
                               revno,
 
67
                               line.rstrip("\r\n")
 
68
                              ])
 
69
 
 
70
        self.treeview.set_model(self.model)
 
71
        self.treeview.set_cursor(0)
 
72
        self.treeview.grab_focus()
 
73
 
 
74
    def _annotate(self, branch, file_id):
 
75
        rev_hist = branch.revision_history()
 
76
        rev_tree = branch.revision_tree(branch.last_revision())
 
77
        rev_id = rev_tree.inventory[file_id].revision
 
78
        weave = branch.weave_store.get_weave(file_id, branch.get_transaction())
 
79
        
 
80
        for origin, text in weave.annotate_iter(rev_id):
 
81
            rev_id = weave.idx_to_name(origin)
 
82
            try:
 
83
                revision = branch.get_revision(rev_id)
 
84
                if rev_id in rev_hist:
 
85
                    revno = branch.revision_id_to_revno(rev_id)
 
86
                else:
 
87
                    revno = "merge"
 
88
            except NoSuchRevision:
 
89
                revision = NoneRevision(rev_id)
 
90
                revno = "?"
 
91
 
 
92
            yield revision, revno, text
 
93
 
 
94
    def _show_log(self, w):
 
95
        (path, col) = self.treeview.get_cursor()
 
96
        rev_id = self.model[path][REVISION_ID_COL]
 
97
        self.logview.set_revision(self.revisions[rev_id])
 
98
 
 
99
    def _create(self):
 
100
        pane = gtk.VPaned()
 
101
        pane.pack1(self._create_annotate_view(), resize=True, shrink=False)
 
102
        pane.pack2(self._create_log_view(), resize=False, shrink=True)
 
103
        (width, height) = self.get_size()
 
104
        pane.set_position(int(height / 1.75))
 
105
        pane.show()
 
106
 
 
107
        vbox = gtk.VBox(False, 12)
 
108
        vbox.set_border_width(12)
 
109
        vbox.pack_start(pane, expand=True, fill=True)
 
110
        vbox.pack_start(self._create_button_box(), expand=False, fill=True)
 
111
        self.add(vbox)
 
112
        vbox.show()
 
113
 
 
114
    def _create_annotate_view(self):
 
115
        sw = gtk.ScrolledWindow()
 
116
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
 
117
        sw.set_shadow_type(gtk.SHADOW_IN)
 
118
        sw.show()
 
119
 
 
120
        self.treeview = gtk.TreeView()
 
121
        self.treeview.set_rules_hint(False)
 
122
        self.treeview.connect("cursor-changed", self._show_log)
 
123
        sw.add(self.treeview)
 
124
        self.treeview.show()
 
125
 
 
126
        cell = gtk.CellRendererText()
 
127
        cell.set_property("xalign", 1.0)
 
128
        cell.set_property("ypad", 0)
 
129
        cell.set_property("family", "Monospace")
 
130
        cell.set_property("cell-background-gdk",
 
131
                          self.treeview.get_style().bg[gtk.STATE_NORMAL])
 
132
        col = gtk.TreeViewColumn()
 
133
        col.set_resizable(False)
 
134
        col.pack_start(cell, expand=True)
 
135
        col.add_attribute(cell, "text", LINE_NUM_COL)
 
136
        self.treeview.append_column(col)
 
137
 
 
138
        cell = gtk.CellRendererText()
 
139
        cell.set_property("ypad", 0)
 
140
        cell.set_property("ellipsize", pango.ELLIPSIZE_END)
 
141
        cell.set_property("cell-background-gdk",
 
142
                          self.get_style().bg[gtk.STATE_NORMAL])
 
143
        col = gtk.TreeViewColumn("Committer")
 
144
        col.set_resizable(True)
 
145
        col.pack_start(cell, expand=True)
 
146
        col.add_attribute(cell, "text", COMMITTER_COL)
 
147
        self.treeview.append_column(col)
 
148
 
 
149
 
 
150
        cell = gtk.CellRendererText()
 
151
        cell.set_property("xalign", 1.0)
 
152
        cell.set_property("ypad", 0)
 
153
        cell.set_property("cell-background-gdk",
 
154
                          self.get_style().bg[gtk.STATE_NORMAL])
 
155
        col = gtk.TreeViewColumn("Revno")
 
156
        col.set_resizable(False)
 
157
        col.pack_start(cell, expand=True)
 
158
        col.add_attribute(cell, "markup", REVNO_COL)
 
159
        self.treeview.append_column(col)
 
160
 
 
161
        cell = gtk.CellRendererText()
 
162
        cell.set_property("ypad", 0)
 
163
        cell.set_property("family", "Monospace")
 
164
        col = gtk.TreeViewColumn()
 
165
        col.set_resizable(False)
 
166
        col.pack_start(cell, expand=True)
 
167
        col.add_attribute(cell, "text", TEXT_LINE_COL)
 
168
        self.treeview.append_column(col)
 
169
 
 
170
        self.treeview.set_search_column(LINE_NUM_COL)
 
171
        
 
172
        return sw
 
173
 
 
174
    def _create_log_view(self):
 
175
        self.logview = LogView()
 
176
        self.logview.show()
 
177
        return self.logview
 
178
 
 
179
    def _create_button_box(self):
 
180
        box = gtk.HButtonBox()
 
181
        box.set_layout(gtk.BUTTONBOX_END)
 
182
        box.show()
 
183
        
 
184
        button = gtk.Button()
 
185
        button.set_use_stock(True)
 
186
        button.set_label("gtk-close")
 
187
        button.connect("clicked", lambda w: self.destroy())
 
188
        button.show()
 
189
        
 
190
        box.pack_start(button, expand=False, fill=False)
 
191
        return box
 
192
 
 
193
 
 
194
class NoneRevision:
 
195
    """ A fake revision.
 
196
 
 
197
    For when a revision is referenced but not present.
 
198
    """
 
199
 
 
200
    def __init__(self, revision_id):
 
201
        self.revision_id = revision_id
 
202
        self.parent_ids = []
 
203
        self.committer = "?"
 
204
        self.message = "?"
 
205
        self.timestamp = 0.0
 
206
        self.timezone = 0
 
207