use a dialog to rename a contact or a group. fixes #2200

This commit is contained in:
Yann Leboulanger 2006-11-18 20:51:50 +00:00
parent 0e1a0c66ee
commit 4fdd526a06
3 changed files with 86 additions and 126 deletions

View File

@ -17,7 +17,9 @@
<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">

View File

@ -1002,7 +1002,7 @@ class FTOverwriteConfirmationDialog(ConfirmationDialog):
class InputDialog:
'''Class for Input dialog'''
def __init__(self, title, label_str, input_str = None, is_modal = True,
ok_handler = None):
ok_handler = None, cancel_handler = None):
# if modal is True you also need to call get_response()
# and ok_handler won't be used
self.xml = gtkgui_helpers.get_glade('input_dialog.glade')
@ -1011,6 +1011,7 @@ ok_handler = None):
self.input_entry = self.xml.get_widget('input_entry')
self.dialog.set_title(title)
label.set_markup(label_str)
self.cancel_handler = cancel_handler
if input_str:
self.input_entry.set_text(input_str)
self.input_entry.select_region(0, -1) # select all
@ -1022,14 +1023,22 @@ ok_handler = None):
okbutton.connect('clicked', self.on_okbutton_clicked)
cancelbutton = self.xml.get_widget('cancelbutton')
cancelbutton.connect('clicked', self.on_cancelbutton_clicked)
self.xml.signal_autoconnect(self)
self.dialog.show_all()
def on_okbutton_clicked(self, widget):
def on_input_dialog_destroy(self, widget):
if self.cancel_handler:
self.cancel_handler()
def on_okbutton_clicked(self, widget):
user_input = self.input_entry.get_text().decode('utf-8')
self.dialog.destroy()
self.ok_handler(user_input)
if isinstance(self.ok_handler, tuple):
self.ok_handler[0](user_input, *self.ok_handler[1:])
else:
self.ok_handler(user_input)
def on_cancelbutton_clicked(self, widget):
def on_cancelbutton_clicked(self, widget):
self.dialog.destroy()
def get_response(self):

View File

@ -54,9 +54,8 @@ C_NAME, # cellrenderer text that holds contact nickame
C_TYPE, # account, group or contact?
C_JID, # the jid of the row
C_ACCOUNT, # cellrenderer text that holds account name
C_EDITABLE, # cellrenderer text that holds name editable or not?
C_SECPIXBUF, # secondary_pixbuf (holds avatar or padlock)
) = range(7)
) = range(6)
class RosterWindow:
'''Class for main window of the GTK+ interface'''
@ -165,7 +164,7 @@ class RosterWindow:
if self.regroup:
show = helpers.get_global_show()
model.append(None, [self.jabber_state_images['16'][show],
_('Merged accounts'), 'account', '', 'all', False, None])
_('Merged accounts'), 'account', '', 'all', None])
self.draw_account(account)
return
@ -180,7 +179,7 @@ class RosterWindow:
model.append(None, [self.jabber_state_images['16'][show],
gtkgui_helpers.escape_for_pango_markup(account),
'account', our_jid, account, False, tls_pixbuf])
'account', our_jid, account, tls_pixbuf])
def draw_account(self, account):
model = self.tree.get_model()
@ -313,8 +312,7 @@ class RosterWindow:
name = contact.get_shown_name()
for i in parent_iters:
# we add some values here. see draw_contact for more
model.append(i, (None, name, 'contact', jid, account,
False, None))
model.append(i, (None, name, 'contact', jid, account, None))
self.draw_contact(jid, account)
self.draw_avatar(jid, account)
# Redraw parent to change icon
@ -347,7 +345,7 @@ class RosterWindow:
iterG = model.append(IterAcct, [
self.jabber_state_images['16']['closed'],
gtkgui_helpers.escape_for_pango_markup(group), 'group',
group, account, False, None])
group, account, None])
self.draw_group(group, account)
if model.iter_n_children(IterAcct) == 1: # We added the first one
self.draw_account(account)
@ -366,8 +364,7 @@ class RosterWindow:
name = contact.get_shown_name()
# we add some values here. see draw_contact for more
model.append(iterG, (None, name, typestr, contact.jid, account,
False, None))
model.append(iterG, (None, name, typestr, contact.jid, account, None))
if gajim.groups[account][group]['expand']:
self.tree.expand_row(model.get_path(iterG), False)
@ -437,7 +434,7 @@ class RosterWindow:
model = self.tree.get_model()
iterAcct = self.get_account_iter(account)
model.append(iterAcct, (None, gajim.nicks[account], 'self_contact', jid,
account, False, None))
account, None))
self.draw_contact(jid, account)
self.draw_avatar(jid, account)
@ -1397,12 +1394,9 @@ class RosterWindow:
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
# we then select Rename and focus-in
# focus-in callback checks on this var and if is NOT None
# it redraws the selected contact resulting in stopping our rename
# procedure. So set this to None to stop that
self._last_selected_contact = []
if gajim.interface.instances.has_key('rename'):
gajim.interface.instances['rename'].dialog.window.present()
return
model = self.tree.get_model()
row_type = model[iter][C_TYPE]
@ -1413,16 +1407,66 @@ class RosterWindow:
return
if row_type in ('contact', 'agent'):
# it's jid
# Remove possible resource indicator (Name (2))
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
name = contact.name
model[iter][C_NAME] = gtkgui_helpers.escape_for_pango_markup(name)
title = _('Rename Contact')
message = _('Enter a new nickname for contact %s') % jid
old_text = gajim.contacts.get_contact_with_highest_priority(account,
jid).name
elif row_type == 'group':
if jid in helpers.special_groups + (_('General'),):
return
old_text = model[iter][C_JID].decode('utf-8')
title = _('Rename Group')
message = _('Enter a new name for group %s') % old_text
model[iter][C_EDITABLE] = True # set 'editable' to True
self.tree.set_cursor(path, self.tree.get_column(0), True)
def on_renamed(new_text, account, row_type, jid, old_text):
if gajim.interface.instances.has_key('rename'):
del gajim.interface.instances['rename']
if row_type in ('contact', 'agent'):
if old_text == new_text:
return
for u in gajim.contacts.get_contact(account, jid):
u.name = new_text
gajim.connections[account].update_contact(jid, new_text, u.groups)
self.draw_contact(jid, account)
# Update opened chat
ctrl = gajim.interface.msg_win_mgr.get_control(jid, account)
if ctrl:
ctrl.update_ui()
win = gajim.interface.msg_win_mgr.get_window(jid, account)
win.redraw_tab(ctrl)
win.show_title()
elif row_type == 'group':
# in C_JID column, we hold the group name (which is not escaped)
if old_text == new_text:
return
# Groups may not change name from or to a special groups
for g in helpers.special_groups:
if g in (new_text, old_text):
return
# get all contacts in that group
for jid in gajim.contacts.get_jid_list(account):
contact = gajim.contacts.get_contact_with_highest_priority(
account, jid)
if old_text in contact.groups:
# set them in the new one and remove it from the old
contact.groups.remove(old_text)
self.remove_contact(contact, account)
if new_text not in contact.groups:
contact.groups.append(new_text)
self.add_contact_to_roster(contact.jid, account)
gajim.connections[account].update_contact(contact.jid,
contact.name, contact.groups)
# If last removed iter was not visible, gajim.groups is not cleaned
if gajim.groups[account].has_key(old_text):
del gajim.groups[account][old_text]
def on_canceled():
if gajim.interface.instances.has_key('rename'):
del gajim.interface.instances['rename']
gajim.interface.instances['rename'] = dialogs.InputDialog(title, message,
old_text, False, (on_renamed, account, row_type, jid, old_text),
on_canceled)
def on_remove_group_item_activated(self, widget, group, account):
dlg = dialogs.ConfirmationDialogCheck(_('Remove Group'),
@ -2327,12 +2371,10 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
if len(list_of_paths) != 1:
return
path = list_of_paths[0]
type = model[path][C_TYPE]
if type in ('contact', 'group', 'agent'):
if not model[path][C_EDITABLE]:
# we are NOT already renaming it
iter = model.get_iter(path)
self.on_rename(widget, iter, path)
type_ = model[path][C_TYPE]
if type_ in ('contact', 'group', 'agent'):
iter = model.get_iter(path)
self.on_rename(widget, iter, path)
elif event.keyval == gtk.keysyms.Delete:
treeselection = self.tree.get_selection()
@ -3377,91 +3419,6 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
account = model[iter][C_ACCOUNT].decode('utf-8')
self.draw_contact(jid, account)
def on_editing_started(self, cell, event, row):
''' start editing a cell in the tree'''
path = self.tree.get_cursor()[0]
self.editing_path = path
def on_editing_canceled(self, cell):
'''editing has been canceled'''
path = self.tree.get_cursor()[0]
# do not set new name if row order has changed
if path != self.editing_path:
self.editing_path = None
return
self.editing_path = None
model = self.tree.get_model()
iter = model.get_iter(path)
account = model[iter][C_ACCOUNT].decode('utf-8')
jid = model[iter][C_JID].decode('utf-8')
type = model[iter][C_TYPE]
# restore the number of resources string at the end of contact name
contacts = gajim.contacts.get_contact(account, jid)
if type in ('contact', 'agent'):
self.draw_contact(jid, account)
# reset editable to False
model[iter][C_EDITABLE] = False
def on_cell_edited(self, cell, row, new_text):
'''When an iter is edited:
if text has changed, rename the contact'''
model = self.tree.get_model()
# if this is a last item in the group, row is invalid
try:
iter = model.get_iter_from_string(row)
except:
self.editing_path = None
return
path = model.get_path(iter)
# do not set new name if row order has changed
if path != self.editing_path:
self.editing_path = None
return
self.editing_path = None
new_text = new_text.decode('utf-8')
account = model[iter][C_ACCOUNT].decode('utf-8')
jid = model[iter][C_JID].decode('utf-8')
type = model[iter][C_TYPE]
model[iter][C_EDITABLE] = False
if type in ('contact', 'agent'):
old_text = gajim.contacts.get_contact_with_highest_priority(account,
jid).name
if old_text != new_text:
for u in gajim.contacts.get_contact(account, jid):
u.name = new_text
gajim.connections[account].update_contact(jid, new_text, u.groups)
self.draw_contact(jid, account)
# Update opened chat
ctrl = gajim.interface.msg_win_mgr.get_control(jid, account)
if ctrl:
ctrl.update_ui()
win = gajim.interface.msg_win_mgr.get_window(jid, account)
win.redraw_tab(ctrl)
win.show_title()
elif type == 'group':
# in C_JID column, we hold the group name (which is not escaped)
old_name = model[iter][C_JID].decode('utf-8')
# Groups may not change name from or to a special groups
for g in helpers.special_groups:
if g in (new_text, old_name):
return
# get all contacts in that group
for jid in gajim.contacts.get_jid_list(account):
contact = gajim.contacts.get_contact_with_highest_priority(account,
jid)
if old_name in contact.groups:
# set them in the new one and remove it from the old
contact.groups.remove(old_name)
self.remove_contact(contact, account)
if not new_text in contact.groups:
contact.groups.append(new_text)
self.add_contact_to_roster(contact.jid, account)
gajim.connections[account].update_contact(contact.jid,
contact.name, contact.groups)
# If last removed iter was not visible, gajim.groups is not cleaned
if gajim.groups[account].has_key(old_name):
del gajim.groups[account][old_name]
def on_service_disco_menuitem_activate(self, widget, account):
server_jid = gajim.config.get_per('accounts', account, 'hostname')
if gajim.interface.instances[account]['disco'].has_key(server_jid):
@ -4128,10 +4085,6 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
def _on_treeview_selection_changed(self, selection):
model, list_of_paths = selection.get_selected_rows()
if len(list_of_paths) == 1 and model[list_of_paths[0]][C_EDITABLE]:
# We are editing this row, do not modify self._last_selected_contact
# Cause that cancel editing
return
if len(self._last_selected_contact):
# update unselected rows
for (jid, account) in self._last_selected_contact:
@ -4200,7 +4153,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
self.gpg_passphrase = {}
#(icon, name, type, jid, account, editable, secondary_pixbuf)
model = gtk.TreeStore(gtk.Image, str, str, str, str, bool, gtk.gdk.Pixbuf)
model = gtk.TreeStore(gtk.Image, str, str, str, str, gtk.gdk.Pixbuf)
model.set_sort_func(1, self.compareIters)
model.set_sort_column_id(1, gtk.SORT_ASCENDING)
@ -4297,12 +4250,8 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
col.set_cell_data_func(render_image, self.iconCellDataFunc, None)
render_text = gtk.CellRendererText() # contact or group or account name
render_text.connect('edited', self.on_cell_edited)
render_text.connect('editing-canceled', self.on_editing_canceled)
render_text.connect('editing-started', self.on_editing_started)
col.pack_start(render_text, expand = True)
col.add_attribute(render_text, 'markup', C_NAME) # where we hold the name
col.add_attribute(render_text, 'editable', C_EDITABLE) # where we hold if the row is editable
col.set_cell_data_func(render_text, self.nameCellDataFunc, None)
render_pixbuf = gtk.CellRendererPixbuf() # tls or avatar img