2 # Copyright (C) 2007 Marco Ferragina <marco.ferragina@gmail.com>
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 from dbus
.mainloop
.glib
import DBusGMainLoop
35 ICON
= os
.path
.join(cwd
, DEFAULT_NOTIFY_ICON
)
36 GLADE_FILE
= os
.path
.join(GLADE_BASE_PATH
, "popup_notification_window.glade")
38 notification_instances
= 0
39 class NotificationWindow
:
40 def __init__(self
, title
, text
, icon
= ICON
, msec
= 3000):
41 global notification_instances
42 notification_instances
+= 1
44 widgets
= gtk
.glade
.XML(GLADE_FILE
, domain
="planimo")
45 self
.window
= widgets
.get_widget('popup_notification_window')
46 close_button
= widgets
.get_widget('close_button')
47 event_type_label
= widgets
.get_widget('event_type_label')
49 event_description_label
= widgets
.get_widget('event_description_label')
50 eventbox
= widgets
.get_widget('eventbox')
51 image
= widgets
.get_widget('notification_image')
54 event_type_label
.set_markup(
55 '<span foreground="black" weight="bold">%s</span>' % title
)
57 self
.window
.modify_bg(gtk
.STATE_NORMAL
,
58 gtk
.gdk
.color_parse('#dab255'))
62 popup_bg_color
= gtk
.gdk
.color_parse(bg_color
)
63 close_button
.modify_bg(gtk
.STATE_NORMAL
, popup_bg_color
)
64 eventbox
.modify_bg(gtk
.STATE_NORMAL
, popup_bg_color
)
65 event_description_label
.set_markup(
66 '<span foreground="black">%s</span>' % text
)
69 image
.set_from_file(icon
)
71 # position the window to bottom-right of screen
72 window_width
, window_height
= self
.window
.get_size()
73 pos_x
= gtk
.gdk
.screen_width() - window_width
- 1
74 pos_y
= gtk
.gdk
.screen_height() - \
75 notification_instances
* (window_height
+ 2)
76 self
.window
.move(pos_x
, pos_y
)
78 widgets
.signal_autoconnect(self
)
79 self
.window
.show_all()
80 gobject
.timeout_add(msec
, self
.on_timeout
)
82 def on_close_button_clicked(self
, widget
):
83 global notification_instances
86 notification_instances
-= 1
89 global notification_instances
92 notification_instances
-= 1
95 dbus_loop
= DBusGMainLoop()
96 session_bus
= dbus
.SessionBus(mainloop
= dbus_loop
)
97 obj
= session_bus
.get_object("org.freedesktop.Notifications",
98 "/org/freedesktop/Notifications")
99 notif
= dbus
.Interface(obj
, "org.freedesktop.Notifications")
106 self
.notif
.connect_to_signal("ActionInvoked", self
.action_cb
)
108 self
.__actions
_list
= []
110 def action_cb(self
, id, act
):
112 handler
= self
.__actions
[act
][0]
117 def set_actions(self
, actions
):
118 self
.__actions
= actions
119 self
.__actions
_list
= []
120 for actname
, values
in actions
.iteritems():
121 self
.__actions
_list
.append(actname
)
122 self
.__actions
_list
.append(values
[1])
124 def notify(self
, title
, message
, icon
= None, msec
= 3000):
129 icon
= os
.path
.join(cwd
, icon
)
131 iconfile
= "file://" + icon
132 # allow bold tag and sub nasty chars
133 message
= message
.replace("&", "&")
134 message
= re
.sub(r
'<(?!/?b>)', "<", message
)
135 message
= re
.sub(r
'(?<!b)>', ">", message
)
140 # Revert to classic window
141 NotificationWindow(title
, message
, icon
, msec
)
155 except Exception, detail
:
156 # Nothing to do with dbus:
157 # Revert to classic window
158 print "Warning: Error while trying to use notification-daemon.\n Reverting to classic method.\n Please upgrade your dbus and libnotify version", detail
159 NotificationWindow(title
, message
, icon
, msec
)
162 if __name__
== "__main__":
164 msg
= '<span size="larger">Test</span> ok'
165 n
.notify("Title", msg
, True, msec
=10000)
168 loop
= gobject
.MainLoop()