More groupchat goodness

This commit is contained in:
Travis Shirk 2006-01-06 06:59:55 +00:00
parent 58f2d03dd3
commit 2a5b0afc44
9 changed files with 510 additions and 165 deletions

View File

@ -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

View File

@ -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:

View File

@ -36,6 +36,7 @@ import gtkgui_helpers
import dialogs
import vcard
import cell_renderer_image
import message_control
try:
import gtkspell

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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()

View File

@ -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 = ''