/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
0.2.4 by Dan Loda
Extract class SpanSelector out of GAnnotateWindow.
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
0.1.14 by Dan Loda
Remember custom spans across sessions.
40
    custom_spans = []
0.2.4 by Dan Loda
Extract class SpanSelector out of GAnnotateWindow.
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
0.1.14 by Dan Loda
Remember custom spans across sessions.
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):
0.2.4 by Dan Loda
Extract class SpanSelector out of GAnnotateWindow.
121
            self.custom_iter = self.model.insert_after(self.custom_iter,
122
                                                       self.separator)
123
            self.custom_iter_top = self.custom_iter.copy()
0.1.14 by Dan Loda
Remember custom spans across sessions.
124
        
125
        if len(self.custom_spans) == self.max_custom_spans:
126
            self.custom_spans.pop(0)
0.2.4 by Dan Loda
Extract class SpanSelector out of GAnnotateWindow.
127
            self.model.remove(self.model.iter_next(self.custom_iter_top))
0.1.14 by Dan Loda
Remember custom spans across sessions.
128
        
129
        self.custom_spans.append(span)
0.2.4 by Dan Loda
Extract class SpanSelector out of GAnnotateWindow.
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
0.1.14 by Dan Loda
Remember custom spans across sessions.
188
0.2.4 by Dan Loda
Extract class SpanSelector out of GAnnotateWindow.
189
"""The "span-changed" signal is emitted when a new span has been selected or
190
entered.
191
0.1.14 by Dan Loda
Remember custom spans across sessions.
192
Callback signature: def callback(SpanSelector, span, [user_param, ...])
0.2.4 by Dan Loda
Extract class SpanSelector out of GAnnotateWindow.
193
"""
194
gobject.signal_new("span-changed", SpanSelector,
195
                   gobject.SIGNAL_RUN_LAST,
196
                   gobject.TYPE_NONE,
197
                   (gobject.TYPE_FLOAT,))
198
0.1.14 by Dan Loda
Remember custom spans across sessions.
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