comparison src/browser/sat_browser/contact_group.py @ 467:97c72fe4a5f2

browser_side: import fixes: - moved browser modules in a sat_browser packages, to avoid import conflicts with std lib (e.g. logging), and let pyjsbuild work normaly - refactored bad import practices: classes are most of time not imported directly, module is imported instead.
author Goffi <goffi@goffi.org>
date Mon, 09 Jun 2014 22:15:26 +0200
parents src/browser/contact_group.py@981ed669d3b3
children 50b286866739
comparison
equal deleted inserted replaced
466:01880aa8ea2d 467:97c72fe4a5f2
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 # Libervia: a Salut à Toi frontend
5 # Copyright (C) 2013, 2014 Adrien Cossa <souliane@mailoo.org>
6
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
16
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20 from pyjamas.ui.FlexTable import FlexTable
21 from pyjamas.ui.DockPanel import DockPanel
22 from pyjamas.Timer import Timer
23 from pyjamas.ui.Button import Button
24 from pyjamas.ui.HorizontalPanel import HorizontalPanel
25 from pyjamas.ui.VerticalPanel import VerticalPanel
26 from pyjamas.ui.DialogBox import DialogBox
27 from pyjamas.ui import HasAlignment
28
29 import dialog
30 import list_manager
31 import contact
32
33
34 class ContactGroupManager(list_manager.ListManager):
35 """A manager for sub-panels to assign contacts to each group."""
36
37 def __init__(self, parent, keys_dict, contact_list, offsets, style):
38 list_manager.ListManager.__init__(self, parent, keys_dict, contact_list, offsets, style)
39 self.registerPopupMenuPanel(entries={"Remove group": {}},
40 callback=lambda sender, key: Timer(5, lambda timer: self.removeContactKey(sender, key)))
41
42 def removeContactKey(self, sender, key):
43 key = sender.getText()
44
45 def confirm_cb(answer):
46 if answer:
47 list_manager.ListManager.removeContactKey(self, key)
48 self._parent.removeKeyFromAddGroupPanel(key)
49
50 _dialog = dialog.ConfirmDialog(confirm_cb, text="Do you really want to delete the group '%s'?" % key)
51 _dialog.show()
52
53 def removeFromRemainingList(self, contacts):
54 list_manager.ListManager.removeFromRemainingList(self, contacts)
55 self._parent.updateContactList(contacts=contacts)
56
57 def addToRemainingList(self, contacts, ignore_key=None):
58 list_manager.ListManager.addToRemainingList(self, contacts, ignore_key)
59 self._parent.updateContactList(contacts=contacts)
60
61
62 class ContactGroupEditor(DockPanel):
63 """Panel for the contact groups manager."""
64
65 def __init__(self, host, parent=None, onCloseCallback=None):
66 DockPanel.__init__(self)
67 self.host = host
68
69 # eventually display in a popup
70 if parent is None:
71 parent = DialogBox(autoHide=False, centered=True)
72 parent.setHTML("Manage contact groups")
73 self._parent = parent
74 self._on_close_callback = onCloseCallback
75 self.all_contacts = self.host.contact_panel.getContacts()
76
77 groups_list = self.host.contact_panel.groups.keys()
78 groups_list.sort()
79
80 self.add_group_panel = self.getAddGroupPanel(groups_list)
81 south_panel = self.getCloseSaveButtons()
82 center_panel = self.getContactGroupManager(groups_list)
83 east_panel = self.getContactList()
84
85 self.add(self.add_group_panel, DockPanel.CENTER)
86 self.add(east_panel, DockPanel.EAST)
87 self.add(center_panel, DockPanel.NORTH)
88 self.add(south_panel, DockPanel.SOUTH)
89
90 self.setCellHorizontalAlignment(center_panel, HasAlignment.ALIGN_LEFT)
91 self.setCellVerticalAlignment(center_panel, HasAlignment.ALIGN_TOP)
92 self.setCellHorizontalAlignment(east_panel, HasAlignment.ALIGN_RIGHT)
93 self.setCellVerticalAlignment(east_panel, HasAlignment.ALIGN_TOP)
94 self.setCellVerticalAlignment(self.add_group_panel, HasAlignment.ALIGN_BOTTOM)
95 self.setCellHorizontalAlignment(self.add_group_panel, HasAlignment.ALIGN_LEFT)
96 self.setCellVerticalAlignment(south_panel, HasAlignment.ALIGN_BOTTOM)
97 self.setCellHorizontalAlignment(south_panel, HasAlignment.ALIGN_CENTER)
98
99 # need to be done after the contact list has been initialized
100 self.groups.setContacts(self.host.contact_panel.groups)
101 self.toggleContacts(showAll=True)
102
103 # Hide the contacts list from the main panel to not confuse the user
104 self.restore_contact_panel = False
105 if self.host.contact_panel.getVisible():
106 self.restore_contact_panel = True
107 self.host.panel._contactsSwitch()
108
109 parent.add(self)
110 parent.setVisible(True)
111 if isinstance(parent, DialogBox):
112 parent.center()
113
114 def getContactGroupManager(self, groups_list):
115 """Set the list manager for the groups"""
116 flex_table = FlexTable(len(groups_list), 2)
117 flex_table.addStyleName('contactGroupEditor')
118 # overwrite the default style which has been set for rich text editor
119 style = {
120 "keyItem": "group",
121 "popupMenuItem": "popupMenuItem",
122 "removeButton": "contactGroupRemoveButton",
123 "buttonCell": "contactGroupButtonCell",
124 "keyPanel": "contactGroupPanel"
125 }
126 self.groups = ContactGroupManager(flex_table, groups_list, self.all_contacts, style=style)
127 self.groups.createWidgets() # widgets are automatically added to FlexTable
128 # FIXME: clean that part which is dangerous
129 flex_table.updateContactList = self.updateContactList
130 flex_table.removeKeyFromAddGroupPanel = self.add_group_panel.groups.remove
131 return flex_table
132
133 def getAddGroupPanel(self, groups_list):
134 """Add the 'Add group' panel to the FlexTable"""
135
136 def add_group_cb(text):
137 self.groups.addContactKey(text)
138 self.add_group_panel.textbox.setFocus(True)
139
140 add_group_panel = dialog.AddGroupPanel(groups_list, add_group_cb)
141 add_group_panel.addStyleName("addContactGroupPanel")
142 return add_group_panel
143
144 def getCloseSaveButtons(self):
145 """Add the buttons to close the dialog / save the groups"""
146 buttons = HorizontalPanel()
147 buttons.addStyleName("marginAuto")
148 buttons.add(Button("Save", listener=self.closeAndSave))
149 buttons.add(Button("Cancel", listener=self.cancelWithoutSaving))
150 return buttons
151
152 def getContactList(self):
153 """Add the contact list to the DockPanel"""
154 self.toggle = Button("", self.toggleContacts)
155 self.toggle.addStyleName("toggleAssignedContacts")
156 self.contacts = contact.GenericContactList(self.host)
157 for contact_ in self.all_contacts:
158 self.contacts.add(contact_)
159 contact_panel = VerticalPanel()
160 contact_panel.add(self.toggle)
161 contact_panel.add(self.contacts)
162 return contact_panel
163
164 def toggleContacts(self, sender=None, showAll=None):
165 """Callback for the toggle button"""
166 if sender is None:
167 sender = self.toggle
168 sender.showAll = showAll if showAll is not None else not sender.showAll
169 if sender.showAll:
170 sender.setText("Hide assigned")
171 else:
172 sender.setText("Show assigned")
173 self.updateContactList(sender)
174
175 def updateContactList(self, sender=None, contacts=None):
176 """Update the contact list regarding the toggle button"""
177 if not hasattr(self, "toggle") or not hasattr(self.toggle, "showAll"):
178 return
179 sender = self.toggle
180 if contacts is not None:
181 if not isinstance(contacts, list):
182 contacts = [contacts]
183 for contact_ in contacts:
184 if contact_ not in self.all_contacts:
185 contacts.remove(contact_)
186 else:
187 contacts = self.all_contacts
188 for contact_ in contacts:
189 if sender.showAll:
190 self.contacts.getContactLabel(contact_).setVisible(True)
191 else:
192 if contact_ in self.groups.remaining_list:
193 self.contacts.getContactLabel(contact_).setVisible(True)
194 else:
195 self.contacts.getContactLabel(contact_).setVisible(False)
196
197 def __close(self):
198 """Remove the widget from parent or close the popup."""
199 if isinstance(self._parent, DialogBox):
200 self._parent.hide()
201 self._parent.remove(self)
202 if self._on_close_callback is not None:
203 self._on_close_callback()
204 if self.restore_contact_panel:
205 self.host.panel._contactsSwitch()
206
207 def cancelWithoutSaving(self):
208 """Ask for confirmation before closing the dialog."""
209 def confirm_cb(answer):
210 if answer:
211 self.__close()
212
213 _dialog = dialog.ConfirmDialog(confirm_cb, text="Do you really want to cancel without saving?")
214 _dialog.show()
215
216 def closeAndSave(self):
217 """Call bridge methods to save the changes and close the dialog"""
218 map_ = {}
219 for contact_ in self.all_contacts:
220 map_[contact_] = set()
221 contacts = self.groups.getContacts()
222 for group in contacts.keys():
223 for contact_ in contacts[group]:
224 try:
225 map_[contact_].add(group)
226 except KeyError:
227 dialog.InfoDialog("Invalid contact",
228 "The contact '%s' is not your contact list but it has been assigned to the group '%s'." % (contact_, group) +
229 "Your changes could not be saved: please check your assignments and save again.", Width="400px").center()
230 return
231 for contact_ in map_.keys():
232 groups = map_[contact_]
233 current_groups = self.host.contact_panel.getContactGroups(contact_)
234 if groups != current_groups:
235 self.host.bridge.call('updateContact', None, contact_, '', list(groups))
236 self.__close()