16
16
from bzrlib.plugins.gtk.window import Window
 
17
17
from bzrlib.plugins.gtk.tags import AddTagDialog
 
18
18
from bzrlib.plugins.gtk.preferences import PreferencesWindow
 
19
 
from bzrlib.plugins.gtk.branchview import TreeView, treemodel
 
 
19
from bzrlib.plugins.gtk.branchview import TreeView
 
20
20
from bzrlib.revision import Revision
 
21
21
from bzrlib.config import BranchConfig
 
22
22
from bzrlib.config import GlobalConfig
 
 
101
101
        vbox.pack_start(self.construct_menubar(), expand=False, fill=True)
 
102
102
        vbox.pack_start(self.construct_navigation(), expand=False, fill=True)
 
 
103
        vbox.pack_start(self.construct_loading_msg(), expand=False, fill=True)
 
104
105
        vbox.pack_start(self.paned, expand=True, fill=True)
 
105
106
        vbox.set_focus_child(self.paned)
 
 
169
170
        go_menu_next = self.next_rev_action.create_menu_item()
 
170
171
        go_menu_prev = self.prev_rev_action.create_menu_item()
 
172
 
        self.go_menu_tags = gtk.MenuItem("_Tags")
 
 
173
        tags_menu = gtk.Menu()
 
 
174
        go_menu_tags = gtk.MenuItem("_Tags")
 
 
175
        go_menu_tags.set_submenu(tags_menu)
 
 
177
        if self.branch.supports_tags():
 
 
178
            tags = self.branch.tags.get_tag_dict().items()
 
 
181
            for tag, revid in tags:
 
 
182
                tag_item = gtk.MenuItem(tag)
 
 
183
                tag_item.connect('activate', self._tag_selected_cb, revid)
 
 
184
                tags_menu.add(tag_item)
 
 
186
            go_menu_tags.set_sensitive(len(tags) != 0)
 
 
188
            go_menu_tags.set_sensitive(False)
 
175
190
        go_menu.add(go_menu_next)
 
176
191
        go_menu.add(go_menu_prev)
 
177
192
        go_menu.add(gtk.SeparatorMenuItem())
 
178
 
        go_menu.add(self.go_menu_tags)
 
 
193
        go_menu.add(go_menu_tags)
 
180
195
        revision_menu = gtk.Menu()
 
181
196
        revision_menuitem = gtk.MenuItem("_Revision")
 
 
198
213
        branch_menu.add(gtk.MenuItem("Pu_ll Revisions"))
 
199
214
        branch_menu.add(gtk.MenuItem("Pu_sh Revisions"))
 
201
 
        help_menu = gtk.Menu()
 
202
 
        help_menuitem = gtk.MenuItem("_Help")
 
203
 
        help_menuitem.set_submenu(help_menu)
 
205
 
        help_about_menuitem = gtk.ImageMenuItem(gtk.STOCK_ABOUT, self.accel_group)
 
206
 
        help_about_menuitem.connect('activate', self._about_dialog_cb)
 
208
 
        help_menu.add(help_about_menuitem)
 
210
216
        menubar.add(file_menuitem)
 
211
217
        menubar.add(edit_menuitem)
 
212
218
        menubar.add(view_menuitem)
 
213
219
        menubar.add(go_menuitem)
 
214
220
        menubar.add(revision_menuitem)
 
215
221
        menubar.add(branch_menuitem)
 
216
 
        menubar.add(help_menuitem)
 
217
222
        menubar.show_all()
 
 
226
    def construct_loading_msg(self):
 
 
227
        image_loading = gtk.image_new_from_stock(gtk.STOCK_REFRESH,
 
 
228
                                                 gtk.ICON_SIZE_BUTTON)
 
 
231
        label_loading = gtk.Label(_("Please wait, loading ancestral graph..."))
 
 
232
        label_loading.set_alignment(0.0, 0.5)
 
 
235
        self.loading_msg_box = gtk.HBox()
 
 
236
        self.loading_msg_box.set_spacing(5)
 
 
237
        self.loading_msg_box.set_border_width(5)        
 
 
238
        self.loading_msg_box.pack_start(image_loading, False, False)
 
 
239
        self.loading_msg_box.pack_start(label_loading, True, True)
 
 
240
        self.loading_msg_box.show()
 
 
242
        return self.loading_msg_box
 
221
244
    def construct_top(self):
 
222
245
        """Construct the top-half of the window."""
 
 
227
250
        self.treeview.connect('revision-selected',
 
228
251
                self._treeselection_changed_cb)
 
229
 
        self.treeview.connect('revision-activated',
 
230
 
                self._tree_revision_activated)
 
232
 
        self.treeview.connect('tag-added', lambda w, t, r: self._update_tags())
 
 
253
        self.treeview.connect('revisions-loaded', 
 
 
254
                lambda x: self.loading_msg_box.hide())
 
234
256
        for col in ["revno", "date"]:
 
235
257
            option = self.config.get_user_option(col + '-column-visible')
 
 
275
297
        self.revisionview.show()
 
276
298
        self.revisionview.set_show_callback(self._show_clicked_cb)
 
277
299
        self.revisionview.connect('notify::revision', self._go_clicked_cb)
 
278
 
        self.treeview.connect('tag-added', lambda w, t, r: self.revisionview.update_tags())
 
279
300
        return self.revisionview
 
281
302
    def _tag_selected_cb(self, menuitem, revid):
 
 
331
352
            self.revisionview.set_revision(revision)
 
332
353
            self.revisionview.set_children(children)
 
334
 
    def _tree_revision_activated(self, widget, path, col):
 
335
 
        # TODO: more than one parent
 
336
 
        """Callback for when a treeview row gets activated."""
 
337
 
        revision = self.treeview.get_revision()
 
338
 
        parents  = self.treeview.get_parents()
 
340
 
        if len(parents) == 0:
 
343
 
            parent_id = parents[0]
 
345
 
        self.show_diff(revision.revision_id, parent_id)
 
346
 
        self.treeview.grab_focus()
 
349
355
    def _back_clicked_cb(self, *args):
 
350
356
        """Callback for when the back button is clicked."""
 
 
362
368
    def _show_clicked_cb(self, revid, parentid):
 
363
369
        """Callback for when the show button for a parent is clicked."""
 
364
 
        self.show_diff(revid, parentid)
 
 
370
        self.treeview.show_diff(revid, parentid)
 
365
371
        self.treeview.grab_focus()
 
367
373
    def _set_revision_cb(self, w, revision_id):
 
 
382
388
    def _tag_revision_cb(self, w):
 
384
390
            self.treeview.set_sensitive(False)
 
385
392
            dialog = AddTagDialog(self.branch.repository, self.treeview.get_revision().revision_id, self.branch)
 
386
393
            response = dialog.run()
 
387
394
            if response != gtk.RESPONSE_NONE:
 
390
397
                if response == gtk.RESPONSE_OK:
 
391
 
                    self.treeview.add_tag(dialog.tagname, dialog._revid)
 
 
399
                        self.branch.lock_write()
 
 
400
                        self.branch.tags.set_tag(dialog.tagname, dialog._revid)
 
 
407
            self.branch.lock_read()
 
 
408
            self.treeview.emit("revision-selected")
 
396
409
            self.treeview.set_sensitive(True)
 
398
 
    def _about_dialog_cb(self, w):
 
399
 
        from bzrlib.plugins.gtk.about import AboutDialog
 
403
411
    def _col_visibility_changed(self, col, property):
 
404
412
        self.config.set_user_option(property + '-column-visible', col.get_active())
 
405
413
        self.treeview.set_property(property + '-column-visible', col.get_active())
 
 
418
426
    def _refresh_clicked(self, w):
 
419
 
        self.treeview.refresh()
 
421
 
    def _update_tags(self):
 
424
 
        if self.branch.supports_tags():
 
425
 
            tags = self.branch.tags.get_tag_dict().items()
 
428
 
            for tag, revid in tags:
 
429
 
                tag_item = gtk.MenuItem(tag)
 
430
 
                tag_item.connect('activate', self._tag_selected_cb, revid)
 
432
 
            self.go_menu_tags.set_submenu(menu)
 
434
 
            self.go_menu_tags.set_sensitive(len(tags) != 0)
 
436
 
            self.go_menu_tags.set_sensitive(False)
 
438
 
        self.go_menu_tags.show_all()
 
440
 
    def show_diff(self, revid=None, parentid=None):
 
441
 
        """Open a new window to show a diff between the given revisions."""
 
442
 
        from bzrlib.plugins.gtk.diff import DiffWindow
 
443
 
        window = DiffWindow(parent=self)
 
446
 
            parentid = NULL_REVISION
 
448
 
        rev_tree    = self.branch.repository.revision_tree(revid)
 
449
 
        parent_tree = self.branch.repository.revision_tree(parentid)
 
451
 
        description = revid + " - " + self.branch.nick
 
452
 
        window.set_diff(description, rev_tree, parent_tree)
 
 
427
        self.treeview.update()