6
Popup window for viewing notifications.
14
from string import Template
16
from MessageList import MessageList
17
from Translations import _
19
logger = logging.getLogger("MessageWindow")
22
"""Maps column names to column numbers."""
27
class MessageWindow(gtk.Window):
28
"""Shows the log of notification messages."""
29
def __init__(self, parent):
30
gtk.Window.__init__(self)
34
self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK)
35
self.set_decorated(False)
36
self.set_resizable(False)
37
self.set_property("skip-taskbar-hint", True)
39
self.set_title(_("Message Window"))
40
self.set_border_width(0)
41
self.set_size_request(400, 400)
43
self._frame = gtk.Frame()
44
self._frame.set_border_width(0)
45
self._frame.set_shadow_type(gtk.SHADOW_OUT)
48
self._vadjust = gtk.Adjustment()
49
self._vadjust.connect("changed", self.on_vadjust_changed)
51
self._vbox = gtk.VBox()
52
self._frame.add(self._vbox)
54
self._scroll = gtk.ScrolledWindow(vadjustment=self._vadjust)
55
self._scroll.set_border_width(5)
56
self._scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
57
self._scroll.connect("size-allocate", self.on_scroll_resize)
58
self._vbox.pack_start(self._scroll, True)
60
self._message_list = MessageList(self)
61
self._scroll.add(self._message_list)
63
# app_name, is_separator, count
64
self._combolist = gtk.ListStore(str, bool, int)
65
self._combobox = gtk.ComboBox(self._combolist)
66
self._combo_app_cell = gtk.CellRendererText()
67
self._combobox.pack_start(self._combo_app_cell, True)
68
self._combobox.add_attribute(self._combo_app_cell, "text", Column.APP_NAME)
69
self._combo_count_cell = gtk.CellRendererText()
70
self._combobox.pack_start(self._combo_count_cell, False)
71
self._combobox.add_attribute(self._combo_count_cell, "text", Column.COUNT)
72
self._combobox.set_row_separator_func(lambda m, i: m.get_value(i, Column.SEPARATOR))
73
self._combobox.connect("changed", self.on_combobox_changed)
74
self._vbox.pack_start(self._combobox, False)
76
self.initialize_combobox()
78
def on_combobox_changed(self, combobox, *args):
79
"""Set the tree filters to the selected app."""
80
active = self._combobox.get_active()
81
self._message_list.unselect_all()
83
self._message_list.set_filter_app(None)
85
iter = self._combobox.get_active_iter()
86
app_name = self._combolist.get_value(iter, Column.APP_NAME)
87
self._message_list.set_filter_app(app_name)
89
def on_scroll_resize(self, scroll, allocation, *args):
90
"""Updates the message list wrap width when the scrolled window resizes."""
91
self._message_list.set_wrap_width(allocation.width)
93
def on_vadjust_changed(self, adjustment, *args):
94
"""Reset the adjustment position when the adjustment is changed (resized), but
95
not moved, so the user can scroll around freely."""
96
self._vadjust.set_value(0)
98
def add_message(self, message):
99
"""Adds a message to the message window."""
100
self._message_list.add_message(message)
102
def clear_messages(self):
103
"""Clears all messages from the message window."""
104
self._message_list.clear()
105
self.initialize_combobox()
107
def clear_selections(self):
108
"""Unselects every row in the treeview and marks the messages as read."""
109
self._message_list.mark_as_read()
110
self._message_list.unselect_all()
112
def show_dropdown(self):
113
"""Shows the dropdown window"""
115
self.align_with_parent()
117
def hide_dropdown(self):
118
"""Hides the dropdown window"""
120
self.clear_selections()
122
def increment_count(self, iter):
123
"""Increments the message count at the given row."""
124
count = self._combolist.get_value(iter, Column.COUNT)
125
self._combolist.set_value(iter, Column.COUNT, count + 1)
127
def decrement_count(self, iter):
128
"""Decrements the message count at the given row."""
129
count = self._combolist.get_value(iter, Column.COUNT)
130
self._combolist.set_value(iter, Column.COUNT, count - 1)
132
def initialize_combobox(self):
133
"""Clear the combobox and set the initial entry."""
134
self._combolist.clear()
135
self._combolist.append([_("All Applications"), False, 0])
137
self._combobox.set_active(0)
139
def set_message_limit(self, n):
140
"""Sets the message limit of the MessageList."""
141
self._message_list.set_message_limit(n)
143
def increment_combobox(self, app_name):
144
"""Updates the combobox app names and message counts."""
145
# Add a separator if there isn't one yet
146
if len(self._combolist) == 1:
147
self._combolist.append(["Separator", True, 0])
149
self.increment_count(self._combolist.get_iter_first())
151
if app_name not in self._comboapps:
152
iter = self._combolist.append([app_name, False, 1])
153
self._comboapps[app_name] = iter
155
self.increment_count(self._comboapps[app_name])
157
def decrement_combobox(self, app_name):
158
"""Updates the combobox app names and message counts."""
159
self.decrement_count(self._combolist.get_iter_first())
161
if app_name in self._comboapps:
162
self.decrement_count(self._comboapps[app_name])
164
def align_with_parent(self):
165
"""Adapted from position_calendar_popup in the GNOME clock applet."""
166
# Get the size of the applet button and the size of this window
167
applet_x, applet_y = x, y = self._parent.get_origin()
168
w, h = self.get_size()
169
button_w, button_h = self._parent.get_size()
171
screen = self.get_screen()
175
# Figure out which monitor we are on
176
for i in range(screen.get_n_monitors()):
177
m = screen.get_monitor_geometry(i)
179
if x >= m.x and x <= m.x + m.width and y >= m.y and y <= m.y + m.height:
186
monitor = gtk.gdk.Rectangle(0, 0, screen.get_width(), screen.get_height())
188
orient = self._parent.get_orient()
190
# Figure out the x, y coordinates of the window and the gravity depending
191
# on the orientation of the panel
192
if orient == gnomeapplet.ORIENT_RIGHT: # Panel on left
194
if (y + h) > monitor.y + monitor.height:
195
y -= (y + h) - (monitor.y + monitor.height)
197
elif orient == gnomeapplet.ORIENT_LEFT: # Panel on right
199
if (y + h) > monitor.y + monitor.height:
200
y -= (y + h) - (monitor.y + monitor.height)
202
elif orient == gnomeapplet.ORIENT_DOWN: # Panel on top
204
if (x + w) > monitor.x + monitor.width:
205
x -= (x + w) - (monitor.x + monitor.width)
207
else: # Panel on bottom
209
if (x + w) > monitor.x + monitor.width:
210
x -= (x + w) - (monitor.x + monitor.width)
212
gravity = gtk.gdk.GRAVITY_NORTH_WEST
214
self.set_gravity(gravity)
218
--------------------------------------------------
238
--------------------------------------------------
239
""".format(applet_x, applet_y, button_w, button_h, orient,
241
monitor.x, monitor.y, monitor.width, monitor.height, monitor_index))