diff --git a/data/glade/input_dialog.glade b/data/glade/input_dialog.glade index 12912060c..c71dd4337 100644 --- a/data/glade/input_dialog.glade +++ b/data/glade/input_dialog.glade @@ -1,160 +1,113 @@ - - - + - - - 6 - - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - True - False - False - - - - - True - False - 6 - - - - True - GTK_BUTTONBOX_END - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - -6 - - - - - - True - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - -5 - - - - - 0 - False - True - GTK_PACK_END - - - - - - 6 - True - False - 6 - - - - True - False - 12 - - - - True - gtk-dialog-question - 6 - 0.5 - 0.5 - 0 - 0 - - - 0 - False - True - - - - - - True - - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - True - True - - - - - 0 - False - True - - - - - - True - True - True - True - 0 - - True - True - - - 0 - False - False - - - - - 0 - True - True - - - - - - + + + + 6 + dialog + False + + + + True + 6 + + + True + 6 + 6 + + + True + 12 + + + True + gtk-dialog-question + 6 + + + False + 0 + + + + + True + True + + + 1 + + + + + False + 0 + + + + + True + True + True + + + False + False + 1 + + + + + 1 + + + + + True + end + + + gtk-cancel + -6 + True + True + True + False + True + + + False + False + 0 + + + + + gtk-ok + -5 + True + True + True + True + False + True + + + False + False + 1 + + + + + False + end + 0 + + + + + diff --git a/src/common/gajim.py b/src/common/gajim.py index 3e3c2a5a5..9a2ff9528 100644 --- a/src/common/gajim.py +++ b/src/common/gajim.py @@ -113,6 +113,7 @@ contacts = Contacts() gc_connected = {} # tell if we are connected to the room or not {acct: {room_jid: True}} gc_passwords = {} # list of the pass required to enter a room {room_jid: password} automatic_rooms = {} # list of rooms that must be automaticaly configured and for which we have a list of invities {account: {room_jid: {'invities': []}}} +new_room_nick = None # if it's != None, use this nick instead of asking for a new nickname when there is a conflict. groups = {} # list of groups newly_added = {} # list of contacts that has just signed in diff --git a/src/dialogs.py b/src/dialogs.py index 8358b4a78..72f8cb56c 100644 --- a/src/dialogs.py +++ b/src/dialogs.py @@ -1580,6 +1580,7 @@ class CommonInputDialog: self.dialog.set_title(title) label.set_markup(label_str) self.cancel_handler = cancel_handler + self.vbox = self.xml.get_widget('vbox') self.ok_handler = ok_handler okbutton = self.xml.get_widget('okbutton') @@ -1589,7 +1590,7 @@ class CommonInputDialog: self.xml.signal_autoconnect(self) self.dialog.show_all() - def on_input_dialog_destroy(self, widget): + def on_input_dialog_delete_event(self, widget, event): if self.cancel_handler: self.cancel_handler() @@ -1610,18 +1611,142 @@ class CommonInputDialog: class InputDialog(CommonInputDialog): '''Class for Input dialog''' def __init__(self, title, label_str, input_str=None, is_modal=True, - ok_handler=None, cancel_handler=None): + ok_handler=None, cancel_handler=None): self.xml = gtkgui_helpers.get_glade('input_dialog.glade') CommonInputDialog.__init__(self, title, label_str, is_modal, ok_handler, - cancel_handler) + cancel_handler) + self.input_entry = self.xml.get_widget('input_entry') + if input_str: + self.set_entry(input_str) + + def set_entry(self, value): + self.input_entry.set_text(value) + self.input_entry.select_region(0, -1) # select all + + def get_text(self): + return self.input_entry.get_text().decode('utf-8') + +class InputDialogCheck(InputDialog): + '''Class for Input dialog''' + def __init__(self, title, label_str, checktext='', input_str=None, + is_modal=True, ok_handler=None, cancel_handler=None): + self.xml = gtkgui_helpers.get_glade('input_dialog.glade') + InputDialog.__init__(self, title, label_str, input_str=input_str, + is_modal=is_modal, ok_handler=ok_handler, + cancel_handler=cancel_handler) self.input_entry = self.xml.get_widget('input_entry') if input_str: self.input_entry.set_text(input_str) self.input_entry.select_region(0, -1) # select all + self.checkbutton = gtk.CheckButton(checktext) + self.vbox.pack_start(self.checkbutton, expand=False, fill=True) + self.checkbutton.show() + + def on_okbutton_clicked(self, widget): + user_input = self.get_text() + if user_input: + user_input = user_input.decode('utf-8') + self.cancel_handler = None + self.dialog.destroy() + if isinstance(self.ok_handler, tuple): + self.ok_handler[0](user_input, self.is_checked(), *self.ok_handler[1:]) + else: + self.ok_handler(user_input, self.is_checked()) + def get_text(self): return self.input_entry.get_text().decode('utf-8') + def is_checked(self): + ''' Get active state of the checkbutton ''' + return self.checkbutton.get_active() + +class ChangeNickDialog(InputDialogCheck): + '''Class for changing room nickname in case of conflict''' + def __init__(self, account, room_jid): + title = _('Unable to join group chat') + check_text = _('Always use this nickname when there is a conflict') + InputDialogCheck.__init__(self, title, '', checktext=check_text, + input_str='', is_modal=True, ok_handler=None, cancel_handler=None) + self.room_queue = [(account, room_jid)] + self.check_next() + + def on_input_dialog_delete_event(self, widget, event): + self.on_cancelbutton_clicked(widget) + return True + + def setup_dialog(self): + self.gc_control = gajim.interface.msg_win_mgr.get_gc_control( + self.room_jid, self.account) + if not self.gc_control and \ + self.room_jid in gajim.interface.minimized_controls[self.account]: + self.gc_control = \ + gajim.interface.minimized_controls[self.account][self.room_jid] + if not self.gc_control: + self.check_next() + return + label = self.xml.get_widget('label') + prompt = _('Your desired nickname in group chat %s is in use or ' + 'registered by another occupant.\nPlease specify another nickname ' + 'below:') % self.room_jid + label.set_markup(prompt) + self.set_entry(self.gc_control.nick + \ + gajim.config.get('gc_proposed_nick_char')) + + def check_next(self): + if len(self.room_queue) == 0: + self.cancel_handler = None + self.dialog.destroy() + del gajim.interface.instances['change_nick_dialog'] + return + self.account, self.room_jid = self.room_queue.pop(0) + self.setup_dialog() + + if gajim.new_room_nick is not None and not gajim.gc_connected[ + self.account][self.room_jid] and self.gc_control.nick != \ + gajim.new_room_nick: + self.dialog.hide() + self.on_ok(gajim.new_room_nick, True) + else: + self.dialog.show() + + def on_okbutton_clicked(self, widget): + nick = self.get_text() + if nick: + nick = nick.decode('utf-8') + # send presence to room + try: + nick = helpers.parse_resource(nick) + except Exception: + # invalid char + dialogs.ErrorDialog(_('Invalid nickname'), + _('The nickname has not allowed characters.')) + return + self.on_ok(nick, self.is_checked()) + + def on_ok(self, nick, is_checked): + if is_checked: + gajim.new_room_nick = nick + gajim.connections[self.account].join_gc(nick, self.room_jid, None, + change_nick=True) + if gajim.gc_connected[self.account][self.room_jid]: + # We are changing nick, we will change self.nick when we receive + # presence that inform that it works + self.gc_control.new_nick = nick + else: + # We are connecting, we will not get a changed nick presence so + # change it NOW. We don't already have a nick so it's harmless + self.gc_control.nick = nick + self.check_next() + + def on_cancelbutton_clicked(self, widget): + self.gc_control.new_nick = '' + self.check_next() + + def add_room(self, account, room_jid): + if (account, room_jid) not in self.room_queue: + self.room_queue.append((account, room_jid)) + class InputTextDialog(CommonInputDialog): '''Class for multilines Input dialog (more place than InputDialog)''' def __init__(self, title, label_str, input_str=None, is_modal=True, diff --git a/src/gajim.py b/src/gajim.py index 8f1fd9daf..4c1ffc55b 100644 --- a/src/gajim.py +++ b/src/gajim.py @@ -506,16 +506,11 @@ class Interface: def handle_event_ask_new_nick(self, account, data): #('ASK_NEW_NICK', account, (room_jid,)) room_jid = data[0] - gc_control = self.msg_win_mgr.get_gc_control(room_jid, account) - if not gc_control and \ - room_jid in self.minimized_controls[account]: - gc_control = self.minimized_controls[account][room_jid] - if gc_control: # user may close the window before we are here - title = _('Unable to join group chat') - prompt = _('Your desired nickname in group chat %s is in use or ' - 'registered by another occupant.\nPlease specify another nickname ' - 'below:') % room_jid - gc_control.show_change_nick_input_dialog(title, prompt) + if 'change_nick_dialog' in self.instances: + self.instances['change_nick_dialog'].add_room(account, room_jid) + else: + self.instances['change_nick_dialog'] = dialogs.ChangeNickDialog( + account, room_jid) def handle_event_http_auth(self, account, data): #('HTTP_AUTH', account, (method, url, transaction_id, iq_obj, msg)) diff --git a/src/groupchat_control.py b/src/groupchat_control.py index 6d88a2b1c..aabbad838 100644 --- a/src/groupchat_control.py +++ b/src/groupchat_control.py @@ -181,7 +181,6 @@ class GroupchatControl(ChatControlBase): self.is_continued=is_continued self.is_anonymous = True - self.change_nick_dialog = None self.actions_button = self.xml.get_widget('muc_window_actions_button') id_ = self.actions_button.connect('clicked', @@ -1787,39 +1786,6 @@ class GroupchatControl(ChatControlBase): else: return 'visitor' - def show_change_nick_input_dialog(self, title, prompt): - '''asks user for new nick and on ok it sets it on room''' - if self.change_nick_dialog: - # A dialog is already opened - return - def on_ok(widget): - nick = self.change_nick_dialog.input_entry.get_text().decode('utf-8') - self.change_nick_dialog = None - try: - nick = helpers.parse_resource(nick) - except Exception: - # invalid char - dialogs.ErrorDialog(_('Invalid nickname'), - _('The nickname has not allowed characters.')) - return - gajim.connections[self.account].join_gc(nick, self.room_jid, None, - change_nick=True) - if gajim.gc_connected[self.account][self.room_jid]: - # We are changing nick, we will change self.nick when we receive - # presence that inform that it works - self.new_nick = nick - else: - # We are connecting, we will not get a changed nick presence so - # change it NOW. We don't already have a nick so it's harmless - self.nick = nick - def on_cancel(): - self.change_nick_dialog = None - self.new_nick = '' - proposed_nick = self.nick + gajim.config.get('gc_proposed_nick_char') - self.change_nick_dialog = dialogs.InputDialog(title, prompt, - proposed_nick, is_modal=False, ok_handler=on_ok, - cancel_handler=on_cancel) - def minimizable(self): if self.contact.jid in gajim.config.get_per('accounts', self.account, 'minimized_gc').split(' '):