* ask only once at a time to change our nickname in a room in case of conflict
* add a checkbutton to use the entered nickname by default without asking anymore. Fixes #5141
This commit is contained in:
parent
425ae28713
commit
235c4d9ab8
|
@ -1,160 +1,113 @@
|
|||
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||
|
||||
<?xml version="1.0"?>
|
||||
<glade-interface>
|
||||
|
||||
<widget class="GtkDialog" id="input_dialog">
|
||||
<property name="border_width">6</property>
|
||||
<property name="title" translatable="yes"></property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<property name="has_separator">False</property>
|
||||
<signal name="destroy" handler="on_input_dialog_destroy" last_modification_time="Sat, 18 Nov 2006 20:23:21 GMT"/>
|
||||
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox10">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">6</property>
|
||||
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area9">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="cancelbutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-6</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="okbutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-5</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox76">
|
||||
<property name="border_width">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">6</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox2960">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">12</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkImage" id="image507">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-dialog-question</property>
|
||||
<property name="icon_size">6</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkEntry" id="input_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">True</property>
|
||||
<property name="visibility">True</property>
|
||||
<property name="max_length">0</property>
|
||||
<property name="text" translatable="yes"></property>
|
||||
<property name="has_frame">True</property>
|
||||
<property name="activates_default">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<!-- interface-requires gtk+ 2.12 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkDialog" id="input_dialog">
|
||||
<property name="border_width">6</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="has_separator">False</property>
|
||||
<signal name="delete_event" handler="on_input_dialog_delete_event"/>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox10">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">6</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox2960">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image507">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-dialog-question</property>
|
||||
<property name="icon-size">6</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label">
|
||||
<property name="visible">True</property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="input_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="activates_default">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area9">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="cancelbutton">
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="response_id">-6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="okbutton">
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="response_id">-5</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
||||
|
|
|
@ -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
|
||||
|
|
131
src/dialogs.py
131
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,
|
||||
|
|
15
src/gajim.py
15
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))
|
||||
|
|
|
@ -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(' '):
|
||||
|
|
Loading…
Reference in New Issue