diff src/browser/sat_browser/contact_group.py @ 736:fe3c2357a8c9

fixes/improve ListManager and contact group manager + better PEP-8 compliance
author souliane <souliane@mailoo.org>
date Thu, 19 Nov 2015 11:41:03 +0100
parents 16079280a39e
children f8a7a046ff9c
line wrap: on
line diff
--- a/src/browser/sat_browser/contact_group.py	Thu Nov 19 11:19:05 2015 +0100
+++ b/src/browser/sat_browser/contact_group.py	Thu Nov 19 11:41:03 2015 +0100
@@ -17,19 +17,20 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from pyjamas.ui.FlexTable import FlexTable
-from pyjamas.ui.DockPanel import DockPanel
-from pyjamas.Timer import Timer
 from pyjamas.ui.Button import Button
+from pyjamas.ui.CheckBox import CheckBox
+from pyjamas.ui.Label import Label
 from pyjamas.ui.HorizontalPanel import HorizontalPanel
 from pyjamas.ui.VerticalPanel import VerticalPanel
 from pyjamas.ui.DialogBox import DialogBox
+from pyjamas.ui.ScrollPanel import ScrollPanel
 from pyjamas.ui import HasAlignment
 
 import dialog
 import list_manager
 import contact_panel
 import contact_list
+from sat_frontends.tools import jid
 
 
 unicode = str  # FIXME: pyjamas workaround
@@ -37,43 +38,39 @@
 
 class ContactGroupManager(list_manager.ListManager):
 
-    def __init__(self, container, keys, contacts, offsets, style):
+    def __init__(self, editor, data, contacts, offsets):
         """
         @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.editor = editor
+        list_manager.ListManager.__init__(self, data, contacts)
         self.registerPopupMenuPanel(entries={"Remove group": {}},
-                                    callback=lambda sender, key: Timer(5, lambda timer: self.removeContactKey(sender, key)))
+                                    callback=lambda sender, key: self.removeGroup(sender))
 
-    def removeContactKey(self, sender, key):
-        key = sender.getText()
+    def removeGroup(self, sender):
+        group = sender.getHTML()
 
         def confirm_cb(answer):
             if answer:
-                list_manager.ListManager.removeItemKey(self, key)
-                self.container.removeKeyFromAddGroupPanel(key)
+                list_manager.ListManager.removeList(self, group)
+                self.editor.add_group_panel.groups.remove(group)
 
-        _dialog = dialog.ConfirmDialog(confirm_cb, text="Do you really want to delete the group '%s'?" % key)
+        _dialog = dialog.ConfirmDialog(confirm_cb, text="Do you really want to delete the group '%s'?" % group)
         _dialog.show()
 
-    def removeFromRemainingList(self, contacts):
-        list_manager.ListManager.removeFromRemainingList(self, contacts)
-        self.container.updateContactList(contacts)
+    def tag(self, contacts):
+        list_manager.ListManager.tag(self, contacts)
+        self.editor.updateContactList(contacts)
 
-    def addToRemainingList(self, contacts, ignore_key=None):
-        list_manager.ListManager.addToRemainingList(self, contacts, ignore_key)
-        self.container.updateContactList(contacts)
+    def untag(self, contacts, ignore_key=None):
+        list_manager.ListManager.untag(self, contacts, ignore_key)
+        self.editor.updateContactList(contacts)
 
 
-class ContactGroupEditor(DockPanel):
+class ContactGroupEditor(VerticalPanel):
     """A big panel including a ContactGroupManager and other UI stuff."""
 
     def __init__(self, host, container=None, onCloseCallback=None):
@@ -83,7 +80,7 @@
         @param container (PanelBase): parent panel or None to display in a popup
         @param onCloseCallback (callable)
         """
-        DockPanel.__init__(self)
+        VerticalPanel.__init__(self, StyleName="contactGroupEditor")
         self.host = host
 
         # eventually display in a popup
@@ -99,28 +96,33 @@
         roster_groups = roster_entities_by_group.keys()
         roster_groups.sort()
 
+        # groups on the left
+        manager = self.initContactGroupManager(roster_entities_by_group)
         self.add_group_panel = self.initAddGroupPanel(roster_groups)
-        south_panel = self.initCloseSaveButtons()
-        center_panel = self.initContactGroupManager(roster_groups)
-        east_panel = self.initContactList()
+        left_container = VerticalPanel(Width="100%")
+        left_container.add(manager)
+        left_container.add(self.add_group_panel)
+        left_container.setCellHorizontalAlignment(self.add_group_panel, HasAlignment.ALIGN_CENTER)
+        left_panel = ScrollPanel(left_container, StyleName="contactGroupManager")
+        left_panel.setAlwaysShowScrollBars(True)
 
-        self.add(self.add_group_panel, DockPanel.CENTER)
-        self.add(east_panel, DockPanel.EAST)
-        self.add(center_panel, DockPanel.NORTH)
-        self.add(south_panel, DockPanel.SOUTH)
+        # contact list on the right
+        east_panel = ScrollPanel(self.initContactList(), StyleName="contactGroupRoster")
+        east_panel.setAlwaysShowScrollBars(True)
+
+        south_panel = self.initCloseSaveButtons()
 
-        self.setCellHorizontalAlignment(center_panel, HasAlignment.ALIGN_LEFT)
-        self.setCellVerticalAlignment(center_panel, HasAlignment.ALIGN_TOP)
-        self.setCellHorizontalAlignment(east_panel, HasAlignment.ALIGN_RIGHT)
-        self.setCellVerticalAlignment(east_panel, HasAlignment.ALIGN_TOP)
-        self.setCellVerticalAlignment(self.add_group_panel, HasAlignment.ALIGN_BOTTOM)
-        self.setCellHorizontalAlignment(self.add_group_panel, HasAlignment.ALIGN_LEFT)
-        self.setCellVerticalAlignment(south_panel, HasAlignment.ALIGN_BOTTOM)
+        main_panel = HorizontalPanel()
+        main_panel.add(left_panel)
+        main_panel.add(east_panel)
+        self.add(Label("You get here an over whole view of your contact groups. There are two ways to assign your contacts to an existing group: write them into auto-completed textboxes or use the right panel to drag and drop them into the group."))
+        self.add(main_panel)
+        self.add(south_panel)
+
         self.setCellHorizontalAlignment(south_panel, HasAlignment.ALIGN_CENTER)
 
         # need to be done after the contact list has been initialized
-        self.groups.resetItems(roster_entities_by_group)
-        self.toggleContacts(showAll=True)
+        self.updateContactList()
 
         # Hide the contacts list from the main panel to not confuse the user
         self.restore_contact_panel = False
@@ -134,31 +136,13 @@
         if isinstance(container, DialogBox):
             container.center()
 
-    def initContactGroupManager(self, groups):
+    def initContactGroupManager(self, data):
         """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"
-                 }
-
-        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
+        self.groups = ContactGroupManager(self, data, self.all_contacts)
+        return self.groups
 
     def initAddGroupPanel(self, groups):
         """Initialise the 'Add group' panel.
@@ -167,7 +151,7 @@
         """
 
         def add_group_cb(key):
-            self.groups.addItemKey(key)
+            self.groups.addList(key)
             self.add_group_panel.textbox.setFocus(True)
 
         add_group_panel = dialog.AddGroupPanel(groups, add_group_cb)
@@ -178,13 +162,15 @@
         """Add the buttons to close the dialog and save the groups."""
         buttons = HorizontalPanel()
         buttons.addStyleName("marginAuto")
+        buttons.add(Button("Cancel", listener=self.cancelWithoutSaving))
         buttons.add(Button("Save", listener=self.closeAndSave))
-        buttons.add(Button("Cancel", listener=self.cancelWithoutSaving))
         return buttons
 
     def initContactList(self):
         """Add the contact list to the DockPanel."""
-        self.toggle = Button("", self.toggleContacts)
+        
+        self.toggle = CheckBox("Hide assigned contacts")
+        self.toggle.addClickListener(lambda dummy: self.updateContactList())
         self.toggle.addStyleName("toggleAssignedContacts")
         self.contacts = contact_panel.ContactsPanel(self.host)
         for contact in self.all_contacts:
@@ -194,39 +180,25 @@
         panel.add(self.contacts)
         return panel
 
-    def toggleContacts(self, sender=None, showAll=None):
-        """Toggle the button to show contacts and the contact list.
-
-        @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.
+        checkbox 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"):
+        if not hasattr(self, "toggle"):
             return
         if contacts is not None:
-            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)
+            contacts = [jid.JID(contact) for contact in contacts]
+            contacts = set(contacts).intersection(self.all_contacts)
         else:
             contacts = self.all_contacts
+
         for contact in contacts:
-            if self.toggle.showAll:
+            if not self.toggle.getChecked():  # show all contacts
                 self.contacts.updateContactBox(contact).setVisible(True)
-            else:
-                if contact in self.groups.items_remaining:
+            else:  # show only non-assigned contacts
+                if contact in self.groups.untagged:
                     self.contacts.updateContactBox(contact).setVisible(True)
                 else:
                     self.contacts.updateContactBox(contact).setVisible(False)
@@ -254,7 +226,8 @@
         """Call bridge methods to save the changes and close the dialog"""
         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())
+        result = {jid.JID(item): keys for item, keys in self.groups.getKeysByItem().iteritems()}
+        groups_by_entity = contact_list.JIDDict(result)
         entities = groups_by_entity.keys()
 
         for invalid in entities.difference(self.all_contacts):