/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 viz/branchwin.py

  • Committer: Daniel Schierbeck
  • Date: 2007-11-05 17:16:09 UTC
  • Revision ID: daniel.schierbeck@gmail.com-20071105171609-p6epw1auedpvlcer
Simplified date format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: UTF-8 -*-
 
2
"""Branch window.
 
3
 
 
4
This module contains the code to manage the branch information window,
 
5
which contains both the revision graph and details panes.
 
6
"""
 
7
 
 
8
__copyright__ = "Copyright © 2005 Canonical Ltd."
 
9
__author__    = "Scott James Remnant <scott@ubuntu.com>"
 
10
 
 
11
 
 
12
import gtk
 
13
import gobject
 
14
import pango
 
15
 
 
16
from bzrlib.plugins.gtk.window import Window
 
17
from bzrlib.plugins.gtk.preferences import PreferencesWindow
 
18
from bzrlib.revision import Revision
 
19
from treeview import TreeView
 
20
 
 
21
class BranchWindow(Window):
 
22
    """Branch window.
 
23
 
 
24
    This object represents and manages a single window containing information
 
25
    for a particular branch.
 
26
    """
 
27
 
 
28
    def __init__(self, branch, start, maxnum, parent=None):
 
29
        """Create a new BranchWindow.
 
30
 
 
31
        :param branch: Branch object for branch to show.
 
32
        :param start: Revision id of top revision.
 
33
        :param maxnum: Maximum number of revisions to display, 
 
34
                       None for no limit.
 
35
        """
 
36
 
 
37
        Window.__init__(self, parent=parent)
 
38
        self.set_border_width(0)
 
39
 
 
40
        self.branch = branch
 
41
        self.start  = start
 
42
        self.maxnum = maxnum
 
43
 
 
44
        self.set_title(branch.nick + " - revision history")
 
45
 
 
46
        # Use three-quarters of the screen by default
 
47
        screen = self.get_screen()
 
48
        monitor = screen.get_monitor_geometry(0)
 
49
        width = int(monitor.width * 0.75)
 
50
        height = int(monitor.height * 0.75)
 
51
        self.set_default_size(width, height)
 
52
 
 
53
        # FIXME AndyFitz!
 
54
        icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
 
55
        self.set_icon(icon)
 
56
 
 
57
        self.accel_group = gtk.AccelGroup()
 
58
        self.add_accel_group(self.accel_group)
 
59
 
 
60
        self.construct()
 
61
 
 
62
    def construct(self):
 
63
        """Construct the window contents."""
 
64
        vbox = gtk.VBox(spacing=0)
 
65
        self.add(vbox)
 
66
 
 
67
        top = self.construct_top()
 
68
 
 
69
        vbox.pack_start(self.construct_menubar(), expand=False, fill=True)
 
70
        vbox.pack_start(self.construct_navigation(), expand=False, fill=True)
 
71
        vbox.pack_start(self.construct_loading_msg(), expand=False, fill=True)
 
72
        
 
73
        paned = gtk.VPaned()
 
74
        paned.pack1(top, resize=True, shrink=False)
 
75
        paned.pack2(self.construct_bottom(), resize=False, shrink=True)
 
76
        paned.show()
 
77
        vbox.pack_start(paned, expand=True, fill=True)
 
78
        vbox.set_focus_child(paned)
 
79
 
 
80
        vbox.show()
 
81
 
 
82
    def construct_menubar(self):
 
83
        menubar = gtk.MenuBar()
 
84
 
 
85
        file_menu = gtk.Menu()
 
86
        file_menuitem = gtk.MenuItem("_File")
 
87
        file_menuitem.set_submenu(file_menu)
 
88
 
 
89
        file_menu_close = gtk.ImageMenuItem(gtk.STOCK_CLOSE)
 
90
        file_menu_close.connect('activate', lambda x: self.destroy())
 
91
        
 
92
        file_menu.add(file_menu_close)
 
93
 
 
94
        edit_menu = gtk.Menu()
 
95
        edit_menuitem = gtk.MenuItem("_Edit")
 
96
        edit_menuitem.set_submenu(edit_menu)
 
97
 
 
98
        edit_menu_find = gtk.ImageMenuItem(gtk.STOCK_FIND)
 
99
 
 
100
        edit_menu_prefs = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES)
 
101
        edit_menu_prefs.connect('activate', lambda x: PreferencesWindow(self.branch.get_config()).show())
 
102
 
 
103
        edit_menu.add(edit_menu_find)
 
104
        edit_menu.add(edit_menu_prefs)
 
105
 
 
106
        view_menu = gtk.Menu()
 
107
        view_menuitem = gtk.MenuItem("_View")
 
108
        view_menuitem.set_submenu(view_menu)
 
109
 
 
110
        view_menu_toolbar = gtk.CheckMenuItem("Show Toolbar")
 
111
        view_menu_toolbar.set_active(True)
 
112
        view_menu_toolbar.connect('toggled', self._toolbar_visibility_changed)
 
113
 
 
114
        view_menu.add(view_menu_toolbar)
 
115
        view_menu.add(gtk.SeparatorMenuItem())
 
116
 
 
117
        for (label, name) in [("Revision _Number", "revno"), ("_Date", "date")]:
 
118
            col = gtk.CheckMenuItem("Show " + label + " Column")
 
119
            col.set_active(self.treeview.get_property(name + "-column-visible"))
 
120
            col.connect('toggled', self._col_visibility_changed, name)
 
121
            view_menu.add(col)
 
122
 
 
123
        go_menu = gtk.Menu()
 
124
        go_menuitem = gtk.MenuItem("_Go")
 
125
        go_menuitem.set_submenu(go_menu)
 
126
        
 
127
        go_menu_back = gtk.ImageMenuItem(gtk.STOCK_GO_DOWN)
 
128
        go_menu_back.connect("activate", self._back_clicked_cb)
 
129
 
 
130
        go_menu_forward = gtk.ImageMenuItem(gtk.STOCK_GO_UP)
 
131
        go_menu_forward.connect("activate", self._fwd_clicked_cb)
 
132
 
 
133
        tags_menu = gtk.Menu()
 
134
        go_menu_tags = gtk.MenuItem("_Tags")
 
135
        go_menu_tags.set_submenu(tags_menu)
 
136
 
 
137
        for (tag, revid) in self.branch.tags.get_tag_dict().items():
 
138
            tag_item = gtk.MenuItem(tag)
 
139
            tag_item.connect('activate', self._tag_selected_cb, revid)
 
140
            tags_menu.add(tag_item)
 
141
 
 
142
        go_menu.add(go_menu_back)
 
143
        go_menu.add(go_menu_forward)
 
144
        go_menu.add(gtk.SeparatorMenuItem())
 
145
        go_menu.add(go_menu_tags)
 
146
 
 
147
        revision_menu = gtk.Menu()
 
148
        revision_menuitem = gtk.MenuItem("_Revision")
 
149
        revision_menuitem.set_submenu(revision_menu)
 
150
 
 
151
        revision_menu.add(gtk.MenuItem("Tag Revision"))
 
152
        revision_menu.add(gtk.MenuItem("View Changes"))
 
153
 
 
154
        branch_menu = gtk.Menu()
 
155
        branch_menuitem = gtk.MenuItem("_Branch")
 
156
        branch_menuitem.set_submenu(branch_menu)
 
157
 
 
158
        branch_menu.add(gtk.MenuItem("Pu_ll Revisions"))
 
159
        branch_menu.add(gtk.MenuItem("Pu_sh Revisions"))
 
160
       
 
161
        menubar.add(file_menuitem)
 
162
        menubar.add(edit_menuitem)
 
163
        menubar.add(view_menuitem)
 
164
        menubar.add(go_menuitem)
 
165
        menubar.add(revision_menuitem)
 
166
        menubar.add(branch_menuitem)
 
167
        menubar.show_all()
 
168
 
 
169
        return menubar
 
170
    
 
171
    def construct_loading_msg(self):
 
172
        image_loading = gtk.image_new_from_stock(gtk.STOCK_REFRESH,
 
173
                                                 gtk.ICON_SIZE_BUTTON)
 
174
        image_loading.show()
 
175
        
 
176
        label_loading = gtk.Label(_("Please wait, loading ancestral graph..."))
 
177
        label_loading.set_alignment(0.0, 0.5)  
 
178
        label_loading.show()
 
179
        
 
180
        self.loading_msg_box = gtk.HBox()
 
181
        self.loading_msg_box.set_spacing(5)
 
182
        self.loading_msg_box.set_border_width(5)        
 
183
        self.loading_msg_box.pack_start(image_loading, False, False)
 
184
        self.loading_msg_box.pack_start(label_loading, True, True)
 
185
        self.loading_msg_box.show()
 
186
        
 
187
        return self.loading_msg_box
 
188
 
 
189
    def construct_top(self):
 
190
        """Construct the top-half of the window."""
 
191
        # FIXME: Make broken_line_length configurable
 
192
        self.treeview = TreeView(self.branch, self.start, self.maxnum, 32)
 
193
 
 
194
        self.treeview.connect("revision-selected",
 
195
                self._treeselection_changed_cb)
 
196
 
 
197
        self.treeview.connect('revisions-loaded', 
 
198
                lambda x: self.loading_msg_box.hide())
 
199
 
 
200
        self.treeview.show()
 
201
 
 
202
        return self.treeview
 
203
 
 
204
    def construct_navigation(self):
 
205
        """Construct the navigation buttons."""
 
206
        self.toolbar = gtk.Toolbar()
 
207
        self.toolbar.set_style(gtk.TOOLBAR_BOTH_HORIZ)
 
208
 
 
209
        self.back_button = gtk.MenuToolButton(stock_id=gtk.STOCK_GO_DOWN)
 
210
        self.back_button.add_accelerator("clicked", self.accel_group, ord('['),
 
211
                                         0, 0)
 
212
        self.back_button.connect("clicked", self._back_clicked_cb)
 
213
        self.toolbar.insert(self.back_button, -1)
 
214
        self.back_button.show()
 
215
 
 
216
        self.fwd_button = gtk.MenuToolButton(stock_id=gtk.STOCK_GO_UP)
 
217
        self.fwd_button.add_accelerator("clicked", self.accel_group, ord(']'),
 
218
                                        0, 0)
 
219
        self.fwd_button.connect("clicked", self._fwd_clicked_cb)
 
220
        self.toolbar.insert(self.fwd_button, -1)
 
221
        self.fwd_button.show()
 
222
 
 
223
        self.toolbar.show()
 
224
 
 
225
        return self.toolbar
 
226
 
 
227
    def construct_bottom(self):
 
228
        """Construct the bottom half of the window."""
 
229
        from bzrlib.plugins.gtk.revisionview import RevisionView
 
230
        self.revisionview = RevisionView(None, tags=[], show_children=True, branch=self.branch)
 
231
        (width, height) = self.get_size()
 
232
        self.revisionview.set_size_request(width, int(height / 2.5))
 
233
        self.revisionview.show()
 
234
        self.revisionview.set_show_callback(self._show_clicked_cb)
 
235
        self.revisionview.set_go_callback(self._go_clicked_cb)
 
236
        return self.revisionview
 
237
 
 
238
    def _tag_selected_cb(self, menuitem, revid):
 
239
        self.treeview.set_revision_id(revid)
 
240
 
 
241
    def _treeselection_changed_cb(self, selection, *args):
 
242
        """callback for when the treeview changes."""
 
243
        revision = self.treeview.get_revision()
 
244
        parents  = self.treeview.get_parents()
 
245
        children = self.treeview.get_children()
 
246
 
 
247
        if revision is not None:
 
248
            back_menu = gtk.Menu()
 
249
            if len(parents) > 0:
 
250
                self.back_button.set_sensitive(True)
 
251
                for parent_id in parents:
 
252
                    parent = self.branch.repository.get_revision(parent_id)
 
253
                    try:
 
254
                        str = ' (' + parent.properties['branch-nick'] + ')'
 
255
                    except KeyError:
 
256
                        str = ""
 
257
 
 
258
                    item = gtk.MenuItem(parent.message.split("\n")[0] + str)
 
259
                    item.connect('activate', self._set_revision_cb, parent_id)
 
260
                    back_menu.add(item)
 
261
                back_menu.show_all()
 
262
            else:
 
263
                self.back_button.set_sensitive(False)
 
264
                back_menu.hide()
 
265
 
 
266
            self.back_button.set_menu(back_menu)
 
267
 
 
268
            fwd_menu = gtk.Menu()
 
269
            if len(children) > 0:
 
270
                self.fwd_button.set_sensitive(True)
 
271
                for child_id in children:
 
272
                    child = self.branch.repository.get_revision(child_id)
 
273
                    try:
 
274
                        str = ' (' + child.properties['branch-nick'] + ')'
 
275
                    except KeyError:
 
276
                        str = ""
 
277
 
 
278
                    item = gtk.MenuItem(child.message.split("\n")[0] + str)
 
279
                    item.connect('activate', self._set_revision_cb, child_id)
 
280
                    fwd_menu.add(item)
 
281
                fwd_menu.show_all()
 
282
            else:
 
283
                self.fwd_button.set_sensitive(False)
 
284
                fwd_menu.hide()
 
285
 
 
286
            self.fwd_button.set_menu(fwd_menu)
 
287
 
 
288
            tags = []
 
289
            if self.branch.supports_tags():
 
290
                tagdict = self.branch.tags.get_reverse_tag_dict()
 
291
                if tagdict.has_key(revision.revision_id):
 
292
                    tags = tagdict[revision.revision_id]
 
293
            self.revisionview.set_revision(revision, tags, children)
 
294
 
 
295
    def _back_clicked_cb(self, *args):
 
296
        """Callback for when the back button is clicked."""
 
297
        self.treeview.back()
 
298
        
 
299
    def _fwd_clicked_cb(self, *args):
 
300
        """Callback for when the forward button is clicked."""
 
301
        self.treeview.forward()
 
302
 
 
303
    def _go_clicked_cb(self, revid):
 
304
        """Callback for when the go button for a parent is clicked."""
 
305
        self.treeview.set_revision_id(revid)
 
306
 
 
307
    def _show_clicked_cb(self, revid, parentid):
 
308
        """Callback for when the show button for a parent is clicked."""
 
309
        self.treeview.show_diff(self.branch, revid, parentid)
 
310
        self.treeview.grab_focus()
 
311
 
 
312
    def _set_revision_cb(self, w, revision_id):
 
313
        self.treeview.set_revision_id(revision_id)
 
314
 
 
315
    def _col_visibility_changed(self, col, property):
 
316
        self.treeview.set_property(property + '-column-visible', col.get_active())
 
317
 
 
318
    def _toolbar_visibility_changed(self, col):
 
319
        if col.get_active():
 
320
            self.toolbar.show() 
 
321
        else:
 
322
            self.toolbar.hide()