/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
256.2.29 by Gary van der Merwe
Implement a TreeModel that loads revisions incrementaly.
15
import treemodel
1 by Scott James Remnant
Commit the first version of bzrk.
16
298.2.1 by Daniel Schierbeck
Refactored the GTK window code, creating a single base window class that handles keyboard events.
17
from bzrlib.plugins.gtk.window import Window
1 by Scott James Remnant
Commit the first version of bzrk.
18
from bzrlib.osutils import format_date
330.2.5 by Daniel Schierbeck
Support persistence of compact view option.
19
from bzrlib.config import GlobalConfig
1 by Scott James Remnant
Commit the first version of bzrk.
20
256.2.5 by Gary van der Merwe
Oops - Renamed file without changeing import lines
21
from linegraph import linegraph, same_branch
1 by Scott James Remnant
Commit the first version of bzrk.
22
from graphcell import CellRendererGraph
256.2.29 by Gary van der Merwe
Implement a TreeModel that loads revisions incrementaly.
23
from treemodel import TreeModel
303 by Daniel Schierbeck
Made basic signaling work.
24
from treeview  import TreeView
1 by Scott James Remnant
Commit the first version of bzrk.
25
298.2.1 by Daniel Schierbeck
Refactored the GTK window code, creating a single base window class that handles keyboard events.
26
class BranchWindow(Window):
1 by Scott James Remnant
Commit the first version of bzrk.
27
    """Branch window.
28
29
    This object represents and manages a single window containing information
30
    for a particular branch.
31
    """
32
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
33
    def __init__(self, branch, start, maxnum, parent=None):
322 by Jelmer Vernooij
Add docstrings.
34
        """Create a new BranchWindow.
35
36
        :param branch: Branch object for branch to show.
37
        :param start: Revision id of top revision.
38
        :param maxnum: Maximum number of revisions to display, 
39
                       None for no limit.
40
        """
41
298.2.1 by Daniel Schierbeck
Refactored the GTK window code, creating a single base window class that handles keyboard events.
42
        Window.__init__(self, parent=parent)
1 by Scott James Remnant
Commit the first version of bzrk.
43
        self.set_border_width(0)
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
44
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
45
        self.branch      = branch
46
        self.start       = start
47
        self.maxnum      = maxnum
330.2.5 by Daniel Schierbeck
Support persistence of compact view option.
48
        self.config      = GlobalConfig()
49
50
        if self.config.get_user_option('viz-compact-view') == 'yes':
51
            self.compact_view = True
52
        else:
53
            self.compact_view = False
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
54
55
        self.set_title(branch.nick + " - revision history")
1 by Scott James Remnant
Commit the first version of bzrk.
56
57
        # Use three-quarters of the screen by default
58
        screen = self.get_screen()
4 by Scott James Remnant
Use the size of the first monitor rather than the entire screen
59
        monitor = screen.get_monitor_geometry(0)
60
        width = int(monitor.width * 0.75)
61
        height = int(monitor.height * 0.75)
1 by Scott James Remnant
Commit the first version of bzrk.
62
        self.set_default_size(width, height)
63
64
        # FIXME AndyFitz!
65
        icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
66
        self.set_icon(icon)
67
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
68
        self.accel_group = gtk.AccelGroup()
69
        self.add_accel_group(self.accel_group)
70
1 by Scott James Remnant
Commit the first version of bzrk.
71
        self.construct()
72
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
73
    def set_revision(self, revision):
74
        self.treeview.set_revision(revision)
75
1 by Scott James Remnant
Commit the first version of bzrk.
76
    def construct(self):
77
        """Construct the window contents."""
327.1.1 by Daniel Schierbeck
Added spacing between toolbar and treeview in the viz.
78
        vbox = gtk.VBox(spacing=5)
44 by David Allouche
reorganise branch window
79
        self.add(vbox)
80
81
        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.
82
        vbox.pack_start(self.construct_loading_msg(), expand=False, fill=True)
83
        
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
84
        self.paned = gtk.VPaned()
85
        self.paned.pack1(self.construct_top(), resize=True, shrink=False)
86
        self.paned.pack2(self.construct_bottom(), resize=False, shrink=True)
87
        self.paned.show()
88
        vbox.pack_start(self.paned, expand=True, fill=True)
89
        vbox.set_focus_child(self.paned)
44 by David Allouche
reorganise branch window
90
91
        vbox.show()
280.2.1 by Gary van der Merwe
Add a message to the viz window to indicate that graph is still loading.
92
    
93
    def construct_loading_msg(self):
94
        image_loading = gtk.image_new_from_stock(gtk.STOCK_REFRESH,
95
                                                 gtk.ICON_SIZE_BUTTON)
96
        image_loading.show()
97
        
98
        label_loading = gtk.Label(_("Please wait, loading ancestral graph..."))
99
        label_loading.set_alignment(0.0, 0.5)        
100
        label_loading.show()
101
        
102
        self.loading_msg_box = gtk.HBox()
103
        self.loading_msg_box.set_spacing(5)
104
        self.loading_msg_box.set_border_width(5)        
105
        self.loading_msg_box.pack_start(image_loading, False, False)
106
        self.loading_msg_box.pack_start(label_loading, True, True)
107
        self.loading_msg_box.show()
108
        
109
        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
110
111
    def construct_top(self):
112
        """Construct the top-half of the window."""
329 by Jelmer Vernooij
Make broken_line_length setting from higher up.
113
        # FIXME: Make broken_line_length configurable
330.2.5 by Daniel Schierbeck
Support persistence of compact view option.
114
        if self.compact_view:
115
            brokenlines = 32
116
        else:
117
            brokenlines = None
118
119
        self.treeview = TreeView(self.branch, self.start, self.maxnum, brokenlines)
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
120
310 by Daniel Schierbeck
Moved to using custom signal for handling revision selections.
121
        self.treeview.connect("revision-selected",
303 by Daniel Schierbeck
Made basic signaling work.
122
                self._treeselection_changed_cb)
123
307 by Daniel Schierbeck
Made load notification work again.
124
        self.treeview.connect('revisions-loaded', 
125
                lambda x: self.loading_msg_box.hide())
126
1 by Scott James Remnant
Commit the first version of bzrk.
127
        self.treeview.show()
128
303 by Daniel Schierbeck
Made basic signaling work.
129
        return self.treeview
44 by David Allouche
reorganise branch window
130
131
    def construct_navigation(self):
132
        """Construct the navigation buttons."""
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
133
        self.toolbar = gtk.Toolbar()
134
        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
135
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
136
        self.back_button = gtk.ToolButton(stock_id=gtk.STOCK_GO_BACK)
137
        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
138
        self.back_button.add_accelerator("clicked", self.accel_group, ord('['),
139
                                         0, 0)
140
        self.back_button.connect("clicked", self._back_clicked_cb)
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
141
        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
142
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
143
        self.fwd_button = gtk.ToolButton(stock_id=gtk.STOCK_GO_FORWARD)
144
        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
145
        self.fwd_button.add_accelerator("clicked", self.accel_group, ord(']'),
146
                                        0, 0)
147
        self.fwd_button.connect("clicked", self._fwd_clicked_cb)
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
148
        self.toolbar.insert(self.fwd_button, -1)
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
149
150
        self.toolbar.insert(gtk.SeparatorToolItem(), -1)
151
152
        brokenlines_button = gtk.ToggleToolButton()
153
        brokenlines_button.set_label("Compact View")
330.2.5 by Daniel Schierbeck
Support persistence of compact view option.
154
        brokenlines_button.set_active(self.compact_view)
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
155
        brokenlines_button.set_is_important(True)
156
        brokenlines_button.connect('toggled', self._brokenlines_toggled_cb)
157
        self.toolbar.insert(brokenlines_button, -1)
158
159
        self.toolbar.show_all()
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
160
161
        return self.toolbar
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
162
163
    def construct_bottom(self):
164
        """Construct the bottom half of the window."""
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
165
        from bzrlib.plugins.gtk.revisionview import RevisionView
166
        self.revisionview = RevisionView(None, tags=[], show_children=True, branch=self.branch)
44 by David Allouche
reorganise branch window
167
        (width, height) = self.get_size()
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
168
        self.revisionview.set_size_request(width, int(height / 2.5))
169
        self.revisionview.show()
170
        self.revisionview.set_show_callback(self._show_clicked_cb)
171
        self.revisionview.set_go_callback(self._go_clicked_cb)
172
        return self.revisionview
265.1.1 by Gary van der Merwe
Show bzr viz interface quickly.
173
    
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)
174
    def _treeselection_changed_cb(self, selection, *args):
303 by Daniel Schierbeck
Made basic signaling work.
175
        """callback for when the treeview changes."""
176
        revision = self.treeview.get_revision()
177
        parents  = self.treeview.get_parents()
178
        children = self.treeview.get_children()
179
180
        if revision is not None:
256.2.62 by Gary van der Merwe
Merge Trunk.
181
            self.back_button.set_sensitive(len(parents) > 0)
182
            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)
183
            tags = []
184
            if self.branch.supports_tags():
185
                tagdict = self.branch.tags.get_reverse_tag_dict()
186
                if tagdict.has_key(revision.revision_id):
187
                    tags = tagdict[revision.revision_id]
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
188
            self.revisionview.set_revision(revision, tags, children)
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
189
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
190
    def _back_clicked_cb(self, *args):
191
        """Callback for when the back button is clicked."""
304 by Daniel Schierbeck
Made forward/back buttons work again.
192
        self.treeview.back()
193
        
5 by Scott James Remnant
Reverse the meaning of the Back and Forward buttons so Back actually
194
    def _fwd_clicked_cb(self, *args):
195
        """Callback for when the forward button is clicked."""
304 by Daniel Schierbeck
Made forward/back buttons work again.
196
        self.treeview.forward()
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
197
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
198
    def _go_clicked_cb(self, revid):
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
199
        """Callback for when the go button for a parent is clicked."""
305 by Daniel Schierbeck
Moved revision selection to the new view.
200
        self.treeview.set_revision(revid)
152 by Jelmer Vernooij
Cleanup some more code.
201
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
202
    def _show_clicked_cb(self, revid, parentid):
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
203
        """Callback for when the show button for a parent is clicked."""
308 by Daniel Schierbeck
Made Show Diff work again.
204
        self.treeview.show_diff(self.branch, revid, parentid)
13 by Scott James Remnant
Keep the focus on the treeview
205
        self.treeview.grab_focus()
46 by Wouter van Heyst
show diff on row activation, LP# 44591
206
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
207
    def _brokenlines_toggled_cb(self, button):
330.2.5 by Daniel Schierbeck
Support persistence of compact view option.
208
        self.compact_view = button.get_active()
209
210
        if self.compact_view:
211
            option = 'yes'
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
212
        else:
330.2.5 by Daniel Schierbeck
Support persistence of compact view option.
213
            option = 'no'
214
215
        self.config.set_user_option('viz-compact-view', option)
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
216
217
        revision = self.treeview.get_revision()
218
219
        self.treeview.destroy()
220
        self.paned.pack1(self.construct_top(), resize=True, shrink=False)
221
222
        gobject.idle_add(self.set_revision, revision.revision_id)