sound support for linux only (with a binder in preferences window)

This commit is contained in:
Yann Leboulanger 2005-02-10 00:07:55 +00:00
parent a8a3c615ec
commit c44861e5b6
3 changed files with 333 additions and 49 deletions

View File

@ -239,6 +239,18 @@ class preference_Window:
self.plugin.roster.mkemoticons() self.plugin.roster.mkemoticons()
else: else:
self.plugin.config['useemoticons'] = 0 self.plugin.config['useemoticons'] = 0
#sound player
self.plugin.config['soundplayer'] = \
self.xml.get_widget('entry_soundplayer').get_text()
#sounds
model = self.sound_tree.get_model()
iter = model.get_iter_first()
events = []
while iter:
events.append(model.get_value(iter, 0))
events.append(model.get_value(iter, 1))
iter = model.iter_next(iter)
self.plugin.config['sounds'] = string.join(events, '\t')
#autopopup #autopopup
if self.chk_autopp.get_active(): if self.chk_autopp.get_active():
self.plugin.config['autopopup'] = 1 self.plugin.config['autopopup'] = 1
@ -319,6 +331,44 @@ class preference_Window:
model.set(iter, 0, self.plugin.config['msg%s_name' % i], 1, self.plugin.config['msg%s' % i]) model.set(iter, 0, self.plugin.config['msg%s_name' % i], 1, self.plugin.config['msg%s' % i])
i += 1 i += 1
def on_msg_cell_edited(self, cell, row, new_text):
model = self.msg_tree.get_model()
iter = model.get_iter_from_string(row)
model.set_value(iter, 0, new_text)
def on_msg_treeview_cursor_changed(self, widget, data=None):
self.xml.get_widget('delete_msg_button').set_sensitive(True)
buf = self.xml.get_widget('msg_textview').get_buffer()
(model, iter) = self.msg_tree.get_selection().get_selected()
name = model.get_value(iter, 0)
msg = model.get_value(iter, 1)
buf.set_text(msg)
def on_new_msg_button_clicked(self, widget, data=None):
model = self.msg_tree.get_model()
iter = model.append()
model.set(iter, 0, 'msg', 1, 'message')
def on_delete_msg_button_clicked(self, widget, data=None):
(model, iter) = self.msg_tree.get_selection().get_selected()
buf = self.xml.get_widget('msg_textview').get_buffer()
model.remove(iter)
buf.set_text('')
self.xml.get_widget('delete_msg_button').set_sensitive(False)
def on_msg_textview_changed(self, widget, data=None):
(model, iter) = self.msg_tree.get_selection().get_selected()
if not iter:
return
buf = self.xml.get_widget('msg_textview').get_buffer()
first_iter, end_iter = buf.get_bounds()
name = model.get_value(iter, 0)
model.set_value(iter, 1, buf.get_text(first_iter, end_iter))
def on_msg_treeview_key_press_event(self, widget, event):
if event.keyval == gtk.keysyms.Delete:
self.on_delete_msg_button_clicked(widget)
def image_is_ok(self, image): def image_is_ok(self, image):
if not os.path.exists(image): if not os.path.exists(image):
return 0 return 0
@ -352,29 +402,11 @@ class preference_Window:
iter = model.append() iter = model.append()
model.set(iter, 0, i, 1,emots[i]) model.set(iter, 0, i, 1,emots[i])
def on_msg_cell_edited(self, cell, row, new_text):
model = self.msg_tree.get_model()
iter = model.get_iter_from_string(row)
model.set_value(iter, 0, new_text)
def on_emot_cell_edited(self, cell, row, new_text): def on_emot_cell_edited(self, cell, row, new_text):
model = self.emot_tree.get_model() model = self.emot_tree.get_model()
iter = model.get_iter_from_string(row) iter = model.get_iter_from_string(row)
model.set_value(iter, 0, new_text) model.set_value(iter, 0, new_text)
def on_msg_treeview_cursor_changed(self, widget, data=None):
self.xml.get_widget('delete_msg_button').set_sensitive(True)
buf = self.xml.get_widget('msg_textview').get_buffer()
(model, iter) = self.msg_tree.get_selection().get_selected()
name = model.get_value(iter, 0)
msg = model.get_value(iter, 1)
buf.set_text(msg)
def on_new_msg_button_clicked(self, widget, data=None):
model = self.msg_tree.get_model()
iter = model.append()
model.set(iter, 0, 'msg', 1, 'message')
def on_button_emoticons_clicked(self, widget, data=None): def on_button_emoticons_clicked(self, widget, data=None):
(model, iter) = self.emot_tree.get_selection().get_selected() (model, iter) = self.emot_tree.get_selection().get_selected()
if not iter: if not iter:
@ -422,13 +454,6 @@ class preference_Window:
self.xml.get_widget('image_emoticon').set_from_file(file) self.xml.get_widget('image_emoticon').set_from_file(file)
model.set_value(iter, 1, file) model.set_value(iter, 1, file)
def on_delete_msg_button_clicked(self, widget, data=None):
(model, iter) = self.msg_tree.get_selection().get_selected()
buf = self.xml.get_widget('msg_textview').get_buffer()
model.remove(iter)
buf.set_text('')
self.xml.get_widget('delete_msg_button').set_sensitive(False)
def on_button_new_emoticon_clicked(self, widget, data=None): def on_button_new_emoticon_clicked(self, widget, data=None):
model = self.emot_tree.get_model() model = self.emot_tree.get_model()
iter = model.append() iter = model.append()
@ -440,15 +465,6 @@ class preference_Window:
return return
model.remove(iter) model.remove(iter)
def on_msg_textview_changed(self, widget, data=None):
(model, iter) = self.msg_tree.get_selection().get_selected()
if not iter:
return
buf = self.xml.get_widget('msg_textview').get_buffer()
first_iter, end_iter = buf.get_bounds()
name = model.get_value(iter, 0)
model.set_value(iter, 1, buf.get_text(first_iter, end_iter))
def on_treeview_emoticons_cursor_changed(self, widget, data=None): def on_treeview_emoticons_cursor_changed(self, widget, data=None):
(model, iter) = self.emot_tree.get_selection().get_selected() (model, iter) = self.emot_tree.get_selection().get_selected()
if not iter: if not iter:
@ -462,14 +478,75 @@ class preference_Window:
for w in widgets: for w in widgets:
w.set_sensitive(widget.get_active()) w.set_sensitive(widget.get_active())
def on_msg_treeview_key_press_event(self, widget, event):
if event.keyval == gtk.keysyms.Delete:
self.on_delete_msg_button_clicked(widget)
def on_treeview_emoticons_key_press_event(self, widget, event): def on_treeview_emoticons_key_press_event(self, widget, event):
if event.keyval == gtk.keysyms.Delete: if event.keyval == gtk.keysyms.Delete:
self.on_button_remove_emoticon_clicked(widget) self.on_button_remove_emoticon_clicked(widget)
def sound_is_ok(self, sound):
if not os.path.exists(sound):
return 0
return 1
def fill_sound_treeview(self):
eventList = ['message']
events = {}
split_line = string.split(self.plugin.config['sounds'], '\t')
for i in range(0, len(split_line)/2):
events[split_line[2*i]] = split_line[2*i+1]
model = self.sound_tree.get_model()
model.clear()
for ev in eventList:
if ev in events:
iter = model.append()
model.set(iter, 0, ev, 1, events[ev])
def on_treeview_sounds_cursor_changed(self, widget, data=None):
(model, iter) = self.sound_tree.get_selection().get_selected()
if not iter:
self.xml.get_widget('entry_sounds').set_text('')
return
str = model.get_value(iter, 1)
self.xml.get_widget('entry_sounds').set_text(str)
def on_button_sounds_clicked(self, widget, data=None):
(model, iter) = self.sound_tree.get_selection().get_selected()
if not iter:
return
file = model.get_value(iter, 1)
dialog = gtk.FileChooserDialog("Choose sound",
None,
gtk.FILE_CHOOSER_ACTION_OPEN,
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_OPEN, gtk.RESPONSE_OK))
dialog.set_default_response(gtk.RESPONSE_OK)
filter = gtk.FileFilter()
filter.set_name("All files")
filter.add_pattern("*")
dialog.add_filter(filter)
filter = gtk.FileFilter()
filter.set_name("Wav Sounds")
filter.add_pattern("*.wav")
dialog.add_filter(filter)
dialog.set_filter(filter)
file = os.path.join(os.getcwd(), file)
dialog.set_filename(file)
file = ''
ok = 0
while(ok == 0):
response = dialog.run()
if response == gtk.RESPONSE_OK:
file = dialog.get_filename()
if self.sound_is_ok(file):
ok = 1
else:
ok = 1
dialog.destroy()
if file:
self.xml.get_widget('entry_sounds').set_text(file)
model.set_value(iter, 1, file)
def __init__(self, plugin): def __init__(self, plugin):
"""Initialize Preference window""" """Initialize Preference window"""
self.xml = gtk.glade.XML(GTKGUI_GLADE, 'Preferences', APP) self.xml = gtk.glade.XML(GTKGUI_GLADE, 'Preferences', APP)
@ -549,6 +626,26 @@ class preference_Window:
col.set_attributes(renderer, text=0) col.set_attributes(renderer, text=0)
self.fill_emot_treeview() self.fill_emot_treeview()
#sound player
self.xml.get_widget('entry_soundplayer').set_text(\
self.plugin.config['soundplayer'])
#sounds
self.sound_tree = self.xml.get_widget('treeview_sounds')
model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
self.sound_tree.set_model(model)
col = gtk.TreeViewColumn('Event')
self.sound_tree.append_column(col)
renderer = gtk.CellRendererText()
col.pack_start(renderer)
col.set_attributes(renderer, text=0)
col = gtk.TreeViewColumn('Sound')
self.sound_tree.append_column(col)
renderer = gtk.CellRendererText()
col.pack_start(renderer)
col.set_attributes(renderer, text=1)
self.fill_sound_treeview()
#Autopopup #Autopopup
st = self.plugin.config['autopopup'] st = self.plugin.config['autopopup']
self.chk_autopp.set_active(st) self.chk_autopp.set_active(st)
@ -645,18 +742,12 @@ class preference_Window:
self.xml.signal_connect('on_cancel_clicked', self.on_cancel) self.xml.signal_connect('on_cancel_clicked', self.on_cancel)
self.xml.signal_connect('on_msg_treeview_cursor_changed', \ self.xml.signal_connect('on_msg_treeview_cursor_changed', \
self.on_msg_treeview_cursor_changed) self.on_msg_treeview_cursor_changed)
self.xml.signal_connect('on_treeview_emoticons_cursor_changed', \
self.on_treeview_emoticons_cursor_changed)
self.xml.signal_connect('on_button_emoticons_clicked', \
self.on_button_emoticons_clicked)
self.xml.signal_connect('on_new_msg_button_clicked', \ self.xml.signal_connect('on_new_msg_button_clicked', \
self.on_new_msg_button_clicked) self.on_new_msg_button_clicked)
self.xml.signal_connect('on_delete_msg_button_clicked', \ self.xml.signal_connect('on_delete_msg_button_clicked', \
self.on_delete_msg_button_clicked) self.on_delete_msg_button_clicked)
self.xml.signal_connect('on_button_new_emoticon_clicked', \ self.xml.signal_connect('on_msg_treeview_key_press_event', \
self.on_button_new_emoticon_clicked) self.on_msg_treeview_key_press_event)
self.xml.signal_connect('on_button_remove_emoticon_clicked', \
self.on_button_remove_emoticon_clicked)
self.xml.signal_connect('on_chk_autopopup_toggled', \ self.xml.signal_connect('on_chk_autopopup_toggled', \
self.on_chk_toggled, [self.chk_autoppaway]) self.on_chk_toggled, [self.chk_autoppaway])
self.xml.signal_connect('on_chk_autoaway_toggled', \ self.xml.signal_connect('on_chk_autoaway_toggled', \
@ -670,10 +761,20 @@ class preference_Window:
self.xml.get_widget('entry_emoticons'), self.xml.get_widget('entry_emoticons'),
self.xml.get_widget('button_emoticons'), self.xml.get_widget('button_emoticons'),
self.xml.get_widget('image_emoticon')]) self.xml.get_widget('image_emoticon')])
self.xml.signal_connect('on_msg_treeview_key_press_event', \ self.xml.signal_connect('on_treeview_emoticons_cursor_changed', \
self.on_msg_treeview_key_press_event) self.on_treeview_emoticons_cursor_changed)
self.xml.signal_connect('on_button_emoticons_clicked', \
self.on_button_emoticons_clicked)
self.xml.signal_connect('on_button_new_emoticon_clicked', \
self.on_button_new_emoticon_clicked)
self.xml.signal_connect('on_button_remove_emoticon_clicked', \
self.on_button_remove_emoticon_clicked)
self.xml.signal_connect('on_treeview_emoticons_key_press_event', \ self.xml.signal_connect('on_treeview_emoticons_key_press_event', \
self.on_treeview_emoticons_key_press_event) self.on_treeview_emoticons_key_press_event)
self.xml.signal_connect('on_treeview_sounds_cursor_changed', \
self.on_treeview_sounds_cursor_changed)
self.xml.signal_connect('on_button_sounds_clicked', \
self.on_button_sounds_clicked)
self.plugin.send('ASK_CONFIG', None, ('GtkGui', 'Logger', {'lognotsep':1,\ self.plugin.send('ASK_CONFIG', None, ('GtkGui', 'Logger', {'lognotsep':1,\
'lognotusr':1})) 'lognotusr':1}))

View File

@ -4678,6 +4678,148 @@ on the server.</property>
<property name="fill">False</property> <property name="fill">False</property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkHSeparator" id="hseparator15">
<property name="visible">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox2911">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">5</property>
<child>
<widget class="GtkLabel" id="label189">
<property name="visible">True</property>
<property name="label" translatable="yes">Sound player :</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="entry_soundplayer">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow29">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTreeView" id="treeview_sounds">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">True</property>
<property name="rules_hint">False</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
<signal name="cursor_changed" handler="on_treeview_sounds_cursor_changed" last_modification_time="Wed, 09 Feb 2005 22:51:36 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox2910">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">5</property>
<child>
<widget class="GtkEntry" id="entry_sounds">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="button_sounds">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">...</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_button_sounds_clicked" last_modification_time="Wed, 09 Feb 2005 23:29:56 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</widget> </widget>
<packing> <packing>
<property name="tab_expand">False</property> <property name="tab_expand">False</property>

View File

@ -54,7 +54,7 @@ pygtk.require('2.0')
import gtk import gtk
from gtk import TRUE, FALSE from gtk import TRUE, FALSE
import gtk.glade,gobject import gtk.glade,gobject
import os,string,time,Queue import os,string,time,Queue, sys
import common.optparser,common.sleepy import common.optparser,common.sleepy
from common import i18n from common import i18n
_ = i18n._ _ = i18n._
@ -2143,6 +2143,21 @@ class roster_Window:
# for state in ('online', 'away', 'xa', 'dnd', 'invisible', 'offline'): # for state in ('online', 'away', 'xa', 'dnd', 'invisible', 'offline'):
# self.xml.get_widget(state).set_image(self.pixbufs[state]) # self.xml.get_widget(state).set_image(self.pixbufs[state])
def sound_is_ok(self, sound):
if not os.path.exists(sound):
return 0
return 1
def mkevents(self):
"""initialize events array"""
self.events = {}
split_line = string.split(self.plugin.config['sounds'], '\t')
for i in range(0, len(split_line)/2):
file = split_line[2*i+1]
if not self.sound_is_ok(file):
continue
self.events[split_line[2*i]] = file
def on_show_off(self, widget): def on_show_off(self, widget):
"""when show offline option is changed : """when show offline option is changed :
redraw the treeview""" redraw the treeview"""
@ -2307,6 +2322,7 @@ class roster_Window:
self.mkpixbufs() self.mkpixbufs()
if self.plugin.config['useemoticons']: if self.plugin.config['useemoticons']:
self.mkemoticons() self.mkemoticons()
self.mkevents()
liststore = gtk.ListStore(gobject.TYPE_STRING, gtk.Image) liststore = gtk.ListStore(gobject.TYPE_STRING, gtk.Image)
self.cb = gtk.ComboBox() self.cb = gtk.ComboBox()
@ -2581,6 +2597,28 @@ class plugin:
return a return a
return None return None
def play_timeout(self, pid):
pidp, r = os.waitpid(pid, os.WNOHANG)
return 0
def play_sound(self, event):
if not self.roster.events.has_key(event):
return
pid = os.fork()
if pid == 0:
argv = self.config['soundplayer'].split()
argv.append(self.roster.events[event])
try:
os.execvp(argv[0], argv)
except:
print _("error while running %s :") % string.join(argv, ' '), \
sys.exc_info()[1]
os._exit(1)
pidp, r = os.waitpid(pid, os.WNOHANG)
if pidp == 0:
gtk.timeout_add(10000, self.play_timeout, pid)
def send(self, event, account, data): def send(self, event, account, data):
self.queueOUT.put((event, account, data)) self.queueOUT.put((event, account, data))
@ -2671,6 +2709,7 @@ class plugin:
jid = string.split(array[0], '/')[0] jid = string.split(array[0], '/')[0]
if string.find(jid, "@") <= 0: if string.find(jid, "@") <= 0:
jid = string.replace(jid, '@', '') jid = string.replace(jid, '@', '')
self.play_sound('message')
self.roster.on_message(jid, array[1], array[2], account) self.roster.on_message(jid, array[1], array[2], account)
def handle_event_msgerror(self, account, array): def handle_event_msgerror(self, account, array):
@ -2967,6 +3006,8 @@ class plugin:
'usetabbedchat': 0,\ 'usetabbedchat': 0,\
'useemoticons': 1,\ 'useemoticons': 1,\
'emoticons':':-)\tplugins/gtkgui/emoticons/smile.png\t(@)\tplugins/gtkgui/emoticons/pussy.png\t8)\tplugins/gtkgui/emoticons/coolglasses.png\t:(\tplugins/gtkgui/emoticons/unhappy.png\t:)\tplugins/gtkgui/emoticons/smile.png\t(})\tplugins/gtkgui/emoticons/hugleft.png\t:$\tplugins/gtkgui/emoticons/blush.png\t(Y)\tplugins/gtkgui/emoticons/yes.png\t:-@\tplugins/gtkgui/emoticons/angry.png\t:-D\tplugins/gtkgui/emoticons/biggrin.png\t(U)\tplugins/gtkgui/emoticons/brheart.png\t(F)\tplugins/gtkgui/emoticons/flower.png\t:-[\tplugins/gtkgui/emoticons/bat.png\t:>\tplugins/gtkgui/emoticons/biggrin.png\t(T)\tplugins/gtkgui/emoticons/phone.png\t(l)\tplugins/gtkgui/emoticons/heart.png\t:-S\tplugins/gtkgui/emoticons/frowing.png\t:-P\tplugins/gtkgui/emoticons/tongue.png\t(h)\tplugins/gtkgui/emoticons/coolglasses.png\t(D)\tplugins/gtkgui/emoticons/drink.png\t:-O\tplugins/gtkgui/emoticons/oh.png\t(f)\tplugins/gtkgui/emoticons/flower.png\t(C)\tplugins/gtkgui/emoticons/coffee.png\t:-o\tplugins/gtkgui/emoticons/oh.png\t({)\tplugins/gtkgui/emoticons/hugright.png\t(*)\tplugins/gtkgui/emoticons/star.png\tB-)\tplugins/gtkgui/emoticons/coolglasses.png\t(z)\tplugins/gtkgui/emoticons/boy.png\t:-d\tplugins/gtkgui/emoticons/biggrin.png\t(E)\tplugins/gtkgui/emoticons/mail.png\t(N)\tplugins/gtkgui/emoticons/no.png\t(p)\tplugins/gtkgui/emoticons/photo.png\t(K)\tplugins/gtkgui/emoticons/kiss.png\t(r)\tplugins/gtkgui/emoticons/rainbow.png\t:-|\tplugins/gtkgui/emoticons/stare.png\t:-s\tplugins/gtkgui/emoticons/frowing.png\t:-p\tplugins/gtkgui/emoticons/tongue.png\t(c)\tplugins/gtkgui/emoticons/coffee.png\t(e)\tplugins/gtkgui/emoticons/mail.png\t;-)\tplugins/gtkgui/emoticons/wink.png\t;-(\tplugins/gtkgui/emoticons/cry.png\t(6)\tplugins/gtkgui/emoticons/devil.png\t:o\tplugins/gtkgui/emoticons/oh.png\t(L)\tplugins/gtkgui/emoticons/heart.png\t(w)\tplugins/gtkgui/emoticons/brflower.png\t:d\tplugins/gtkgui/emoticons/biggrin.png\t(Z)\tplugins/gtkgui/emoticons/boy.png\t(u)\tplugins/gtkgui/emoticons/brheart.png\t:|\tplugins/gtkgui/emoticons/stare.png\t(P)\tplugins/gtkgui/emoticons/photo.png\t:O\tplugins/gtkgui/emoticons/oh.png\t(R)\tplugins/gtkgui/emoticons/rainbow.png\t(t)\tplugins/gtkgui/emoticons/phone.png\t(i)\tplugins/gtkgui/emoticons/lamp.png\t;)\tplugins/gtkgui/emoticons/wink.png\t;(\tplugins/gtkgui/emoticons/cry.png\t:p\tplugins/gtkgui/emoticons/tongue.png\t(H)\tplugins/gtkgui/emoticons/coolglasses.png\t:s\tplugins/gtkgui/emoticons/frowing.png\t;\'-(\tplugins/gtkgui/emoticons/cry.png\t:-(\tplugins/gtkgui/emoticons/unhappy.png\t:-)\tplugins/gtkgui/emoticons/smile.png\t(b)\tplugins/gtkgui/emoticons/beer.png\t8-)\tplugins/gtkgui/emoticons/coolglasses.png\t(B)\tplugins/gtkgui/emoticons/beer.png\t(W)\tplugins/gtkgui/emoticons/brflower.png\t:D\tplugins/gtkgui/emoticons/biggrin.png\t(y)\tplugins/gtkgui/emoticons/yes.png\t(8)\tplugins/gtkgui/emoticons/music.png\t:@\tplugins/gtkgui/emoticons/angry.png\tB)\tplugins/gtkgui/emoticons/coolglasses.png\t:-$\tplugins/gtkgui/emoticons/blush.png\t:\'(\tplugins/gtkgui/emoticons/cry.png\t(n)\tplugins/gtkgui/emoticons/no.png\t(k)\tplugins/gtkgui/emoticons/kiss.png\t:->\tplugins/gtkgui/emoticons/biggrin.png\t:[\tplugins/gtkgui/emoticons/bat.png\t(I)\tplugins/gtkgui/emoticons/lamp.png\t:P\tplugins/gtkgui/emoticons/tongue.png\t(%)\tplugins/gtkgui/emoticons/cuffs.png\t(d)\tplugins/gtkgui/emoticons/drink.png\t:S\tplugins/gtkgui/emoticons/frowing.png',\ 'emoticons':':-)\tplugins/gtkgui/emoticons/smile.png\t(@)\tplugins/gtkgui/emoticons/pussy.png\t8)\tplugins/gtkgui/emoticons/coolglasses.png\t:(\tplugins/gtkgui/emoticons/unhappy.png\t:)\tplugins/gtkgui/emoticons/smile.png\t(})\tplugins/gtkgui/emoticons/hugleft.png\t:$\tplugins/gtkgui/emoticons/blush.png\t(Y)\tplugins/gtkgui/emoticons/yes.png\t:-@\tplugins/gtkgui/emoticons/angry.png\t:-D\tplugins/gtkgui/emoticons/biggrin.png\t(U)\tplugins/gtkgui/emoticons/brheart.png\t(F)\tplugins/gtkgui/emoticons/flower.png\t:-[\tplugins/gtkgui/emoticons/bat.png\t:>\tplugins/gtkgui/emoticons/biggrin.png\t(T)\tplugins/gtkgui/emoticons/phone.png\t(l)\tplugins/gtkgui/emoticons/heart.png\t:-S\tplugins/gtkgui/emoticons/frowing.png\t:-P\tplugins/gtkgui/emoticons/tongue.png\t(h)\tplugins/gtkgui/emoticons/coolglasses.png\t(D)\tplugins/gtkgui/emoticons/drink.png\t:-O\tplugins/gtkgui/emoticons/oh.png\t(f)\tplugins/gtkgui/emoticons/flower.png\t(C)\tplugins/gtkgui/emoticons/coffee.png\t:-o\tplugins/gtkgui/emoticons/oh.png\t({)\tplugins/gtkgui/emoticons/hugright.png\t(*)\tplugins/gtkgui/emoticons/star.png\tB-)\tplugins/gtkgui/emoticons/coolglasses.png\t(z)\tplugins/gtkgui/emoticons/boy.png\t:-d\tplugins/gtkgui/emoticons/biggrin.png\t(E)\tplugins/gtkgui/emoticons/mail.png\t(N)\tplugins/gtkgui/emoticons/no.png\t(p)\tplugins/gtkgui/emoticons/photo.png\t(K)\tplugins/gtkgui/emoticons/kiss.png\t(r)\tplugins/gtkgui/emoticons/rainbow.png\t:-|\tplugins/gtkgui/emoticons/stare.png\t:-s\tplugins/gtkgui/emoticons/frowing.png\t:-p\tplugins/gtkgui/emoticons/tongue.png\t(c)\tplugins/gtkgui/emoticons/coffee.png\t(e)\tplugins/gtkgui/emoticons/mail.png\t;-)\tplugins/gtkgui/emoticons/wink.png\t;-(\tplugins/gtkgui/emoticons/cry.png\t(6)\tplugins/gtkgui/emoticons/devil.png\t:o\tplugins/gtkgui/emoticons/oh.png\t(L)\tplugins/gtkgui/emoticons/heart.png\t(w)\tplugins/gtkgui/emoticons/brflower.png\t:d\tplugins/gtkgui/emoticons/biggrin.png\t(Z)\tplugins/gtkgui/emoticons/boy.png\t(u)\tplugins/gtkgui/emoticons/brheart.png\t:|\tplugins/gtkgui/emoticons/stare.png\t(P)\tplugins/gtkgui/emoticons/photo.png\t:O\tplugins/gtkgui/emoticons/oh.png\t(R)\tplugins/gtkgui/emoticons/rainbow.png\t(t)\tplugins/gtkgui/emoticons/phone.png\t(i)\tplugins/gtkgui/emoticons/lamp.png\t;)\tplugins/gtkgui/emoticons/wink.png\t;(\tplugins/gtkgui/emoticons/cry.png\t:p\tplugins/gtkgui/emoticons/tongue.png\t(H)\tplugins/gtkgui/emoticons/coolglasses.png\t:s\tplugins/gtkgui/emoticons/frowing.png\t;\'-(\tplugins/gtkgui/emoticons/cry.png\t:-(\tplugins/gtkgui/emoticons/unhappy.png\t:-)\tplugins/gtkgui/emoticons/smile.png\t(b)\tplugins/gtkgui/emoticons/beer.png\t8-)\tplugins/gtkgui/emoticons/coolglasses.png\t(B)\tplugins/gtkgui/emoticons/beer.png\t(W)\tplugins/gtkgui/emoticons/brflower.png\t:D\tplugins/gtkgui/emoticons/biggrin.png\t(y)\tplugins/gtkgui/emoticons/yes.png\t(8)\tplugins/gtkgui/emoticons/music.png\t:@\tplugins/gtkgui/emoticons/angry.png\tB)\tplugins/gtkgui/emoticons/coolglasses.png\t:-$\tplugins/gtkgui/emoticons/blush.png\t:\'(\tplugins/gtkgui/emoticons/cry.png\t(n)\tplugins/gtkgui/emoticons/no.png\t(k)\tplugins/gtkgui/emoticons/kiss.png\t:->\tplugins/gtkgui/emoticons/biggrin.png\t:[\tplugins/gtkgui/emoticons/bat.png\t(I)\tplugins/gtkgui/emoticons/lamp.png\t:P\tplugins/gtkgui/emoticons/tongue.png\t(%)\tplugins/gtkgui/emoticons/cuffs.png\t(d)\tplugins/gtkgui/emoticons/drink.png\t:S\tplugins/gtkgui/emoticons/frowing.png',\
'soundplayer': 'play',\
'sounds': 'message\tsounds/message.wav',\
'x-position': 0,\ 'x-position': 0,\
'y-position': 0,\ 'y-position': 0,\
'width': 150,\ 'width': 150,\