/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
1 by Scott James Remnant
Commit the first version of bzrk.
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
298.2.1 by Daniel Schierbeck
Refactored the GTK window code, creating a single base window class that handles keyboard events.
16
from bzrlib.plugins.gtk.window import Window
338 by Daniel Schierbeck
Added Preferences menu item.
17
from bzrlib.plugins.gtk.preferences import PreferencesWindow
333 by Daniel Schierbeck
Removed unnecessary imports.
18
from treeview import TreeView
1 by Scott James Remnant
Commit the first version of bzrk.
19
298.2.1 by Daniel Schierbeck
Refactored the GTK window code, creating a single base window class that handles keyboard events.
20
class BranchWindow(Window):
1 by Scott James Remnant
Commit the first version of bzrk.
21
    """Branch window.
22
23
    This object represents and manages a single window containing information
24
    for a particular branch.
25
    """
26
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
27
    def __init__(self, branch, start, maxnum, parent=None):
322 by Jelmer Vernooij
Add docstrings.
28
        """Create a new BranchWindow.
29
30
        :param branch: Branch object for branch to show.
31
        :param start: Revision id of top revision.
32
        :param maxnum: Maximum number of revisions to display, 
33
                       None for no limit.
34
        """
35
298.2.1 by Daniel Schierbeck
Refactored the GTK window code, creating a single base window class that handles keyboard events.
36
        Window.__init__(self, parent=parent)
1 by Scott James Remnant
Commit the first version of bzrk.
37
        self.set_border_width(0)
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
38
39
        self.branch = branch
40
        self.start  = start
41
        self.maxnum = maxnum
42
43
        self.set_title(branch.nick + " - revision history")
1 by Scott James Remnant
Commit the first version of bzrk.
44
45
        # Use three-quarters of the screen by default
46
        screen = self.get_screen()
4 by Scott James Remnant
Use the size of the first monitor rather than the entire screen
47
        monitor = screen.get_monitor_geometry(0)
48
        width = int(monitor.width * 0.75)
49
        height = int(monitor.height * 0.75)
1 by Scott James Remnant
Commit the first version of bzrk.
50
        self.set_default_size(width, height)
51
52
        # FIXME AndyFitz!
53
        icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
54
        self.set_icon(icon)
55
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
56
        self.accel_group = gtk.AccelGroup()
57
        self.add_accel_group(self.accel_group)
58
1 by Scott James Remnant
Commit the first version of bzrk.
59
        self.construct()
60
61
    def construct(self):
62
        """Construct the window contents."""
331 by Daniel Schierbeck
Added basic menu bar.
63
        vbox = gtk.VBox(spacing=0)
44 by David Allouche
reorganise branch window
64
        self.add(vbox)
65
331 by Daniel Schierbeck
Added basic menu bar.
66
        vbox.pack_start(self.construct_menubar(), expand=False, fill=True)
44 by David Allouche
reorganise branch window
67
        vbox.pack_start(self.construct_navigation(), expand=False, fill=True)
280.2.1 by Gary van der Merwe
Add a message to the viz window to indicate that graph is still loading.
68
        vbox.pack_start(self.construct_loading_msg(), expand=False, fill=True)
69
        
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
70
        paned = gtk.VPaned()
71
        paned.pack1(self.construct_top(), resize=True, shrink=False)
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
72
        paned.pack2(self.construct_bottom(), resize=False, shrink=True)
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
73
        paned.show()
44 by David Allouche
reorganise branch window
74
        vbox.pack_start(paned, expand=True, fill=True)
75
        vbox.set_focus_child(paned)
76
77
        vbox.show()
331 by Daniel Schierbeck
Added basic menu bar.
78
79
    def construct_menubar(self):
80
        menubar = gtk.MenuBar()
81
82
        file_menu = gtk.Menu()
334 by Daniel Schierbeck
Added icons to menus.
83
        file_menuitem = gtk.MenuItem("_File")
331 by Daniel Schierbeck
Added basic menu bar.
84
        file_menuitem.set_submenu(file_menu)
85
334 by Daniel Schierbeck
Added icons to menus.
86
        file_menu_close = gtk.ImageMenuItem(gtk.STOCK_CLOSE)
331 by Daniel Schierbeck
Added basic menu bar.
87
        file_menu_close.connect('activate', lambda x: self.destroy())
88
        
89
        file_menu.add(file_menu_close)
90
338 by Daniel Schierbeck
Added Preferences menu item.
91
        edit_menu = gtk.Menu()
92
        edit_menuitem = gtk.MenuItem("_Edit")
93
        edit_menuitem.set_submenu(edit_menu)
94
340 by Daniel Schierbeck
Added edit->find menu item stub.
95
        edit_menu_find = gtk.ImageMenuItem(gtk.STOCK_FIND)
96
338 by Daniel Schierbeck
Added Preferences menu item.
97
        edit_menu_prefs = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES)
98
        edit_menu_prefs.connect('activate', lambda x: PreferencesWindow(self.branch.get_config()).show())
99
340 by Daniel Schierbeck
Added edit->find menu item stub.
100
        edit_menu.add(edit_menu_find)
338 by Daniel Schierbeck
Added Preferences menu item.
101
        edit_menu.add(edit_menu_prefs)
102
331 by Daniel Schierbeck
Added basic menu bar.
103
        go_menu = gtk.Menu()
334 by Daniel Schierbeck
Added icons to menus.
104
        go_menuitem = gtk.MenuItem("_Go")
331 by Daniel Schierbeck
Added basic menu bar.
105
        go_menuitem.set_submenu(go_menu)
106
        
334 by Daniel Schierbeck
Added icons to menus.
107
        go_menu_back = gtk.ImageMenuItem(gtk.STOCK_GO_BACK)
108
        go_menu_back.connect("activate", self._back_clicked_cb)
109
110
        go_menu_forward = gtk.ImageMenuItem(gtk.STOCK_GO_FORWARD)
111
        go_menu_forward.connect("activate", self._fwd_clicked_cb)
331 by Daniel Schierbeck
Added basic menu bar.
112
332 by Daniel Schierbeck
Made tag selection work.
113
        tags_menu = gtk.Menu()
334 by Daniel Schierbeck
Added icons to menus.
114
        go_menu_tags = gtk.MenuItem("_Tags")
115
        go_menu_tags.set_submenu(tags_menu)
332 by Daniel Schierbeck
Made tag selection work.
116
117
        for (tag, revid) in self.branch.tags.get_tag_dict().items():
118
            tag_item = gtk.MenuItem(tag)
119
            tag_item.connect('activate', self._tag_selected_cb, revid)
120
            tags_menu.add(tag_item)
121
334 by Daniel Schierbeck
Added icons to menus.
122
        go_menu.add(go_menu_back)
123
        go_menu.add(go_menu_forward)
124
        go_menu.add(gtk.SeparatorMenuItem())
125
        go_menu.add(go_menu_tags)
126
335 by Daniel Schierbeck
Added Revision menu.
127
        revision_menu = gtk.Menu()
128
        revision_menuitem = gtk.MenuItem("_Revision")
129
        revision_menuitem.set_submenu(revision_menu)
130
336 by Daniel Schierbeck
Changed wording to comply with HIG guidelines.
131
        revision_menu.add(gtk.MenuItem("Tag Revision"))
132
        revision_menu.add(gtk.MenuItem("View Changes"))
335 by Daniel Schierbeck
Added Revision menu.
133
334 by Daniel Schierbeck
Added icons to menus.
134
        branch_menu = gtk.Menu()
135
        branch_menuitem = gtk.MenuItem("_Branch")
136
        branch_menuitem.set_submenu(branch_menu)
137
336 by Daniel Schierbeck
Changed wording to comply with HIG guidelines.
138
        branch_menu.add(gtk.MenuItem("Pu_ll Revisions"))
139
        branch_menu.add(gtk.MenuItem("Pu_sh Revisions"))
334 by Daniel Schierbeck
Added icons to menus.
140
       
331 by Daniel Schierbeck
Added basic menu bar.
141
        menubar.add(file_menuitem)
338 by Daniel Schierbeck
Added Preferences menu item.
142
        menubar.add(edit_menuitem)
331 by Daniel Schierbeck
Added basic menu bar.
143
        menubar.add(go_menuitem)
335 by Daniel Schierbeck
Added Revision menu.
144
        menubar.add(revision_menuitem)
331 by Daniel Schierbeck
Added basic menu bar.
145
        menubar.add(branch_menuitem)
146
        menubar.show_all()
147
148
        return menubar
280.2.1 by Gary van der Merwe
Add a message to the viz window to indicate that graph is still loading.
149
    
150
    def construct_loading_msg(self):
151
        image_loading = gtk.image_new_from_stock(gtk.STOCK_REFRESH,
152
                                                 gtk.ICON_SIZE_BUTTON)
153
        image_loading.show()
154
        
155
        label_loading = gtk.Label(_("Please wait, loading ancestral graph..."))
331 by Daniel Schierbeck
Added basic menu bar.
156
        label_loading.set_alignment(0.0, 0.5)  
280.2.1 by Gary van der Merwe
Add a message to the viz window to indicate that graph is still loading.
157
        label_loading.show()
158
        
159
        self.loading_msg_box = gtk.HBox()
160
        self.loading_msg_box.set_spacing(5)
161
        self.loading_msg_box.set_border_width(5)        
162
        self.loading_msg_box.pack_start(image_loading, False, False)
163
        self.loading_msg_box.pack_start(label_loading, True, True)
164
        self.loading_msg_box.show()
165
        
166
        return self.loading_msg_box
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
167
168
    def construct_top(self):
169
        """Construct the top-half of the window."""
329 by Jelmer Vernooij
Make broken_line_length setting from higher up.
170
        # FIXME: Make broken_line_length configurable
171
        self.treeview = TreeView(self.branch, self.start, self.maxnum, 32)
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
172
310 by Daniel Schierbeck
Moved to using custom signal for handling revision selections.
173
        self.treeview.connect("revision-selected",
303 by Daniel Schierbeck
Made basic signaling work.
174
                self._treeselection_changed_cb)
175
307 by Daniel Schierbeck
Made load notification work again.
176
        self.treeview.connect('revisions-loaded', 
177
                lambda x: self.loading_msg_box.hide())
178
1 by Scott James Remnant
Commit the first version of bzrk.
179
        self.treeview.show()
180
303 by Daniel Schierbeck
Made basic signaling work.
181
        return self.treeview
44 by David Allouche
reorganise branch window
182
183
    def construct_navigation(self):
184
        """Construct the navigation buttons."""
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
185
        self.toolbar = gtk.Toolbar()
186
        self.toolbar.set_style(gtk.TOOLBAR_BOTH_HORIZ)
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
187
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
188
        self.back_button = gtk.ToolButton(stock_id=gtk.STOCK_GO_BACK)
189
        self.back_button.set_is_important(True)
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
190
        self.back_button.add_accelerator("clicked", self.accel_group, ord('['),
191
                                         0, 0)
192
        self.back_button.connect("clicked", self._back_clicked_cb)
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
193
        self.toolbar.insert(self.back_button, -1)
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
194
        self.back_button.show()
195
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
196
        self.fwd_button = gtk.ToolButton(stock_id=gtk.STOCK_GO_FORWARD)
197
        self.fwd_button.set_is_important(True)
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
198
        self.fwd_button.add_accelerator("clicked", self.accel_group, ord(']'),
199
                                        0, 0)
200
        self.fwd_button.connect("clicked", self._fwd_clicked_cb)
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
201
        self.toolbar.insert(self.fwd_button, -1)
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
202
        self.fwd_button.show()
203
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
204
        self.toolbar.show()
205
206
        return self.toolbar
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
207
208
    def construct_bottom(self):
209
        """Construct the bottom half of the window."""
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
210
        from bzrlib.plugins.gtk.revisionview import RevisionView
211
        self.revisionview = RevisionView(None, tags=[], show_children=True, branch=self.branch)
44 by David Allouche
reorganise branch window
212
        (width, height) = self.get_size()
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
213
        self.revisionview.set_size_request(width, int(height / 2.5))
214
        self.revisionview.show()
215
        self.revisionview.set_show_callback(self._show_clicked_cb)
216
        self.revisionview.set_go_callback(self._go_clicked_cb)
217
        return self.revisionview
332 by Daniel Schierbeck
Made tag selection work.
218
219
    def _tag_selected_cb(self, menuitem, revid):
220
        self.treeview.set_revision(revid)
341 by Daniel Schierbeck
Merged with trunk.
221
280.1.2 by Daniel Schierbeck
Switched to handle the 'changed' signal from the treeview's treeselection instead of the 'cursor-changed' signal from the treeview itself, allowing more flexibility (particularly the ability to handle programmatic selections)
222
    def _treeselection_changed_cb(self, selection, *args):
303 by Daniel Schierbeck
Made basic signaling work.
223
        """callback for when the treeview changes."""
224
        revision = self.treeview.get_revision()
225
        parents  = self.treeview.get_parents()
226
        children = self.treeview.get_children()
227
228
        if revision is not None:
256.2.62 by Gary van der Merwe
Merge Trunk.
229
            self.back_button.set_sensitive(len(parents) > 0)
230
            self.fwd_button.set_sensitive(len(children) > 0)
280.1.2 by Daniel Schierbeck
Switched to handle the 'changed' signal from the treeview's treeselection instead of the 'cursor-changed' signal from the treeview itself, allowing more flexibility (particularly the ability to handle programmatic selections)
231
            tags = []
232
            if self.branch.supports_tags():
233
                tagdict = self.branch.tags.get_reverse_tag_dict()
234
                if tagdict.has_key(revision.revision_id):
235
                    tags = tagdict[revision.revision_id]
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
236
            self.revisionview.set_revision(revision, tags, children)
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
237
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
238
    def _back_clicked_cb(self, *args):
239
        """Callback for when the back button is clicked."""
304 by Daniel Schierbeck
Made forward/back buttons work again.
240
        self.treeview.back()
241
        
5 by Scott James Remnant
Reverse the meaning of the Back and Forward buttons so Back actually
242
    def _fwd_clicked_cb(self, *args):
243
        """Callback for when the forward button is clicked."""
304 by Daniel Schierbeck
Made forward/back buttons work again.
244
        self.treeview.forward()
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
245
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
246
    def _go_clicked_cb(self, revid):
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
247
        """Callback for when the go button for a parent is clicked."""
305 by Daniel Schierbeck
Moved revision selection to the new view.
248
        self.treeview.set_revision(revid)
152 by Jelmer Vernooij
Cleanup some more code.
249
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
250
    def _show_clicked_cb(self, revid, parentid):
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
251
        """Callback for when the show button for a parent is clicked."""
308 by Daniel Schierbeck
Made Show Diff work again.
252
        self.treeview.show_diff(self.branch, revid, parentid)
13 by Scott James Remnant
Keep the focus on the treeview
253
        self.treeview.grab_focus()
46 by Wouter van Heyst
show diff on row activation, LP# 44591
254