Mercurial > libervia-web
comparison libervia.py @ 16:099c05a0dcab
browser side: microblog panel improvments
- panels can now be changed by DnD
- contacts panel's title can be used by DnD for the global microblog panel
- microblogs now appear in reverse order (from bottom to top)
- MicroblogPanel now use a ScrollPanel and 100% space
- user's message now appear in correct group when using groupblog
- MagicBox renamed to UniBox
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 15 Apr 2011 02:01:34 +0200 |
parents | 9bf8ed012adc |
children | c725b702e927 |
comparison
equal
deleted
inserted
replaced
15:78bfc398926b | 16:099c05a0dcab |
---|---|
23 from pyjamas.ui.SimplePanel import SimplePanel | 23 from pyjamas.ui.SimplePanel import SimplePanel |
24 from pyjamas.ui.RootPanel import RootPanel | 24 from pyjamas.ui.RootPanel import RootPanel |
25 from pyjamas.ui.VerticalPanel import VerticalPanel | 25 from pyjamas.ui.VerticalPanel import VerticalPanel |
26 from pyjamas.ui.HorizontalPanel import HorizontalPanel | 26 from pyjamas.ui.HorizontalPanel import HorizontalPanel |
27 from pyjamas.ui.HTMLPanel import HTMLPanel | 27 from pyjamas.ui.HTMLPanel import HTMLPanel |
28 from pyjamas.ui.ScrollPanel import ScrollPanel | |
28 from pyjamas.ui.Grid import Grid | 29 from pyjamas.ui.Grid import Grid |
29 from pyjamas.ui.Label import Label | 30 from pyjamas.ui.Label import Label |
30 from pyjamas.ui import HasAlignment | 31 from pyjamas.ui import HasAlignment |
31 from pyjamas.ui.MenuBar import MenuBar | 32 from pyjamas.ui.MenuBar import MenuBar |
32 from pyjamas.ui.MenuItem import MenuItem | 33 from pyjamas.ui.MenuItem import MenuItem |
117 Window.alert("Tarot selected") | 118 Window.alert("Tarot selected") |
118 | 119 |
119 def onXiangqiGame(self): | 120 def onXiangqiGame(self): |
120 Window.alert("Xiangqi selected") | 121 Window.alert("Xiangqi selected") |
121 | 122 |
122 class MagicBox(AutoCompleteTextBox): | 123 class UniBox(AutoCompleteTextBox): |
123 | 124 |
124 def __init__(self, host): | 125 def __init__(self, host): |
125 AutoCompleteTextBox.__init__(self) | 126 AutoCompleteTextBox.__init__(self) |
126 self.host = host | 127 self.host = host |
127 | 128 |
136 def complete(self): | 137 def complete(self): |
137 #self.visible=False #XXX: self.visible is not unset in pyjamas when ENTER is pressed and a completion is done | 138 #self.visible=False #XXX: self.visible is not unset in pyjamas when ENTER is pressed and a completion is done |
138 #XXX: fixed directly on pyjamas, if the patch is accepted, no need to walk around this | 139 #XXX: fixed directly on pyjamas, if the patch is accepted, no need to walk around this |
139 return AutoCompleteTextBox.complete(self) | 140 return AutoCompleteTextBox.complete(self) |
140 | 141 |
141 class EmptyPanel(DropWidget, SimplePanel): | 142 class DropCell(DropWidget): |
142 """Empty dropable panel""" | 143 """Cell in the middle grid which replace itself with the dropped widget on DnD""" |
143 | 144 |
144 def __init__(self, host, data): | 145 def __init__(self): |
145 SimplePanel.__init__(self) | |
146 self.host = host | |
147 self.data = data | |
148 _panel = HTMLPanel(" ") | |
149 self.add(_panel) | |
150 self.setHeight('100%') | |
151 DropWidget.__init__(self) | 146 DropWidget.__init__(self) |
152 | 147 |
153 def onDragEnter(self, event): | 148 def onDragEnter(self, event): |
149 print "drag enter" | |
154 self.addStyleName('dragover') | 150 self.addStyleName('dragover') |
155 DOM.eventPreventDefault(event) | 151 DOM.eventPreventDefault(event) |
156 | 152 |
157 def onDragLeave(self, event): | 153 def onDragLeave(self, event): |
154 print "drag leave" | |
158 self.removeStyleName('dragover') | 155 self.removeStyleName('dragover') |
159 | 156 |
160 def onDragOver(self, event): | 157 def onDragOver(self, event): |
161 DOM.eventPreventDefault(event) | 158 DOM.eventPreventDefault(event) |
159 | |
160 def _getCellAndRow(self, grid, event): | |
161 """Return cell and row index where the event is occuring""" | |
162 cell = grid.getEventTargetCell(event) | |
163 row = DOM.getParent(cell) | |
164 return (row.rowIndex, cell.cellIndex) | |
165 | |
162 | 166 |
163 def onDrop(self, event): | 167 def onDrop(self, event): |
164 print "Empty Panel: onDrop" | 168 print "Empty Panel: onDrop" |
165 dt = event.dataTransfer | 169 dt = event.dataTransfer |
166 #'text', 'text/plain', and 'Text' are equivalent. | 170 #'text', 'text/plain', and 'Text' are equivalent. |
172 except: | 176 except: |
173 print "no message found" | 177 print "no message found" |
174 item=' ' | 178 item=' ' |
175 item_type = None | 179 item_type = None |
176 DOM.eventPreventDefault(event) | 180 DOM.eventPreventDefault(event) |
177 _mblog = MicroblogPanel(self.host, item) | |
178 if item_type=="GROUP": | 181 if item_type=="GROUP": |
182 _mblog = MicroblogPanel(self.host, item) | |
179 _mblog.setAcceptedGroup(item) | 183 _mblog.setAcceptedGroup(item) |
180 self.host.mpanels.insert(0,_mblog) | 184 elif item_type=="CONTACT": |
181 self.host.middle_panel.changePanel(self.data,self.host.mpanels[0]) | 185 _mblog = MicroblogPanel(self.host, accept_all=True) |
182 | 186 self.host.mpanels.remove(self) |
183 | 187 self.host.mpanels.append(_mblog) |
184 | 188 print "DEBUG" |
189 grid = self.getParent() | |
190 row_idx, cell_idx = self._getCellAndRow(grid, event) | |
191 self.removeFromParent() | |
192 grid.setWidget(row_idx, cell_idx, _mblog) | |
193 print "index:", row_idx, cell_idx | |
194 #FIXME: delete object ? Check the right way with pyjamas | |
195 #self.host.middle_panel.changePanel(self.data,self.host.mpanels[0]) | |
196 | |
197 | |
198 class EmptyPanel(DropCell, SimplePanel): | |
199 """Empty dropable panel""" | |
200 | |
201 def __init__(self, host): | |
202 SimplePanel.__init__(self) | |
203 self.host = host | |
204 _panel = HTMLPanel(" ") | |
205 self.add(_panel) | |
206 self.setHeight('100%') | |
207 DropCell.__init__(self) | |
208 | |
185 class MicroblogEntry(SimplePanel): | 209 class MicroblogEntry(SimplePanel): |
186 | 210 |
187 def __init__(self, body, author, timestamp): | 211 def __init__(self, body, author, timestamp): |
188 SimplePanel.__init__(self) | 212 SimplePanel.__init__(self) |
189 | 213 |
196 ) | 220 ) |
197 panel.setStyleName('microblogEntry') | 221 panel.setStyleName('microblogEntry') |
198 self.add(panel) | 222 self.add(panel) |
199 | 223 |
200 | 224 |
201 class MicroblogPanel(VerticalPanel): | 225 class MicroblogPanel(DropCell, ScrollPanel): |
202 | 226 |
203 def __init__(self,host, title=' ', accept_all=False): | 227 def __init__(self,host, title=' ', accept_all=False): |
228 """Panel used to show microblog | |
229 @param title: title of the panel | |
230 @param accept_all: if true, show every message, without filtering jids""" | |
204 self.host = host | 231 self.host = host |
205 self.accept_all = accept_all | 232 self.accept_all = accept_all |
206 title=title.replace('<','<').replace('>','>') | 233 title=title.replace('<','<').replace('>','>') |
207 VerticalPanel.__init__(self) | |
208 self.accepted_groups = [] | 234 self.accepted_groups = [] |
209 _class = ['mb_panel_header'] | 235 _class = ['mb_panel_header'] |
210 if title == ' ': | 236 if title == ' ': |
211 _class.append('empty_header') | 237 _class.append('empty_header') |
212 self.add(HTMLPanel("<div class='%s'>%s</div>" % (','.join(_class),title))) | 238 ScrollPanel.__init__(self) |
239 self.vpanel = VerticalPanel() | |
240 self.vpanel.add(HTMLPanel("<div class='%s'>%s</div>" % (','.join(_class),title))) | |
241 self.vpanel.setWidth('100%') | |
242 self.setHeight('100%') | |
213 self.setStyleName('microblogPanel') | 243 self.setStyleName('microblogPanel') |
244 self.add(self.vpanel) | |
245 DropCell.__init__(self) | |
214 | 246 |
215 def addEntry(self, text, author=None, timestamp=None): | 247 def addEntry(self, text, author=None, timestamp=None): |
216 """Add an entry to the panel | 248 """Add an entry to the panel |
217 @param text: main text of the entry | 249 @param text: main text of the entry |
218 @param author: who wrote the entry | 250 @param author: who wrote the entry |
219 @param date: when the entry was written""" | 251 @param date: when the entry was written""" |
220 _entry = MicroblogEntry(text, author, timestamp) | 252 _entry = MicroblogEntry(text, author, timestamp) |
221 self.add(_entry) | 253 self.vpanel.insert(_entry,1) |
222 | 254 |
223 def setAcceptedGroup(self, group): | 255 def setAcceptedGroup(self, group): |
224 """Set the group which can be displayed in this panel | 256 """Set the group which can be displayed in this panel |
225 @param group: string of the group, or list of string | 257 @param group: string of the group, or list of string |
226 """ | 258 """ |
237 return True | 269 return True |
238 for group in self.accepted_groups: | 270 for group in self.accepted_groups: |
239 if self.host.contactPanel.isContactInGroup(group, jid): | 271 if self.host.contactPanel.isContactInGroup(group, jid): |
240 return True | 272 return True |
241 return False | 273 return False |
274 | |
242 | 275 |
243 | 276 |
244 class MiddlePannel(HorizontalPanel): | 277 class MiddlePannel(HorizontalPanel): |
245 | 278 |
246 def __init__(self, host): | 279 def __init__(self, host): |
269 | 302 |
270 self.setHorizontalAlignment(HasAlignment.ALIGN_LEFT) | 303 self.setHorizontalAlignment(HasAlignment.ALIGN_LEFT) |
271 self.setVerticalAlignment(HasAlignment.ALIGN_TOP) | 304 self.setVerticalAlignment(HasAlignment.ALIGN_TOP) |
272 | 305 |
273 menu = Menu() | 306 menu = Menu() |
274 magic_box = host.magicBox | 307 uni_box = host.uniBox |
275 self.middle_panel = MiddlePannel(self.host) | 308 self.middle_panel = MiddlePannel(self.host) |
276 self.middle_panel.setWidth('100%') | 309 self.middle_panel.setWidth('100%') |
277 | 310 |
278 self.add(menu) | 311 self.add(menu) |
279 self.add(magic_box) | 312 self.add(uni_box) |
280 self.add(self.middle_panel) | 313 self.add(self.middle_panel) |
281 | 314 |
282 self.setCellHeight(menu, "5%") | 315 self.setCellHeight(menu, "5%") |
283 self.setCellHeight(magic_box, "5%") | 316 self.setCellHeight(uni_box, "5%") |
284 self.setCellVerticalAlignment(magic_box, HasAlignment.ALIGN_CENTER) | 317 self.setCellVerticalAlignment(uni_box, HasAlignment.ALIGN_CENTER) |
285 self.setCellHorizontalAlignment(magic_box, HasAlignment.ALIGN_CENTER) | 318 self.setCellHorizontalAlignment(uni_box, HasAlignment.ALIGN_CENTER) |
286 self.setCellHeight(self.middle_panel, "90%") | 319 self.setCellHeight(self.middle_panel, "90%") |
287 self.setCellWidth(self.middle_panel, "100%") | 320 self.setCellWidth(self.middle_panel, "100%") |
288 | 321 |
289 self.setWidth("100%") | 322 self.setWidth("100%") |
290 self.setHeight("100%") | 323 self.setHeight("100%") |
291 | 324 |
292 class SatWebFrontend: | 325 class SatWebFrontend: |
293 def onModuleLoad(self): | 326 def onModuleLoad(self): |
294 self.bridge = BridgeCall() | 327 self.bridge = BridgeCall() |
295 self.bridge_signals = BridgeSignals() | 328 self.bridge_signals = BridgeSignals() |
296 self.magicBox = MagicBox(self) | 329 self.uniBox = UniBox(self) |
297 self.magicBox.addKey("@@: ") | 330 self.uniBox.addKey("@@: ") |
298 self.contactPanel = ContactPanel(self) | 331 self.contactPanel = ContactPanel(self) |
299 self.panel = MainPanel(self) | 332 self.panel = MainPanel(self) |
300 self.middle_panel = self.panel.middle_panel | 333 self.middle_panel = self.panel.middle_panel |
301 self.mpanels = [MicroblogPanel(self, accept_all=True)] | 334 self.mpanels = [EmptyPanel(self), MicroblogPanel(self, accept_all=True), EmptyPanel(self)] |
302 self.middle_panel.changePanel(1,self.mpanels[0]) | 335 self.middle_panel.changePanel(0,self.mpanels[0]) |
303 self.middle_panel.changePanel(0,EmptyPanel(self, 0)) | 336 self.middle_panel.changePanel(1,self.mpanels[1]) |
304 self.middle_panel.changePanel(2,EmptyPanel(self, 2)) | 337 self.middle_panel.changePanel(2,self.mpanels[2]) |
305 self._dialog = None | 338 self._dialog = None |
306 RootPanel().add(self.panel) | 339 RootPanel().add(self.panel) |
307 self._register = RegisterCall() | 340 self._register = RegisterCall() |
308 self._register.call('isRegistered',self._isRegisteredCB) | 341 self._register.call('isRegistered',self._isRegisteredCB) |
309 | 342 |
347 def _personalEventCb(self, sender, event_type, data, profile): | 380 def _personalEventCb(self, sender, event_type, data, profile): |
348 if event_type == "MICROBLOG": | 381 if event_type == "MICROBLOG": |
349 if not data.has_key('content'): | 382 if not data.has_key('content'): |
350 print ("WARNING: No content found in microblog data") | 383 print ("WARNING: No content found in microblog data") |
351 return | 384 return |
385 print dir('') | |
386 if data.has_key('groups'): | |
387 _groups = set(data['groups'].split() if data['groups'] else []) | |
388 else: | |
389 _groups=None | |
390 print "_groups=",_groups | |
352 for panel in self.mpanels: | 391 for panel in self.mpanels: |
353 if isinstance(panel,MicroblogPanel) and panel.isJidAccepted(sender): | 392 if isinstance(panel,MicroblogPanel) and (panel.isJidAccepted(sender) or _groups == None or _groups.intersection(panel.accepted_groups)): |
354 print "sender:",sender | 393 print "sender:",sender |
355 content = data['content'] | 394 content = data['content'] |
356 author = data.get('author') | 395 author = data.get('author') |
357 print "timestamp: %s" % data.get('timestamp') | 396 print "timestamp: %s" % data.get('timestamp') |
358 timestamp = float(data.get('timestamp',0)) #XXX: int doesn't work here | 397 timestamp = float(data.get('timestamp',0)) #XXX: int doesn't work here |