Add list parameter to all buddy list UI ops.
[pidgin-git.git] / finch / plugins / pietray.py
blobb76256a7cea4cf768ad292c2780030b12fa7028a
1 #!/usr/bin/env python
3 # NOTICE: This script is currently broken as the libpurple DBus
4 # bindings have been removed.
6 # This is a dbus script to show a docklet for Finch. This should work
7 # for any 'compatible' purple client.
9 # By 'compatible', I mean any client that sets and updates the
10 # "unseen-count" data on the conversations.
12 # It allows doing the following things:
13 # - It allows changing status.
14 # - It shows the current status and info about unread messages in
15 # the tooltip.
16 # - It can blink on unread IM/Chat messages, and it allows canging
17 # the preference for that.
19 # It requires GTK+ 2.10 or above, since it uses GtkStatusIcon.
21 # Sadrul <sadrul@pidgin.im>
23 from __future__ import absolute_import, division, print_function
25 import os # to get the pkg-config output
27 import pygtk
28 pygtk.require("2.0") # noqa
29 import gtk
30 import dbus
31 import dbus.glib
34 bus = dbus.SessionBus()
35 obj = bus.get_object("im.pidgin.purple.PurpleService",
36 "/im/pidgin/purple/PurpleObject")
37 purple = dbus.Interface(obj, "im.pidgin.purple.PurpleInterface")
40 def pack_image_label(menu, image, label):
41 item = gtk.ImageMenuItem(label)
42 if image:
43 img = gtk.Image()
44 img.set_from_stock(image, 1)
45 item.set_image(img)
46 menu.append(item)
47 return item
50 def activate_primitive_status(item, status):
51 saved = purple.PurpleSavedstatusFindTransientByTypeAndMessage(status, "")
52 if not saved:
53 saved = purple.PurpleSavedstatusNew("", status)
54 purple.PurpleSavedstatusActivate(saved)
57 def activate_popular_status(item, time):
58 saved = purple.PurpleSavedstatusFindByCreationTime(time)
59 if saved:
60 purple.PurpleSavedstatusActivate(saved)
63 def generate_status_menu(menu):
64 item = gtk.MenuItem("Available")
65 item.connect("activate", activate_primitive_status, 2)
66 menu.append(item)
68 item = gtk.MenuItem("Away")
69 item.connect("activate", activate_primitive_status, 5)
70 menu.append(item)
72 item = gtk.MenuItem("Invisible")
73 item.connect("activate", activate_primitive_status, 4)
74 menu.append(item)
76 item = gtk.MenuItem("Offline")
77 item.connect("activate", activate_primitive_status, 1)
78 menu.append(item)
80 menu.append(gtk.MenuItem())
82 popular = purple.PurpleSavedstatusesGetPopular(10)
83 for pop in popular:
84 title = purple.PurpleSavedstatusGetTitle(pop).replace('_', '__')
85 item = gtk.MenuItem(title)
86 item.set_data("timestamp",
87 purple.PurpleSavedstatusGetCreationTime(pop))
88 item.connect("activate", activate_popular_status,
89 purple.PurpleSavedstatusGetCreationTime(pop))
90 menu.append(item)
93 def toggle_pref(item, pref):
94 purple.PurplePrefsSetBool(pref, item.get_active())
97 def quit_finch(item, null):
98 # XXX: Ask first
99 purple.PurpleCoreQuit()
100 gtk.main_quit()
103 def close_docklet(item, null):
104 gtk.main_quit()
107 def popup_menu(icon, button, tm, none):
108 menu = gtk.Menu()
110 # item = gtk.ImageMenuItem(gtk.STOCK_QUIT)
111 # item.connect("activate", quit_finch, None)
112 # menu.append(item)
114 item = gtk.ImageMenuItem(gtk.STOCK_CLOSE)
115 item.connect("activate", close_docklet, None)
116 menu.append(item)
118 menu.append(gtk.MenuItem())
120 item = gtk.CheckMenuItem("Blink for unread IM")
121 item.set_active(
122 purple.PurplePrefsGetBool("/plugins/dbus/docklet/blink/im"))
123 item.connect("activate", toggle_pref, "/plugins/dbus/docklet/blink/im")
124 menu.append(item)
126 item = gtk.CheckMenuItem("Blink for unread Chats")
127 item.set_active(
128 purple.PurplePrefsGetBool("/plugins/dbus/docklet/blink/chat"))
129 item.connect("activate", toggle_pref, "/plugins/dbus/docklet/blink/chat")
130 menu.append(item)
132 menu.append(gtk.MenuItem())
134 # item = pack_image_label(menu, None, "Change Status...")
135 item = gtk.MenuItem("Change Status...")
136 menu.append(item)
137 submenu = gtk.Menu()
138 item.set_submenu(submenu)
139 generate_status_menu(submenu)
141 menu.show_all()
142 menu.popup(None, None, None, button, tm)
145 def get_status_message():
146 status_names = {
147 1: 'Offline',
148 2: 'Available',
149 4: 'Invisible',
150 5: 'Away',
153 status = purple.PurpleSavedstatusGetCurrent()
154 msg = purple.PurpleSavedstatusGetMessage(status)
155 if msg and len(msg) > 0:
156 text = msg + " "
157 else:
158 text = ""
159 text += "(" + status_names[purple.PurpleSavedstatusGetType(status)] + ")"
160 return text
163 def detect_unread_conversations():
164 im = purple.PurplePrefsGetBool("/plugins/dbus/docklet/blink/im")
165 chat = purple.PurplePrefsGetBool("/plugins/dbus/docklet/blink/chat")
166 tooltip = ""
167 blink = False
168 if im and chat:
169 convs = purple.PurpleGetConversations()
170 elif im:
171 convs = purple.PurpleGetIms()
172 elif chat:
173 convs = purple.PurpleGetChats()
174 else:
175 convs = None
176 for conv in convs:
177 count = purple.PurpleConversationGetData(conv, "unseen-count")
178 if count and count > 0:
179 blink = True
180 tooltip += "\n%s (%d)" % (purple.PurpleConversationGetName(conv),
181 count)
182 t.set_from_file(path + "/share/pixmaps/pidgin.png")
183 if blink:
184 # I hate this icon
185 # t.set_from_file(path +
186 # "/share/pixmaps/pidgin/tray/22/tray-message.png")
187 tooltip = "\nUnread Messages:" + tooltip
188 # There's going to be some way to expose the client's display name in
189 # 2.1.0. Use that instead of hardcoding Finch here.
190 t.set_tooltip("Finch: " + get_status_message() + tooltip)
191 t.set_blinking(blink)
194 def conversation_updated(conv, type):
195 detect_unread_conversations()
198 def savedstatus_changed(new, old):
199 # Change the icon for status perhaps?
200 detect_unread_conversations()
203 def init_prefs():
204 if not purple.PurplePrefsExists("/plugins/dbus/docklet/blink"):
205 purple.PurplePrefsAddNone("/plugins")
206 purple.PurplePrefsAddNone("/plugins/dbus")
207 purple.PurplePrefsAddNone("/plugins/dbus/docklet")
208 purple.PurplePrefsAddNone("/plugins/dbus/docklet/blink")
209 purple.PurplePrefsAddBool("/plugins/dbus/docklet/blink/im", True)
210 purple.PurplePrefsAddBool("/plugins/dbus/docklet/blink/chat", True)
213 pkg = os.popen("pkg-config --variable=prefix pidgin")
214 path = pkg.readline().rstrip()
216 bus.add_signal_receiver(conversation_updated,
217 dbus_interface="im.pidgin.purple.PurpleInterface",
218 signal_name="ConversationUpdated")
220 bus.add_signal_receiver(savedstatus_changed,
221 dbus_interface="im.pidgin.purple.PurpleInterface",
222 signal_name="SavedstatusChanged")
224 t = gtk.StatusIcon()
225 t.connect("popup-menu", popup_menu, None)
227 try:
228 init_prefs()
229 detect_unread_conversations()
230 gtk.main()
231 except:
232 dialog = gtk.Dialog("pietray: Error", None,
233 gtk.DIALOG_NO_SEPARATOR | gtk.DIALOG_MODAL,
234 ("Close", gtk.RESPONSE_CLOSE))
235 dialog.set_resizable(False)
236 error_label = gtk.Label("There was some error. Perhaps a purple client is "
237 "not running.")
238 dialog.vbox.pack_start(error_label, False, False, 0)
239 dialog.show_all()
240 dialog.run()