Close to usable for chat, receiving messages, etc.

This commit is contained in:
Travis Shirk 2005-12-31 21:55:44 +00:00
parent 1102356937
commit c30ee542dc
9 changed files with 157 additions and 100 deletions

View File

@ -41,6 +41,7 @@ APP = i18n.APP
GTKGUI_GLADE = 'gtkgui.glade'
################################################################################
class ChatControlBase(MessageControl):
# FIXME
'''TODO
@ -113,6 +114,8 @@ class ChatControlBase(MessageControl):
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)
self.print_time_timeout_id = None
def _paint_banner(self):
'''Repaint banner with theme color'''
theme = gajim.config.get('roster_theme')
@ -371,6 +374,25 @@ class ChatControlBase(MessageControl):
start, end = buffer.get_bounds()
buffer.delete(start, end)
def print_time_timeout(self, arg):
if gajim.config.get('print_time') == 'sometimes':
conv_textview = self.conv_textview
buffer = conv_textview.get_buffer()
end_iter = buffer.get_end_iter()
tim = time.localtime()
tim_format = time.strftime('%H:%M', tim)
buffer.insert_with_tags_by_name(end_iter, '\n' + tim_format,
'time_sometimes')
# scroll to the end of the textview
if conv_textview.at_the_end():
# we are at the end
conv_textview.scroll_to_end()
return True # loop again
if self.print_time_timeout_id:
del self.print_time_timeout_id
return False
################################################################################
class ChatControl(ChatControlBase):
'''A control for standard 1-1 chat'''
TYPE_ID = 1
@ -591,7 +613,7 @@ class ChatControl(ChatControlBase):
self.kbd_activity_in_last_30_secs = False
def print_conversation(self, text, frm = '', tim = None,
encrypted = False, subject = None):
encrypted = False, subject = None):
'''Print a line in the conversation:
if contact is set to status: it's a status message
if contact is set to another value: it's an outgoing message

View File

@ -502,7 +502,7 @@ class PreferencesWindow:
def toggle_emoticons(self):
'''Update emoticons state in Opened Chat Windows'''
for win in gajim.interface.msg_win_mgr.windows.values():
for win in gajim.interface.msg_win_mgr.windows():
win.toggle_emoticons()
def on_add_remove_emoticons_button_clicked(self, widget):
@ -639,13 +639,8 @@ class PreferencesWindow:
def update_print_time(self):
'''Update time in Opened Chat Windows'''
for a in gajim.connections:
window = gajim.interface.instances[a]['chats']
if window.has_key('tabbed'):
window['tabbed'].update_print_time()
else:
for jid in window.keys():
window[jid].update_print_time()
for msg_win in gajim.interface.msg_win_mgr.windows():
msg_win.update_print_time()
def on_time_never_radiobutton_toggled(self, widget):
if widget.get_active():
@ -683,7 +678,7 @@ class PreferencesWindow:
def update_text_tags(self):
'''Update color tags in Opened Chat Windows'''
for win in gajim.interface.msg_win_mgr.windows.values():
for win in gajim.interface.msg_win_mgr.windows():
win.update_tags()
def on_preference_widget_color_set(self, widget, text):
@ -701,7 +696,7 @@ class PreferencesWindow:
def update_text_font(self):
'''Update text font in Opened Chat Windows'''
for win in gajim.interface.msg_win_mgr.windows.values():
for win in gajim.interface.msg_win_mgr.windows():
win.update_font()
def on_incoming_msg_colorbutton_color_set(self, widget):

View File

@ -953,22 +953,17 @@ class PopupNotificationWindow:
gajim.interface.roster.add_contact_to_roster(contact.jid,
self.account)
if self.msg_type == 'pm': # It's a private message
gajim.interface.roster.new_chat(contact, self.account)
chats_window = gajim.interface.instances[self.account]['chats'][self.jid]
chats_window.set_active_tab(self.jid)
chats_window.window.present()
elif self.msg_type in ('normal', 'file-request', 'file-request-error',
if self.msg_type in ('normal', 'file-request', 'file-request-error',
'file-send-error', 'file-error', 'file-stopped', 'file-completed'):
# Get the first single message event
ev = gajim.get_first_event(self.account, self.jid, self.msg_type)
gajim.interface.roster.open_event(self.account, self.jid, ev)
else: # 'chat'
else: # chat or pm
assert(self.msg_type == 'chat' or self.msg_type == 'pm')
gajim.interface.roster.new_chat(contact, self.account)
chats_window = gajim.interface.instances[self.account]['chats'][self.jid]
chats_window.set_active_tab(self.jid)
chats_window.window.present()
msg_window = gajim.interface.msg_win_mgr.get_window(self.jid)
msg_window.set_active_tab(self.jid)
msg_window.window.present()
self.adjust_height_and_move_popup_notification_windows()

View File

@ -375,6 +375,7 @@ class Interface:
if gajim.config.get_per('soundevents', 'contact_connected',
'enabled') and gajim.allow_notifications[account]:
helpers.play_sound('contact_connected')
# FIXME
if not self.instances[account]['chats'].has_key(jid) and \
not gajim.awaiting_events[account].has_key(jid) and \
gajim.config.get('notify_on_signin') and \
@ -395,6 +396,7 @@ class Interface:
if gajim.config.get_per('soundevents', 'contact_disconnected',
'enabled'):
helpers.play_sound('contact_disconnected')
# FIXME
if not self.instances[account]['chats'].has_key(jid) and \
not gajim.awaiting_events[account].has_key(jid) and \
gajim.config.get('notify_on_signout'):
@ -437,6 +439,7 @@ class Interface:
if self.instances[account]['gc'].has_key(jid): # it's a Private Message
nick = gajim.get_nick_from_fjid(array[0])
fjid = array[0]
# FIXME
if not self.instances[account]['chats'].has_key(fjid) and \
not gajim.awaiting_events[account].has_key(fjid):
if show_notification:
@ -452,6 +455,7 @@ class Interface:
# Handle chat states
contact = gajim.get_first_contact_instance_from_jid(account, jid)
# FIXME
if self.instances[account]['chats'].has_key(jid):
chat_win = self.instances[account]['chats'][jid]
if chatstate is not None: # he or she sent us reply, so he supports jep85
@ -472,6 +476,7 @@ class Interface:
return
first = False
# FIXME
if not self.instances[account]['chats'].has_key(jid) and \
not gajim.awaiting_events[account].has_key(jid):
first = True
@ -509,6 +514,7 @@ class Interface:
if jid in gcs:
if len(jids) > 1: # it's a pm
nick = jids[1]
# FIXME
if not self.instances[account]['chats'].has_key(fjid):
gc = gcs[jid]
tv = gc.list_treeview[jid]
@ -521,6 +527,7 @@ class Interface:
c = Contact(jid = fjid, name = nick, groups = ['none'],
show = show, ask = 'none')
self.roster.new_chat(c, account)
# FIXME
self.instances[account]['chats'][fjid].print_conversation(
'Error %s: %s' % (array[1], array[2]), fjid, 'status')
return
@ -676,6 +683,7 @@ class Interface:
# show avatar in chat
win = None
# FIXME
if self.instances[account]['chats'].has_key(jid):
win = self.instances[account]['chats'][jid]
elif resource and self.instances[account]['chats'].has_key(
@ -710,6 +718,7 @@ class Interface:
show = array[1]
status = array[2]
# print status in chat window and update status/GPG image
# FIXME
if self.instances[account]['chats'].has_key(fjid):
contact = self.instances[account]['chats'][fjid].contacts[fjid]
contact.show = show
@ -1273,12 +1282,14 @@ class Interface:
if wins['gc'].has_key(jid):
w = wins['gc'][jid]
elif typ == 'chat':
# FIXME
if wins['chats'].has_key(jid):
w = wins['chats'][jid]
else:
self.roster.new_chat(gajim.contacts[account][jid][0], account)
w = wins['chats'][jid]
elif typ == 'pm':
# FIXME
if wins['chats'].has_key(jid):
w = wins['chats'][jid]
else:

View File

@ -290,6 +290,24 @@ class MessageWindow:
return ctl
return None
def controls(self):
for ctl in self._controls.values():
yield ctl
def update_print_time(self):
if gajim.config.get('print_time') != 'sometimes':
for ctl in self.controls():
if ctl.print_time_timeout_id:
gobject.source_remove(ctl.print_time_timeout_id)
del ctl.print_time_timeout_id
else:
for ctl in self.controls():
if not ctl.print_time_timeout_id:
ctl.print_time_timeout()
ctl.print_time_timeout_id = gobject.timeout_add(300000,
ctl.print_time_timeout, None)
class MessageWindowMgr:
'''A manager and factory for MessageWindow objects'''
@ -307,7 +325,7 @@ class MessageWindowMgr:
CONFIG_ALWAYS: The key is MessageWindowMgr.MAIN_WIN
CONFIG_PERACCT: The key is the account name
CONFIG_PERTYPE: The key is a message type constant'''
self.windows = {}
self._windows = {}
# Map the mode to a int constant for frequent compares
mode = gajim.config.get('one_message_window')
self.mode = common.config.opt_one_window_types.index(mode)
@ -321,7 +339,7 @@ class MessageWindowMgr:
return win
def _gtkWinToMsgWin(self, gtk_win):
for w in self.windows.values():
for w in self._windows.values():
if w.window == gtk_win:
return w
return None
@ -335,11 +353,10 @@ class MessageWindowMgr:
# TODO: Clean up windows
def get_window(self, jid):
for win in self.windows.values():
for win in self._windows.values():
if win.get_control_from_jid(jid):
return win
return None
def has_window(self, jid):
return self.get_window(jid)
@ -356,16 +373,30 @@ class MessageWindowMgr:
win = None
try:
win = self.windows[key]
win = self._windows[key]
except KeyError:
# FIXME
print "Creating tabbed chat window for '%s'" % str(key)
win = self._new_window()
self.windows[key] = win
self._windows[key] = win
assert(win)
return win
def get_control(self, jid):
win = self.get_window(jid)
if win:
return win.get_control_from_jid(jid)
return None
def windows(self):
for w in self._windows.values():
yield w
def controls(self):
for w in self._windows:
for c in w.controls():
yield c
class MessageControl(gtk.VBox):
'''An abstract base widget that can embed in the gtk.Notebook of a MessageWindow'''
@ -381,6 +412,7 @@ class MessageControl(gtk.VBox):
self.compact_view_always = False
self.compact_view_current = False
self.nb_unread = 0
self.print_time_timeout_id = None
self.xml = gtk.glade.XML(GTKGUI_GLADE, widget_name, APP)
self.widget = self.xml.get_widget(widget_name)
@ -399,6 +431,12 @@ class MessageControl(gtk.VBox):
pass # NOTE: Derived classes SHOULD implement this
def update_tags(self):
pass # NOTE: Derived classes SHOULD implement this
def print_time_timeout(self, arg):
# NOTE: Derived classes SHOULD implement this
if self.print_time_timeout_id:
gobject.source_remove(self.print_time_timeout_id)
del self.print_time_timeout_id
return False
def markup_tab_label(self, label_str, chatstate):
# NOTE: Derived classes SHOULD implement this
# Reurn a markup'd label and optional gtk.Color

View File

@ -236,7 +236,7 @@ class SignalObject(DbusPrototype):
first_connected_acct = None
for acct in accounts:
if gajim.connections[acct].connected > 1: # account is online
if gajim.interface.instances[acct]['chats'].has_key(jid):
if gajim.interface.msg_win_mgr.has_window(jid):
connected_account = acct
break
# jid is in roster
@ -257,7 +257,7 @@ class SignalObject(DbusPrototype):
if connected_account:
gajim.interface.roster.new_chat_from_jid(connected_account, jid)
# preserve the 'steal focus preservation'
win = gajim.interface.instances[connected_account]['chats'][jid].window
win = gajim.interface.msg_win_mgr.get_window(jid].window
if win.get_property('visible'):
win.window.focus()
return True

View File

@ -709,19 +709,21 @@ class RosterWindow:
self.add_contact_to_roster(contact.jid, account)
self.draw_contact(contact.jid, account)
# print status in chat window and update status/GPG image
if gajim.interface.instances[account]['chats'].has_key(contact.jid):
if gajim.interface.msg_win_mgr.has_window(contact.jid):
jid = contact.jid
gajim.interface.instances[account]['chats'][jid].set_state_image(jid)
win = gajim.interface.msg_win_mgr.get_window(contact.jid)
ctl = win.get_control_from_jid(jid)
ctl.update_state()
name = contact.name
if contact.resource != '':
name += '/' + contact.resource
uf_show = helpers.get_uf_show(show)
gajim.interface.instances[account]['chats'][jid].print_conversation(
_('%s is now %s (%s)') % (name, uf_show, status), jid, 'status')
if contact == gajim.get_contact_instance_with_highest_priority(\
account, contact.jid):
gajim.interface.instances[account]['chats'][jid].draw_name_banner(contact)
ctl.print_conversation(_('%s is now %s (%s)') % (name, uf_show, status),
'status')
if contact == gajim.get_contact_instance_with_highest_priority(account,
contact.jid):
ctl.draw_banner()
def on_info(self, widget, user, account):
'''Call vcard_information_window class to display user's information'''
@ -897,8 +899,9 @@ class RosterWindow:
keys[user.jid] = keyID[0]
for u in gajim.contacts[account][user.jid]:
u.keyID = keyID[0]
if gajim.interface.instances[account]['chats'].has_key(user.jid):
gajim.interface.instances[account]['chats'][user.jid].draw_widgets(user)
if gajim.interface.msg_win_mgr.has_window(user.jid):
ctl = gajim.interface.msg_win_mgr.get_control(user.jid)
ctl.draw_widgets()
keys_str = ''
for jid in keys:
keys_str += jid + ' ' + keys[jid] + ' '
@ -1356,17 +1359,19 @@ _('If "%s" accepts this request you will know his or her status.') %jid)
model = self.tree.get_model()
iter = model.get_iter(path)
type = model[iter][C_TYPE]
# FIXME
if type in ('agent', 'contact'):
account = model[iter][C_ACCOUNT].decode('utf-8')
jid = model[iter][C_JID].decode('utf-8')
if gajim.interface.instances[account]['chats'].has_key(jid):
gajim.interface.instances[account]['chats'][jid].set_active_tab(jid)
win = None
if gajim.interface.msg_win_mgr.has_window(jid):
win = gajim.interface.msg_win_mgr.get_window(jid)
elif gajim.contacts[account].has_key(jid):
c = gajim.get_contact_instance_with_highest_priority(account, jid)
c = gajim.get_contact_instance_with_highest_priority(account,
jid)
self.new_chat(c, account)
gajim.interface.instances[account]['chats'][jid].set_active_tab(jid)
gajim.interface.instances[account]['chats'][jid].window.present()
win = gajim.interface.msg_win_mgr.get_window(jid)
win.set_active_tab(jid)
win.window.present()
elif type == 'account':
account = model[iter][C_ACCOUNT]
if account != 'all':
@ -1412,7 +1417,6 @@ _('If "%s" accepts this request you will know his or her status.') %jid)
_('Contact "%s" will be removed from your roster') % (user.name),
_('By removing this contact you also by default remove authorization resulting in him or her always seeing you as offline.'),
_('I want this contact to know my status after removal'))
# FIXME:
# maybe use 2 optionboxes from which the user can select? (better)
if window.get_response() == gtk.RESPONSE_OK:
remove_auth = True
@ -1422,7 +1426,7 @@ _('If "%s" accepts this request you will know his or her status.') %jid)
for u in gajim.contacts[account][user.jid]:
self.remove_contact(u, account)
del gajim.contacts[account][u.jid]
if user.jid in gajim.interface.instances[account]['chats']:
if gajim.interface.msg_win_mgr.has_window(user.jid):
user1 = Contact(jid = user.jid, name = user.name,
groups = [_('not in the roster')], show = 'not in the roster',
status = '', ask = 'none', keyID = user.keyID)
@ -1657,11 +1661,8 @@ _('If "%s" accepts this request you will know his or her status.') %jid)
ChatControl.TYPE_ID)
chat_control = ChatControl(mw, contact, account)
mw.new_tab(chat_control)
# REMOVE: eliminate all usage of gajim.interface.instances[account]['chats']
##################################
def new_chat_from_jid(self, account, jid):
# FIXME
if gajim.contacts[account].has_key(jid):
contact = gajim.get_contact_instance_with_highest_priority(account, jid)
else:
@ -1676,10 +1677,11 @@ _('If "%s" accepts this request you will know his or her status.') %jid)
gajim.contacts[account][jid] = [contact]
self.add_contact_to_roster(contact.jid, account)
if not gajim.interface.instances[account]['chats'].has_key(jid):
if not gajim.interface.msg_win_mgr.has_window(contact.jid):
self.new_chat(contact, account)
gajim.interface.instances[account]['chats'][jid].set_active_tab(jid)
gajim.interface.instances[account]['chats'][jid].window.present()
mw = gajim.interface.msg_win_mgr.get_window(contact.jid)
mw.set_active_tab(jid)
mw.window.present()
def new_room(self, jid, nick, account):
# FIXME: Not contact. Use jid and nick
@ -1690,12 +1692,9 @@ _('If "%s" accepts this request you will know his or her status.') %jid)
GroupchatControl.TYPE_ID)
gc_control = ChatControl(mw, contact, account)
mw.new_tab(gc_control)
# REMOVE: eliminate all usage of gajim.interface.instances[account]['gc']
##################################
def on_message(self, jid, msg, tim, account, encrypted = False,
# FIXME
msg_type = '', subject = None, resource = ''):
msg_type = '', subject = None, resource = ''):
'''when we receive a message'''
if not gajim.contacts[account].has_key(jid):
keyID = ''
@ -1736,13 +1735,14 @@ _('If "%s" accepts this request you will know his or her status.') %jid)
return
# We print if window is opened and it's not a single message
if gajim.interface.instances[account]['chats'].has_key(jid) and \
msg_type != 'normal':
typ = ''
if msg_type == 'error':
typ = 'status'
gajim.interface.instances[account]['chats'][jid].print_conversation(
msg, jid, typ, tim = tim, encrypted = encrypted, subject = subject)
if gajim.interface.msg_win_mgr.has_window(jid) and msg_type != 'normal':
# FIXME: Remove
# typ = ''
# if msg_type == 'error':
# typ = 'status'
ctl = gajim.interface.msg_win_mgr.get_control(jid)
ctl.print_conversation(msg, jid, tim = tim, encrypted = encrypted,
subject = subject)
return
# We save it in a queue
@ -1754,7 +1754,7 @@ _('If "%s" accepts this request you will know his or her status.') %jid)
qs[jid].append((kind, (msg, subject, msg_type, tim, encrypted, resource)))
self.nb_unread += 1
if popup:
if not gajim.interface.instances[account]['chats'].has_key(jid):
if not gajim.interface.msg_win_mgr.has_window(jid):
c = gajim.get_contact_instance_with_highest_priority(account, jid)
self.new_chat(c, account)
if path:
@ -1932,22 +1932,18 @@ _('If "%s" accepts this request you will know his or her status.') %jid)
recent = False
if self.nb_unread > 0:
unread = True
for account in accounts:
if gajim.interface.instances[account]['chats'].has_key('tabbed'):
wins = [gajim.interface.instances[account]['chats']['tabbed']]
else:
wins = gajim.interface.instances[account]['chats'].values()
for win in wins:
unrd = 0
for jid in win.nb_unread:
unrd += win.nb_unread[jid]
if unrd:
unread = True
for win in gajim.interface.msg_win_mgr.windows.values():
unrd = 0
for ctl in win.controls():
unrd += ctl.nb_unread
if unrd:
unread = True
break
for ctl in win.control():
jid = ctl.contact.jid
if time.time() - gajim.last_message_time[account][ji] < 2:
recent = True
break
for jid in win.contacts:
if time.time() - gajim.last_message_time[account][jid] < 2:
recent = True
break
if unread:
dialog = dialogs.ConfirmationDialog(_('You have unread messages'),
_('Messages will only be available for reading them later if you have history enabled.'))
@ -2201,12 +2197,13 @@ _('If "%s" accepts this request you will know his or her status.') %jid)
# Update the systray
if gajim.interface.systray_enabled:
gajim.interface.systray.set_img()
for ctl in gajim.interface.msg_win_mgr.controls():
ctl.update_state()
# FIXME: All of this will go away with the above
for account in gajim.connections:
# Update opened chat windows
for jid in gajim.interface.instances[account]['chats']:
if jid != 'tabbed':
gajim.interface.instances[account]['chats'][jid].set_state_image(
jid)
# FIXME
# Update opened groupchat windows
gcs = gajim.interface.instances[account]['gc']
if gcs.has_key('tabbed'):
@ -2218,7 +2215,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 gajim.interface.msg_win_mgr.windows.values():
for win in gajim.interface.msg_win_mgr.windows():
win.repaint_themed_widgets()
for account in gajim.connections:
for addr in gajim.interface.instances[account]['disco']:

View File

@ -101,13 +101,13 @@ class Systray:
self.set_img()
def start_chat(self, widget, account, jid):
if gajim.interface.instances[account]['chats'].has_key(jid):
gajim.interface.instances[account]['chats'][jid].window.present()
gajim.interface.instances[account]['chats'][jid].set_active_tab(jid)
if gajim.interface.msg_win_mgr.has_window(jid):
gajim.interface.msg_win_mgr.get_window(jid).set_active_tab(jid)
gajim.interface.msg_win_mgr.get_window(jid).present()
elif gajim.contacts[account].has_key(jid):
gajim.interface.roster.new_chat(
gajim.contacts[account][jid][0], account)
gajim.interface.instances[account]['chats'][jid].set_active_tab(jid)
gajim.interface.roster.new_chat(gajim.contacts[account][jid][0],
account)
gajim.interface.msg_win_mgr.get_window(jid).set_active_tab(jid)
def on_new_message_menuitem_activate(self, widget, account):
"""When new message menuitem is activated:

View File

@ -244,13 +244,12 @@ class NotificationAreaTooltip(BaseTooltip, StatusTable):
for acct in gajim.connections:
# we count unread chat/pm messages
chat_wins = gajim.interface.instances[acct]['chats']
for jid in chat_wins:
if jid != 'tabbed':
if gajim.contacts[acct].has_key(jid):
unread_chat += chat_wins[jid].nb_unread[jid]
else:
unread_pm += chat_wins[jid].nb_unread[jid]
for ctl in gajim.interface.msg_win_mgr.controls():
if gajim.contacts[acct].has_key(jid):
unread_chat += ctl.nb_unread
else:
unread_pm += ctl.nb_unread
# FIXME
# we count unread gc/pm messages
gc_wins = gajim.interface.instances[acct]['gc']
for jid in gc_wins: