101
98
self.annotations.append(revision)
103
100
if not self.plain:
104
self._set_oldest_newest()
105
# Recall that calling activate_default will emit "span-changed",
106
# so self._span_changed_cb will take care of initial highlighting
107
self.span_selector.activate_default()
102
self.annomodel.foreach(self._highlight_annotation, now)
109
104
branch.repository.unlock()
144
139
current_revision.committer = self.branch.get_config().username()
145
140
current_revision.timestamp = time.time()
146
141
current_revision.message = '[Not yet committed]'
142
current_revision.parent_ids = tree.get_parent_ids()
147
143
current_revno = '%d?' % (self.branch.revno() + 1)
148
144
repository = self.branch.repository
149
145
if self.revision_id == CURRENT_REVISION:
152
148
revision_id = self.revision_id
153
149
dotted = self._dotted_revnos(repository, revision_id)
154
revision_cache = RevisionCache(repository)
150
revision_cache = RevisionCache(repository, self.revisions)
155
151
for origin, text in tree.annotate_iter(file_id):
158
revision = revision_cache.get_revision(rev_id)
159
revno = dotted.get(rev_id, 'merge')
162
except NoSuchRevision:
164
if rev_id == CURRENT_REVISION:
165
revision = current_revision
166
revno = current_revno
153
if rev_id == CURRENT_REVISION:
154
revision = current_revision
155
revno = current_revno
158
revision = revision_cache.get_revision(rev_id)
159
revno = dotted.get(rev_id, 'merge')
162
except NoSuchRevision:
168
163
revision = FakeRevision(rev_id)
171
166
yield revision, revno, text
173
def _set_oldest_newest(self):
174
rev_dates = map(lambda i: self.revisions[i].timestamp, self.revisions)
175
if len(rev_dates) == 0:
177
oldest = min(rev_dates)
178
newest = max(rev_dates)
180
span = self._span_from_seconds(time.time() - oldest)
181
self.span_selector.set_to_oldest_span(span)
183
span = self._span_from_seconds(newest - oldest)
184
self.span_selector.set_newest_to_oldest_span(span)
186
def _span_from_seconds(self, seconds):
187
return (seconds / (24 * 60 * 60))
189
def _span_changed_cb(self, w, span):
190
self.annotate_colormap.set_span(span)
192
self.annomodel.foreach(self._highlight_annotation, now)
194
168
def _highlight_annotation(self, model, path, iter, now):
195
169
revision_id, = model.get(iter, REVISION_ID_COL)
196
170
revision = self.revisions[revision_id]
197
171
model.set(iter, HIGHLIGHT_COLOR_COL,
198
172
self.annotate_colormap.get_color(revision, now))
200
def _show_log(self, w):
174
def _selected_revision(self):
201
175
(path, col) = self.annoview.get_cursor()
178
return self.annomodel[path][REVISION_ID_COL]
180
def _show_log(self, w):
181
rev_id = self._selected_revision()
204
rev_id = self.annomodel[path][REVISION_ID_COL]
205
184
self.logview.set_revision(self.revisions[rev_id])
207
186
def _create(self):
208
187
self.logview = self._create_log_view()
209
188
self.annoview = self._create_annotate_view()
210
self.span_selector = self._create_span_selector()
212
190
vbox = gtk.VBox(False, 12)
213
191
vbox.set_border_width(12)
238
216
self.add_accel_group(accels)
240
218
hbox = gtk.HBox(True, 6)
241
hbox.pack_start(self.span_selector, expand=False, fill=True)
242
hbox.pack_start(self._create_button_box(), expand=False, fill=True)
219
hbox.pack_start(self._create_prev_button(), expand=False, fill=True)
220
hbox.pack_end(self._create_button_box(), expand=False, fill=True)
244
222
vbox.pack_start(hbox, expand=False, fill=True)
333
def _create_prev_button(self):
334
box = gtk.HButtonBox()
335
box.set_layout(gtk.BUTTONBOX_START)
338
button = gtk.Button()
339
button.set_use_stock(True)
340
button.set_label("gtk-go-back")
341
button.connect("clicked", lambda w: self.go_back())
343
box.pack_start(button, expand=False, fill=False)
347
rev_id = self._selected_revision()
348
parent_id = self.revisions[rev_id].parent_ids[0]
349
tree = self.branch.repository.revision_tree(parent_id)
350
if self.file_id in tree:
351
offset = self.get_scroll_offset(tree)
352
(row,), col = self.annoview.get_cursor()
353
self.annotate(tree, self.branch, self.file_id)
354
self.annoview.set_cursor(row+offset)
356
def get_scroll_offset(self, tree):
357
old = self.tree.get_file(self.file_id)
358
new = tree.get_file(self.file_id)
359
(row,), col = self.annoview.get_cursor()
360
matcher = patiencediff.PatienceSequenceMatcher(None, old.readlines(),
362
for i, j, n in matcher.get_matching_blocks():
363
368
class FakeRevision:
364
369
""" A fake revision.
378
383
class RevisionCache(object):
379
384
"""A caching revision source"""
380
def __init__(self, real_source):
385
def __init__(self, real_source, seed_cache=None):
381
386
self.__real_source = real_source
387
if seed_cache is None:
390
self.__cache = dict(seed_cache)
384
392
def get_revision(self, revision_id):
385
393
if revision_id not in self.__cache: