From b7761d725601f56066fffa349714eb3246d66345 Mon Sep 17 00:00:00 2001 From: Travis Shirk Date: Sat, 31 Dec 2005 04:53:14 +0000 Subject: [PATCH] Moved MessageWindowMgr singleton to gajim.interface and emoticon menu support --- src/chat_control.py | 61 ++++++++++++++++++++++++++++++++++++++++++- src/config.py | 10 ++----- src/gajim.py | 5 ++++ src/gtkgui.glade | 8 +++--- src/message_window.py | 38 +++++++++++++++++++++++++++ src/roster_window.py | 7 ++--- 6 files changed, 111 insertions(+), 18 deletions(-) diff --git a/src/chat_control.py b/src/chat_control.py index 5ad38e423..5a899cba4 100644 --- a/src/chat_control.py +++ b/src/chat_control.py @@ -12,6 +12,8 @@ ## GNU General Public License for more details. ## +import os, os.path +import math import gtk import gtk.glade import pango @@ -87,6 +89,13 @@ class ChatControlBase(MessageControl): self.nb_unread = 0 + # Emoticons menu + # set image no matter if user wants at this time emoticons or not + # (so toggle works ok) + img = self.xml.get_widget('emoticons_button_image') + img.set_from_file(os.path.join(gajim.DATA_DIR, 'emoticons', 'smile.png')) + self.toggle_emoticons() + def _paint_banner(self): '''Repaint banner with theme color''' theme = gajim.config.get('roster_theme') @@ -265,6 +274,57 @@ class ChatControlBase(MessageControl): self.redraw_tab(jid) self.show_title(urgent) + def toggle_emoticons(self): + '''hide show emoticons_button and make sure emoticons_menu is always there + when needed''' + emoticons_button = self.xml.get_widget('emoticons_button') + if gajim.config.get('useemoticons'): + self.emoticons_menu = self.prepare_emoticons_menu() + emoticons_button.show() + emoticons_button.set_no_show_all(False) + else: + self.emoticons_menu = None + emoticons_button.hide() + emoticons_button.set_no_show_all(True) + + def prepare_emoticons_menu(self): + menu = gtk.Menu() + + def append_emoticon(w, d): + buffer = self.msg_textview.get_buffer() + if buffer.get_char_count(): + buffer.insert_at_cursor(' %s ' % d) + else: # we are the beginning of buffer + buffer.insert_at_cursor('%s ' % d) + self.msg_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 on_emoticons_button_clicked(self, widget): + '''popup emoticons menu''' + #FIXME: BUG http://bugs.gnome.org/show_bug.cgi?id=316786 + self.button_clicked = widget + self.emoticons_menu.popup(None, None, self.position_menu_under_button, 1, 0) + + class ChatControl(ChatControlBase): '''A control for standard 1-1 chat''' def __init__(self, parent_win, contact, acct): @@ -475,7 +535,6 @@ class ChatControl(ChatControlBase): self.mouse_over_in_last_30_secs = False self.kbd_activity_in_last_30_secs = False - def print_conversation(self, text, frm = '', tim = None, encrypted = False, subject = None): '''Print a line in the conversation: diff --git a/src/config.py b/src/config.py index 714b84190..54736144a 100644 --- a/src/config.py +++ b/src/config.py @@ -502,14 +502,8 @@ class PreferencesWindow: def toggle_emoticons(self): '''Update emoticons state 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'].toggle_emoticons() - else: - for jid in windows.keys(): - windows[jid].toggle_emoticons() + for win in gajim.interface.msg_win_mgr.windows.values(): + win.toggle_emoticons() def on_add_remove_emoticons_button_clicked(self, widget): if gajim.interface.instances.has_key('manage_emots'): diff --git a/src/gajim.py b/src/gajim.py index e5ea10a43..5565fe114 100755 --- a/src/gajim.py +++ b/src/gajim.py @@ -38,6 +38,8 @@ from common import i18n i18n.init() _ = i18n._ +from message_window import MessageWindowMgr + try: import gtk except RuntimeError, msg: @@ -1450,6 +1452,9 @@ class Interface: gobject.timeout_add(200, self.process_connections) gobject.timeout_add(500, self.read_sleepy) + # This is the manager and factory of message windows + self.msg_win_mgr = MessageWindowMgr() + def test_migration(migration): if not migration.PROCESSING: dialog = gtk.Dialog() diff --git a/src/gtkgui.glade b/src/gtkgui.glade index d1d01feb3..42191fbe0 100644 --- a/src/gtkgui.glade +++ b/src/gtkgui.glade @@ -19395,7 +19395,7 @@ Status message 6 - + True Click to insert an emoticon (Alt+E) True @@ -19410,7 +19410,7 @@ Status message 0 - + True 0.5 0.5 @@ -20034,7 +20034,7 @@ topic 6 - + True Click to insert an emoticon (Alt+E) True @@ -20049,7 +20049,7 @@ topic 0 - + True 0.5 0.5 diff --git a/src/message_window.py b/src/message_window.py index 6be780a1f..7f4572b4e 100644 --- a/src/message_window.py +++ b/src/message_window.py @@ -202,7 +202,12 @@ class MessageWindow: def is_active(self): return self.window.is_active() + def get_origin(self): + return self.window.window.get_origin() + def toggle_emoticons(self): + for ctl in self._controls.values(): + ctl.toggle_emoticons() class MessageWindowMgr: '''A manager and factory for MessageWindow objects''' @@ -286,6 +291,8 @@ class MessageControl(gtk.VBox): self.xml = gtk.glade.XML(GTKGUI_GLADE, widget_name, APP) self.widget = self.xml.get_widget(widget_name) + # Autoconnect glade signals + self.xml.signal_autoconnect(self) def draw_widgets(self): pass # NOTE: Derived classes should implement this @@ -293,6 +300,8 @@ class MessageControl(gtk.VBox): pass # NOTE: Derived classes SHOULD implement this def update_state(self): pass # NOTE: Derived classes SHOULD implement this + def toggle_emoticons(self): + pass # NOTE: Derived classes MAY implement this def send_message(self, message, keyID = '', chatstate = None): '''Send the given message to the active tab''' @@ -306,4 +315,33 @@ class MessageControl(gtk.VBox): # Send and update history gajim.connections[self.account].send_message(jid, message, keyID, chatstate) + def position_menu_under_button(self, menu): + #FIXME: BUG http://bugs.gnome.org/show_bug.cgi?id=316786 + # pass btn instance when this bug is over + button = self.button_clicked + # here I get the coordinates of the button relative to + # window (self.window) + button_x, button_y = button.allocation.x, button.allocation.y + + # now convert them to X11-relative + window_x, window_y = self.parent_win.get_origin() + x = window_x + button_x + y = window_y + button_y + + menu_width, menu_height = menu.size_request() + + ## should we pop down or up? + if (y + button.allocation.height + menu_height + < gtk.gdk.screen_height()): + # now move the menu below the button + y += button.allocation.height + else: + # now move the menu above the button + y -= menu_height + + + # push_in is True so all the menuitems are always inside screen + push_in = True + return (x, y, push_in) + diff --git a/src/roster_window.py b/src/roster_window.py index 9a41ec86a..8495906b9 100644 --- a/src/roster_window.py +++ b/src/roster_window.py @@ -48,7 +48,6 @@ from gajim import Contact from common import gajim from common import helpers from common import i18n -from message_window import MessageWindowMgr from chat_control import ChatControl _ = i18n._ @@ -1652,7 +1651,7 @@ _('If "%s" accepts this request you will know his or her status.') %jid) def new_chat(self, contact, account): # Get target window - mw = self.msg_win_mgr.get_window(contact, account, None) # FIXME: type arg + mw = gajim.interface.msg_win_mgr.get_window(contact, account, None) # FIXME: type arg chat_control = ChatControl(mw, contact, account) mw.new_tab(chat_control) @@ -2225,7 +2224,7 @@ _('If "%s" accepts this request you will know his or her status.') %jid) def repaint_themed_widgets(self): '''Notify windows that contain themed widgets to repaint them''' - for win in self.msg_win_mgr.windows.values(): + for win in gajim.interface.msg_win_mgr.windows.values(): win.repaint_themed_widgets() for account in gajim.connections: for addr in gajim.interface.instances[account]['disco']: @@ -2732,5 +2731,3 @@ _('If "%s" accepts this request you will know his or her status.') %jid) gajim.interface.instances['account_creation_wizard'] = \ config.AccountCreationWizardWindow() - # This is the manager and factory of message windows - self.msg_win_mgr = MessageWindowMgr()