13
14
from string import Template
15
16
from About import show_about
17
from Config import Config
16
18
from Icon import clear_icon_cache, load_icon
19
from ImageToggleButton import ImageToggleButton
17
20
from MessageWindow import MessageWindow
18
21
from Notification import Notification
22
from Preferences import show_preferences
19
23
from Translations import _, ngettext
25
logger = logging.getLogger("Main")
21
27
class Main(object):
22
28
"""The main applet wrapper."""
23
29
def __init__(self, applet, iid):
24
30
self._applet = applet
25
self._applet.connect("size-allocate", self.on_allocate)
31
self._applet.set_background_widget(applet)
32
self._applet.connect("change-size", self.on_change_size)
33
self._applet.connect("change-orient", self.on_change_orient)
27
35
self._unread_messages = 0
29
size = self.get_icon_size(self.get_applet_size())
32
self._image = gtk.Image()
33
self._image.set_from_pixbuf(self._read_icon)
35
self._button = gtk.ToggleButton()
36
self._button.set_relief(gtk.RELIEF_NONE)
37
self._button.set_image(self._image)
38
self._button.connect("button_press_event", self.do_not_eat_button_press)
36
self._show_count = False
38
self._applet_size = self.get_applet_size()
40
icon_size = self.get_icon_size(self._applet_size)
41
self.load_icons(icon_size)
43
self._button = ImageToggleButton()
44
self._button.set_from_pixbuf(self._read_icon)
45
self._button.set_orient(self.get_orient())
39
46
self._button.connect("toggled", self.on_button_toggled)
40
48
self._applet.add(self._button)
42
50
self._applet.setup_menu(Template("""
44
52
<menuitem name="Clear" verb="Clear" _label="$clear_label" pixtype="stock" pixname="gtk-clear"/>
46
54
<menuitem name="About" verb="About" _label="$about_label" pixtype="stock" pixname="gtk-about"/>
55
<menuitem name="Preferences" verb="Preferences" _label="$preferences_label" pixtype="stock" pixname="gtk-preferences"/>
49
58
about_label=_("_About"),
50
clear_label=_("_Clear Messages")), [
59
clear_label=_("_Clear Messages"),
60
preferences_label=_("_Preferences")), [
51
61
("Clear", lambda a, b: self.on_clear_messages(a)),
52
("About", lambda a, b: self.on_show_about(a))
62
("About", lambda a, b: self.on_show_about(a)),
63
("Preferences", lambda a, b: self.on_show_preferences(a))
55
66
self._window = MessageWindow(self)
73
self._blacklist = Config("~/.config/recent-notifications/blacklist")
75
self._preferences = Config("~/.config/recent-notifications/preferences")
76
self._preferences.set_if_unset("debug", False)
77
self._preferences.set_if_unset("message_limit", 0)
78
self._preferences.set_if_unset("show_count", False)
79
self._preferences.add_listener("debug", self.on_preference_change)
80
self._preferences.add_listener("message_limit", self.on_preference_change)
81
self._preferences.add_listener("show_count", self.on_preference_change)
82
self._preferences.notify_all()
62
84
self._notify = Notification()
85
self._notify.set_blacklist(self._blacklist)
63
86
self._notify.connect("message-received", self.on_message_received)
88
self._theme = gtk.icon_theme_get_default()
89
self._theme.connect("changed", self.on_theme_changed)
91
def add_to_blacklist(self, app_name):
92
"""Adds the given app_name to the blacklist."""
93
self._blacklist.set(app_name, True)
95
def get_blacklist_items(self):
96
"""Returns a list of (app_name, boolean) tuples for the blacklist items."""
98
for key in self._blacklist:
99
result.append((key, self._blacklist.get_bool(key)))
102
def set_debug(self, debug):
103
"""Enables/disables debug messages."""
104
global_logger = logging.getLogger("")
106
global_logger.setLevel(logging.DEBUG)
108
global_logger.setLevel(logging.ERROR)
65
110
def get_applet_size(self):
66
111
"""Gets the size of the applet."""
67
112
return self._applet.get_size()
115
160
icon = self._read_icon
117
if icon != self._image.get_pixbuf():
118
self._image.set_from_pixbuf(icon)
162
if icon != self._button.get_pixbuf():
163
self._button.set_from_pixbuf(icon)
120
165
def update_unread_messages(self):
121
166
"""Updates the unread message tooltip."""
122
167
n = self._unread_messages
123
168
label = ngettext("1 unread message", "{0} unread messages", n).format(n)
124
169
self._button.set_tooltip_text(label)
171
self._button.set_label(str(n))
173
def show_window(self):
174
"""Shows the applet window"""
175
self._button.set_has_tooltip(False)
176
self._window.show_dropdown()
178
def hide_window(self):
179
"""Hides the applet window"""
180
self._button.set_has_tooltip(True)
181
self._window.hide_dropdown()
182
self._unread_messages = 0
128
def do_not_eat_button_press(self, widget, event):
129
"""Adapted from the GNOME clock applet."""
130
if event.button != 1:
131
widget.stop_emission("button_press_event")
135
def on_allocate(self, applet, alloc):
187
def on_change_size(self, applet, size):
136
188
"""Update the icon size if the panel size changes."""
137
if self.get_orient() in [gnomeapplet.ORIENT_DOWN, gnomeapplet.ORIENT_UP]:
138
size_alloc = alloc.height
140
size_alloc = alloc.width
142
icon_size = self.get_icon_size(size_alloc)
144
if self._read_icon != None and icon_size != self._read_icon.get_width():
145
self.load_icons(size)
146
self.update_applet_image()
148
def on_applet_destroyed(self, *args):
189
if self._applet_size == size:
192
self._applet_size = size
193
icon_size = self.get_icon_size(size)
194
self.load_icons(icon_size)
195
self.update_applet_image()
197
def on_change_orient(self, applet, orient):
198
"""Updates the button orientation when the panel changes orientation"""
199
self._button.set_orient(orient)
201
def on_applet_destroyed(self, applet):
149
202
"""Stop the message notifications before destroying the applet."""
150
203
self._notify.close()
152
def on_button_toggled(self, button, *args):
205
def on_button_toggled(self, button):
153
206
"""Show/Hide the message window when the button is toggled."""
154
207
if button.get_active():
155
self._window.show_all()
156
self._window.align_with_parent()
158
self._window.hide_all()
159
self._window.clear_selections()
160
self._unread_messages = 0
163
def on_clear_messages(self, *args):
212
def on_clear_messages(self, item):
164
213
"""Clear messages from the message window."""
165
214
self._window.clear_messages()
166
215
clear_icon_cache()
168
217
def on_message_received(self, monitor, message):
169
218
"""Received a message from the notifier."""
170
# Discard volume notifications
171
if not message.is_volume_notification():
172
self._window.add_message(message)
173
self._unread_messages += 1
219
self._window.add_message(message)
220
self._unread_messages += 1
176
def on_show_about(self, *args):
223
def on_show_about(self, item):
177
224
"""Show the about dialog."""
227
def on_show_preferences(self, item):
228
"""Show the preferences dialog."""
229
show_preferences(self)
231
def on_preference_change(self, key, value):
232
"""Triggers actions on preference changes."""
234
self.set_debug(self._preferences.get_bool(key, False))
235
elif key == "message_limit":
236
self._window.set_message_limit(self._preferences.get_int(key, 0))
237
elif key == "show_count":
238
self._show_count = self._preferences.get_bool(key, False)
242
self._button.set_label("")
244
def on_theme_changed(self, theme):
245
"""Updates applet icons when the theme changes"""
247
icon_size = self.get_icon_size(self._applet_size)
248
self.load_icons(icon_size)
249
self.update_applet_image()