/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 annotate/spanselector.py

  • Committer: Vincent Ladeuil
  • Date: 2008-06-10 15:25:47 UTC
  • mto: This revision was merged to the branch mainline in revision 504.
  • Revision ID: v.ladeuil+lp@free.fr-20080610152547-dwmil1p8pd0mfpnl
Fix third failing test (thanks to jam).

* tests/test_commit.py:
(TestPendingRevisions.test_pending_revisions_multi_merge): Fix
provided by jam: bzr we now filter the pending merges so that only
the 'heads()' are included. We just ensure that the pending merges
contain the unique tips for the ancestries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005 Dan Loda <danloda@gmail.com>
 
2
 
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
 
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
 
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
 
 
18
import pygtk
 
19
pygtk.require("2.0")
 
20
import gobject
 
21
import gtk
 
22
 
 
23
 
 
24
(
 
25
    SPAN_DAYS_COL,
 
26
    SPAN_STR_COL,
 
27
    SPAN_IS_SEPARATOR_COL,
 
28
    SPAN_IS_CUSTOM_COL
 
29
) = range(4)
 
30
 
 
31
 
 
32
class SpanSelector(gtk.HBox):
 
33
    """Encapsulates creation and functionality of widgets used for changing
 
34
    highlight spans.
 
35
    
 
36
    Note that calling any activate_* methods will emit "span-changed".
 
37
    """
 
38
    
 
39
    max_custom_spans = 4
 
40
    custom_spans = []
 
41
    last_selected = None
 
42
 
 
43
    def __init__(self, homogeneous=False, spacing=6):
 
44
        gtk.HBox.__init__(self, homogeneous, spacing)
 
45
 
 
46
        self.model = self._create_model()
 
47
        self.combo = self._create_combobox(self.model)
 
48
        self.entry = self._create_custom_entry()
 
49
 
 
50
        label = gtk.Label("Highlighting spans:")
 
51
        label.show()
 
52
 
 
53
        self.pack_start(label, expand=False, fill=True)
 
54
        self.pack_start(self.combo, expand=False, fill=False)
 
55
        self.pack_start(self.entry, expand=False, fill=False)
 
56
 
 
57
    def set_to_oldest_span(self, span):
 
58
        """Set the span associated with the "to Oldest Revision" entry."""
 
59
        self.model.set_value(self.oldest_iter, SPAN_DAYS_COL, span)
 
60
 
 
61
    def set_newest_to_oldest_span(self, span):
 
62
        """Set the span associated with the "Newest to Oldset" entry."""
 
63
        self.model.set_value(self.newest_iter, SPAN_DAYS_COL, span)
 
64
 
 
65
    def set_max_custom_spans(self, n):
 
66
        """Store up to n custom span entries in the combo box."""
 
67
        self.max_custom_spans = n
 
68
 
 
69
    def activate(self, iter):
 
70
        """Activate the row pointed to by gtk.TreeIter iter."""
 
71
        index = self._get_index_from_iter(iter)
 
72
        self.combo.set_active(index)
 
73
 
 
74
    def activate_last_selected(self):
 
75
        """Activate the previously selected row.
 
76
 
 
77
        Expected to be used when cancelling custom entry or revieved bad
 
78
        input.
 
79
        """
 
80
        if self.last_selected:
 
81
            self.activate(self.last_selected)
 
82
 
 
83
    def activate_default(self):
 
84
        """Activate the default row."""
 
85
        # TODO allow setting of default?
 
86
        self.activate(self.oldest_iter)
 
87
 
 
88
    def _get_index_from_iter(self, iter):
 
89
        """Returns a row index integer from iterator."""
 
90
        return int(self.model.get_string_from_iter(iter))
 
91
 
 
92
    def _combo_changed_cb(self, w):
 
93
        model = w.get_model()
 
94
        iter = w.get_active_iter()
 
95
 
 
96
        if model.get_value(iter, SPAN_IS_CUSTOM_COL):
 
97
            self._request_custom_span()
 
98
        else:
 
99
            self.last_selected = iter
 
100
            self.emit("span-changed", model.get_value(iter, SPAN_DAYS_COL))
 
101
 
 
102
    def _activate_custom_span_cb(self, w):
 
103
        self.entry.hide_all()
 
104
        self.combo.show()
 
105
 
 
106
        span = float(w.get_text())
 
107
        
 
108
        if span == 0:
 
109
            # FIXME this works as "cancel", returning to the previous span,
 
110
            # but it emits "span-changed", which isn't necessary.
 
111
            self.activate_last_selected()
 
112
            return
 
113
 
 
114
        self.add_custom_span(span)
 
115
        self.emit("custom-span-added", span)
 
116
 
 
117
        self.activate(self.custom_iter)
 
118
 
 
119
    def add_custom_span(self, span):
 
120
        if not len(self.custom_spans):
 
121
            self.custom_iter = self.model.insert_after(self.custom_iter,
 
122
                                                       self.separator)
 
123
            self.custom_iter_top = self.custom_iter.copy()
 
124
        
 
125
        if len(self.custom_spans) == self.max_custom_spans:
 
126
            self.custom_spans.pop(0)
 
127
            self.model.remove(self.model.iter_next(self.custom_iter_top))
 
128
        
 
129
        self.custom_spans.append(span)
 
130
        self.custom_iter = self.model.insert_after(
 
131
            self.custom_iter, [span, "%.2f Days" % span, False, False])
 
132
 
 
133
    def _request_custom_span(self):
 
134
        self.combo.hide()
 
135
        self.entry.show_all()
 
136
 
 
137
    def _create_model(self):
 
138
        # [span in days, span as string, row is seperator?, row is select
 
139
        # default?]
 
140
        m = gtk.ListStore(gobject.TYPE_FLOAT,
 
141
                          gobject.TYPE_STRING,
 
142
                          gobject.TYPE_BOOLEAN,
 
143
                          gobject.TYPE_BOOLEAN)
 
144
 
 
145
        self.separator = [0., "", True, False]
 
146
        
 
147
        self.oldest_iter = m.append([0., "to Oldest Revision", False, False])
 
148
        self.newest_iter = m.append([0., "Newest to Oldest", False, False])
 
149
        m.append(self.separator)
 
150
        m.append([1., "1 Day", False, False])
 
151
        m.append([7., "1 Week", False, False])
 
152
        m.append([30., "1 Month", False, False])
 
153
        self.custom_iter = m.append([365., "1 Year", False, False])
 
154
        m.append(self.separator)
 
155
        m.append([0., "Custom...", False, True])
 
156
 
 
157
        return m
 
158
 
 
159
    def _create_combobox(self, model):
 
160
        cb = gtk.ComboBox(model)
 
161
        cb.set_row_separator_func(
 
162
            lambda m, i: m.get_value(i, SPAN_IS_SEPARATOR_COL))
 
163
        cell = gtk.CellRendererText()
 
164
        cb.pack_start(cell, False)
 
165
        cb.add_attribute(cell, "text", SPAN_STR_COL)
 
166
        cb.connect("changed", self._combo_changed_cb)
 
167
        cb.show()
 
168
 
 
169
        return cb
 
170
 
 
171
    def _create_custom_entry(self):
 
172
        entry = gtk.HBox(False, 6)
 
173
        
 
174
        spin = gtk.SpinButton(digits=2)
 
175
        spin.set_numeric(True)
 
176
        spin.set_increments(1., 10.)
 
177
        spin.set_range(0., 100 * 365) # I presume 100 years is sufficient
 
178
        spin.connect("activate", self._activate_custom_span_cb)
 
179
        spin.connect("show", lambda w: w.grab_focus())
 
180
 
 
181
        label = gtk.Label("Days")
 
182
 
 
183
        entry.pack_start(spin, expand=False, fill=False)
 
184
        entry.pack_start(label, expand=False, fill=False)
 
185
 
 
186
        return entry
 
187
 
 
188
 
 
189
"""The "span-changed" signal is emitted when a new span has been selected or
 
190
entered.
 
191
 
 
192
Callback signature: def callback(SpanSelector, span, [user_param, ...])
 
193
"""
 
194
gobject.signal_new("span-changed", SpanSelector,
 
195
                   gobject.SIGNAL_RUN_LAST,
 
196
                   gobject.TYPE_NONE,
 
197
                   (gobject.TYPE_FLOAT,))
 
198
 
 
199
"""The "custom-span-added" signal is emitted after a custom span has been
 
200
added, but before it has been selected.
 
201
 
 
202
Callback signature: def callback(SpanSelector, span, [user_param, ...])
 
203
"""
 
204
gobject.signal_new("custom-span-added", SpanSelector,
 
205
                   gobject.SIGNAL_RUN_LAST,
 
206
                   gobject.TYPE_NONE,
 
207
                   (gobject.TYPE_FLOAT,))
 
208