6
Popup window for viewing notifications.
13
class MessageWindow(gtk.Window):
14
"""Shows the log of notification messages."""
15
def __init__(self, parent, limit_messages = 5):
16
gtk.Window.__init__(self)
19
self._limit_messages = limit_messages
21
self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK)
22
self.set_decorated(False)
23
self.set_resizable(False)
25
self.set_title("Message Window")
26
self.set_border_width(5)
27
self.set_size_request(400, -1)
29
self._vbox = gtk.VBox(True, 5)
32
self._empty_label = gtk.Label("No messages")
33
self._vbox.pack_start(self._empty_label)
37
def add_message(self, message):
38
"""Adds a message to the message window."""
39
widget = MessageWidget(message)
40
self._messages.append(widget)
41
self._vbox.pack_start(widget)
43
if self._empty_label != None:
44
self._vbox.remove(self._empty_label)
45
self._empty_label.destroy()
46
self._empty_label = None
48
if len(self._messages) > self._limit_messages:
49
message = self._messages.pop(0)
50
self._vbox.remove(message)
53
def align_with_parent(self):
54
"""Adapted from position_calendar_popup in the GNOME clock applet."""
55
# Get the size of the applet button and the size of this window
56
x, y = self._parent.get_origin()
57
w, h = self.size_request()
58
button_w, button_h = self._parent.get_size()
60
screen = self.get_screen()
63
# Figure out which monitor we are on
64
for i in range(screen.get_n_monitors()):
65
m = screen.get_monitor_geometry(i)
67
if x >= m.x and x <= m.x + m.width and y >= m.y and y <= m.y + m.height:
73
monitor = gtk.gdk.Rectangle(0, 0, screen.get_width(), screen.get_height())
75
orient = self._parent.get_orient()
77
# Figure out the x, y coordinates of the window and the gravity depending
78
# on the orientation of the panel
79
if orient == gnomeapplet.ORIENT_RIGHT: # Panel on left
81
if (y + h) > monitor.y + monitor.height:
82
y -= (y + h) - (monitor.y + monitor.height)
84
if (y + h) > (monitor.height / 2):
85
gravity = gtk.gdk.GRAVITY_SOUTH_WEST
87
gravity = gtk.gdk.GRAVITY_NORTH_WEST
89
elif orient == gnomeapplet.ORIENT_LEFT: # Panel on right
91
if (y + h) > monitor.y + monitor.height:
92
y -= (y + h) - (monitor.y + monitor.height)
94
if (y + h) > (monitor.height / 2):
95
gravity = gtk.gdk.GRAVITY_SOUTH_EAST
97
gravity = gtk.gdk.GRAVITY_NORTH_EAST
99
elif orient == gnomeapplet.ORIENT_DOWN: # Panel on top
101
if (x + w) > monitor.x + monitor.width:
102
x -= (x + w) - (monitor.x + monitor.width)
104
gravity = gtk.gdk.GRAVITY_NORTH_WEST
106
else: # Panel on bottom
108
if (x + w) > monitor.x + monitor.width:
109
x -= (x + w) - (monitor.x + monitor.width)
111
gravity = gtk.gdk.GRAVITY_SOUTH_WEST
114
self.set_gravity(gravity)
116
class MessageWidget(gtk.Frame):
117
"""Widget to display a Notifications.Message."""
118
def __init__(self, message):
119
gtk.Frame.__init__(self)
121
self._message = message
123
self._vbox = gtk.VBox(False)
126
self._hbox = gtk.HBox(False)
127
self._vbox.pack_start(self._hbox, True, True)
129
icon_pixbuf = message.get_icon_pixbuf()
130
if icon_pixbuf != None:
131
self._icon_image = gtk.image_new_from_pixbuf(icon_pixbuf)
132
self._icon_image.set_alignment(0, 0)
133
self._icon_image.set_padding(5, 5)
134
self._hbox.pack_start(self._icon_image, False, False)
136
self._text_vbox = gtk.VBox(False)
137
self._hbox.pack_start(self._text_vbox, True, True)
139
self._title_label = gtk.Label(message.summary)
140
self._title_label.set_alignment(0, 0)
141
self._title_label.set_padding(5, 5)
142
attr = pango.AttrList()
143
attr.insert(pango.AttrWeight(pango.WEIGHT_BOLD, 0, -1))
144
self._title_label.set_attributes(attr)
145
self._text_vbox.pack_start(self._title_label, False, False)
147
self._body_label = MessageBody(message.body)
148
self._body_label.set_alignment(0, 0)
149
self._body_label.set_padding(5, 5)
150
self._body_label.set_line_wrap(True)
151
self._text_vbox.pack_start(self._body_label, True, True)
153
self._timestamp_label = gtk.Label(message.formatted_timestamp() + " from " + message.app_name)
154
self._timestamp_label.set_padding(5, 5)
155
attr = pango.AttrList()
156
attr.insert(pango.AttrScale(pango.SCALE_SMALL, 0, -1))
157
self._timestamp_label.set_attributes(attr)
158
self._vbox.pack_start(self._timestamp_label, False, False)
160
class MessageBody(gtk.Label):
161
"""Implements a workaround from:
162
http://www.16software.com/blog/dynamic-label-wrapping-in-gtk
163
that fixes the label overflow problems I have been having
164
with a long message body."""
165
def __init__(self, text):
166
gtk.Label.__init__(self, text)
168
self.set_line_wrap(True)
169
self.connect("size-allocate", self.on_size_allocate)
171
def on_size_allocate(self, widget, rect):
172
self.set_size_request(rect.width - 10, -1)