1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """a view display messages containing warnings, errors and information."""
23
24 import gettext
25 import os
26 import time
27
28 import pango
29 import gtk
30
31 from flumotion.common import log
32 from flumotion.common.documentation import getMessageWebLink
33 from flumotion.common.i18n import Translator
34 from flumotion.common.messages import ERROR, WARNING, INFO
35 from flumotion.configure import configure
36 from flumotion.common.pygobject import gsignal
37
38 _ = gettext.gettext
39 __version__ = "$Rev: 8476 $"
40 _stock_icons = {
41 ERROR: gtk.STOCK_DIALOG_ERROR,
42 WARNING: gtk.STOCK_DIALOG_WARNING,
43 INFO: gtk.STOCK_DIALOG_INFO,
44 }
45 _headings = {
46 ERROR: _('Error'),
47 WARNING: _('Warning'),
48 INFO: _('Note'),
49 }
50
51
73
74
75
76
77
79 """
80 I am a widget that can show messages.
81 """
82
83
84
85 gsignal('resize-event', bool)
86
100
102 h1 = gtk.HBox()
103 self.pack_start(h1, False, False, 0)
104
105 self.hline = gtk.HSeparator()
106 h1.pack_start(self.hline, True, True, 3)
107
108 h2 = gtk.HBox()
109 h1.pack_end(h2, False, False, 0)
110 self.buttonbox = h2
111
112 sw = gtk.ScrolledWindow()
113 sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
114 sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
115 self.pack_start(sw, True, True, 0)
116 self.sw = sw
117
118
119
120 tv = gtk.TextView()
121 tv.set_wrap_mode(gtk.WRAP_WORD)
122 tv.set_left_margin(6)
123 tv.set_right_margin(6)
124 tv.set_accepts_tab(False)
125 tv.set_cursor_visible(False)
126 tv.set_editable(False)
127
128
129 tv.connect('event-after', self._after_textview__event)
130 tv.connect('motion-notify-event',
131 self._on_textview___motion_notify_event)
132 sw.add(tv)
133 self.textview = tv
134
135 self.show_all()
136
144
146 """
147 Add a message to me.
148 @type m: L{flumotion.common.messages.Message}
149 """
150
151
152
153 self.clearMessage(m.id)
154
155
156 b = MessageButton(m)
157 b.sigid = b.connect('toggled', self._on_message_button__toggled, m)
158 b.show()
159 self.buttonbox.pack_start(b, False, False, 0)
160
161 firstButton = self._sortMessages()
162
163 self.show()
164 if not self.active_button:
165 b.set_active(True)
166 elif b == firstButton:
167 b.set_active(True)
168
170 """
171 Clear all messages with the given id.
172 Will bring the remaining most important message to the front,
173 or hide the view completely if no messages are left.
174 """
175 for button in self.buttonbox.get_children():
176 if button.message.id != id:
177 continue
178
179 self.buttonbox.remove(button)
180 button.disconnect(button.sigid)
181 button.sigid = 0
182 if not self.buttonbox.get_children():
183 self.active_button = None
184 self.hide()
185 elif self.active_button == button:
186 self.active_button = self.buttonbox.get_children()[0]
187 self.active_button.set_active(True)
188 break
189
191 """Disable timestamps for this MessageView,
192 it will make it easier to understand the error messages and
193 make it suitable for end users.
194 """
195 self._disableTimestamps = True
196
197
198
231
233
234 children = [(-w.message.level, w.message.priority, w)
235 for w in self.buttonbox.get_children()]
236 children.sort()
237 children.reverse()
238 children = [(i, children[i][2]) for i in range(len(children))]
239 for child in children:
240 self.buttonbox.reorder_child(child[1], child[0])
241
242
243 return children[0][1]
244
245
246
265
266
267
269 x, y = textview.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET,
270 int(event.x), int(event.y))
271 tags = textview.get_iter_at_location(x, y).get_tags()
272
273
274 textview.window.get_pointer()
275
276
277 cursor = None
278 for tag in tags:
279 if tag.get_data('link'):
280 cursor = gtk.gdk.Cursor(gtk.gdk.HAND2)
281 break
282 textview.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(cursor)
283 return False
284
285 - def _after_textview__event(self, textview, event):
286 if event.type != gtk.gdk.BUTTON_RELEASE:
287 return False
288 if event.button != 1:
289 return False
290
291 textbuffer = textview.get_buffer()
292
293 bounds = textbuffer.get_selection_bounds()
294 if bounds:
295 [start, end] = bounds
296 if start.get_offset() != end.get_offset():
297 return False
298
299 x, y = textview.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET,
300 int(event.x), int(event.y))
301 iter = textview.get_iter_at_location(x, y)
302
303 for tag in iter.get_tags():
304 link = tag.get_data('link')
305 if link:
306 import webbrowser
307 log.debug('messageview', 'opening %s' % link)
308 webbrowser.open(link)
309 break
310
311 return False
312