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