Mercurial > libervia-web
comparison src/browser/contact_group.py @ 449:981ed669d3b3
/!\ reorganize all the file hierarchy, move the code and launching script to src:
- browser_side --> src/browser
- public --> src/browser_side/public
- libervia.py --> src/browser/libervia_main.py
- libervia_server --> src/server
- libervia_server/libervia.sh --> src/libervia.sh
- twisted --> src/twisted
- new module src/common
- split constants.py in 3 files:
- src/common/constants.py
- src/browser/constants.py
- src/server/constants.py
- output --> html (generated by pyjsbuild during the installation)
- new option/parameter "data_dir" (-d) to indicates the directory containing html and server_css
- setup.py installs libervia to the following paths:
- src/common --> <LIB>/libervia/common
- src/server --> <LIB>/libervia/server
- src/twisted --> <LIB>/twisted
- html --> <SHARE>/libervia/html
- server_side --> <SHARE>libervia/server_side
- LIBERVIA_INSTALL environment variable takes 2 new options with prompt confirmation:
- clean: remove previous installation directories
- purge: remove building and previous installation directories
You may need to update your sat.conf and/or launching script to update the following options/parameters:
- ssl_certificate
- data_dir
author | souliane <souliane@mailoo.org> |
---|---|
date | Tue, 20 May 2014 06:41:16 +0200 |
parents | browser_side/contact_group.py@8ecc5a7062e4 |
children |
comparison
equal
deleted
inserted
replaced
448:14c35f7f1ef5 | 449:981ed669d3b3 |
---|---|
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 from dialog import ConfirmDialog, InfoDialog | |
30 from list_manager import ListManager | |
31 import dialog | |
32 import contact | |
33 | |
34 | |
35 class ContactGroupManager(ListManager): | |
36 """A manager for sub-panels to assign contacts to each group.""" | |
37 | |
38 def __init__(self, parent, keys_dict, contact_list, offsets, style): | |
39 ListManager.__init__(self, parent, keys_dict, contact_list, offsets, style) | |
40 self.registerPopupMenuPanel(entries={"Remove group": {}}, | |
41 callback=lambda sender, key: Timer(5, lambda timer: self.removeContactKey(sender, key))) | |
42 | |
43 def removeContactKey(self, sender, key): | |
44 key = sender.getText() | |
45 | |
46 def confirm_cb(answer): | |
47 if answer: | |
48 ListManager.removeContactKey(self, key) | |
49 self._parent.removeKeyFromAddGroupPanel(key) | |
50 | |
51 _dialog = ConfirmDialog(confirm_cb, text="Do you really want to delete the group '%s'?" % key) | |
52 _dialog.show() | |
53 | |
54 def removeFromRemainingList(self, contacts): | |
55 ListManager.removeFromRemainingList(self, contacts) | |
56 self._parent.updateContactList(contacts=contacts) | |
57 | |
58 def addToRemainingList(self, contacts, ignore_key=None): | |
59 ListManager.addToRemainingList(self, contacts, ignore_key) | |
60 self._parent.updateContactList(contacts=contacts) | |
61 | |
62 | |
63 class ContactGroupEditor(DockPanel): | |
64 """Panel for the contact groups manager.""" | |
65 | |
66 def __init__(self, host, parent=None, onCloseCallback=None): | |
67 DockPanel.__init__(self) | |
68 self.host = host | |
69 | |
70 # eventually display in a popup | |
71 if parent is None: | |
72 parent = DialogBox(autoHide=False, centered=True) | |
73 parent.setHTML("Manage contact groups") | |
74 self._parent = parent | |
75 self._on_close_callback = onCloseCallback | |
76 self.all_contacts = self.host.contact_panel.getContacts() | |
77 | |
78 groups_list = self.host.contact_panel.groups.keys() | |
79 groups_list.sort() | |
80 | |
81 self.add_group_panel = self.getAddGroupPanel(groups_list) | |
82 south_panel = self.getCloseSaveButtons() | |
83 center_panel = self.getContactGroupManager(groups_list) | |
84 east_panel = self.getContactList() | |
85 | |
86 self.add(self.add_group_panel, DockPanel.CENTER) | |
87 self.add(east_panel, DockPanel.EAST) | |
88 self.add(center_panel, DockPanel.NORTH) | |
89 self.add(south_panel, DockPanel.SOUTH) | |
90 | |
91 self.setCellHorizontalAlignment(center_panel, HasAlignment.ALIGN_LEFT) | |
92 self.setCellVerticalAlignment(center_panel, HasAlignment.ALIGN_TOP) | |
93 self.setCellHorizontalAlignment(east_panel, HasAlignment.ALIGN_RIGHT) | |
94 self.setCellVerticalAlignment(east_panel, HasAlignment.ALIGN_TOP) | |
95 self.setCellVerticalAlignment(self.add_group_panel, HasAlignment.ALIGN_BOTTOM) | |
96 self.setCellHorizontalAlignment(self.add_group_panel, HasAlignment.ALIGN_LEFT) | |
97 self.setCellVerticalAlignment(south_panel, HasAlignment.ALIGN_BOTTOM) | |
98 self.setCellHorizontalAlignment(south_panel, HasAlignment.ALIGN_CENTER) | |
99 | |
100 # need to be done after the contact list has been initialized | |
101 self.groups.setContacts(self.host.contact_panel.groups) | |
102 self.toggleContacts(showAll=True) | |
103 | |
104 # Hide the contacts list from the main panel to not confuse the user | |
105 self.restore_contact_panel = False | |
106 if self.host.contact_panel.getVisible(): | |
107 self.restore_contact_panel = True | |
108 self.host.panel._contactsSwitch() | |
109 | |
110 parent.add(self) | |
111 parent.setVisible(True) | |
112 if isinstance(parent, DialogBox): | |
113 parent.center() | |
114 | |
115 def getContactGroupManager(self, groups_list): | |
116 """Set the list manager for the groups""" | |
117 flex_table = FlexTable(len(groups_list), 2) | |
118 flex_table.addStyleName('contactGroupEditor') | |
119 # overwrite the default style which has been set for rich text editor | |
120 style = { | |
121 "keyItem": "group", | |
122 "popupMenuItem": "popupMenuItem", | |
123 "removeButton": "contactGroupRemoveButton", | |
124 "buttonCell": "contactGroupButtonCell", | |
125 "keyPanel": "contactGroupPanel" | |
126 } | |
127 self.groups = ContactGroupManager(flex_table, groups_list, self.all_contacts, style=style) | |
128 self.groups.createWidgets() # widgets are automatically added to FlexTable | |
129 # FIXME: clean that part which is dangerous | |
130 flex_table.updateContactList = self.updateContactList | |
131 flex_table.removeKeyFromAddGroupPanel = self.add_group_panel.groups.remove | |
132 return flex_table | |
133 | |
134 def getAddGroupPanel(self, groups_list): | |
135 """Add the 'Add group' panel to the FlexTable""" | |
136 | |
137 def add_group_cb(text): | |
138 self.groups.addContactKey(text) | |
139 self.add_group_panel.textbox.setFocus(True) | |
140 | |
141 add_group_panel = dialog.AddGroupPanel(groups_list, add_group_cb) | |
142 add_group_panel.addStyleName("addContactGroupPanel") | |
143 return add_group_panel | |
144 | |
145 def getCloseSaveButtons(self): | |
146 """Add the buttons to close the dialog / save the groups""" | |
147 buttons = HorizontalPanel() | |
148 buttons.addStyleName("marginAuto") | |
149 buttons.add(Button("Save", listener=self.closeAndSave)) | |
150 buttons.add(Button("Cancel", listener=self.cancelWithoutSaving)) | |
151 return buttons | |
152 | |
153 def getContactList(self): | |
154 """Add the contact list to the DockPanel""" | |
155 self.toggle = Button("", self.toggleContacts) | |
156 self.toggle.addStyleName("toggleAssignedContacts") | |
157 self.contacts = contact.GenericContactList(self.host) | |
158 for contact_ in self.all_contacts: | |
159 self.contacts.add(contact_) | |
160 contact_panel = VerticalPanel() | |
161 contact_panel.add(self.toggle) | |
162 contact_panel.add(self.contacts) | |
163 return contact_panel | |
164 | |
165 def toggleContacts(self, sender=None, showAll=None): | |
166 """Callback for the toggle button""" | |
167 if sender is None: | |
168 sender = self.toggle | |
169 sender.showAll = showAll if showAll is not None else not sender.showAll | |
170 if sender.showAll: | |
171 sender.setText("Hide assigned") | |
172 else: | |
173 sender.setText("Show assigned") | |
174 self.updateContactList(sender) | |
175 | |
176 def updateContactList(self, sender=None, contacts=None): | |
177 """Update the contact list regarding the toggle button""" | |
178 if not hasattr(self, "toggle") or not hasattr(self.toggle, "showAll"): | |
179 return | |
180 sender = self.toggle | |
181 if contacts is not None: | |
182 if not isinstance(contacts, list): | |
183 contacts = [contacts] | |
184 for contact_ in contacts: | |
185 if contact_ not in self.all_contacts: | |
186 contacts.remove(contact_) | |
187 else: | |
188 contacts = self.all_contacts | |
189 for contact_ in contacts: | |
190 if sender.showAll: | |
191 self.contacts.getContactLabel(contact_).setVisible(True) | |
192 else: | |
193 if contact_ in self.groups.remaining_list: | |
194 self.contacts.getContactLabel(contact_).setVisible(True) | |
195 else: | |
196 self.contacts.getContactLabel(contact_).setVisible(False) | |
197 | |
198 def __close(self): | |
199 """Remove the widget from parent or close the popup.""" | |
200 if isinstance(self._parent, DialogBox): | |
201 self._parent.hide() | |
202 self._parent.remove(self) | |
203 if self._on_close_callback is not None: | |
204 self._on_close_callback() | |
205 if self.restore_contact_panel: | |
206 self.host.panel._contactsSwitch() | |
207 | |
208 def cancelWithoutSaving(self): | |
209 """Ask for confirmation before closing the dialog.""" | |
210 def confirm_cb(answer): | |
211 if answer: | |
212 self.__close() | |
213 | |
214 _dialog = ConfirmDialog(confirm_cb, text="Do you really want to cancel without saving?") | |
215 _dialog.show() | |
216 | |
217 def closeAndSave(self): | |
218 """Call bridge methods to save the changes and close the dialog""" | |
219 map_ = {} | |
220 for contact_ in self.all_contacts: | |
221 map_[contact_] = set() | |
222 contacts = self.groups.getContacts() | |
223 for group in contacts.keys(): | |
224 for contact_ in contacts[group]: | |
225 try: | |
226 map_[contact_].add(group) | |
227 except KeyError: | |
228 InfoDialog("Invalid contact", | |
229 "The contact '%s' is not your contact list but it has been assigned to the group '%s'." % (contact_, group) + | |
230 "Your changes could not be saved: please check your assignments and save again.", Width="400px").center() | |
231 return | |
232 for contact_ in map_.keys(): | |
233 groups = map_[contact_] | |
234 current_groups = self.host.contact_panel.getContactGroups(contact_) | |
235 if groups != current_groups: | |
236 self.host.bridge.call('updateContact', None, contact_, '', list(groups)) | |
237 self.__close() |