More groupchat goodness
This commit is contained in:
parent
58f2d03dd3
commit
2a5b0afc44
|
@ -281,18 +281,16 @@ class ChatControlBase(MessageControl):
|
|||
def _process_command(self, message):
|
||||
if not message:
|
||||
return False
|
||||
|
||||
if message == '/clear':
|
||||
self.conv_textview.clear() # clear conversation
|
||||
# FIXME: Need this function
|
||||
self.clear(self.msg_textview) # clear message textview too
|
||||
return True
|
||||
elif message == '/compact':
|
||||
self.set_compact_view(not self.compact_view_current)
|
||||
# FIXME: Need this function
|
||||
self.clear(self.msg_textview)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return False
|
||||
|
||||
def send_message(self, message, keyID = '', type = 'chat', chatstate = None):
|
||||
'''Send the given message to the active tab'''
|
||||
|
@ -308,19 +306,6 @@ class ChatControlBase(MessageControl):
|
|||
# Clear msg input
|
||||
message_buffer = self.msg_textview.get_buffer()
|
||||
message_buffer.set_text('') # clear message buffer (and tv of course)
|
||||
# FIXME GC ONLY
|
||||
# if contact is None:
|
||||
# # contact was from pm in MUC
|
||||
# room, nick = gajim.get_room_and_nick_from_fjid(jid)
|
||||
# gc_contact = gajim.contacts.get_gc_contact(self.account, room, nick)
|
||||
# if not gc_contact:
|
||||
# # contact left the room, or we left the room
|
||||
# dialogs.ErrorDialog(_('Sending private message failed'),
|
||||
# #in second %s code replaces with nickname
|
||||
# _('You are no longer in room "%s" or "%s" has left.') % \
|
||||
# (room, nick)).get_response()
|
||||
# return
|
||||
|
||||
|
||||
def save_sent_message(self, message):
|
||||
#save the message, so user can scroll though the list with key up/down
|
||||
|
@ -433,13 +418,6 @@ class ChatControlBase(MessageControl):
|
|||
def update_tags(self):
|
||||
self.conv_textview.update_tags()
|
||||
|
||||
def set_compact_view(self, state):
|
||||
'''Toggle compact view. state is bool'''
|
||||
MessageControl.set_compact_view(self, state)
|
||||
# make the last message visible, when changing to "full view"
|
||||
if not state:
|
||||
gobject.idle_add(self.conv_textview.scroll_to_end_iter)
|
||||
|
||||
def clear(self, tv):
|
||||
buffer = tv.get_buffer()
|
||||
start, end = buffer.get_bounds()
|
||||
|
@ -559,10 +537,10 @@ class ChatControlBase(MessageControl):
|
|||
if not self.nb_unread:
|
||||
return
|
||||
jid = self.contact.jid
|
||||
if self.conv_textview.at_the_end() and self.window.is_active():
|
||||
if self.conv_textview.at_the_end() and self.parent_win.window.is_active():
|
||||
#we are at the end
|
||||
self.nb_unread = self.get_specific_unread()
|
||||
self.parent_win.redraw_tab(jid)
|
||||
self.parent_win.redraw_tab(self.contact)
|
||||
self.parent_win.show_title()
|
||||
if gajim.interface.systray_enabled:
|
||||
gajim.interface.systray.remove_jid(jid, self.account,
|
||||
|
@ -600,6 +578,55 @@ class ChatControlBase(MessageControl):
|
|||
color.blue = int((color.blue * p) + (mask * (1 - p)))
|
||||
return color
|
||||
|
||||
def remove_possible_switch_to_menuitems(self, menu):
|
||||
''' remove duplicate 'Switch to' if they exist and return clean menu'''
|
||||
childs = menu.get_children()
|
||||
|
||||
contact = self.parent_win.get_active_contact()
|
||||
jid = contact.jid
|
||||
if _('not in the roster') in contact.groups: # for add_to_roster_menuitem
|
||||
childs[5].show()
|
||||
childs[5].set_no_show_all(False)
|
||||
else:
|
||||
childs[5].hide()
|
||||
childs[5].set_no_show_all(True)
|
||||
|
||||
if self.type_id == message_control.TYPE_GC:
|
||||
start_removing_from = 7 # # this is from the seperator and after
|
||||
else:
|
||||
start_removing_from = 6 # this is from the seperator and after
|
||||
|
||||
for child in childs[start_removing_from:]:
|
||||
menu.remove(child)
|
||||
return menu
|
||||
|
||||
def set_compact_view(self, state):
|
||||
'''Toggle compact view. state is bool'''
|
||||
MessageControl.set_compact_view(self, state)
|
||||
# make the last message visible, when changing to "full view"
|
||||
if not state:
|
||||
gobject.idle_add(self.conv_textview.scroll_to_end_iter)
|
||||
|
||||
if self.type_id == message_control.TYPE_GC:
|
||||
widgets = [
|
||||
self.xml.get_widget('banner_eventbox'),
|
||||
self.xml.get_widget('gc_actions_hbox'),
|
||||
self.xml.get_widget('list_scrolledwindow'),
|
||||
]
|
||||
else:
|
||||
widgets = [
|
||||
self.xml.get_widget('banner_eventbox'),
|
||||
self.xml.get_widget('actions_hbox'),
|
||||
]
|
||||
|
||||
for widget in widgets:
|
||||
if state:
|
||||
widget.set_no_show_all(True)
|
||||
widget.hide()
|
||||
else:
|
||||
widget.set_no_show_all(False)
|
||||
widget.show_all()
|
||||
|
||||
################################################################################
|
||||
class ChatControl(ChatControlBase):
|
||||
'''A control for standard 1-1 chat'''
|
||||
|
@ -1004,28 +1031,6 @@ class ChatControl(ChatControlBase):
|
|||
|
||||
return tab_img
|
||||
|
||||
def remove_possible_switch_to_menuitems(self, menu):
|
||||
''' remove duplicate 'Switch to' if they exist and return clean menu'''
|
||||
childs = menu.get_children()
|
||||
|
||||
contact = self.parent_win.get_active_contact()
|
||||
jid = contact.jid
|
||||
if _('not in the roster') in contact.groups: # for add_to_roster_menuitem
|
||||
childs[5].show()
|
||||
childs[5].set_no_show_all(False)
|
||||
else:
|
||||
childs[5].hide()
|
||||
childs[5].set_no_show_all(True)
|
||||
start_removing_from = 6 # this is from the seperator and after
|
||||
|
||||
# FIXME: GC only
|
||||
# elif :
|
||||
# start_removing_from = 7 # # this is from the seperator and after
|
||||
|
||||
for child in childs[start_removing_from:]:
|
||||
menu.remove(child)
|
||||
return menu
|
||||
|
||||
def prepare_context_menu(self):
|
||||
'''sets compact view menuitem active state
|
||||
sets active and sensitivity state for toggle_gpg_menuitem
|
||||
|
@ -1051,28 +1056,6 @@ class ChatControl(ChatControlBase):
|
|||
|
||||
return menu
|
||||
|
||||
def set_compact_view(self, state):
|
||||
'''Toggle compact view. state is bool'''
|
||||
ChatControlBase.set_compact_view(self, state)
|
||||
|
||||
widgets = [
|
||||
self.xml.get_widget('banner_eventbox'),
|
||||
self.xml.get_widget('actions_hbox'),
|
||||
]
|
||||
# FIXME GC only
|
||||
# elif self.widget_name == 'groupchat_window':
|
||||
# widgets = [self.xmls[jid].get_widget('banner_eventbox'),
|
||||
# self.xmls[jid].get_widget('gc_actions_hbox'),
|
||||
# self.xmls[jid].get_widget('list_scrolledwindow'),
|
||||
# ]
|
||||
for widget in widgets:
|
||||
if state:
|
||||
widget.set_no_show_all(True)
|
||||
widget.hide()
|
||||
else:
|
||||
widget.set_no_show_all(False)
|
||||
widget.show_all()
|
||||
|
||||
def send_chatstate(self, state, contact = None):
|
||||
''' sends OUR chatstate as STANDLONE chat state message (eg. no body)
|
||||
to contact only if new chatstate is different from the previous one
|
||||
|
@ -1292,9 +1275,8 @@ class ChatControl(ChatControlBase):
|
|||
# Is it a pm ?
|
||||
is_pm = False
|
||||
room_jid, nick = gajim.get_room_and_nick_from_fjid(jid)
|
||||
# FIXME: Accessing gc's, here?
|
||||
gcs = gajim.interface.instances[self.account]['gc']
|
||||
if gcs.has_key(room_jid):
|
||||
control = gajim.interface.msg_win_mgr.get_control(room_jid)
|
||||
if control.type_id == message_control.TYPE_GC:
|
||||
is_pm = True
|
||||
events_to_keep = []
|
||||
for event in l:
|
||||
|
@ -1309,16 +1291,16 @@ class ChatControl(ChatControlBase):
|
|||
else:
|
||||
kind = 'print_queue'
|
||||
self.print_conversation(data[0], kind, tim = data[3],
|
||||
encrypted = data[4], subject = data[1])
|
||||
encrypted = data[4], subject = data[1])
|
||||
|
||||
# remove from gc nb_unread if it's pm or from roster
|
||||
if is_pm:
|
||||
gcs[room_jid].nb_unread[room_jid] -= 1
|
||||
control.nb_unread -= 1
|
||||
else:
|
||||
gajim.interface.roster.nb_unread -= 1
|
||||
|
||||
if is_pm:
|
||||
gcs[room_jid].show_title()
|
||||
control.parent_win.show_title()
|
||||
else:
|
||||
gajim.interface.roster.show_title()
|
||||
# Keep only non-messages events
|
||||
|
@ -1327,12 +1309,10 @@ class ChatControl(ChatControlBase):
|
|||
else:
|
||||
del gajim.awaiting_events[self.account][jid]
|
||||
typ = 'chat' # Is it a normal chat or a pm ?
|
||||
# # reset to status image in gc if it is a pm
|
||||
# # FIXME: New data structure
|
||||
# gcs = gajim.interface.instances[self.account]['gc']
|
||||
# if gcs.has_key(room_jid):
|
||||
# gcs[room_jid].draw_all_roster()
|
||||
# typ = 'pm'
|
||||
# reset to status image in gc if it is a pm
|
||||
if is_pm:
|
||||
control.draw_widgets()
|
||||
typ = 'pm'
|
||||
|
||||
gajim.interface.roster.draw_contact(jid, self.account)
|
||||
if gajim.interface.systray_enabled:
|
||||
|
@ -1344,7 +1324,7 @@ class ChatControl(ChatControlBase):
|
|||
gajim.interface.roster.really_remove_contact(self.contact,
|
||||
self.account)
|
||||
elif typ == 'pm':
|
||||
gcs[room_jid].remove_contact(room_jid, nick)
|
||||
control.remove_contact(nick)
|
||||
|
||||
def show_bigger_avatar(self, small_avatar):
|
||||
'''resizes the avatar, if needed, so it has at max half the screen size
|
||||
|
|
|
@ -145,8 +145,7 @@ def get_real_jid_from_fjid(account, fjid):
|
|||
if not nick: # It's not a fake_jid, it is a real jid
|
||||
return fjid # we return the real jid
|
||||
real_jid = fjid
|
||||
gcs = interface.instances[account]['gc']
|
||||
if gcs.has_key(room_jid):
|
||||
if interface.msg_win_mgr.get_control(room_jid):
|
||||
# It's a pm, so if we have real jid it's in contact.jid
|
||||
gc_contact = contacts.get_gc_contact(account, room_jid, nick)
|
||||
if not gc_contact:
|
||||
|
|
|
@ -36,6 +36,7 @@ import gtkgui_helpers
|
|||
import dialogs
|
||||
import vcard
|
||||
import cell_renderer_image
|
||||
import message_control
|
||||
|
||||
try:
|
||||
import gtkspell
|
||||
|
|
109
src/gajim.py
109
src/gajim.py
|
@ -35,6 +35,8 @@ import pygtk
|
|||
|
||||
import message_control
|
||||
|
||||
from chat_control import ChatControlBase
|
||||
|
||||
from common import exceptions
|
||||
from common import i18n
|
||||
i18n.init()
|
||||
|
@ -176,10 +178,9 @@ class Interface:
|
|||
title = data[1]
|
||||
prompt = data[2]
|
||||
proposed_nick = data[3]
|
||||
w = self.instances[account]['gc']
|
||||
if w.has_key(room_jid): # user may close the window before we are here
|
||||
w[room_jid].show_change_nick_input_dialog(title, prompt, proposed_nick,
|
||||
room_jid)
|
||||
gc_control = gajim.interface.msg_win_mgr.get_control(room_jid)
|
||||
if gc_control: # user may close the window before we are here
|
||||
gc_control.show_change_nick_input_dialog(title, prompt, proposed_nick)
|
||||
|
||||
def handle_event_http_auth(self, account, data):
|
||||
#('HTTP_AUTH', account, (method, url, transaction_id, iq_obj))
|
||||
|
@ -219,9 +220,9 @@ class Interface:
|
|||
(jid_from, file_props))
|
||||
conn.disconnect_transfer(file_props)
|
||||
return
|
||||
if jid_from in self.instances[account]['gc']:
|
||||
self.instances[account]['gc'][jid_from].print_conversation(
|
||||
'Error %s: %s' % (array[2], array[1]), jid_from)
|
||||
ctl = gajim.interface.msg_win_mgr.get_control(jid_from)
|
||||
if ctl and ctl.type_id == message_control.TYPE_GC:
|
||||
ctl.print_conversation('Error %s: %s' % (array[2], array[1]))
|
||||
|
||||
def handle_event_con_type(self, account, con_type):
|
||||
# ('CON_TYPE', account, con_type) which can be 'ssl', 'tls', 'tcp'
|
||||
|
@ -240,8 +241,9 @@ class Interface:
|
|||
if not gajim.gc_connected.has_key(account):
|
||||
return
|
||||
for room_jid in gajim.gc_connected[account]:
|
||||
if self.instances[account]['gc'].has_key(room_jid):
|
||||
self.instances[account]['gc'][room_jid].got_disconnected(room_jid)
|
||||
gc_control = gajim.interface.msg_win_mgr.get_control(room_jid)
|
||||
if gc_control:
|
||||
gc_control.got_disconnected()
|
||||
else:
|
||||
gobject.timeout_add(30000, self.allow_notif, account)
|
||||
model[self.roster.status_message_menuitem_iter][3] = True # sensitivity for this menuitem
|
||||
|
@ -476,34 +478,33 @@ class Interface:
|
|||
fjid = array[0]
|
||||
jids = fjid.split('/', 1)
|
||||
jid = jids[0]
|
||||
gcs = self.instances[account]['gc']
|
||||
if jid in gcs:
|
||||
if len(jids) > 1: # it's a pm
|
||||
nick = jids[1]
|
||||
if not gajim.interface.msg_win_mgr.has_window(fjid):
|
||||
gc = gcs[jid]
|
||||
tv = gc.list_treeview[jid]
|
||||
model = tv.get_model()
|
||||
i = gc.get_contact_iter(jid, nick)
|
||||
if i:
|
||||
show = model[i][3]
|
||||
else:
|
||||
show = 'offline'
|
||||
gc_c = gajim.contacts.create_gc_contact(room_jid = jid,
|
||||
name = nick, show = show)
|
||||
c = gajim.contacts.contact_from_gc_contct(c)
|
||||
self.roster.new_chat(c, account)
|
||||
ctl = gajim.interface.msg_win_mgr.get_control(fjid)
|
||||
ctl.print_conversation('Error %s: %s' % (array[1], array[2]),
|
||||
'status')
|
||||
gcs = gajim.interface.msg_win_mgr.get_controls(message_window.TYPE_GC)
|
||||
for gc_control in gcs:
|
||||
if jid == gc_control.contact.jid:
|
||||
if len(jids) > 1: # it's a pm
|
||||
nick = jids[1]
|
||||
if not gajim.interface.msg_win_mgr.get_control(fjid):
|
||||
tv = gc_control.list_treeview
|
||||
model = tv.get_model()
|
||||
i = gc_control.get_contact_iter(nick)
|
||||
if i:
|
||||
show = model[i][3]
|
||||
else:
|
||||
show = 'offline'
|
||||
gc_c = gajim.contacts.create_gc_contact(room_jid = jid,
|
||||
name = nick, show = show)
|
||||
c = gajim.contacts.contact_from_gc_contct(c)
|
||||
self.roster.new_chat(c, account, private_chat = True)
|
||||
ctl = gajim.interface.msg_win_mgr.get_control(fjid)
|
||||
ctl.print_conversation('Error %s: %s' % (array[1], array[2]),
|
||||
'status')
|
||||
return
|
||||
|
||||
gc_control.print_conversation('Error %s: %s' % (array[1], array[2]))
|
||||
if gc_control.parent_win.get_active_jid() == jid:
|
||||
gc_control.set_subject(gc_control.subject)
|
||||
return
|
||||
# FIXME
|
||||
gcs[jid].print_conversation('Error %s: %s' % \
|
||||
(array[1], array[2]), jid)
|
||||
if gcs[jid].get_active_jid() == jid:
|
||||
gcs[jid].set_subject(jid,
|
||||
gcs[jid].subjects[jid])
|
||||
return
|
||||
|
||||
if jid.find('@') <= 0:
|
||||
jid = jid.replace('@', '')
|
||||
self.roster.on_message(jid, _('error while sending') + \
|
||||
|
@ -723,12 +724,12 @@ class Interface:
|
|||
#('GC_SUBJECT', account, (jid, subject))
|
||||
jids = array[0].split('/', 1)
|
||||
jid = jids[0]
|
||||
if not self.instances[account]['gc'].has_key(jid):
|
||||
gc_control = gajim.interface.msg_win_mgr.get_control(jid)
|
||||
if not gc_control:
|
||||
return
|
||||
self.instances[account]['gc'][jid].set_subject(jid, array[1])
|
||||
gc_control.set_subject(array[1])
|
||||
if len(jids) > 1:
|
||||
self.instances[account]['gc'][jid].print_conversation(
|
||||
'%s has set the subject to %s' % (jids[1], array[1]), jid)
|
||||
gc_control.print_conversation('%s has set the subject to %s' % (jids[1], array[1]))
|
||||
|
||||
def handle_event_gc_config(self, account, array):
|
||||
#('GC_CONFIG', account, (jid, config)) config is a dict
|
||||
|
@ -953,14 +954,12 @@ class Interface:
|
|||
def handle_event_signed_in(self, account, empty):
|
||||
'''SIGNED_IN event is emitted when we sign in, so handle it'''
|
||||
# join already open groupchats
|
||||
for room_jid in self.instances[account]['gc']:
|
||||
if room_jid == 'tabbed':
|
||||
continue
|
||||
for gc_control in gajim.interface.msg_win_mgr.get_controls(message_control.TYPE_GC):
|
||||
room_jid = gc_control.contact.jid
|
||||
if gajim.gc_connected[account][room_jid]:
|
||||
continue
|
||||
room, server = gajim.get_room_name_and_server_from_room_jid(
|
||||
room_jid)
|
||||
nick = self.instances[account]['gc'][room_jid].nicks[room_jid]
|
||||
room, server = gajim.get_room_name_and_server_from_room_jid(room_jid)
|
||||
nick = gc_control.nick
|
||||
password = ''
|
||||
if gajim.gc_passwords.has_key(room_jid):
|
||||
password = gajim.gc_passwords[room_jid]
|
||||
|
@ -1242,17 +1241,16 @@ class Interface:
|
|||
|
||||
def handle_event(self, account, jid, typ):
|
||||
w = None
|
||||
if typ == 'gc':
|
||||
if wins['gc'].has_key(jid):
|
||||
w = wins['gc'][jid]
|
||||
elif typ == 'chat':
|
||||
if typ == message_control.TYPE_GC:
|
||||
w = gajim.interface.msg_win_mgr.get_window(jid)
|
||||
elif typ == message_control.TYPE_CHAT:
|
||||
if gajim.interface.msg_win_mgr.has_window(jid):
|
||||
w = gajim.interface.msg_win_mgr.get_window(jid)
|
||||
else:
|
||||
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
|
||||
self.roster.new_chat(contact, account)
|
||||
w = gajim.interface.msg_win_mgr.get_window(jid)
|
||||
elif typ == 'pm':
|
||||
elif typ == message_control.TYPE_PM:
|
||||
if gajim.interface.msg_win_mgr.has_window(jid):
|
||||
w = gajim.interface.msg_win_mgr.get_window(jid)
|
||||
else:
|
||||
|
@ -1266,7 +1264,7 @@ class Interface:
|
|||
gc_contact = gajim.contacts.create_gc_contact(room_jid = room_jid,
|
||||
name = nick, show = show)
|
||||
c = gajim.contacts.contact_from_gc_contct(gc_contact)
|
||||
self.roster.new_chat(c, account)
|
||||
self.roster.new_chat(c, account, private_chat = True)
|
||||
w = gajim.interface.msg_win_mgr.get_window(jid)
|
||||
elif typ in ('normal', 'file-request', 'file-request-error',
|
||||
'file-send-error', 'file-error', 'file-stopped', 'file-completed'):
|
||||
|
@ -1278,8 +1276,11 @@ class Interface:
|
|||
w.set_active_tab(jid)
|
||||
w.window.present()
|
||||
w.window.window.focus()
|
||||
tv = w.conversation_textviews[jid]
|
||||
tv.scroll_to_end()
|
||||
ctl = w.get_control(jid)
|
||||
# Using isinstance here because we want to catch all derived types
|
||||
if isinstance(ctl, ChatControlBase):
|
||||
tv = ctl.conv_textview
|
||||
tv.scroll_to_end()
|
||||
|
||||
def __init__(self):
|
||||
gajim.interface = self
|
||||
|
|
|
@ -63,6 +63,28 @@ class PrivateChatControl(ChatControl):
|
|||
self.TYPE_ID = 'pm'
|
||||
self.display_name = _('Private chat')
|
||||
|
||||
def send_message(self, message):
|
||||
'''call this function to send our message'''
|
||||
if not message:
|
||||
return
|
||||
|
||||
# We need to make sure that we can still send through the room and that the
|
||||
# recipient did not go away
|
||||
contact = gajim.contacts.get_first_contact_from_jid(self.account, self.contact.jid)
|
||||
if contact is None:
|
||||
# contact was from pm in MUC
|
||||
room, nick = gajim.get_room_and_nick_from_fjid(self.contact.jid)
|
||||
gc_contact = gajim.contacts.get_gc_contact(self.account, room, nick)
|
||||
if not gc_contact:
|
||||
dialogs.ErrorDialog(
|
||||
_('Sending private message failed'),
|
||||
#in second %s code replaces with nickname
|
||||
_('You are no longer in room "%s" or "%s" has left.') % \
|
||||
(room, nick)).get_response()
|
||||
return
|
||||
|
||||
ChatControl.send_message(self, message)
|
||||
|
||||
class GroupchatControl(ChatControlBase):
|
||||
TYPE_ID = message_control.TYPE_GC
|
||||
|
||||
|
@ -255,7 +277,7 @@ class GroupchatControl(ChatControlBase):
|
|||
menu = self.gc_popup_menu
|
||||
childs = menu.get_children()
|
||||
# compact_view_menuitem
|
||||
childs[5].set_active(self.compact_view_current_state)
|
||||
childs[5].set_active(self.compact_view_current)
|
||||
menu = self.remove_possible_switch_to_menuitems(menu)
|
||||
return menu
|
||||
|
||||
|
@ -303,7 +325,8 @@ class GroupchatControl(ChatControlBase):
|
|||
else:
|
||||
gc_c = gajim.contacts.get_gc_contact(self.account, self.room_jid, nick)
|
||||
c = gajim.contacts.contact_from_gc_contact(gc_c)
|
||||
gajim.interface.roster.new_chat(c, self.account)
|
||||
print "creating PM chat"
|
||||
gajim.interface.roster.new_chat(c, self.account, private_chat = True)
|
||||
# Scroll to line
|
||||
self.list_treeview.expand_row(path[0:1], False)
|
||||
self.list_treeview.scroll_to_cell(path)
|
||||
|
@ -536,9 +559,32 @@ class GroupchatControl(ChatControlBase):
|
|||
print "draw_roster"
|
||||
for nick in gajim.contacts.get_nick_list(self.account, self.room_jid):
|
||||
gc_contact = gajim.contacts.get_gc_contact(self.account, self.room_jid, nick)
|
||||
self.add_contact_to_roster(self.room_jid, nick, gc_contact.show,
|
||||
gc_contact.role, gc_contact.affiliation, gc_contact.status,
|
||||
gc_contact.jid)
|
||||
self.add_contact_to_roster(nick, gc_contact.show, gc_contact.role,
|
||||
gc_contact.affiliation, gc_contact.status,
|
||||
gc_contact.jid)
|
||||
|
||||
def on_send_pm(self, widget=None, model=None, iter=None, nick=None, msg=None):
|
||||
'''opens a chat window and msg is not None sends private message to a
|
||||
contact in a room'''
|
||||
if nick is None:
|
||||
nick = model[iter][C_NICK].decode('utf-8')
|
||||
fjid = gajim.construct_fjid(self.room_jid, nick) # 'fake' jid
|
||||
|
||||
chat_win = gajim.interface.msg_win_mgr.get_window(fjid)
|
||||
if not chat_win:
|
||||
gc_c = gajim.contacts.get_gc_contact(self.account, self.room_jid, nick)
|
||||
c = gajim.contacts.contact_from_gc_contact(gc_c)
|
||||
print "creating PM chat"
|
||||
gajim.interface.roster.new_chat(c, self.account, private_chat = True)
|
||||
chat_win = gajim.interface.msg_win_mgr.get_window(fjid)
|
||||
chat_control = chat_win.get_control(fjid)
|
||||
|
||||
#make active here in case we need to send a message
|
||||
chat_win.set_active_tab(fjid)
|
||||
|
||||
if msg:
|
||||
chat_control.send_message(msg)
|
||||
chat_win.window.present()
|
||||
|
||||
def draw_contact(self, nick, selected=False, focus=False):
|
||||
iter = self.get_contact_iter(nick)
|
||||
|
@ -708,3 +754,308 @@ class GroupchatControl(ChatControlBase):
|
|||
if model.iter_n_children(parent_iter) == 0:
|
||||
model.remove(parent_iter)
|
||||
|
||||
def _process_command(self, message):
|
||||
if message[0] != '/':
|
||||
return False
|
||||
|
||||
# Handle common commands
|
||||
if ChatControlBase._process_command(self, message):
|
||||
return True
|
||||
|
||||
message = message[1:]
|
||||
message_array = message.split(' ', 1)
|
||||
command = message_array.pop(0).lower()
|
||||
if message_array == ['']:
|
||||
message_array = []
|
||||
|
||||
if command == 'nick':
|
||||
# example: /nick foo
|
||||
if len(message_array):
|
||||
nick = message_array[0]
|
||||
gajim.connections[self.account].change_gc_nick(self.room_jid, nick)
|
||||
self.clear(self.msg_textview)
|
||||
else:
|
||||
self.get_command_help(command)
|
||||
return True
|
||||
elif command == 'query' or command == 'chat':
|
||||
# Open a chat window to the specified nick
|
||||
# example: /query foo
|
||||
if len(message_array):
|
||||
nick = message_array.pop(0)
|
||||
nicks = gajim.contacts.get_nick_list(self.account, self.room_jid)
|
||||
if nick in nicks:
|
||||
self.on_send_pm(nick = nick)
|
||||
self.clear(self.msg_textview)
|
||||
else:
|
||||
self.print_conversation(_('Nickname not found: %s') % nick)
|
||||
else:
|
||||
self.get_command_help(command)
|
||||
return True
|
||||
elif command == 'msg':
|
||||
# Send a message to a nick. Also opens a private message window.
|
||||
# example: /msg foo Hey, what's up?
|
||||
if len(message_array):
|
||||
message_array = message_array[0].split()
|
||||
nick = message_array.pop(0)
|
||||
room_nicks = gajim.contacts.get_nick_list(self.account, self.room_jid)
|
||||
if nick in room_nicks:
|
||||
privmsg = ' '.join(message_array)
|
||||
self.on_send_pm(nick=nick, msg=privmsg)
|
||||
self.clear(self.msg_textview)
|
||||
else:
|
||||
self.print_conversation(_('Nickname not found: %s') % nick)
|
||||
else:
|
||||
self.get_command_help(command)
|
||||
return True
|
||||
elif command == 'topic':
|
||||
# display or change the room topic
|
||||
# example: /topic : print topic
|
||||
# /topic foo : change topic to foo
|
||||
if len(message_array):
|
||||
new_topic = message_array.pop(0)
|
||||
gajim.connections[self.account].send_gc_subject(self.room_jid,
|
||||
new_topic)
|
||||
else:
|
||||
self.print_conversation(self.subject)
|
||||
self.clear(self.msg_textview)
|
||||
return True
|
||||
elif command == 'invite':
|
||||
# invite a user to a room for a reason
|
||||
# example: /invite user@example.com reason
|
||||
if len(message_array):
|
||||
message_array = message_array[0].split()
|
||||
invitee = message_array.pop(0)
|
||||
if invitee.find('@') >= 0:
|
||||
reason = ' '.join(message_array)
|
||||
gajim.connections[self.account].send_invite(self.room_jid,
|
||||
invitee, reason)
|
||||
s = _('Invited %(contact_jid)s to %(room_jid)s.') % {
|
||||
'contact_jid': invitee,
|
||||
'room_jid': self.room_jid}
|
||||
self.print_conversation(s)
|
||||
self.clear(self.msg_textview)
|
||||
else:
|
||||
#%s is something the user wrote but it is not a jid so we inform
|
||||
s = _('%s does not appear to be a valid JID') % invitee
|
||||
self.print_conversation(s)
|
||||
else:
|
||||
self.get_command_help(command)
|
||||
return True
|
||||
elif command == 'join':
|
||||
# example: /join room@conference.example.com/nick
|
||||
if len(message_array):
|
||||
message_array = message_array[0]
|
||||
if message_array.find('@') >= 0:
|
||||
room, servernick = message_array.split('@')
|
||||
if servernick.find('/') >= 0:
|
||||
server, nick = servernick.split('/', 1)
|
||||
else:
|
||||
server = servernick
|
||||
nick = ''
|
||||
#join_gc window is needed in order to provide for password entry.
|
||||
if gajim.interface.instances[self.account].has_key('join_gc'):
|
||||
gajim.interface.instances[self.account]['join_gc'].\
|
||||
window.present()
|
||||
else:
|
||||
try:
|
||||
gajim.interface.instances[self.account]['join_gc'] =\
|
||||
dialogs.JoinGroupchatWindow(self.account,
|
||||
server = server, room = room, nick = nick)
|
||||
except RuntimeError:
|
||||
pass
|
||||
self.clear(self.msg_textview)
|
||||
else:
|
||||
#%s is something the user wrote but it is not a jid so we inform
|
||||
s = _('%s does not appear to be a valid JID') % message_array
|
||||
self.print_conversation(s)
|
||||
else:
|
||||
self.get_command_help(command)
|
||||
return True
|
||||
elif command == 'leave' or command == 'part' or command == 'close':
|
||||
# Leave the room and close the tab or window
|
||||
# FIXME: Sometimes this doesn't actually leave the room. Why?
|
||||
reason = 'offline'
|
||||
if len(message_array):
|
||||
reason = message_array.pop(0)
|
||||
self.remove_tab(reason)
|
||||
return True
|
||||
elif command == 'ban':
|
||||
if len(message_array):
|
||||
message_array = message_array[0].split()
|
||||
nick = message_array.pop(0)
|
||||
room_nicks = gajim.contacts.get_nick_list(self.account, self.room_jid)
|
||||
reason = ' '.join(message_array)
|
||||
if nick in room_nicks:
|
||||
ban_jid = gajim.construct_fjid(self.room_jid, nick)
|
||||
gajim.connections[self.account].gc_set_affiliation(self.room_jid,
|
||||
ban_jid, 'outcast', reason)
|
||||
self.clear(self.msg_textview)
|
||||
elif nick.find('@') >= 0:
|
||||
gajim.connections[self.account].gc_set_affiliation(self.room_jid,
|
||||
nick, 'outcast', reason)
|
||||
self.clear(self.msg_textview)
|
||||
else:
|
||||
self.print_conversation(_('Nickname not found: %s') % nick)
|
||||
else:
|
||||
self.get_command_help(command)
|
||||
return True
|
||||
elif command == 'kick':
|
||||
if len(message_array):
|
||||
message_array = message_array[0].split()
|
||||
nick = message_array.pop(0)
|
||||
room_nicks = gajim.contacts.get_nick_list(self.account, self.room_jid)
|
||||
reason = ' '.join(message_array)
|
||||
if nick in room_nicks:
|
||||
gajim.connections[self.account].gc_set_role(self.room_jid, nick,
|
||||
'none', reason)
|
||||
self.clear(self.msg_textview)
|
||||
else:
|
||||
self.print_conversation(_('Nickname not found: %s') % nick)
|
||||
else:
|
||||
self.get_command_help(command)
|
||||
return True
|
||||
elif command == 'help':
|
||||
if len(message_array):
|
||||
subcommand = message_array.pop(0)
|
||||
self.get_command_help(subcommand)
|
||||
else:
|
||||
self.get_command_help(command)
|
||||
self.clear(self.msg_textview)
|
||||
return True
|
||||
elif command == 'say':
|
||||
if len(message_array):
|
||||
gajim.connections[self.account].send_gc_message(self.room_jid,
|
||||
message[4:])
|
||||
self.clear(self.msg_textview)
|
||||
else:
|
||||
self.get_command_help(command)
|
||||
return True
|
||||
else:
|
||||
self.print_conversation(_('No such command: /%s (if you want to send this, '
|
||||
'prefix it with /say)') % command)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def send_message(self, message):
|
||||
'''call this function to send our message'''
|
||||
if not message:
|
||||
return
|
||||
|
||||
if message != '' or message != '\n':
|
||||
self.save_sent_message(message)
|
||||
|
||||
if not self._process_command(message):
|
||||
# Send the message
|
||||
gajim.connections[self.account].send_gc_message(self.room_jid, message)
|
||||
self.msg_textview.get_buffer().set_text('')
|
||||
self.msg_textview.grab_focus()
|
||||
|
||||
def get_command_help(self, command):
|
||||
if command == 'help':
|
||||
self.print_conversation(_('Commands: %s') % self.muc_cmds)
|
||||
elif command == 'ban':
|
||||
s = _('Usage: /%s <nickname|JID> [reason], bans the JID from the room.'
|
||||
' The nickname of an occupant may be substituted, but not if it contains "@".'
|
||||
' If the JID is currently in the room, he/she/it will also be kicked.'
|
||||
' Does NOT support spaces in nickname.') % command
|
||||
self.print_conversation(s)
|
||||
elif command == 'chat' or command == 'query':
|
||||
self.print_conversation(_('Usage: /%s <nickname>, opens a private chat '
|
||||
'window to the specified occupant.') % command)
|
||||
elif command == 'clear':
|
||||
self.print_conversation(_('Usage: /%s, clears the text window.') % command)
|
||||
elif command == 'close' or command == 'leave' or command == 'part':
|
||||
self.print_conversation(_('Usage: /%s [reason], closes the current window '
|
||||
'or tab, displaying reason if specified.') % command)
|
||||
elif command == 'compact':
|
||||
self.print_conversation(_('Usage: /%s, sets the groupchat window to compact '
|
||||
'mode.') % command)
|
||||
elif command == 'invite':
|
||||
self.print_conversation(_('Usage: /%s <JID> [reason], invites JID to the '
|
||||
'current room, optionally providing a reason.') % command)
|
||||
elif command == 'join':
|
||||
self.print_conversation(_('Usage: /%s <room>@<server>[/nickname], offers to '
|
||||
'join room@server optionally using specified '
|
||||
'nickname.') % command)
|
||||
elif command == 'kick':
|
||||
self.print_conversation(_('Usage: /%s <nickname> [reason], removes the occupant '
|
||||
'specified by nickname from the room and optionally '
|
||||
'displays a reason. Does NOT support spaces in '
|
||||
'nickname.') % command)
|
||||
elif command == 'me':
|
||||
self.print_conversation(_('Usage: /%s <action>, sends action to the current '
|
||||
'room. Use third person. (e.g. /%s explodes.)') %\
|
||||
(command, command))
|
||||
elif command == 'msg':
|
||||
s = _('Usage: /%s <nickname> [message], opens a private message window and '
|
||||
'sends message to the occupant specified by nickname.') % command
|
||||
self.print_conversation(s)
|
||||
elif command == 'nick':
|
||||
s = _('Usage: /%s <nickname>, changes your nickname in current room.') % command
|
||||
self.print_conversation(s)
|
||||
elif command == 'topic':
|
||||
self.print_conversation(_('Usage: /%s [topic], displays or updates the current '
|
||||
'room topic.') % command)
|
||||
elif command == 'say':
|
||||
self.print_conversation(_('Usage: /%s <message>, sends a message without '
|
||||
'looking for other commands.') % command)
|
||||
else:
|
||||
self.print_conversation(_('No help info for /%s') % command)
|
||||
|
||||
def get_role(self, nick):
|
||||
gc_contact = gajim.contacts.get_gc_contact(self.account, self.room_jid, nick)
|
||||
if gc_contact:
|
||||
return gc_contact.role
|
||||
else:
|
||||
return 'visitor'
|
||||
|
||||
def show_change_nick_input_dialog(self, title, prompt, proposed_nick = None):
|
||||
'''asks user for new nick and on ok it sets it on room'''
|
||||
instance = dialogs.InputDialog(title, prompt, proposed_nick)
|
||||
response = instance.get_response()
|
||||
if response == gtk.RESPONSE_OK:
|
||||
nick = instance.input_entry.get_text().decode('utf-8')
|
||||
self.nick = nick
|
||||
gajim.connections[self.account].change_gc_nick(self.room_jid, nick)
|
||||
|
||||
def shutdown(self):
|
||||
gajim.connections[self.account].send_gc_status(self.nick, self.room_jid,
|
||||
show='offline', status=reason)
|
||||
# They can already be removed by the destroy function
|
||||
if self.room_jid in gajim.contacts.get_gc_list(self.account):
|
||||
gajim.contacts.remove_room(self.account, self.room_jid)
|
||||
del gajim.gc_connected[self.account][self.room_jid]
|
||||
|
||||
def allow_shutdown(self):
|
||||
# FIXME:
|
||||
# whether to ask for comfirmation before closing muc
|
||||
if gajim.config.get('confirm_close_muc'):
|
||||
names = []
|
||||
if not room_jid:
|
||||
for r_jid in self.xmls:
|
||||
if gajim.gc_connected[self.account][r_jid]:
|
||||
names.append(gajim.get_nick_from_jid(r_jid))
|
||||
else:
|
||||
names = [room_jid]
|
||||
|
||||
rooms_no = len(names)
|
||||
if rooms_no >= 2: # if we are in many rooms
|
||||
pritext = _('Are you sure you want to leave rooms "%s"?') % ', '.join(names)
|
||||
sectext = _('If you close this window, you will be disconnected from these rooms.')
|
||||
|
||||
elif rooms_no == 1: # just in one room
|
||||
pritext = _('Are you sure you want to leave room "%s"?') % names[0]
|
||||
sectext = _('If you close this window, you will be disconnected from this room.')
|
||||
|
||||
if rooms_no > 0:
|
||||
dialog = dialogs.ConfirmationDialogCheck(pritext, sectext,
|
||||
_('Do _not ask me again'))
|
||||
|
||||
if dialog.is_checked():
|
||||
gajim.config.set('confirm_close_muc', False)
|
||||
dialog.destroy()
|
||||
|
||||
if dialog.get_response() != gtk.RESPONSE_OK:
|
||||
return False
|
||||
return True
|
||||
|
|
|
@ -19054,7 +19054,7 @@ Maybe I'll refactor later</property>
|
|||
<property name="show_tabs">True</property>
|
||||
<property name="show_border">True</property>
|
||||
<property name="tab_pos">GTK_POS_TOP</property>
|
||||
<property name="scrollable">False</property>
|
||||
<property name="scrollable">True</property>
|
||||
<property name="enable_popup">False</property>
|
||||
|
||||
<child>
|
||||
|
@ -19875,7 +19875,7 @@ topic</property>
|
|||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow48">
|
||||
<widget class="GtkScrolledWindow" id="list_scrolledwindow">
|
||||
<property name="width_request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
|
||||
|
@ -20108,7 +20108,7 @@ topic</property>
|
|||
<property name="right_padding">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox3015">
|
||||
<widget class="GtkHBox" id="gc_actions_hbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">2</property>
|
||||
|
|
|
@ -558,12 +558,19 @@ class MessageWindowMgr:
|
|||
return win
|
||||
|
||||
def get_control(self, jid):
|
||||
'''Amonst all windows, return the MessageControl for jid'''
|
||||
'''Amongst all windows, return the MessageControl for jid'''
|
||||
win = self.get_window(jid)
|
||||
if win:
|
||||
return win.get_control(jid)
|
||||
return None
|
||||
|
||||
def get_controls(self, type):
|
||||
ctls = []
|
||||
for c in self.controls():
|
||||
if c.type_id == type:
|
||||
ctls.append(c)
|
||||
return ctls
|
||||
|
||||
def windows(self):
|
||||
for w in self._windows.values():
|
||||
yield w
|
||||
|
|
|
@ -1529,11 +1529,9 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
|
|||
passphrase)
|
||||
gajim.connections[account].gpg_passphrase(passphrase)
|
||||
|
||||
for room_jid in gajim.interface.instances[account]['gc']:
|
||||
if room_jid != 'tabbed':
|
||||
nick = gajim.interface.instances[account]['gc'][room_jid].nicks[room_jid]
|
||||
gajim.connections[account].send_gc_status(nick, room_jid, status,
|
||||
txt)
|
||||
for gc_control in gajim.interface.msg_win_mgr.get_controls(message_control.TYPE_GC):
|
||||
gajim.connections[account].send_gc_status(gc_control.nick, gc_control.room_jid,
|
||||
status, txt)
|
||||
gajim.connections[account].change_status(status, txt, sync, auto)
|
||||
if status == 'online' and gajim.interface.sleeper.getState() != \
|
||||
common.sleepy.STATE_UNKNOWN:
|
||||
|
@ -1672,14 +1670,24 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
|
|||
self.update_status_combobox()
|
||||
self.make_menu()
|
||||
|
||||
def new_chat(self, contact, account):
|
||||
def new_chat(self, contact, account, private_chat = False):
|
||||
# Get target window, create a control, and associate it with the window
|
||||
if not private_chat:
|
||||
type = message_control.TYPE_CHAT
|
||||
else:
|
||||
type = message_control.TYPE_PM
|
||||
|
||||
mw = gajim.interface.msg_win_mgr.get_window(contact.jid)
|
||||
if not mw:
|
||||
mw = gajim.interface.msg_win_mgr.create_window(contact, account,
|
||||
ChatControl.TYPE_ID)
|
||||
chat_control = ChatControl(mw, contact, account)
|
||||
mw = gajim.interface.msg_win_mgr.create_window(contact, account, type)
|
||||
|
||||
if not private_chat:
|
||||
chat_control = ChatControl(mw, contact, account)
|
||||
else:
|
||||
chat_control = PrivateChatControl(mw, contact, account)
|
||||
|
||||
mw.new_tab(chat_control)
|
||||
|
||||
if gajim.awaiting_events[account].has_key(contact.jid):
|
||||
# We call this here to avoid race conditions with widget validation
|
||||
chat_control.read_queue()
|
||||
|
|
|
@ -250,15 +250,13 @@ class NotificationAreaTooltip(BaseTooltip, StatusTable):
|
|||
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:
|
||||
if jid != 'tabbed':
|
||||
pm_msgs = gc_wins[jid].get_specific_unread(jid)
|
||||
unread_gc += gc_wins[jid].nb_unread[jid]
|
||||
unread_gc -= pm_msgs
|
||||
unread_pm += pm_msgs
|
||||
chat_t = message_control.TYPE_GC
|
||||
for gc_control in gajim.interface.msg_win_mgr.get_controls(chat_t):
|
||||
pm_msgs = gc_control.get_specific_unread()
|
||||
unread_gc += gc_control.nb_unread
|
||||
unread_gc -= pm_msgs
|
||||
unread_pm += pm_msgs
|
||||
|
||||
if unread_chat or unread_single_chat or unread_gc or unread_pm:
|
||||
text = ''
|
||||
|
|
Loading…
Reference in New Issue