Mercurial > libervia-web
diff src/browser/sat_browser/contact_group.py @ 600:32dbbc941123 frontends_multi_profiles
browser_side: fixes the contact group manager
author | souliane <souliane@mailoo.org> |
---|---|
date | Fri, 06 Feb 2015 17:53:01 +0100 |
parents | a5019e62c3e9 |
children | e0021d571eef |
line wrap: on
line diff
--- a/src/browser/sat_browser/contact_group.py Fri Feb 06 19:31:30 2015 +0100 +++ b/src/browser/sat_browser/contact_group.py Fri Feb 06 17:53:01 2015 +0100 @@ -31,11 +31,24 @@ import contact_list +unicode = str # FIXME: pyjamas workaround + + class ContactGroupManager(list_manager.ListManager): - """A manager for sub-panels to assign contacts to each group.""" - def __init__(self, parent, keys_dict, contacts, offsets, style): - list_manager.ListManager.__init__(self, parent, keys_dict, contacts, offsets, style) + def __init__(self, container, keys, contacts, offsets, style): + """ + @param container (FlexTable): FlexTable parent widget + @param keys (dict{unicode: dict{unicode: unicode}}): dict binding items + keys to their display config data. + @param contacts (list): list of contacts + @param offsets (dict): define widgets positions offsets within container: + - "x_first": the x offset for the first widget's row on the grid + - "x": the x offset for all widgets rows, except the first one if "x_first" is defined + - "y": the y offset for all widgets columns on the grid + @param style (dict): define CSS styles + """ + list_manager.ListManager.__init__(self, container, keys, contacts, offsets, style) self.registerPopupMenuPanel(entries={"Remove group": {}}, callback=lambda sender, key: Timer(5, lambda timer: self.removeContactKey(sender, key))) @@ -44,43 +57,51 @@ def confirm_cb(answer): if answer: - list_manager.ListManager.removeContactKey(self, key) - self._parent.removeKeyFromAddGroupPanel(key) + list_manager.ListManager.removeItemKey(self, key) + self.container.removeKeyFromAddGroupPanel(key) _dialog = dialog.ConfirmDialog(confirm_cb, text="Do you really want to delete the group '%s'?" % key) _dialog.show() def removeFromRemainingList(self, contacts): list_manager.ListManager.removeFromRemainingList(self, contacts) - self._parent.updateContactList(contacts=contacts) + self.container.updateContactList(contacts) def addToRemainingList(self, contacts, ignore_key=None): list_manager.ListManager.addToRemainingList(self, contacts, ignore_key) - self._parent.updateContactList(contacts=contacts) + self.container.updateContactList(contacts) class ContactGroupEditor(DockPanel): - """Panel for the contact groups manager.""" + """A big panel including a ContactGroupManager and other UI stuff.""" + + def __init__(self, host, container=None, onCloseCallback=None): + """ - def __init__(self, host, parent=None, onCloseCallback=None): + @param host (SatWebFrontend) + @param container (PanelBase): parent panel or None to display in a popup + @param onCloseCallback (callable) + """ DockPanel.__init__(self) self.host = host # eventually display in a popup - if parent is None: - parent = DialogBox(autoHide=False, centered=True) - parent.setHTML("Manage contact groups") - self._parent = parent + if container is None: + container = DialogBox(autoHide=False, centered=True) + container.setHTML("Manage contact groups") + self.container = container self._on_close_callback = onCloseCallback - self.all_contacts = self.host.contact_panel.getContacts() - groups_list = self.host.contact_panel.groups.keys() - groups_list.sort() + self.all_contacts = contact_list.JIDList(self.host.contact_list.roster_entities) + roster_entities_by_group = self.host.contact_list.roster_entities_by_group + del roster_entities_by_group[None] # remove the empty group + roster_groups = roster_entities_by_group.keys() + roster_groups.sort() - self.add_group_panel = self.getAddGroupPanel(groups_list) - south_panel = self.getCloseSaveButtons() - center_panel = self.getContactGroupManager(groups_list) - east_panel = self.getContactList() + self.add_group_panel = self.initAddGroupPanel(roster_groups) + south_panel = self.initCloseSaveButtons() + center_panel = self.initContactGroupManager(roster_groups) + east_panel = self.initContactList() self.add(self.add_group_panel, DockPanel.CENTER) self.add(east_panel, DockPanel.EAST) @@ -97,108 +118,123 @@ self.setCellHorizontalAlignment(south_panel, HasAlignment.ALIGN_CENTER) # need to be done after the contact list has been initialized - self.groups.setContacts(self.host.contact_panel.groups) + self.groups.resetItems(roster_entities_by_group) self.toggleContacts(showAll=True) # Hide the contacts list from the main panel to not confuse the user self.restore_contact_panel = False - if self.host.contact_panel.getVisible(): + clist = self.host.contact_list + if clist.getVisible(): self.restore_contact_panel = True self.host.panel._contactsSwitch() - parent.add(self) - parent.setVisible(True) - if isinstance(parent, DialogBox): - parent.center() + container.add(self) + container.setVisible(True) + if isinstance(container, DialogBox): + container.center() - def getContactGroupManager(self, groups_list): - """Set the list manager for the groups""" - flex_table = FlexTable(len(groups_list), 2) + def initContactGroupManager(self, groups): + """Initialise the contact group manager. + + @param groups (list[unicode]): contact groups + """ + flex_table = FlexTable() flex_table.addStyleName('contactGroupEditor') + # overwrite the default style which has been set for rich text editor - style = { - "keyItem": "group", - "popupMenuItem": "popupMenuItem", - "removeButton": "contactGroupRemoveButton", - "buttonCell": "contactGroupButtonCell", - "keyPanel": "contactGroupPanel" - } - self.groups = ContactGroupManager(flex_table, groups_list, self.all_contacts, style=style) - self.groups.createWidgets() # widgets are automatically added to FlexTable + style = {"keyItem": "group", + "popupMenuItem": "popupMenuItem", + "removeButton": "contactGroupRemoveButton", + "buttonCell": "contactGroupButtonCell", + "keyPanel": "contactGroupPanel" + } + + groups = {group: {} for group in groups} + self.groups = ContactGroupManager(flex_table, groups, self.all_contacts, style=style) + self.groups.createWidgets() # widgets are automatically added to the FlexTable + # FIXME: clean that part which is dangerous flex_table.updateContactList = self.updateContactList flex_table.removeKeyFromAddGroupPanel = self.add_group_panel.groups.remove + return flex_table - def getAddGroupPanel(self, groups_list): - """Add the 'Add group' panel to the FlexTable""" + def initAddGroupPanel(self, groups): + """Initialise the 'Add group' panel. - def add_group_cb(text): - self.groups.addContactKey(text) + @param groups (list[unicode]): contact groups + """ + + def add_group_cb(key): + self.groups.addItemKey(key) self.add_group_panel.textbox.setFocus(True) - add_group_panel = dialog.AddGroupPanel(groups_list, add_group_cb) + add_group_panel = dialog.AddGroupPanel(groups, add_group_cb) add_group_panel.addStyleName("addContactGroupPanel") return add_group_panel - def getCloseSaveButtons(self): - """Add the buttons to close the dialog / save the groups""" + def initCloseSaveButtons(self): + """Add the buttons to close the dialog and save the groups.""" buttons = HorizontalPanel() buttons.addStyleName("marginAuto") buttons.add(Button("Save", listener=self.closeAndSave)) buttons.add(Button("Cancel", listener=self.cancelWithoutSaving)) return buttons - def getContactList(self): - """Add the contact list to the DockPanel""" + def initContactList(self): + """Add the contact list to the DockPanel.""" self.toggle = Button("", self.toggleContacts) self.toggle.addStyleName("toggleAssignedContacts") - self.contacts = contact_list.BaseContactPanel(self.host) - for contact_ in self.all_contacts: - self.contacts.add(contact_) + self.contacts = contact_list.BaseContactsPanel(self.host) + for contact in self.all_contacts: + self.contacts.add(contact) contact_panel = VerticalPanel() contact_panel.add(self.toggle) contact_panel.add(self.contacts) return contact_panel def toggleContacts(self, sender=None, showAll=None): - """Callback for the toggle button""" - if sender is None: - sender = self.toggle - sender.showAll = showAll if showAll is not None else not sender.showAll - if sender.showAll: - sender.setText("Hide assigned") - else: - sender.setText("Show assigned") - self.updateContactList(sender) + """Toggle the button to show contacts and the contact list. - def updateContactList(self, sender=None, contacts=None): - """Update the contact list regarding the toggle button""" + @param sender (Button) + @param showAll (bool): if set, initialise with True to show all contacts + or with False to show only the ones that are not assigned yet. + """ + self.toggle.showAll = (not self.toggle.showAll) if showAll is None else showAll + self.toggle.setText("Hide assigned" if self.toggle.showAll else "Show assigned") + self.updateContactList() + + def updateContactList(self, contacts=None): + """Update the contact list's items visibility, depending of the toggle + button and the "contacts" attribute. + + @param contacts (list): contacts to be updated, or None to update all. + """ if not hasattr(self, "toggle") or not hasattr(self.toggle, "showAll"): return - sender = self.toggle if contacts is not None: - if not isinstance(contacts, list): - contacts = [contacts] - for contact_ in contacts: - if contact_ not in self.all_contacts: - contacts.remove(contact_) + to_remove = set() + for contact in contacts: + if contact not in self.all_contacts: + to_remove.add(contact) + for contact in to_remove: + contacts.remove(contact) else: contacts = self.all_contacts - for contact_ in contacts: - if sender.showAll: - self.contacts.getContactBox(contact_).setVisible(True) + for contact in contacts: + if self.toggle.showAll: + self.contacts.getContactBox(contact).setVisible(True) else: - if contact_ in self.groups.remaining_list: - self.contacts.getContactBox(contact_).setVisible(True) + if contact in self.groups.items_remaining: + self.contacts.getContactBox(contact).setVisible(True) else: - self.contacts.getContactBox(contact_).setVisible(False) + self.contacts.getContactBox(contact).setVisible(False) def __close(self): """Remove the widget from parent or close the popup.""" - if isinstance(self._parent, DialogBox): - self._parent.hide() - self._parent.remove(self) + if isinstance(self.container, DialogBox): + self.container.hide() + self.container.remove(self) if self._on_close_callback is not None: self._on_close_callback() if self.restore_contact_panel: @@ -215,22 +251,21 @@ def closeAndSave(self): """Call bridge methods to save the changes and close the dialog""" - map_ = {} - for contact_ in self.all_contacts: - map_[contact_] = set() - contacts = self.groups.getContacts() - for group in contacts.keys(): - for contact_ in contacts[group]: - try: - map_[contact_].add(group) - except KeyError: - dialog.InfoDialog("Invalid contact", - "The contact '%s' is not your contact list but it has been assigned to the group '%s'." % (contact_, group) + - "Your changes could not be saved: please check your assignments and save again.", Width="400px").center() - return - for contact_ in map_.keys(): - groups = map_[contact_] - current_groups = self.host.contact_panel.getContactGroups(contact_) - if groups != current_groups: - self.host.bridge.call('updateContact', None, contact_, '', list(groups)) + old_groups_by_entity = contact_list.JIDDict(self.host.contact_list.roster_groups_by_entity) + old_entities = old_groups_by_entity.keys() + groups_by_entity = contact_list.JIDDict(self.groups.getKeysByItem()) + entities = groups_by_entity.keys() + + for invalid in entities.difference(self.all_contacts): + dialog.InfoDialog("Invalid contact(s)", + "The contact '%s' is not in your contact list but has been assigned to: '%s'." % (invalid, "', '".join(groups_by_entity[invalid])) + + "Your changes could not be saved: please check your assignments and save again.", Width="400px").center() + return + + for entity in old_entities.difference(entities): + self.host.bridge.call('updateContact', None, unicode(entity), '', []) + + for entity, groups in groups_by_entity.iteritems(): + if entity not in old_groups_by_entity or groups != old_groups_by_entity[entity]: + self.host.bridge.call('updateContact', None, unicode(entity), '', list(groups)) self.__close()