make ChangeStatusMessageDialog asychronous. see #4147

This commit is contained in:
Yann Leboulanger 2008-08-04 13:34:29 +00:00
parent 80f6d7909c
commit 1a3a795908
3 changed files with 181 additions and 159 deletions

View File

@ -518,8 +518,9 @@ class ChangeMoodDialog:
self.window.destroy() self.window.destroy()
class ChangeStatusMessageDialog: class ChangeStatusMessageDialog:
def __init__(self, show = None): def __init__(self, on_response, show = None):
self.show = show self.show = show
self.on_response = on_response
self.xml = gtkgui_helpers.get_glade('change_status_message_dialog.glade') self.xml = gtkgui_helpers.get_glade('change_status_message_dialog.glade')
self.window = self.xml.get_widget('change_status_message_dialog') self.window = self.xml.get_widget('change_status_message_dialog')
self.window.set_transient_for(gajim.interface.roster.window) self.window.set_transient_for(gajim.interface.roster.window)
@ -563,6 +564,10 @@ class ChangeStatusMessageDialog:
for msg_name in sorted_keys_list: for msg_name in sorted_keys_list:
self.message_liststore.append((msg_name,)) self.message_liststore.append((msg_name,))
self.xml.signal_autoconnect(self) self.xml.signal_autoconnect(self)
if self.countdown_time > 0:
self.countdown()
gobject.timeout_add(1000, self.countdown)
self.window.connect('response', self.on_dialog_response)
self.window.show_all() self.window.show_all()
def countdown(self): def countdown(self):
@ -580,14 +585,8 @@ class ChangeStatusMessageDialog:
self.window.set_title(self.title_text) self.window.set_title(self.title_text)
return False return False
def run(self): def on_dialog_response(self, dialog, response):
'''Wait for OK or Cancel button to be pressed and return status messsage if response == gtk.RESPONSE_OK:
(None if users pressed Cancel or x button of WM'''
if self.countdown_time > 0:
self.countdown()
gobject.timeout_add(1000, self.countdown)
rep = self.window.run()
if rep == gtk.RESPONSE_OK:
beg, end = self.message_buffer.get_bounds() beg, end = self.message_buffer.get_bounds()
message = self.message_buffer.get_text(beg, end).decode('utf-8')\ message = self.message_buffer.get_text(beg, end).decode('utf-8')\
.strip() .strip()
@ -598,7 +597,7 @@ class ChangeStatusMessageDialog:
else: else:
message = None # user pressed Cancel button or X wm button message = None # user pressed Cancel button or X wm button
self.window.destroy() self.window.destroy()
return message self.on_response(message)
def on_message_combobox_changed(self, widget): def on_message_combobox_changed(self, widget):
self.countdown_enabled = False self.countdown_enabled = False

View File

@ -2081,26 +2081,29 @@ class RosterWindow:
if sys.platform == 'darwin': if sys.platform == 'darwin':
self.make_menu(force = True) self.make_menu(force = True)
def get_status_message(self, show): def get_status_message(self, show, on_response):
if show in gajim.config.get_per('defaultstatusmsg'): if show in gajim.config.get_per('defaultstatusmsg'):
if gajim.config.get_per('defaultstatusmsg', show, 'enabled'): if gajim.config.get_per('defaultstatusmsg', show, 'enabled'):
return gajim.config.get_per('defaultstatusmsg', show, 'message') on_response(gajim.config.get_per('defaultstatusmsg', show,
'message'))
return
if (show == 'online' and not gajim.config.get('ask_online_status')) or \ if (show == 'online' and not gajim.config.get('ask_online_status')) or \
(show in ('offline', 'invisible') (show in ('offline', 'invisible')
and not gajim.config.get('ask_offline_status')): and not gajim.config.get('ask_offline_status')):
return '' on_response('')
dlg = dialogs.ChangeStatusMessageDialog(show) return
dlg = dialogs.ChangeStatusMessageDialog(on_response, show)
dlg.window.present() # show it on current workspace dlg.window.present() # show it on current workspace
message = dlg.run()
return message
def change_status(self, widget, account, status): def change_status(self, widget, account, status):
def change(account, status): def change(account, status):
message = self.get_status_message(status) def on_response(message):
if message is None: if message is None:
# user pressed Cancel to change status message dialog # user pressed Cancel to change status message dialog
return return
self.send_status(account, status, message) self.send_status(account, status, message)
self.get_status_message(status, on_response)
if status == 'invisible' and self.connected_rooms(account): if status == 'invisible' and self.connected_rooms(account):
dialogs.ConfirmationDialog( dialogs.ConfirmationDialog(
@ -2219,7 +2222,7 @@ class RosterWindow:
gajim.interface.hide_systray() gajim.interface.hide_systray()
gtk.main_quit() gtk.main_quit()
def on_quit_request(self, widget = None): def on_quit_request(self, widget=None):
''' user want to quit. Check if he should be warned about messages ''' user want to quit. Check if he should be warned about messages
pending. Terminate all sessions and send offline to all connected pending. Terminate all sessions and send offline to all connected
account. We do NOT really quit gajim here ''' account. We do NOT really quit gajim here '''
@ -2229,45 +2232,50 @@ class RosterWindow:
if gajim.connections[acct].connected: if gajim.connections[acct].connected:
get_msg = True get_msg = True
break break
if get_msg:
message = self.get_status_message('offline') def on_continue(message):
if message is None: if message is None:
# user pressed Cancel to change status message dialog # user pressed Cancel to change status message dialog
return return
# check if we have unread messages
unread = gajim.events.get_nb_events()
if not gajim.config.get('notify_on_all_muc_messages'):
unread_not_to_notify = gajim.events.get_nb_events(
['printed_gc_msg'])
unread -= unread_not_to_notify
# check if we have unread messages # check if we have recent messages
unread = gajim.events.get_nb_events() recent = False
if not gajim.config.get('notify_on_all_muc_messages'): for win in gajim.interface.msg_win_mgr.windows():
unread_not_to_notify = gajim.events.get_nb_events(['printed_gc_msg']) for ctrl in win.controls():
unread -= unread_not_to_notify fjid = ctrl.get_full_jid()
if gajim.last_message_time[ctrl.account].has_key(fjid):
if time.time() - gajim.last_message_time[ctrl.account][fjid] < 2:
recent = True
break
if recent:
break
# check if we have recent messages if unread or recent:
recent = False dialog = dialogs.ConfirmationDialog(_('You have unread messages'),
for win in gajim.interface.msg_win_mgr.windows(): _('Messages will only be available for reading them later if you'
for ctrl in win.controls(): ' have history enabled and contact is in your roster.'))
fjid = ctrl.get_full_jid() if dialog.get_response() != gtk.RESPONSE_OK:
if gajim.last_message_time[ctrl.account].has_key(fjid): return
if time.time() - gajim.last_message_time[ctrl.account][fjid] < 2:
recent = True
break
if recent:
break
if unread or recent: self.quit_on_next_offline = 0
dialog = dialogs.ConfirmationDialog(_('You have unread messages'), for acct in accounts:
_('Messages will only be available for reading them later if you' if gajim.connections[acct].connected:
' have history enabled and contact is in your roster.')) self.quit_on_next_offline += 1
if dialog.get_response() != gtk.RESPONSE_OK: self.send_status(acct, 'offline', message)
return
self.quit_on_next_offline = 0 if not self.quit_on_next_offline:
for acct in accounts: self.quit_gtkgui_interface()
if gajim.connections[acct].connected:
self.quit_on_next_offline += 1
self.send_status(acct, 'offline', message)
if not self.quit_on_next_offline: if get_msg:
self.quit_gtkgui_interface() self.get_status_message('offline', on_continue)
else:
self.on_continue('')
################################################################################ ################################################################################
### Menu and GUI callbacks ### Menu and GUI callbacks
@ -2514,57 +2522,64 @@ class RosterWindow:
def on_block(self, widget, titer, group_list): def on_block(self, widget, titer, group_list):
''' When clicked on the 'block' button in context menu. ''' ''' When clicked on the 'block' button in context menu. '''
model = self.modelfilter def on_continue(msg):
accounts = [] if msg is None:
msg = self.get_status_message('offline') # user pressed Cancel to change status message dialog
if group_list is None: return
jid = model[titer][C_JID].decode('utf-8') model = self.modelfilter
account = model[titer][C_ACCOUNT].decode('utf-8') accounts = []
accounts.append(account) if group_list is None:
self.send_status(account, 'offline', msg, to = jid) jid = model[titer][C_JID].decode('utf-8')
new_rule = {'order': u'1', 'type': u'jid', 'action': u'deny', account = model[titer][C_ACCOUNT].decode('utf-8')
'value' : jid, 'child': [u'message', u'iq', u'presence-out']} accounts.append(account)
gajim.connections[account].blocked_list.append(new_rule) self.send_status(account, 'offline', msg, to = jid)
# needed for draw_contact: new_rule = {'order': u'1', 'type': u'jid', 'action': u'deny',
gajim.connections[account].blocked_contacts.append(jid) 'value' : jid, 'child': [u'message', u'iq', u'presence-out']}
self.draw_contact(jid, account)
else:
if titer is None:
for (contact, account) in group_list:
if account not in accounts:
if not gajim.connections[account].privacy_rules_supported:
continue
accounts.append(account)
self.send_status(account, 'offline', msg, to=contact.jid)
new_rule = {'order': u'1', 'type': u'jid',
'action': u'deny', 'value' : contact.jid,
'child': [u'message', u'iq', u'presence-out']}
gajim.connections[account].blocked_list.append(new_rule)
# needed for draw_contact:
gajim.connections[account].blocked_contacts.append(contact.jid)
self.draw_contact(contact.jid, account)
else:
group = model[titer][C_JID].decode('utf-8')
for (contact, account) in group_list:
if account not in accounts:
if not gajim.connections[account].privacy_rules_supported:
continue
accounts.append(account)
# needed for draw_group:
gajim.connections[account].blocked_groups.append(group)
self.draw_group(group, account)
self.send_status(account, 'offline', msg, to=contact.jid)
self.draw_contact(contact.jid, account)
new_rule = {'order': u'1', 'type': u'group', 'action': u'deny',
'value' : group, 'child': [u'message', u'iq', u'presence-out']}
gajim.connections[account].blocked_list.append(new_rule) gajim.connections[account].blocked_list.append(new_rule)
for account in accounts: # needed for draw_contact:
gajim.connections[account].set_privacy_list( gajim.connections[account].blocked_contacts.append(jid)
'block', gajim.connections[account].blocked_list) self.draw_contact(jid, account)
if len(gajim.connections[account].blocked_list) == 1: else:
gajim.connections[account].set_active_list('block') if titer is None:
gajim.connections[account].set_default_list('block') for (contact, account) in group_list:
gajim.connections[account].get_privacy_list('block') if account not in accounts:
if not gajim.connections[account].privacy_rules_supported:
continue
accounts.append(account)
self.send_status(account, 'offline', msg, to=contact.jid)
new_rule = {'order': u'1', 'type': u'jid',
'action': u'deny', 'value' : contact.jid,
'child': [u'message', u'iq', u'presence-out']}
gajim.connections[account].blocked_list.append(new_rule)
# needed for draw_contact:
gajim.connections[account].blocked_contacts.append(
contact.jid)
self.draw_contact(contact.jid, account)
else:
group = model[titer][C_JID].decode('utf-8')
for (contact, account) in group_list:
if account not in accounts:
if not gajim.connections[account].privacy_rules_supported:
continue
accounts.append(account)
# needed for draw_group:
gajim.connections[account].blocked_groups.append(group)
self.draw_group(group, account)
self.send_status(account, 'offline', msg, to=contact.jid)
self.draw_contact(contact.jid, account)
new_rule = {'order': u'1', 'type': u'group', 'action': u'deny',
'value' : group, 'child': [u'message', u'iq',
u'presence-out']}
gajim.connections[account].blocked_list.append(new_rule)
for account in accounts:
gajim.connections[account].set_privacy_list(
'block', gajim.connections[account].blocked_list)
if len(gajim.connections[account].blocked_list) == 1:
gajim.connections[account].set_active_list('block')
gajim.connections[account].set_default_list('block')
gajim.connections[account].get_privacy_list('block')
self.get_status_message('offline', on_continue)
def on_unblock(self, widget, titer, group_list): def on_unblock(self, widget, titer, group_list):
''' When clicked on the 'unblock' button in context menu. ''' ''' When clicked on the 'unblock' button in context menu. '''
@ -2954,10 +2969,10 @@ class RosterWindow:
def on_change_status_message_activate(self, widget, account): def on_change_status_message_activate(self, widget, account):
show = gajim.SHOW_LIST[gajim.connections[account].connected] show = gajim.SHOW_LIST[gajim.connections[account].connected]
dlg = dialogs.ChangeStatusMessageDialog(show) def on_response(message):
message = dlg.run() if message is not None: # None is if user pressed Cancel
if message is not None: # None is if user pressed Cancel self.send_status(account, show, message)
self.send_status(account, show, message) dialogs.ChangeStatusMessageDialog(on_response, show)
def on_add_to_roster(self, widget, contact, account): def on_add_to_roster(self, widget, contact, account):
dialogs.AddNewContactWindow(account, contact.jid, contact.name) dialogs.AddNewContactWindow(account, contact.jid, contact.name)
@ -3062,16 +3077,17 @@ class RosterWindow:
show = helpers.get_global_show() show = helpers.get_global_show()
if show == 'offline': if show == 'offline':
return True return True
dlg = dialogs.ChangeStatusMessageDialog(show) def on_response(message):
message = dlg.run() if message is None:
if not message: return True
return True for acct in gajim.connections:
for acct in gajim.connections: if not gajim.config.get_per('accounts', acct,
if not gajim.config.get_per('accounts', acct, 'sync_with_global_status'):
'sync_with_global_status'): continue
continue current_show = gajim.SHOW_LIST[gajim.connections[acct].\
current_show = gajim.SHOW_LIST[gajim.connections[acct].connected] connected]
self.send_status(acct, current_show, message) self.send_status(acct, current_show, message)
dialogs.ChangeStatusMessageDialog(on_response, show)
return True return True
elif event.button == 1: # Left click elif event.button == 1: # Left click
@ -3164,9 +3180,9 @@ class RosterWindow:
def on_send_custom_status(self, widget, contact_list, show, group=None): def on_send_custom_status(self, widget, contact_list, show, group=None):
'''send custom status''' '''send custom status'''
dlg = dialogs.ChangeStatusMessageDialog(show) def on_response(message):
message = dlg.run() if message is None: # None if user pressed Cancel
if message is not None: # None if user pressed Cancel return
for (contact, account) in contact_list: for (contact, account) in contact_list:
our_jid = gajim.get_jid_from_account(account) our_jid = gajim.get_jid_from_account(account)
accounts = [] accounts = []
@ -3182,6 +3198,7 @@ class RosterWindow:
if not gajim.interface.status_sent_to_users.has_key(account): if not gajim.interface.status_sent_to_users.has_key(account):
gajim.interface.status_sent_to_users[account] = {} gajim.interface.status_sent_to_users[account] = {}
gajim.interface.status_sent_to_users[account][contact.jid] = show gajim.interface.status_sent_to_users[account][contact.jid] = show
dialogs.ChangeStatusMessageDialog(on_response, show)
def on_status_combobox_changed(self, widget): def on_status_combobox_changed(self, widget):
'''When we change our status via the combobox''' '''When we change our status via the combobox'''
@ -3205,20 +3222,20 @@ class RosterWindow:
# 'Change status message' selected: # 'Change status message' selected:
# do not change show, just show change status dialog # do not change show, just show change status dialog
status = model[self.previous_status_combobox_active][2].decode('utf-8') status = model[self.previous_status_combobox_active][2].decode('utf-8')
dlg = dialogs.ChangeStatusMessageDialog(status) def on_response(message):
message = dlg.run() if message is not None: # None if user pressed Cancel
if message is not None: # None if user pressed Cancel for account in accounts:
for account in accounts: if not gajim.config.get_per('accounts', account,
if not gajim.config.get_per('accounts', account, 'sync_with_global_status'):
'sync_with_global_status'): continue
continue current_show = gajim.SHOW_LIST[
current_show = gajim.SHOW_LIST[ gajim.connections[account].connected]
gajim.connections[account].connected] self.send_status(account, current_show, message)
self.send_status(account, current_show, message) self.combobox_callback_active = False
self.combobox_callback_active = False self.status_combobox.set_active(
self.status_combobox.set_active( self.previous_status_combobox_active)
self.previous_status_combobox_active) self.combobox_callback_active = True
self.combobox_callback_active = True dialogs.ChangeStatusMessageDialog(on_response, status)
return return
# we are about to change show, so save this new show so in case # we are about to change show, so save this new show so in case
# after user chooses "Change status message" menuitem # after user chooses "Change status message" menuitem
@ -3245,28 +3262,33 @@ class RosterWindow:
if dialog.get_response() != gtk.RESPONSE_OK: if dialog.get_response() != gtk.RESPONSE_OK:
self.update_status_combobox() self.update_status_combobox()
return return
message = self.get_status_message(status)
if message is None: # user pressed Cancel to change status message dialog
self.update_status_combobox()
return
global_sync_accounts = []
for acct in accounts:
if gajim.config.get_per('accounts', acct, 'sync_with_global_status'):
global_sync_accounts.append(acct)
global_sync_connected_accounts = gajim.get_number_of_connected_accounts(
global_sync_accounts)
for account in accounts:
if not gajim.config.get_per('accounts', account,
'sync_with_global_status'):
continue
# we are connected (so we wanna change show and status)
# or no account is connected and we want to connect with new show and
# status
if not global_sync_connected_accounts > 0 or \ def on_continue(message):
gajim.connections[account].connected > 0: if message is None:
self.send_status(account, status, message) # user pressed Cancel to change status message dialog
self.update_status_combobox() self.update_status_combobox()
return
global_sync_accounts = []
for acct in accounts:
if gajim.config.get_per('accounts', acct,
'sync_with_global_status'):
global_sync_accounts.append(acct)
global_sync_connected_accounts = \
gajim.get_number_of_connected_accounts(global_sync_accounts)
for account in accounts:
if not gajim.config.get_per('accounts', account,
'sync_with_global_status'):
continue
# we are connected (so we wanna change show and status)
# or no account is connected and we want to connect with new show
# and status
if not global_sync_connected_accounts > 0 or \
gajim.connections[account].connected > 0:
self.send_status(account, status, message)
self.update_status_combobox()
self.get_status_message(status, on_continue)
def on_preferences_menuitem_activate(self, widget): def on_preferences_menuitem_activate(self, widget):
if gajim.interface.instances.has_key('preferences'): if gajim.interface.instances.has_key('preferences'):

View File

@ -358,10 +358,9 @@ class Systray:
model = gajim.interface.roster.status_combobox.get_model() model = gajim.interface.roster.status_combobox.get_model()
active = gajim.interface.roster.status_combobox.get_active() active = gajim.interface.roster.status_combobox.get_active()
status = model[active][2].decode('utf-8') status = model[active][2].decode('utf-8')
dlg = dialogs.ChangeStatusMessageDialog(status) def on_response(message):
dlg.window.present() if message is None: # None if user press Cancel
message = dlg.run() return
if message is not None: # None if user press Cancel
accounts = gajim.connections.keys() accounts = gajim.connections.keys()
for acct in accounts: for acct in accounts:
if not gajim.config.get_per('accounts', acct, if not gajim.config.get_per('accounts', acct,
@ -369,6 +368,8 @@ class Systray:
continue continue
show = gajim.SHOW_LIST[gajim.connections[acct].connected] show = gajim.SHOW_LIST[gajim.connections[acct].connected]
gajim.interface.roster.send_status(acct, show, message) gajim.interface.roster.send_status(acct, show, message)
dlg = dialogs.ChangeStatusMessageDialog(on_response, status)
dlg.window.present()
def show_tooltip(self, widget): def show_tooltip(self, widget):
position = widget.window.get_origin() position = widget.window.get_origin()