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()
else:
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
if self.chk_autopp.get_active():
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])
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):
if not os.path.exists(image):
return 0
@ -352,29 +402,11 @@ class preference_Window:
iter = model.append()
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):
model = self.emot_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_button_emoticons_clicked(self, widget, data=None):
(model, iter) = self.emot_tree.get_selection().get_selected()
if not iter:
@ -422,13 +454,6 @@ class preference_Window:
self.xml.get_widget('image_emoticon').set_from_file(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):
model = self.emot_tree.get_model()
iter = model.append()
@ -440,15 +465,6 @@ class preference_Window:
return
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):
(model, iter) = self.emot_tree.get_selection().get_selected()
if not iter:
@ -462,14 +478,75 @@ class preference_Window:
for w in widgets:
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):
if event.keyval == gtk.keysyms.Delete:
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):
"""Initialize Preference window"""
self.xml = gtk.glade.XML(GTKGUI_GLADE, 'Preferences', APP)
@ -548,6 +625,26 @@ class preference_Window:
col.pack_start(renderer, True)
col.set_attributes(renderer, text=0)
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
st = self.plugin.config['autopopup']
@ -645,18 +742,12 @@ class preference_Window:
self.xml.signal_connect('on_cancel_clicked', self.on_cancel)
self.xml.signal_connect('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.on_new_msg_button_clicked)
self.xml.signal_connect('on_delete_msg_button_clicked', \
self.on_delete_msg_button_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_msg_treeview_key_press_event', \
self.on_msg_treeview_key_press_event)
self.xml.signal_connect('on_chk_autopopup_toggled', \
self.on_chk_toggled, [self.chk_autoppaway])
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('button_emoticons'),
self.xml.get_widget('image_emoticon')])
self.xml.signal_connect('on_msg_treeview_key_press_event', \
self.on_msg_treeview_key_press_event)
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_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.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,\
'lognotusr':1}))

View File

@ -4678,6 +4678,148 @@ on the server.</property>
<property name="fill">False</property>
</packing>
</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>
<packing>
<property name="tab_expand">False</property>

View File

@ -54,7 +54,7 @@ pygtk.require('2.0')
import gtk
from gtk import TRUE, FALSE
import gtk.glade,gobject
import os,string,time,Queue
import os,string,time,Queue, sys
import common.optparser,common.sleepy
from common import i18n
_ = i18n._
@ -2143,6 +2143,21 @@ class roster_Window:
# for state in ('online', 'away', 'xa', 'dnd', 'invisible', 'offline'):
# 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):
"""when show offline option is changed :
redraw the treeview"""
@ -2307,6 +2322,7 @@ class roster_Window:
self.mkpixbufs()
if self.plugin.config['useemoticons']:
self.mkemoticons()
self.mkevents()
liststore = gtk.ListStore(gobject.TYPE_STRING, gtk.Image)
self.cb = gtk.ComboBox()
@ -2581,6 +2597,28 @@ class plugin:
return a
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):
self.queueOUT.put((event, account, data))
@ -2671,6 +2709,7 @@ class plugin:
jid = string.split(array[0], '/')[0]
if string.find(jid, "@") <= 0:
jid = string.replace(jid, '@', '')
self.play_sound('message')
self.roster.on_message(jid, array[1], array[2], account)
def handle_event_msgerror(self, account, array):
@ -2967,6 +3006,8 @@ class plugin:
'usetabbedchat': 0,\
'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',\
'soundplayer': 'play',\
'sounds': 'message\tsounds/message.wav',\
'x-position': 0,\
'y-position': 0,\
'width': 150,\