diff --git a/src/chat_control.py b/src/chat_control.py index 74fe0e87d1714bb6e742e7e795cbc469b1878bac..41f4ce8b79917cd5d429d3626cb1cb211cc929fb 100644 --- a/src/chat_control.py +++ b/src/chat_control.py @@ -26,7 +26,6 @@ import gtkgui_helpers import message_control import dialogs import history_window -import locale from common import gajim from common import helpers @@ -161,7 +160,7 @@ class ChatControlBase(MessageControl): '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() + 'words feature will not be used')) gajim.config.set('use_speller', False) self.style_event_id = 0 @@ -171,7 +170,6 @@ class ChatControlBase(MessageControl): if gajim.connections[self.account].connected < 2: # we are not connected dialog = dialogs.ErrorDialog(_('A connection is not available'), _('Your message can not be sent until you are connected.')) - dialog.get_response() return message_buffer = self.msg_textview.get_buffer() start_iter = message_buffer.get_start_iter() @@ -373,7 +371,6 @@ class ChatControlBase(MessageControl): if gajim.connections[self.account].connected < 2: # we are not connected dialog = dialogs.ErrorDialog(_('A connection is not available'), _('Your message can not be sent until you are connected.')) - dialog.get_response() send_message = False if send_message: @@ -1571,8 +1568,8 @@ class ChatControl(ChatControlBase): def _on_toggle_gpg_menuitem_activate(self, widget): # update the button # this is reverse logic, as we are on 'activate' (before change happens) - is_active = self.xml.get_widget('gpg_togglebutton').get_active() - tb.set_active(not is_active) + tb = self.xml.get_widget('gpg_togglebutton') + tb.set_active(not tb.get_active()) def got_connected(self): ChatControlBase.got_connected(self) diff --git a/src/config.py b/src/config.py index 7fbdad308e3b74a5ca80069a6ddbda6a16b591a8..8f92b4db017209529e67ca783f2027afea530045 100644 --- a/src/config.py +++ b/src/config.py @@ -1118,22 +1118,20 @@ class AccountModificationWindow: if gajim.connections[self.account].connected != 0: dialogs.ErrorDialog( _('You are currently connected to the server'), - _('To change the account name, you must be disconnected.')).\ - get_response() + _('To change the account name, you must be disconnected.')) return if len(gajim.awaiting_events[self.account]): dialogs.ErrorDialog(_('Unread events'), _('To change the account name, you must read all pending ' - 'events.')).\ - get_response() + 'events.')) return if (name == ''): dialogs.ErrorDialog(_('Invalid account name'), - _('Account name cannot be empty.')).get_response() + _('Account name cannot be empty.')) return if name.find(' ') != -1: dialogs.ErrorDialog(_('Invalid account name'), - _('Account name cannot contain spaces.')).get_response() + _('Account name cannot contain spaces.')) return jid = self.xml.get_widget('jid_entry').get_text().decode('utf-8') @@ -1142,14 +1140,14 @@ class AccountModificationWindow: jid = helpers.parse_jid(jid) except helpers.InvalidFormat, s: pritext = _('Invalid Jabber ID') - dialogs.ErrorDialog(pritext, str(s)).get_response() + dialogs.ErrorDialog(pritext, str(s)) return n, hn = jid.split('@', 1) if not n: pritext = _('Invalid Jabber ID') sectext = _('A Jabber ID must be in the form "user@servername".') - dialogs.ErrorDialog(pritext, sectext).get_response() + dialogs.ErrorDialog(pritext, sectext) return resource = self.xml.get_widget('resource_entry').get_text().decode('utf-8') @@ -1157,7 +1155,7 @@ class AccountModificationWindow: resource = helpers.parse_resource(resource) except helpers.InvalidFormat, s: pritext = _('Invalid Jabber ID') - dialogs.ErrorDialog(pritext, (s)).get_response() + dialogs.ErrorDialog(pritext, (s)) return config['savepass'] = self.xml.get_widget( @@ -1205,7 +1203,7 @@ class AccountModificationWindow: custom_port = int(custom_port) except: dialogs.ErrorDialog(_('Invalid entry'), - _('Custom port must be a port number.')).get_response() + _('Custom port must be a port number.')) return config['custom_port'] = custom_port config['custom_host'] = self.xml.get_widget( @@ -1289,15 +1287,6 @@ class AccountModificationWindow: config['use_ft_proxies']: gajim.connections[self.account].discover_ft_proxies() - if relogin_needed: - dialog = dialogs.YesNoDialog(_('Relogin now?'), - _('If you want all the changes to apply instantly, ' - 'you must relogin.')) - if dialog.get_response() == gtk.RESPONSE_YES: - do_relogin = True - else: - do_relogin = False - for opt in config: gajim.config.set_per('accounts', name, opt, config[opt]) if config['savepass']: @@ -1312,13 +1301,19 @@ class AccountModificationWindow: gajim.interface.save_config() self.window.destroy() - if relogin_needed and do_relogin: - show_before = gajim.SHOW_LIST[gajim.connections[name].connected] - status_before = gajim.connections[name].status - gajim.interface.roster.send_status(name, 'offline', - _('Be right back.')) - gobject.timeout_add(500, gajim.interface.roster.send_status, name, - show_before, status_before) + if relogin_needed: + def relog(widget): + self.dialog.destroy() + show_before = gajim.SHOW_LIST[gajim.connections[self.account].\ + connected] + status_before = gajim.connections[self.account].status + gajim.interface.roster.send_status(self.account, 'offline', + _('Be right back.')) + gobject.timeout_add(500, gajim.interface.roster.send_status, + self.account, show_before, status_before) + self.dialog = dialogs.YesNoDialog(_('Relogin now?'), + _('If you want all the changes to apply instantly, ' + 'you must relogin.'), on_response_yes = relog) def on_change_password_button_clicked(self, widget): try: @@ -1336,7 +1331,7 @@ class AccountModificationWindow: def on_edit_details_button_clicked(self, widget): if not gajim.interface.instances.has_key(self.account): dialogs.ErrorDialog(_('No such account available'), - _('You must create your account before editing your personal information.')).get_response() + _('You must create your account before editing your personal information.')) return jid = self.xml.get_widget('jid_entry').get_text().decode('utf-8') @@ -1344,8 +1339,7 @@ class AccountModificationWindow: if not gajim.connections.has_key(self.account) or \ gajim.connections[self.account].connected < 2: dialogs.ErrorDialog(_('You are not connected to the server'), -_('Without a connection, you can not edit your personal information.') -).get_response() + _('Without a connection, you can not edit your personal information.')) return # in infos the key jid is OUR jid so we save the vcardwindow instance there @@ -1376,7 +1370,7 @@ _('Without a connection, you can not edit your personal information.') secret_keys = [] if not secret_keys: dialogs.ErrorDialog(_('Failed to get secret keys'), -_('There was a problem retrieving your OpenPGP secret keys.')).get_response() + _('There was a problem retrieving your OpenPGP secret keys.')) return secret_keys['None'] = 'None' instance = dialogs.ChooseGPGKeyDialog(_('OpenPGP Key Selection'), @@ -1656,8 +1650,7 @@ class AccountsWindow: account = model.get_value(iter, 0).decode('utf-8') if len(gajim.awaiting_events[account]): dialogs.ErrorDialog(_('Unread events'), - _('Read all pending events before removing this account.')).\ - get_response() + _('Read all pending events before removing this account.')) return if gajim.interface.instances[account].has_key('remove_account'): gajim.interface.instances[account]['remove_account'].window.present() @@ -2112,31 +2105,33 @@ class RemoveAccountWindow: self.window.show_all() def on_remove_button_clicked(self, widget): + def remove(widget): + self.dialog.destroy() + if gajim.connections[self.account].connected and \ + not self.remove_and_unregister_radiobutton.get_active(): + # change status to offline only if we will not remove this JID from + # server + gajim.connections[self.account].change_status('offline', 'offline') + if self.remove_and_unregister_radiobutton.get_active(): + if not gajim.connections[self.account].password: + passphrase = '' + w = dialogs.PassphraseDialog( + _('Password Required'), + _('Enter your password for account %s') % self.account, + _('Save password')) + passphrase, save = w.run() + if passphrase == -1: + # We don't remove account cause we canceled pw window + return + gajim.connections[self.account].password = passphrase + gajim.connections[self.account].unregister_account(self._on_remove_success) + else: + self._on_remove_success(True) if gajim.connections[self.account].connected: - dialog = dialogs.ConfirmationDialog( + self.dialog = dialogs.ConfirmationDialog( _('Account "%s" is connected to the server' % self.account), - _('If you remove it, the connection will be lost.')) - if dialog.get_response() != gtk.RESPONSE_OK: - return - # change status to offline only if we will not remove this JID from server - if not self.remove_and_unregister_radiobutton.get_active(): - gajim.connections[self.account].change_status('offline', 'offline') - - if self.remove_and_unregister_radiobutton.get_active(): - if not gajim.connections[self.account].password: - passphrase = '' - w = dialogs.PassphraseDialog( - _('Password Required'), - _('Enter your password for account %s') % self.account, - _('Save password')) - passphrase, save = w.run() - if passphrase == -1: - # We don't remove account cause we canceled pw window - return - gajim.connections[self.account].password = passphrase - gajim.connections[self.account].unregister_account(self._on_remove_success) - else: - self._on_remove_success(True) + _('If you remove it, the connection will be lost.'), + on_response_ok = remove) def _on_remove_success(self, res): # action of unregistration has failed, we don't remove the account @@ -2298,7 +2293,7 @@ class ManageBookmarksWindow: if self.server_entry.get_text().decode('utf-8') == '' or self.room_entry.get_text().decode('utf-8') == '': dialogs.ErrorDialog(_('This bookmark has invalid data'), -_('Please be sure to fill out server and room fields or remove this bookmark.')).get_response() +_('Please be sure to fill out server and room fields or remove this bookmark.')) return False return True @@ -2536,7 +2531,7 @@ class AccountCreationWizardWindow: if not username: pritext = _('Invalid username') sectext = _('You must provide a username to configure this account.') - dialogs.ErrorDialog(pritext, sectext).get_response() + dialogs.ErrorDialog(pritext, sectext) return server = widgets['server_comboboxentry'].child.get_text() savepass = widgets['save_password_checkbutton'].get_active() @@ -2545,12 +2540,12 @@ class AccountCreationWizardWindow: if not self.modify: if password == '': dialogs.ErrorDialog(_('Invalid password'), - _('You must enter a password for the new account.')).get_response() + _('You must enter a password for the new account.')) return if widgets['pass2_entry'].get_text() != password: dialogs.ErrorDialog(_('Passwords do not match'), - _('The passwords typed in both fields must be identical.')).get_response() + _('The passwords typed in both fields must be identical.')) return jid = username + '@' + server @@ -2559,7 +2554,7 @@ class AccountCreationWizardWindow: jid = helpers.parse_jid(jid) except helpers.InvalidFormat, s: pritext = _('Invalid Jabber ID') - dialogs.ErrorDialog(pritext, str(s)).get_response() + dialogs.ErrorDialog(pritext, str(s)) return already_in_jids = [] @@ -2571,7 +2566,7 @@ class AccountCreationWizardWindow: if jid in already_in_jids: pritext = _('Duplicate Jabber ID') sectext = _('This account is already configured in Gajim.') - dialogs.ErrorDialog(pritext, sectext).get_response() + dialogs.ErrorDialog(pritext, sectext) return self.account = server @@ -2694,7 +2689,7 @@ _('You can set advanced account options by pressing Advanced button, or later by def save_account(self, login, server, savepass, password): if self.account in gajim.connections: dialogs.ErrorDialog(_('Account name is in use'), - _('You already have an account using this name.')).get_response() + _('You already have an account using this name.')) return con = connection.Connection(self.account) con.password = password diff --git a/src/dialogs.py b/src/dialogs.py index 8b2cde0f1cef3bb22b1084be698cbb2229765eab..501419c51cab9eff7232502f7e6ddb74bda16873 100644 --- a/src/dialogs.py +++ b/src/dialogs.py @@ -450,13 +450,13 @@ _('Please fill in the data of the contact you want to add in account %s') %accou jid = helpers.parse_jid(jid) except helpers.InvalidFormat, s: pritext = _('Invalid User ID') - ErrorDialog(pritext, str(s)).get_response() + ErrorDialog(pritext, str(s)) return # No resource in jid if jid.find('/') >= 0: pritext = _('Invalid User ID') - ErrorDialog(pritext, _('The user ID must not contain a resource.')).get_response() + ErrorDialog(pritext, _('The user ID must not contain a resource.')) return # Check if jid is already in roster @@ -464,7 +464,7 @@ _('Please fill in the data of the contact you want to add in account %s') %accou c = gajim.contacts.get_first_contact_from_jid(self.account, jid) if _('Not in Roster') not in c.groups and c.sub in ('both', 'to'): ErrorDialog(_('Contact already in roster'), - _('This contact is already listed in your roster.')).get_response() + _('This contact is already listed in your roster.')) return message_buffer = self.xml.get_widget('message_textview').get_buffer() @@ -589,14 +589,45 @@ class Dialog(gtk.Dialog): return index < len(buttons) and buttons[index] or None class HigDialog(gtk.MessageDialog): - def __init__(self, parent, type, buttons, pritext, sectext): + def __init__(self, parent, type, buttons, pritext, sectext, + on_response_ok = None, on_response_cancel = None, on_response_yes = None, + on_response_no = None): gtk.MessageDialog.__init__(self, parent, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL, type, buttons, message_format = pritext) self.format_secondary_text(sectext) + buttons = self.action_area.get_children() + possible_response = {gtk.STOCK_OK: on_response_ok, + gtk.STOCK_CANCEL: on_response_cancel, gtk.STOCK_YES: on_response_yes, + gtk.STOCK_NO: on_response_no} + for b in buttons: + for response in possible_response: + if b.get_label() == response: + if not possible_response[response]: + b.connect('clicked', self.just_destroy) + elif isinstance(possible_response[response], tuple): + if len(possible_response[response]) == 1: + b.connect('clicked', possible_response[response][0]) + else: + b.connect('clicked', *possible_response[response]) + else: + b.connect('clicked', possible_response[response]) + break + + def just_destroy(self, widget): + self.destroy() + + def popup(self): + # Give focus to top vbox + vb = self.get_children()[0].get_children()[0] + vb.set_flags(gtk.CAN_FOCUS) + vb.grab_focus() + self.show_all() + def get_response(self): + '''Be carefull: this function uses dialog.run() function so GUI is not updated''' # Give focus to top vbox vb = self.get_children()[0].get_children()[0] vb.set_flags(gtk.CAN_FOCUS) @@ -608,45 +639,49 @@ class HigDialog(gtk.MessageDialog): class ConfirmationDialog(HigDialog): '''HIG compliant confirmation dialog.''' - def __init__(self, pritext, sectext=''): + def __init__(self, pritext, sectext='', on_response_ok = None, + on_response_cancel = None): HigDialog.__init__(self, None, - gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, pritext, sectext) + gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, pritext, sectext, + on_response_ok, on_response_cancel) + self.popup() class WarningDialog(HigDialog): def __init__(self, pritext, sectext=''): '''HIG compliant warning dialog.''' HigDialog.__init__( self, None, - gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, pritext, sectext) + gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, pritext, sectext) + self.popup() class InformationDialog(HigDialog): def __init__(self, pritext, sectext=''): '''HIG compliant info dialog.''' HigDialog.__init__( self, None, - gtk.MESSAGE_INFO, gtk.BUTTONS_OK, pritext, sectext) - ok_button = self.action_area.get_children()[0] - ok_button.connect('clicked', self.on_ok_button_clicked) - self.show_all() - - def on_ok_button_clicked(self, widget): - self.destroy() + gtk.MESSAGE_INFO, gtk.BUTTONS_OK, pritext, sectext) + self.popup() class ErrorDialog(HigDialog): def __init__(self, pritext, sectext=''): '''HIG compliant error dialog.''' HigDialog.__init__( self, None, - gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, pritext, sectext) + gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, pritext, sectext) + self.popup() class YesNoDialog(HigDialog): - def __init__(self, pritext, sectext=''): + def __init__(self, pritext, sectext='', on_response_yes = None, + on_response_no = None): '''HIG compliant YesNo dialog.''' HigDialog.__init__( self, None, - gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, pritext, sectext) + gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, pritext, sectext, + on_response_yes = on_response_yes, on_response_no = on_response_no) class ConfirmationDialogCheck(ConfirmationDialog): '''HIG compliant confirmation dialog with checkbutton.''' - def __init__(self, pritext, sectext='', checktext = ''): - HigDialog.__init__(self, None, gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, - pritext, sectext) + def __init__(self, pritext, sectext='', checktext = '', + on_response_ok = None, on_response_cancel = None): + HigDialog.__init__(self, None, gtk.MESSAGE_QUESTION, + gtk.BUTTONS_OK_CANCEL, pritext, sectext, on_response_ok, + on_response_cancel) self.set_default_response(gtk.RESPONSE_OK) @@ -775,7 +810,7 @@ class JoinGroupchatWindow: nick = gajim.nicks[self.account] if gajim.connections[account].connected < 2: ErrorDialog(_('You are not connected to the server'), -_('You can not join a group chat unless you are connected.')).get_response() +_('You can not join a group chat unless you are connected.')) raise RuntimeError, 'You must be connected to join a groupchat' self._empty_required_widgets = [] @@ -911,8 +946,7 @@ class NewMessageDialog: if gajim.connections[self.account].connected <= 1: #if offline or connecting ErrorDialog(_('Connection not available'), - _('Please make sure you are connected with "%s".' % self.account) - ).get_response() + _('Please make sure you are connected with "%s".' % self.account)) return gajim.interface.roster.new_chat_from_jid(self.account, jid) @@ -922,7 +956,7 @@ class ChangePasswordDialog: # 'account' can be None if we are about to create our first one if not account or gajim.connections[account].connected < 2: ErrorDialog(_('You are not connected to the server'), -_('Without a connection, you can not change your password.')).get_response() + _('Without a connection, you can not change your password.')) raise RuntimeError, 'You are not connected to the server' self.account = account self.xml = gtk.glade.XML(GTKGUI_GLADE, 'change_password_dialog', APP) @@ -941,12 +975,12 @@ _('Without a connection, you can not change your password.')).get_response() password1 = self.password1_entry.get_text().decode('utf-8') if not password1: ErrorDialog(_('Invalid password'), - _('You must enter a password.')).get_response() + _('You must enter a password.')) continue password2 = self.password2_entry.get_text().decode('utf-8') if password1 != password2: ErrorDialog(_('Passwords do not match'), - _('The passwords typed in both fields must be identical.')).get_response() + _('The passwords typed in both fields must be identical.')) continue message = password1 else: @@ -1164,7 +1198,7 @@ class SingleMessageWindow: gtkspell.Spell(self.message_textview) except gobject.GError, msg: #FIXME: add a ui for this use spell.set_language() - 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() + 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')) gajim.config.set('use_speller', False) self.send_button.set_no_show_all(True) @@ -1288,8 +1322,7 @@ class SingleMessageWindow: if gajim.connections[self.account].connected <= 1: # if offline or connecting ErrorDialog(_('Connection not available'), - _('Please make sure you are connected with "%s".' % self.account) - ).get_response() + _('Please make sure you are connected with "%s".' % self.account)) return to_whom_jid = self.to_entry.get_text().decode('utf-8') subject = self.subject_entry.get_text().decode('utf-8') @@ -1408,8 +1441,7 @@ class XMLConsoleWindow: if gajim.connections[self.account].connected <= 1: #if offline or connecting ErrorDialog(_('Connection not available'), - _('Please make sure you are connected with "%s".' % self.account) - ).get_response() + _('Please make sure you are connected with "%s".' % self.account)) return begin_iter, end_iter = self.input_tv_buffer.get_bounds() stanza = self.input_tv_buffer.get_text(begin_iter, end_iter).decode('utf-8') @@ -1439,9 +1471,11 @@ class XMLConsoleWindow: class InvitationReceivedDialog: def __init__(self, account, room_jid, contact_jid, password = None, comment = None): - + + self.room_jid = room_jid + self.account = account xml = gtk.glade.XML(GTKGUI_GLADE, 'invitation_received_dialog', APP) - dialog = xml.get_widget('invitation_received_dialog') + self.dialog = xml.get_widget('invitation_received_dialog') #FIXME: use nickname instead of contact_jid pritext = _('%(contact_jid)s has invited you to %(room_jid)s room') % { @@ -1454,12 +1488,20 @@ class InvitationReceivedDialog: label_text += '\n\n%s' % sectext xml.get_widget('label').set_markup(label_text) - - response = dialog.run() - dialog.destroy() - if response == gtk.RESPONSE_YES: - room, server = gajim.get_room_name_and_server_from_room_jid(room_jid) - JoinGroupchatWindow(account, server = server, room = room) + + xml.get_widget('deny_button').connect('clicked', + self.on_deny_button_clicked) + xml.get_widget('accept_button').connect('clicked', + self.on_accept_button_clicked) + self.dialog.show_all() + + def on_deny_button_clicked(self, widget): + self.dialog.destroy() + + def on_accept_button_clicked(self, widget): + self.dialog.destroy() + room, server = gajim.get_room_name_and_server_from_room_jid(self.room_jid) + JoinGroupchatWindow(self.account, server = server, room = room) class ProgressDialog: def __init__(self, title_text, during_text, messages_queue): diff --git a/src/disco.py b/src/disco.py index b9a57d96c6d0bd020441b10c9a2b2749760fc40d..ce6b20f17fdbd413b78e670942b2172bccd8dee2 100644 --- a/src/disco.py +++ b/src/disco.py @@ -417,7 +417,7 @@ class ServiceDiscoveryWindow: # Check connection if gajim.connections[account].connected < 2: dialogs.ErrorDialog(_('You are not connected to the server'), -_('Without a connection, you can not browse available services')).get_response() +_('Without a connection, you can not browse available services')) raise RuntimeError, 'You must be connected to browse services' # Get a ServicesCache object. @@ -635,12 +635,12 @@ _('Without a connection, you can not browse available services')).get_response() # We can't travel anywhere else. self.destroy() dialogs.ErrorDialog(_('The service could not be found'), -_('There is no service at the address you entered, or it is not responding. Check the address and try again.')).get_response() +_('There is no service at the address you entered, or it is not responding. Check the address and try again.')) return klass = self.cache.get_browser(identities, features) if not klass: dialogs.ErrorDialog(_('The service is not browsable'), -_('This type of service does not contain any items to browse.')).get_response() +_('This type of service does not contain any items to browse.')) return elif klass is None: klass = AgentBrowser @@ -922,7 +922,7 @@ class AgentBrowser: # We can't travel anywhere else. self.window.destroy() dialogs.ErrorDialog(_('The service is not browsable'), -_('This service does not contain any items to browse.')).get_response() +_('This service does not contain any items to browse.')) return # We got a list of items for item in items: diff --git a/src/filetransfers_window.py b/src/filetransfers_window.py index 4aea6a6e9d4c30e0913ad923b1cfe8308d483a82..2856984fc464fc2c2e5d94262661144029f82631 100644 --- a/src/filetransfers_window.py +++ b/src/filetransfers_window.py @@ -159,6 +159,16 @@ class FileTransfersWindow: ''' show a dialog saying that file (file_props) has been transferred''' self.window.present() self.window.window.focus() + + def on_open(widget, file_props): + self.dialog.destroy() + if not file_props.has_key('file-name'): + return + (path, file) = os.path.split(file_props['file-name']) + if os.path.exists(path) and os.path.isdir(path): + helpers.launch_file_manager(path) + self.tree.get_selection().unselect_all() + if file_props['type'] == 'r': # file path is used below in 'Save in' (file_path, file_name) = os.path.split(file_props['file-name']) @@ -190,22 +200,18 @@ class FileTransfersWindow: if file_props['type'] == 'r': sectext += '\n\t' +_('Saved in: %s') % \ gtkgui_helpers.escape_for_pango_markup(file_path) - dialog = dialogs.HigDialog(None, gtk.MESSAGE_INFO, gtk.BUTTONS_NONE, + self.dialog = dialogs.HigDialog(None, gtk.MESSAGE_INFO, gtk.BUTTONS_NONE, _('File transfer completed'), sectext) if file_props['type'] == 'r': - dialog.add_buttons(_('_Open Containing Folder'), gtk.RESPONSE_ACCEPT) - dialog.add_buttons(gtk.STOCK_OK, gtk.RESPONSE_OK) - dialog.show_all() - response = dialog.run() - dialog.destroy() - if response == gtk.RESPONSE_ACCEPT: - if not file_props.has_key('file-name'): - return - (path, file) = os.path.split(file_props['file-name']) - if os.path.exists(path) and os.path.isdir(path): - helpers.launch_file_manager(path) - self.tree.get_selection().unselect_all() - + button = gtk.Button(_('_Open Containing Folder')) + button.connect('clicked', on_open, file_props) + self.dialog.action_area.pack_start(button) + ok_button = self.dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) + def on_ok(widget): + self.dialog.destroy() + ok_button.connect('clicked', on_ok) + self.dialog.show_all() + def show_request_error(self, file_props): ''' show error dialog to the recipient saying that transfer has been canceled''' @@ -213,7 +219,7 @@ class FileTransfersWindow: self.window.window.focus() dialogs.InformationDialog(_('File transfer canceled'), _('Connection with peer cannot be established.')) self.tree.get_selection().unselect_all() - + def show_send_error(self, file_props): ''' show error dialog to the sender saying that transfer has been canceled''' @@ -222,7 +228,7 @@ class FileTransfersWindow: dialogs.InformationDialog(_('File transfer canceled'), _('Connection with peer cannot be established.')) self.tree.get_selection().unselect_all() - + def show_stopped(self, jid, file_props): self.window.present() self.window.window.focus() @@ -235,9 +241,9 @@ _('Connection with peer cannot be established.')) sectext += '\n\t' + _('Sender: %s') % \ gtkgui_helpers.escape_for_pango_markup(jid) dialogs.ErrorDialog(_('File transfer stopped by the contact of the other side'), \ - sectext).get_response() + sectext) self.tree.get_selection().unselect_all() - + def show_file_send_request(self, account, contact): last_send_dir = gajim.config.get('last_send_dir') dialog = gtk.FileChooserDialog(title=_('Choose File to Send...'), @@ -269,15 +275,15 @@ _('Connection with peer cannot be established.')) else: dialog.destroy() break - + def send_file(self, account, contact, file_path): ''' start the real transfer(upload) of the file ''' if gtkgui_helpers.file_is_locked(file_path): pritext = _('Gajim cannot access this file') sextext = _('This file is being used by another process.') - dialogs.ErrorDialog(pritext, sextext).get_response() + dialogs.ErrorDialog(pritext, sextext) return - + if isinstance(contact, str): if contact.find('/') == -1: return @@ -292,7 +298,7 @@ _('Connection with peer cannot be established.')) self.add_transfer(account, contact, file_props) gajim.connections[account].send_file_request(file_props) return True - + def confirm_overwrite_cb(self, dialog, file_props): file_path = dialog.get_filename() file_path = gtkgui_helpers.decode_filechooser_file_paths((file_path,))[0] @@ -316,7 +322,6 @@ _('Connection with peer cannot be established.')) file requested by a contact''' if file_props is None or not file_props.has_key('name'): return - last_save_dir = gajim.config.get('last_save_dir') sec_text = '\t' + _('File: %s') % file_props['name'] if file_props.has_key('size'): sec_text += '\n\t' + _('Size: %s') % \ @@ -326,8 +331,8 @@ _('Connection with peer cannot be established.')) if file_props.has_key('desc'): sec_text += '\n\t' + _('Description: %s') % file_props['desc'] prim_text = _('%s wants to send you a file:') % contact.jid - dialog = dialogs.ConfirmationDialog(prim_text, sec_text) - if dialog.get_response() == gtk.RESPONSE_OK: + def on_response_ok(widet, account, contact, file_props): + self.dialog.destroy() dialog = gtk.FileChooserDialog(title=_('Save File as...'), action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, @@ -340,6 +345,7 @@ _('Connection with peer cannot be established.')) dialog.connect('confirm-overwrite', self.confirm_overwrite_cb, file_props) gtk28 = True + last_save_dir = gajim.config.get('last_save_dir') if last_save_dir and os.path.isdir(last_save_dir): dialog.set_current_folder(last_save_dir) else: @@ -366,9 +372,16 @@ _('Connection with peer cannot be established.')) gajim.connections[account].send_file_rejection(file_props) dialog.destroy() break - else: + + def on_response_cancel(widget, account, file_props): + self.dialog.destroy() gajim.connections[account].send_file_rejection(file_props) - + + self.dialog = dialogs.ConfirmationDialog(prim_text, sec_text, + on_response_ok = (on_response_ok, account, contact, file_props), + on_response_cancel = (on_response_cancel, account, file_props)) + self.dialog.run() + def set_images(self): ''' create pixbufs for status images in transfer rows''' self.images = {} @@ -533,11 +546,11 @@ _('Connection with peer cannot be established.')) stat = os.stat(file_path) else: - dialogs.ErrorDialog(_('Invalid File'), _('File: ') + file_path).get_response() + dialogs.ErrorDialog(_('Invalid File'), _('File: ') + file_path) return None if stat[6] == 0: dialogs.ErrorDialog(_('Invalid File'), - _('It is not possible to send empty files')).get_response() + _('It is not possible to send empty files')) return None file_props['elapsed-time'] = 0 file_props['size'] = unicode(stat[6]) diff --git a/src/gajim.py b/src/gajim.py index e8b9d30ab4b467905474bb96dfd9155fe6ec94e8..805ca74133d1e5b84d4ad8adc03e7c4a52525d59 100755 --- a/src/gajim.py +++ b/src/gajim.py @@ -192,11 +192,11 @@ class Interface: def handle_event_warning(self, unused, data): #('WARNING', account, (title_text, section_text)) - dialogs.WarningDialog(data[0], data[1]).get_response() + dialogs.WarningDialog(data[0], data[1]) def handle_event_error(self, unused, data): #('ERROR', account, (title_text, section_text)) - dialogs.ErrorDialog(data[0], data[1]).get_response() + dialogs.ErrorDialog(data[0], data[1]) def handle_event_information(self, unused, data): #('INFORMATION', account, (title_text, section_text)) @@ -214,13 +214,14 @@ class Interface: def handle_event_http_auth(self, account, data): #('HTTP_AUTH', account, (method, url, transaction_id, iq_obj)) - dialog = dialogs.ConfirmationDialog(_('HTTP (%s) Authorization for %s (id: %s)') \ - % (data[0], data[1], data[2]), _('Do you accept this request?')) - if dialog.get_response() == gtk.RESPONSE_OK: - answer = 'yes' - else: - answer = 'no' - gajim.connections[account].build_http_auth_answer(data[3], answer) + def response(widget, account, iq_obj, answer): + self.dialog.destroy() + gajim.connections[account].build_http_auth_answer(iq_obj, answer) + + self.dialog = dialogs.YesNoDialog(_('HTTP (%s) Authorization for %s (id: %s)') \ + % (data[0], data[1], data[2]), _('Do you accept this request?'), + on_response_yes = (response, account, data[3], 'yes'), + on_response_no = (response, account, data[3], 'no')) def handle_event_error_answer(self, account, array): #('ERROR_ANSWER', account, (id, jid_from. errmsg, errcode)) @@ -518,6 +519,8 @@ class Interface: # Handle chat states contact = gajim.contacts.get_contact(account, jid, resource) + if isinstance(contact, list): + contact = contact[0] if contact: contact.composing_jep = composing_jep if chat_control and chat_control.type_id == message_control.TYPE_CHAT: @@ -716,7 +719,7 @@ class Interface: array[2]) else: dialogs.ErrorDialog(_('Contact with "%s" cannot be established'\ -% array[0]), _('Check your connection or try again later.')).get_response() +% array[0]), _('Check your connection or try again later.')) def handle_event_agent_info_items(self, account, array): #('AGENT_INFO_ITEMS', account, (agent, node, items)) @@ -943,7 +946,7 @@ class Interface: keyID = gajim.config.get_per('accounts', account, 'keyid') self.roster.forget_gpg_passphrase(keyID) dialogs.WarningDialog(_('Your passphrase is incorrect'), - _('You are currently connected without your OpenPGP key.')).get_response() + _('You are currently connected without your OpenPGP key.')) def handle_event_roster_info(self, account, array): #('ROSTER_INFO', account, (jid, name, sub, ask, groups)) @@ -1560,7 +1563,7 @@ class Interface: # it is good to notify the user # in case he or she cannot see the output of the console dialogs.ErrorDialog(_('Could not save your settings and preferences'), - err_str).get_response() + err_str) sys.exit() def handle_event(self, account, jid, typ): diff --git a/src/gajim_themes_window.py b/src/gajim_themes_window.py index b526039f75b2423d24bea13462ab5508b8f58c99..09498b17b467ba6599fc0f3223fd4f2adf9d1f0f 100644 --- a/src/gajim_themes_window.py +++ b/src/gajim_themes_window.py @@ -164,7 +164,7 @@ class GajimThemesWindow: if self.current_theme == gajim.config.get('roster_theme'): dialogs.ErrorDialog( _('You cannot delete your current theme'), - _('Please first choose another for your current theme.')).get_response() + _('Please first choose another for your current theme.')) return self.theme_options_vbox.set_sensitive(False) gajim.config.del_per('themes', self.current_theme) diff --git a/src/groupchat_control.py b/src/groupchat_control.py index 15efd4dc25376c5a4e90ba41890df0d608544ca5..9cab0f3d8abee74ae969d7f5aded438cca828197 100644 --- a/src/groupchat_control.py +++ b/src/groupchat_control.py @@ -84,7 +84,7 @@ class PrivateChatControl(ChatControl): _('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() + (room, nick)) return ChatControl.send_message(self, message) @@ -1171,8 +1171,7 @@ class GroupchatControl(ChatControlBase): if bookmark['jid'] == bm['jid']: dialogs.ErrorDialog( _('Bookmark already set'), - _('Room "%s" is already in your bookmarks.') % bm['jid']).\ - get_response() + _('Room "%s" is already in your bookmarks.') % bm['jid']) return gajim.connections[self.account].bookmarks.append(bm) diff --git a/src/history_manager.py b/src/history_manager.py index b4bd40481a2a969b39718e8bb5a92ab1083a61af..6deb5c4287a80a6779e7c79d7edc4112749368c7 100755 --- a/src/history_manager.py +++ b/src/history_manager.py @@ -53,7 +53,7 @@ class HistoryManager: def __init__(self): if not os.path.exists(LOG_DB_PATH): dialogs.ErrorDialog(_('Cannot find history logs database'), - '%s does not exist.' % LOG_DB_PATH).get_response() + '%s does not exist.' % LOG_DB_PATH) sys.exit() xml = gtk.glade.XML('history_manager.glade', @@ -412,76 +412,78 @@ class HistoryManager: paths_len = len(list_of_paths) if paths_len == 0: # nothing is selected return + + def on_ok(widget, liststore, list_of_paths): + # delete all rows from db that match jid_id + list_of_rowrefs = [] + for path in list_of_paths: # make them treerowrefs (it's needed) + list_of_rowrefs.append(gtk.TreeRowReference(liststore, path)) + + for rowref in list_of_rowrefs: + path = rowref.get_path() + if path is None: + continue + jid_id = liststore[path][1] + del liststore[path] # remove from UI + # remove from db + self.cur.execute(''' + DELETE FROM logs + WHERE jid_id = ? + ''', (jid_id,)) + + # now delete "jid, jid_id" row from jids table + self.cur.execute(''' + DELETE FROM jids + WHERE jid_id = ? + ''', (jid_id,)) + + self.con.commit() + + self.AT_LEAST_ONE_DELETION_DONE = True + pri_text = i18n.ngettext( 'Do you really want to delete logs of the selected contact?', 'Do you really want to delete logs of the selected contacts?', paths_len) - dialog = dialogs.ConfirmationDialog(pri_text, - _('This is an irreversible operation.')) - if dialog.get_response() != gtk.RESPONSE_OK: - return + self.dialog = dialogs.ConfirmationDialog(pri_text, + _('This is an irreversible operation.'), on_response_ok = (on_ok, + liststore, list_of_paths)) - # delete all rows from db that match jid_id - list_of_rowrefs = [] - for path in list_of_paths: # make them treerowrefs (it's needed) - list_of_rowrefs.append(gtk.TreeRowReference(liststore, path)) - - for rowref in list_of_rowrefs: - path = rowref.get_path() - if path is None: - continue - jid_id = liststore[path][1] - del liststore[path] # remove from UI - # remove from db - self.cur.execute(''' - DELETE FROM logs - WHERE jid_id = ? - ''', (jid_id,)) - - # now delete "jid, jid_id" row from jids table - self.cur.execute(''' - DELETE FROM jids - WHERE jid_id = ? - ''', (jid_id,)) - - self.con.commit() - - self.AT_LEAST_ONE_DELETION_DONE = True - def _delete_logs(self, liststore, list_of_paths): paths_len = len(list_of_paths) if paths_len == 0: # nothing is selected return + + def on_ok(widget, liststore, list_of_paths): + self.dialog.destroy() + # delete rows from db that match log_line_id + list_of_rowrefs = [] + for path in list_of_paths: # make them treerowrefs (it's needed) + list_of_rowrefs.append(gtk.TreeRowReference(liststore, path)) + + for rowref in list_of_rowrefs: + path = rowref.get_path() + if path is None: + continue + log_line_id = liststore[path][0] + del liststore[path] # remove from UI + # remove from db + self.cur.execute(''' + DELETE FROM logs + WHERE log_line_id = ? + ''', (log_line_id,)) + + self.con.commit() + + self.AT_LEAST_ONE_DELETION_DONE = True + pri_text = i18n.ngettext( 'Do you really want to delete the selected message?', 'Do you really want to delete the selected messages?', paths_len) - dialog = dialogs.ConfirmationDialog(pri_text, - _('This is an irreversible operation.')) - if dialog.get_response() != gtk.RESPONSE_OK: - return - - # delete rows from db that match log_line_id - list_of_rowrefs = [] - for path in list_of_paths: # make them treerowrefs (it's needed) - list_of_rowrefs.append(gtk.TreeRowReference(liststore, path)) - - for rowref in list_of_rowrefs: - path = rowref.get_path() - if path is None: - continue - log_line_id = liststore[path][0] - del liststore[path] # remove from UI - # remove from db - self.cur.execute(''' - DELETE FROM logs - WHERE log_line_id = ? - ''', (log_line_id,)) - - self.con.commit() - - self.AT_LEAST_ONE_DELETION_DONE = True - + self.dialog = dialogs.ConfirmationDialog(pri_text, + _('This is an irreversible operation.'), on_response_ok = (on_ok, + liststore, list_of_paths)) def on_search_db_button_clicked(self, widget): text = self.search_entry.get_text() diff --git a/src/roster_window.py b/src/roster_window.py index b257f025df9bbb574f244e48bd145dd52195561c..e28118ad6022280b673a391324e5fd004d4d9335 100644 --- a/src/roster_window.py +++ b/src/roster_window.py @@ -513,13 +513,12 @@ class RosterWindow: win = gajim.interface.msg_win_mgr.get_window(room_jid, account) win.window.present() win.set_active_tab(room_jid, account) - dialogs.ErrorDialog(_('You are already in room %s') % room_jid - ).get_response() + dialogs.ErrorDialog(_('You are already in room %s') % room_jid) return invisible_show = gajim.SHOW_LIST.index('invisible') if gajim.connections[account].connected == invisible_show: dialogs.ErrorDialog(_('You cannot join a room while you are invisible') - ).get_response() + ) return room, server = room_jid.split('@') if not gajim.interface.msg_win_mgr.has_window(room_jid, account): @@ -1065,8 +1064,8 @@ class RosterWindow: gajim.contacts.remove_contact(account, contact) return - window = dialogs.ConfirmationDialog(_('Transport "%s" will be removed') % contact.jid, _('You will no longer be able to send and receive messages to contacts from this transport.')) - if window.get_response() == gtk.RESPONSE_OK: + def remove(widget, contact, account): + self.dialog.destroy() gajim.connections[account].unsubscribe_agent(contact.jid + '/' \ + contact.resource) # remove transport from treeview @@ -1086,6 +1085,8 @@ class RosterWindow: gajim.contacts.remove_jid(account, contact.jid) gajim.contacts.remove_contact(account, contact) + self.dialog = dialogs.ConfirmationDialog(_('Transport "%s" will be removed') % contact.jid, _('You will no longer be able to send and receive messages to contacts from this transport.'), on_response_ok = (remove, contact, account)) + def on_rename(self, widget, iter, path): # this function is called either by F2 or by Rename menuitem # to display that menuitem we show a menu, that does focus-out @@ -1732,22 +1733,15 @@ _('If "%s" accepts this request you will know his or her status.') % jid) def on_req_usub(self, widget, contact, account): '''Remove a contact''' - check_string = _('I want this contact to know my status after removal') - if contact.sub == 'to': - check_string = '' - window = dialogs.ConfirmationDialogCheck( - _('Contact "%s" will be removed from your roster') % ( - contact.get_shown_name()), - _('By removing this contact you also by default remove authorization resulting in him or her always seeing you as offline.'), check_string) - # maybe use 2 optionboxes from which the contact can select? (better) - if window.get_response() == gtk.RESPONSE_OK: + def on_ok(widget, contact, account): + self.dialog.destroy() remove_auth = True - if window.is_checked(): + if contact.sub != 'to' and self.dialog.is_checked(): remove_auth = False gajim.connections[account].unsubscribe(contact.jid, remove_auth) - for u in gajim.contacts.get_contact(account, contact.jid): - self.remove_contact(u, account) - gajim.contacts.remove_jid(account, u.jid) + for c in gajim.contacts.get_contact(account, contact.jid): + self.remove_contact(c, account) + gajim.contacts.remove_jid(account, c.jid) if not remove_auth and contact.sub == 'both': contact.name = '' contact.groups = [] @@ -1761,6 +1755,18 @@ _('If "%s" accepts this request you will know his or her status.') % jid) keyID = contact.keyID) gajim.contacts.add_contact(account, c) self.add_contact_to_roster(contact.jid, account) + pritext = _('Contact "%s" will be removed from your roster') % \ + contact.get_shown_name() + if contact.sub == 'to': + self.dialog = dialogs.ConfirmationDialog(pritext, + _('By removing this contact you also remove authorization resulting in him or her always seeing you as offline.'), + on_response_ok = (on_ok, contact, account)) + else: + self.dialog = dialogs.ConfirmationDialogCheck(pritext, + _('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'), + on_response_ok = (on_ok, contact, account)) + # maybe use 2 optionboxes from which the contact can select? (better) def forget_gpg_passphrase(self, keyid): if self.gpg_passphrase.has_key(keyid): @@ -1878,17 +1884,23 @@ _('If "%s" accepts this request you will know his or her status.') % jid) return False def change_status(self, widget, account, status): - if status == 'invisible': - if self.connected_rooms(account): - dialog = dialogs.ConfirmationDialog( - _('You are participating in one or more group chats'), - _('Changing your status to invisible will result in disconnection from those group chats. Are you sure you want to go invisible?')) - if dialog.get_response() != gtk.RESPONSE_OK: - return - message = self.get_status_message(status) - if message is None: # user pressed Cancel to change status message dialog - return - self.send_status(account, status, message) + def change(widget, account, status): + if self.dialog: + self.dialog.destroy() + message = self.get_status_message(status) + if message is None: + # user pressed Cancel to change status message dialog + return + self.send_status(account, status, message) + + self.dialog = None + if status == 'invisible' and self.connected_rooms(account): + self.dialog = dialogs.ConfirmationDialog( + _('You are participating in one or more group chats'), + _('Changing your status to invisible will result in disconnection from those group chats. Are you sure you want to go invisible?'), + on_response_ok = (change, account, status)) + else: + change(None, account, status) def on_status_combobox_changed(self, widget): '''When we change our status via the combobox''' @@ -1902,8 +1914,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid) accounts = gajim.connections.keys() if len(accounts) == 0: dialogs.ErrorDialog(_('No account available'), - _('You must create an account before you can chat with other contacts.') - ).get_response() + _('You must create an account before you can chat with other contacts.')) self.update_status_combobox() return status = model[active][2].decode('utf-8') @@ -2177,7 +2188,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid) invisible_show = gajim.SHOW_LIST.index('invisible') if gajim.connections[account].connected == invisible_show: dialogs.ErrorDialog(_('You cannot join a room while you are invisible') - ).get_response() + ) return if gajim.interface.instances[account].has_key('join_gc'): gajim.interface.instances[account]['join_gc'].window.present() diff --git a/src/vcard.py b/src/vcard.py index d877acd1f0bca878341ed97a0fac1313d8714701..f680436359ea8ff3db743dfadc8670b3cb517dfb 100644 --- a/src/vcard.py +++ b/src/vcard.py @@ -229,8 +229,7 @@ class VcardWindow: scaled_pixbuf = gtkgui_helpers.get_scaled_pixbuf(pixbuf, 'notification') except gobject.GError, msg: # unknown format - dialogs.ErrorDialog(_('Could not load image'), - msg).get_response() + dialogs.ErrorDialog(_('Could not load image'), msg) continue else: path_to_file = os.path.join(gajim.TMP, 'avatar_scaled.png') @@ -481,7 +480,7 @@ class VcardWindow: if gajim.connections[self.account].connected < 2: dialogs.ErrorDialog(_('You are not connected to the server'), _('Without a connection you can not publish your contact ' - 'information.')).get_response() + 'information.')) return vcard = self.make_vcard() nick = '' @@ -509,7 +508,7 @@ class VcardWindow: gajim.connections[self.account].request_vcard(self.jid) else: dialogs.ErrorDialog(_('You are not connected to the server'), - _('Without a connection, you can not get your contact information.')).get_response() + _('Without a connection, you can not get your contact information.')) def change_to_vcard(self): self.xml.get_widget('information_notebook').remove_page(0)