/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: Jelmer Vernooij
  • Date: 2012-03-29 13:15:14 UTC
  • mfrom: (786.1.1 register-lazy)
  • Revision ID: jelmer@samba.org-20120329131514-knrl1w2wzntx89rv
Use lazy registration.

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
from gi.repository import GObject
 
19
from gi.repository import Gtk
 
20
 
 
21
 
 
22
(
 
23
    SPAN_DAYS_COL,
 
24
    SPAN_STR_COL,
 
25
    SPAN_IS_SEPARATOR_COL,
 
26
    SPAN_IS_CUSTOM_COL
 
27
) = range(4)
 
28
 
 
29
 
 
30
class SpanSelector(Gtk.HBox):
 
31
    """Encapsulates creation and functionality of widgets used for changing
 
32
    highlight spans.
 
33
 
 
34
    Note that calling any activate_* methods will emit "span-changed".
 
35
    """
 
36
 
 
37
    max_custom_spans = 4
 
38
    custom_spans = []
 
39
    last_selected = None
 
40
 
 
41
    def __init__(self, homogeneous=False, spacing=6):
 
42
        super(SpanSelector, self).__init__(
 
43
            homogeneous=homogeneous, spacing=spacing)
 
44
 
 
45
        self.model = self._create_model()
 
46
        self.combo = self._create_combobox(self.model)
 
47
        self.entry = self._create_custom_entry()
 
48
 
 
49
        label = Gtk.Label(label="Highlighting spans:")
 
50
        label.show()
 
51
 
 
52
        self.pack_start(label, False, True, True, 0)
 
53
        self.pack_start(self.combo, False, False, True, 0)
 
54
        self.pack_start(self.entry, False, False, True, 0)
 
55
 
 
56
    def set_to_oldest_span(self, span):
 
57
        """Set the span associated with the "to Oldest Revision" entry."""
 
58
        self.model.set_value(self.oldest_iter, SPAN_DAYS_COL, span)
 
59
 
 
60
    def set_newest_to_oldest_span(self, span):
 
61
        """Set the span associated with the "Newest to Oldset" entry."""
 
62
        self.model.set_value(self.newest_iter, SPAN_DAYS_COL, span)
 
63
 
 
64
    def set_max_custom_spans(self, n):
 
65
        """Store up to n custom span entries in the combo box."""
 
66
        self.max_custom_spans = n
 
67
 
 
68
    def activate(self, iter):
 
69
        """Activate the row pointed to by Gtk.TreeIter iter."""
 
70
        index = self._get_index_from_iter(iter)
 
71
        self.combo.set_active(index)
 
72
 
 
73
    def activate_last_selected(self):
 
74
        """Activate the previously selected row.
 
75
 
 
76
        Expected to be used when cancelling custom entry or revieved bad
 
77
        input.
 
78
        """
 
79
        if self.last_selected:
 
80
            self.activate(self.last_selected)
 
81
 
 
82
    def activate_default(self):
 
83
        """Activate the default row."""
 
84
        # TODO allow setting of default?
 
85
        self.activate(self.oldest_iter)
 
86
 
 
87
    def _get_index_from_iter(self, iter):
 
88
        """Returns a row index integer from iterator."""
 
89
        return int(self.model.get_string_from_iter(iter))
 
90
 
 
91
    def _combo_changed_cb(self, w):
 
92
        model = w.get_model()
 
93
        iter = w.get_active_iter()
 
94
 
 
95
        if model.get_value(iter, SPAN_IS_CUSTOM_COL):
 
96
            self._request_custom_span()
 
97
        else:
 
98
            self.last_selected = iter
 
99
            self.emit("span-changed", model.get_value(iter, SPAN_DAYS_COL))
 
100
 
 
101
    def _activate_custom_span_cb(self, w):
 
102
        self.entry.hide()
 
103
        self.combo.show()
 
104
 
 
105
        span = float(w.get_text())
 
106
 
 
107
        if span == 0:
 
108
            # FIXME this works as "cancel", returning to the previous span,
 
109
            # but it emits "span-changed", which isn't necessary.
 
110
            self.activate_last_selected()
 
111
            return
 
112
 
 
113
        self.add_custom_span(span)
 
114
        self.emit("custom-span-added", span)
 
115
 
 
116
        self.activate(self.custom_iter)
 
117
 
 
118
    def add_custom_span(self, span):
 
119
        if not len(self.custom_spans):
 
120
            self.custom_iter = self.model.insert_after(self.custom_iter,
 
121
                                                       self.separator)
 
122
            self.custom_iter_top = self.custom_iter.copy()
 
123
 
 
124
        if len(self.custom_spans) == self.max_custom_spans:
 
125
            self.custom_spans.pop(0)
 
126
            self.model.remove(self.model.iter_next(self.custom_iter_top))
 
127
 
 
128
        self.custom_spans.append(span)
 
129
        self.custom_iter = self.model.insert_after(
 
130
            self.custom_iter, [span, "%.2f Days" % span, False, False])
 
131
 
 
132
    def _request_custom_span(self):
 
133
        self.combo.hide()
 
134
        self.entry.show_all()
 
135
 
 
136
    def _create_model(self):
 
137
        # [span in days, span as string, row is seperator?, row is select
 
138
        # default?]
 
139
        m = Gtk.ListStore(GObject.TYPE_FLOAT,
 
140
                          GObject.TYPE_STRING,
 
141
                          GObject.TYPE_BOOLEAN,
 
142
                          GObject.TYPE_BOOLEAN)
 
143
 
 
144
        self.separator = [0., "", True, False]
 
145
 
 
146
        self.oldest_iter = m.append([0., "to Oldest Revision", False, False])
 
147
        self.newest_iter = m.append([0., "Newest to Oldest", False, False])
 
148
        m.append(self.separator)
 
149
        m.append([1., "1 Day", False, False])
 
150
        m.append([7., "1 Week", False, False])
 
151
        m.append([30., "1 Month", False, False])
 
152
        self.custom_iter = m.append([365., "1 Year", False, False])
 
153
        m.append(self.separator)
 
154
        m.append([0., "Custom...", False, True])
 
155
 
 
156
        return m
 
157
 
 
158
    def _create_combobox(self, model):
 
159
        cb = Gtk.ComboBox(model)
 
160
        cb.set_row_separator_func(
 
161
            lambda m, i: m.get_value(i, SPAN_IS_SEPARATOR_COL))
 
162
        cell = Gtk.CellRendererText()
 
163
        cb.pack_start(cell, False)
 
164
        cb.add_attribute(cell, "text", SPAN_STR_COL)
 
165
        cb.connect("changed", self._combo_changed_cb)
 
166
        cb.show()
 
167
 
 
168
        return cb
 
169
 
 
170
    def _create_custom_entry(self):
 
171
        entry = Gtk.HBox(False, 6)
 
172
 
 
173
        spin = Gtk.SpinButton(digits=2)
 
174
        spin.set_numeric(True)
 
175
        spin.set_increments(1., 10.)
 
176
        spin.set_range(0., 100 * 365) # I presume 100 years is sufficient
 
177
        spin.connect("activate", self._activate_custom_span_cb)
 
178
        spin.connect("show", lambda w: w.grab_focus())
 
179
 
 
180
        label = Gtk.Label(label="Days")
 
181
 
 
182
        entry.pack_start(spin, False, False, True, 0)
 
183
        entry.pack_start(label, False, False, True, 0)
 
184
 
 
185
        return entry
 
186
 
 
187
 
 
188
"""The "span-changed" signal is emitted when a new span has been selected or
 
189
entered.
 
190
 
 
191
Callback signature: def callback(SpanSelector, span, [user_param, ...])
 
192
"""
 
193
GObject.signal_new("span-changed", SpanSelector,
 
194
                   GObject.SignalFlags.RUN_LAST,
 
195
                   None,
 
196
                   (GObject.TYPE_FLOAT,))
 
197
 
 
198
"""The "custom-span-added" signal is emitted after a custom span has been
 
199
added, but before it has been selected.
 
200
 
 
201
Callback signature: def callback(SpanSelector, span, [user_param, ...])
 
202
"""
 
203
GObject.signal_new("custom-span-added", SpanSelector,
 
204
                   GObject.SignalFlags.RUN_LAST,
 
205
                   None,
 
206
                   (GObject.TYPE_FLOAT,))
 
207