[Michele Campeotto] we now have an emoticon selector!
This commit is contained in:
parent
518391c2aa
commit
03684ad385
4 changed files with 167 additions and 20 deletions
63
src/chat.py
63
src/chat.py
|
@ -22,6 +22,7 @@ import gtk.glade
|
||||||
import pango
|
import pango
|
||||||
import gobject
|
import gobject
|
||||||
import time
|
import time
|
||||||
|
import math
|
||||||
|
|
||||||
import dialogs
|
import dialogs
|
||||||
import history_window
|
import history_window
|
||||||
|
@ -89,10 +90,22 @@ class Chat:
|
||||||
self.notebook.set_show_tabs(gajim.config.get('tabs_always_visible'))
|
self.notebook.set_show_tabs(gajim.config.get('tabs_always_visible'))
|
||||||
self.notebook.set_show_border(gajim.config.get('tabs_border'))
|
self.notebook.set_show_border(gajim.config.get('tabs_border'))
|
||||||
|
|
||||||
|
if gajim.config.get('useemoticons'):
|
||||||
|
self.emoticons_menu = self.emoticons_menu()
|
||||||
|
|
||||||
# muc attention states (when we are mentioned in a muc)
|
# muc attention states (when we are mentioned in a muc)
|
||||||
# if the room jid is in the list, the room has mentioned us
|
# if the room jid is in the list, the room has mentioned us
|
||||||
self.muc_attentions = []
|
self.muc_attentions = []
|
||||||
|
|
||||||
|
def update_emoticons_button(self):
|
||||||
|
for jid in self.xmls:
|
||||||
|
if gajim.config.get('useemoticons'):
|
||||||
|
self.xmls[jid].get_widget('emoticons_button').show()
|
||||||
|
self.xmls[jid].get_widget('emoticons_button').set_no_show_all(False)
|
||||||
|
else:
|
||||||
|
self.xmls[jid].get_widget('emoticons_button').hide()
|
||||||
|
self.xmls[jid].get_widget('emoticons_button').set_no_show_all(True)
|
||||||
|
|
||||||
def update_font(self):
|
def update_font(self):
|
||||||
font = pango.FontDescription(gajim.config.get('conversation_font'))
|
font = pango.FontDescription(gajim.config.get('conversation_font'))
|
||||||
for jid in self.xmls:
|
for jid in self.xmls:
|
||||||
|
@ -353,6 +366,10 @@ class Chat:
|
||||||
menu.popup(None, None, self.position_actions_menu, 1, 0)
|
menu.popup(None, None, self.position_actions_menu, 1, 0)
|
||||||
menu.show_all()
|
menu.show_all()
|
||||||
|
|
||||||
|
def on_emoticons_button_clicked(self, widget):
|
||||||
|
'''popup emoticons menu'''
|
||||||
|
self.emoticons_menu.popup(None, None, None, 1, 0)
|
||||||
|
|
||||||
def position_actions_menu(self, menu):
|
def position_actions_menu(self, menu):
|
||||||
# here I get the coordinates of the button relative to
|
# here I get the coordinates of the button relative to
|
||||||
# window (self.window)
|
# window (self.window)
|
||||||
|
@ -425,6 +442,35 @@ class Chat:
|
||||||
|
|
||||||
return menu
|
return menu
|
||||||
|
|
||||||
|
def emoticons_menu(self):
|
||||||
|
menu = gtk.Menu()
|
||||||
|
|
||||||
|
def append_emoticon(w, d):
|
||||||
|
jid = self.get_active_jid()
|
||||||
|
message_textview = self.message_textviews[jid]
|
||||||
|
message_textview.get_buffer().insert_at_cursor(" %s " % d)
|
||||||
|
message_textview.grab_focus()
|
||||||
|
|
||||||
|
counter = 0
|
||||||
|
# Calculate the side lenght of the popup to make it a square
|
||||||
|
size = int(round(math.sqrt(len(gajim.interface.emoticons_images))))
|
||||||
|
for image in gajim.interface.emoticons_images:
|
||||||
|
item = gtk.MenuItem()
|
||||||
|
img = gtk.Image()
|
||||||
|
if type(image[1]) == gtk.gdk.PixbufAnimation:
|
||||||
|
img.set_from_animation(image[1])
|
||||||
|
else:
|
||||||
|
img.set_from_pixbuf(image[1])
|
||||||
|
item.add(img)
|
||||||
|
item.connect('activate', append_emoticon, image[0])
|
||||||
|
#FIXME: add tooltip with ascii
|
||||||
|
menu.attach(item,
|
||||||
|
counter % size, counter % size + 1,
|
||||||
|
counter / size, counter / size + 1)
|
||||||
|
counter += 1
|
||||||
|
menu.show_all()
|
||||||
|
return menu
|
||||||
|
|
||||||
def popup_menu(self, event):
|
def popup_menu(self, event):
|
||||||
menu = self.prepare_context_menu()
|
menu = self.prepare_context_menu()
|
||||||
# common menuitems (tab switches)
|
# common menuitems (tab switches)
|
||||||
|
@ -645,6 +691,13 @@ class Chat:
|
||||||
dialogs.ErrorDialog(unicode(msg), _('If that is not your language for which you want to highlight misspelled words, then please set your $LANG as appropriate. Eg. for French do export LANG=fr_FR or export LANG=fr_FR.UTF-8 in ~/.bash_profile or to make it global in /etc/profile.\n\nHighlighting misspelled words feature will not be used')).get_response()
|
dialogs.ErrorDialog(unicode(msg), _('If that is not your language for which you want to highlight misspelled words, then please set your $LANG as appropriate. Eg. for French do export LANG=fr_FR or export LANG=fr_FR.UTF-8 in ~/.bash_profile or to make it global in /etc/profile.\n\nHighlighting misspelled words feature will not be used')).get_response()
|
||||||
gajim.config.set('use_speller', False)
|
gajim.config.set('use_speller', False)
|
||||||
|
|
||||||
|
if gajim.config.get('useemoticons'):
|
||||||
|
self.xmls[jid].get_widget('emoticons_button').show()
|
||||||
|
self.xmls[jid].get_widget('emoticons_button').set_no_show_all(False)
|
||||||
|
else:
|
||||||
|
self.xmls[jid].get_widget('emoticons_button').hide()
|
||||||
|
self.xmls[jid].get_widget('emoticons_button').set_no_show_all(True)
|
||||||
|
|
||||||
conv_textview.modify_font(font)
|
conv_textview.modify_font(font)
|
||||||
conv_buffer = conv_textview.get_buffer()
|
conv_buffer = conv_textview.get_buffer()
|
||||||
end_iter = conv_buffer.get_end_iter()
|
end_iter = conv_buffer.get_end_iter()
|
||||||
|
@ -744,6 +797,16 @@ class Chat:
|
||||||
elif event.keyval == gtk.keysyms.c and \
|
elif event.keyval == gtk.keysyms.c and \
|
||||||
(event.state & gtk.gdk.MOD1_MASK): # alt + C toggles compact view
|
(event.state & gtk.gdk.MOD1_MASK): # alt + C toggles compact view
|
||||||
self.set_compact_view(not self.compact_view_current_state)
|
self.set_compact_view(not self.compact_view_current_state)
|
||||||
|
elif event.keyval == gtk.keysyms.e and \
|
||||||
|
(event.state & gtk.gdk.MOD1_MASK): # alt + E opens emoticons menu
|
||||||
|
if gajim.config.get('useemoticons'):
|
||||||
|
parent = self.message_textviews[jid]
|
||||||
|
def set_emoticons_menu_position(w, parent=parent):
|
||||||
|
window = parent.get_window(gtk.TEXT_WINDOW_WIDGET)
|
||||||
|
origin = window.get_origin()
|
||||||
|
size = window.get_size()
|
||||||
|
return (origin[0], origin[1] + size[1], 0)
|
||||||
|
self.emoticons_menu.popup(None, None, set_emoticons_menu_position, 1, 0)
|
||||||
elif event.keyval == gtk.keysyms.Page_Down:
|
elif event.keyval == gtk.keysyms.Page_Down:
|
||||||
if event.state & gtk.gdk.SHIFT_MASK: # SHIFT + PAGE DOWN
|
if event.state & gtk.gdk.SHIFT_MASK: # SHIFT + PAGE DOWN
|
||||||
conv_textview = self.conversation_textviews[jid]
|
conv_textview = self.conversation_textviews[jid]
|
||||||
|
|
|
@ -501,7 +501,19 @@ class PreferencesWindow:
|
||||||
def on_use_emoticons_checkbutton_toggled(self, widget):
|
def on_use_emoticons_checkbutton_toggled(self, widget):
|
||||||
self.on_checkbutton_toggled(widget, 'useemoticons',
|
self.on_checkbutton_toggled(widget, 'useemoticons',
|
||||||
[self.xml.get_widget('add_remove_emoticons_button')])
|
[self.xml.get_widget('add_remove_emoticons_button')])
|
||||||
|
self.update_emoticons_button()
|
||||||
|
|
||||||
|
def update_emoticons_button(self):
|
||||||
|
'''Update emoticons button in Opened Chat Windows'''
|
||||||
|
for a in gajim.connections:
|
||||||
|
for kind in ('chats', 'gc'):
|
||||||
|
windows = gajim.interface.instances[a][kind]
|
||||||
|
if windows.has_key('tabbed'):
|
||||||
|
windows['tabbed'].update_emoticons_button()
|
||||||
|
else:
|
||||||
|
for jid in windows.keys():
|
||||||
|
windows[jid].update_emoticons_button()
|
||||||
|
|
||||||
def on_add_remove_emoticons_button_clicked(self, widget):
|
def on_add_remove_emoticons_button_clicked(self, widget):
|
||||||
if gajim.interface.instances.has_key('manage_emots'):
|
if gajim.interface.instances.has_key('manage_emots'):
|
||||||
gajim.interface.instances['manage_emots'].window.present()
|
gajim.interface.instances['manage_emots'].window.present()
|
||||||
|
@ -1947,7 +1959,7 @@ class ManageEmoticonsWindow:
|
||||||
self.xml.signal_autoconnect(self)
|
self.xml.signal_autoconnect(self)
|
||||||
|
|
||||||
def on_manage_emoticons_window_destroy(self, widget):
|
def on_manage_emoticons_window_destroy(self, widget):
|
||||||
gajim.interface.init_regexp() # update regexp [emoticons included]
|
gajim.interface.init_emoticons() # update emoticons
|
||||||
# remove us from open windows
|
# remove us from open windows
|
||||||
del gajim.interface.instances['manage_emots']
|
del gajim.interface.instances['manage_emots']
|
||||||
|
|
||||||
|
|
45
src/gajim.py
45
src/gajim.py
|
@ -1064,16 +1064,17 @@ class Interface:
|
||||||
basic_pattern = links + mail + formatting
|
basic_pattern = links + mail + formatting
|
||||||
self.basic_pattern_re = sre.compile(basic_pattern, sre.IGNORECASE)
|
self.basic_pattern_re = sre.compile(basic_pattern, sre.IGNORECASE)
|
||||||
|
|
||||||
# When an emoticon is bordered by an alpha-numeric character it is NOT
|
if gajim.config.get('useemoticons'):
|
||||||
# expanded. e.g., foo:) NO, foo :) YES, (brb) NO, (:)) YES, etc.
|
# When an emoticon is bordered by an alpha-numeric character it is NOT
|
||||||
emoticons_pattern = '(?<!\w)(?:'
|
# expanded. e.g., foo:) NO, foo :) YES, (brb) NO, (:)) YES, etc.
|
||||||
# sort keys by length so :qwe emot is checked before :q
|
emoticons_pattern = '(?<!\w)(?:'
|
||||||
keys = self.emoticons.keys()
|
# sort keys by length so :qwe emot is checked before :q
|
||||||
keys.sort(self.on_emoticon_sort)
|
keys = self.emoticons.keys()
|
||||||
for emoticon in keys: # travel thru emoticons list
|
keys.sort(self.on_emoticon_sort)
|
||||||
emoticon_escaped = sre.escape(emoticon) # espace regexp metachars
|
for emoticon in keys: # travel thru emoticons list
|
||||||
emoticons_pattern += emoticon_escaped + '|' # | means or in regexp
|
emoticon_escaped = sre.escape(emoticon) # espace regexp metachars
|
||||||
emoticons_pattern = emoticons_pattern[:-1] + ')(?!\w)'
|
emoticons_pattern += emoticon_escaped + '|'# | means or in regexp
|
||||||
|
emoticons_pattern = emoticons_pattern[:-1] + ')(?!\w)'
|
||||||
|
|
||||||
# because emoticons match later (in the string) they need to be after
|
# because emoticons match later (in the string) they need to be after
|
||||||
# basic matches that may occur earlier
|
# basic matches that may occur earlier
|
||||||
|
@ -1095,19 +1096,26 @@ class Interface:
|
||||||
def on_launch_browser_mailer(self, widget, url, kind):
|
def on_launch_browser_mailer(self, widget, url, kind):
|
||||||
helpers.launch_browser_mailer(kind, url)
|
helpers.launch_browser_mailer(kind, url)
|
||||||
|
|
||||||
def init_regexp(self):
|
def init_emoticons(self):
|
||||||
#initialize emoticons dictionary
|
if not gajim.config.get('useemoticons'):
|
||||||
|
return
|
||||||
|
|
||||||
|
#initialize emoticons dictionary and unique images list
|
||||||
|
self.emoticons_images = list()
|
||||||
self.emoticons = dict()
|
self.emoticons = dict()
|
||||||
|
|
||||||
emots = gajim.config.get_per('emoticons')
|
emots = gajim.config.get_per('emoticons')
|
||||||
for emot in emots:
|
for emot in emots:
|
||||||
emot_file = gajim.config.get_per('emoticons', emot, 'path')
|
emot_file = gajim.config.get_per('emoticons', emot, 'path')
|
||||||
if not self.image_is_ok(emot_file):
|
if not self.image_is_ok(emot_file):
|
||||||
continue
|
continue
|
||||||
|
if not emot_file in self.emoticons.values():
|
||||||
|
pix = gtk.gdk.pixbuf_new_from_file(emot_file)
|
||||||
|
if emot_file.endswith('.gif'):
|
||||||
|
pix = gtk.gdk.PixbufAnimation(emot_file)
|
||||||
|
self.emoticons_images.append((emot, pix))
|
||||||
self.emoticons[emot.upper()] = emot_file
|
self.emoticons[emot.upper()] = emot_file
|
||||||
|
|
||||||
# update regular expressions
|
|
||||||
self.make_regexps()
|
|
||||||
|
|
||||||
def register_handlers(self):
|
def register_handlers(self):
|
||||||
self.handlers = {
|
self.handlers = {
|
||||||
'ROSTER': self.handle_event_roster,
|
'ROSTER': self.handle_event_roster,
|
||||||
|
@ -1247,7 +1255,7 @@ class Interface:
|
||||||
'grouptextcolor', 'groupbgcolor', 'groupfont', 'groupfontattrs',
|
'grouptextcolor', 'groupbgcolor', 'groupfont', 'groupfontattrs',
|
||||||
'contacttextcolor', 'contactbgcolor', 'contactfont', 'contactfontattrs',
|
'contacttextcolor', 'contactbgcolor', 'contactfont', 'contactfontattrs',
|
||||||
'bannertextcolor', 'bannerbgcolor']
|
'bannertextcolor', 'bannerbgcolor']
|
||||||
|
|
||||||
default = gajim.config.themes_default
|
default = gajim.config.themes_default
|
||||||
for theme_name in default:
|
for theme_name in default:
|
||||||
gajim.config.add_per('themes', theme_name)
|
gajim.config.add_per('themes', theme_name)
|
||||||
|
@ -1340,7 +1348,8 @@ class Interface:
|
||||||
if gajim.config.get('check_for_new_version'):
|
if gajim.config.get('check_for_new_version'):
|
||||||
check_for_new_version.Check_for_new_version_dialog()
|
check_for_new_version.Check_for_new_version_dialog()
|
||||||
|
|
||||||
self.init_regexp()
|
self.init_emoticons()
|
||||||
|
self.make_regexps()
|
||||||
|
|
||||||
# get instances for windows/dialogs that will show_all()/hide()
|
# get instances for windows/dialogs that will show_all()/hide()
|
||||||
self.instances['file_transfers'] = dialogs.FileTransfersWindow()
|
self.instances['file_transfers'] = dialogs.FileTransfersWindow()
|
||||||
|
|
|
@ -9790,6 +9790,38 @@ topic</property>
|
||||||
<property name="homogeneous">False</property>
|
<property name="homogeneous">False</property>
|
||||||
<property name="spacing">6</property>
|
<property name="spacing">6</property>
|
||||||
|
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkButton" id="emoticons_button">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="tooltip" translatable="yes">Click to insert an emoticon</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
|
<property name="focus_on_click">True</property>
|
||||||
|
<accessibility>
|
||||||
|
<atkproperty name="AtkObject::accessible_name" translatable="yes">Emoticons</atkproperty>
|
||||||
|
</accessibility>
|
||||||
|
<signal name="clicked" handler="on_emoticons_button_clicked" last_modification_time="Wed, 14 Sep 2005 15:16:41 GMT"/>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkImage" id="image1239">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="stock">gtk-about</property>
|
||||||
|
<property name="icon_size">4</property>
|
||||||
|
<property name="xalign">0.5</property>
|
||||||
|
<property name="yalign">0.5</property>
|
||||||
|
<property name="xpad">0</property>
|
||||||
|
<property name="ypad">0</property>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkButton" id="actions_button">
|
<widget class="GtkButton" id="actions_button">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -11318,6 +11350,37 @@ Status message</property>
|
||||||
<property name="homogeneous">False</property>
|
<property name="homogeneous">False</property>
|
||||||
<property name="spacing">6</property>
|
<property name="spacing">6</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkButton" id="emoticons_button">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="tooltip" translatable="yes">Click to insert an emoticon</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
|
<property name="focus_on_click">True</property>
|
||||||
|
<accessibility>
|
||||||
|
<atkproperty name="AtkObject::accessible_name" translatable="yes">Emoticons</atkproperty>
|
||||||
|
</accessibility>
|
||||||
|
<signal name="clicked" handler="on_emoticons_button_clicked" last_modification_time="Wed, 14 Sep 2005 15:16:41 GMT"/>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkImage" id="image1239">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="stock">gtk-about</property>
|
||||||
|
<property name="icon_size">4</property>
|
||||||
|
<property name="xalign">0.5</property>
|
||||||
|
<property name="yalign">0.5</property>
|
||||||
|
<property name="xpad">0</property>
|
||||||
|
<property name="ypad">0</property>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkButton" id="actions_button">
|
<widget class="GtkButton" id="actions_button">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
|
Loading…
Add table
Reference in a new issue