Mercurial > libervia-web
comparison browser_side/panels.py @ 210:3092f6b1710c
browser side: make the OK button title for group selector configureable + few "cosmetic" changes (PEP 8...)
fix bug 15
fix bug 33
author | souliane <souliane@mailoo.org> |
---|---|
date | Fri, 06 Sep 2013 15:40:33 +0200 |
parents | 4d7054542751 |
children | 8bbac49765d6 |
comparison
equal
deleted
inserted
replaced
209:4564c7bc06a7 | 210:3092f6b1710c |
---|---|
46 import dialog | 46 import dialog |
47 import base_widget | 47 import base_widget |
48 from pyjamas import Window | 48 from pyjamas import Window |
49 from __pyjamas__ import doc | 49 from __pyjamas__ import doc |
50 | 50 |
51 | |
51 class UniBoxPanel(SimplePanel): | 52 class UniBoxPanel(SimplePanel): |
52 """Panel containing the UniBox""" | 53 """Panel containing the UniBox""" |
53 | 54 |
54 def __init__(self, host): | 55 def __init__(self, host): |
55 SimplePanel.__init__(self) | 56 SimplePanel.__init__(self) |
56 self.setStyleName('uniBoxPanel') | 57 self.setStyleName('uniBoxPanel') |
57 self.unibox = UniBox(host) | 58 self.unibox = UniBox(host) |
58 self.unibox.setWidth('100%') | 59 self.unibox.setWidth('100%') |
59 self.add(self.unibox) | 60 self.add(self.unibox) |
60 | 61 |
62 | |
61 class UniBox(TextArea, MouseHandler): #AutoCompleteTextBox): | 63 class UniBox(TextArea, MouseHandler): #AutoCompleteTextBox): |
62 """This text box is used as a main typing point, for message, microblog, etc""" | 64 """This text box is used as a main typing point, for message, microblog, etc""" |
63 | 65 |
64 def __init__(self, host): | 66 def __init__(self, host): |
65 TextArea.__init__(self) | 67 TextArea.__init__(self) |
66 #AutoCompleteTextBox.__init__(self) | 68 #AutoCompleteTextBox.__init__(self) |
67 self.__size = (0,0) | 69 self.__size = (0, 0) |
68 self._popup = None | 70 self._popup = None |
69 self._timer = Timer(notify=self._timeCb) | 71 self._timer = Timer(notify=self._timeCb) |
70 self.host = host | 72 self.host = host |
71 self.setStyleName('uniBox') | 73 self.setStyleName('uniBox') |
72 self.addKeyboardListener(self) | 74 self.addKeyboardListener(self) |
82 def removeKey(self, key): | 84 def removeKey(self, key): |
83 try: | 85 try: |
84 self.getCompletionItems().completions.remove(key) | 86 self.getCompletionItems().completions.remove(key) |
85 except KeyError: | 87 except KeyError: |
86 print "WARNING: trying to remove an unknown key" | 88 print "WARNING: trying to remove an unknown key" |
87 | |
88 | 89 |
89 def showWarning(self, target_data): | 90 def showWarning(self, target_data): |
90 target_hook, _type, msg = target_data | 91 target_hook, _type, msg = target_data |
91 if _type == "NONE": | 92 if _type == "NONE": |
92 return | 93 return |
113 self._popup.setStyleName("warningPopup") | 114 self._popup.setStyleName("warningPopup") |
114 if style: | 115 if style: |
115 self._popup.addStyleName(style) | 116 self._popup.addStyleName(style) |
116 | 117 |
117 left = 0 | 118 left = 0 |
118 top = 0 #max(0, self.getAbsoluteTop() - contents.getOffsetHeight() - 2) | 119 top = 0 #max(0, self.getAbsoluteTop() - contents.getOffsetHeight() - 2) |
119 self._popup.setPopupPosition(left, top) | 120 self._popup.setPopupPosition(left, top) |
120 self._popup.show() | 121 self._popup.show() |
121 | 122 |
122 def _timeCb(self, timer): | 123 def _timeCb(self, timer): |
123 if self._popup: | 124 if self._popup: |
219 | 220 |
220 #self.visible=False #XXX: self.visible is not unset in pyjamas when ENTER is pressed and a completion is done | 221 #self.visible=False #XXX: self.visible is not unset in pyjamas when ENTER is pressed and a completion is done |
221 #XXX: fixed directly on pyjamas, if the patch is accepted, no need to walk around this | 222 #XXX: fixed directly on pyjamas, if the patch is accepted, no need to walk around this |
222 return AutoCompleteTextBox.complete(self)""" | 223 return AutoCompleteTextBox.complete(self)""" |
223 | 224 |
225 | |
224 class MicroblogItem(): | 226 class MicroblogItem(): |
225 #XXX: should be moved in a separated module | 227 #XXX: should be moved in a separated module |
226 | 228 |
227 def __init__(self, data): | 229 def __init__(self, data): |
228 self.id = data['id'] | 230 self.id = data['id'] |
229 self.type = data.get('type','main_item') | 231 self.type = data.get('type', 'main_item') |
230 self.content = data['content'] | 232 self.content = data['content'] |
231 self.author = data['author'] | 233 self.author = data['author'] |
232 self.timestamp = float(data.get('timestamp',0)) #XXX: int doesn't work here | 234 self.timestamp = float(data.get('timestamp', 0)) #XXX: int doesn't work here |
233 self.comments = data.get('comments', False) | 235 self.comments = data.get('comments', False) |
234 if self.comments: | 236 if self.comments: |
235 try: | 237 try: |
236 self.comments_hash = (data['comments_service'], data['comments_node']) | 238 self.comments_hash = (data['comments_service'], data['comments_node']) |
237 self.comments_service = data['comments_service'] | 239 self.comments_service = data['comments_service'] |
241 self.comments = False | 243 self.comments = False |
242 if set(("service","node")).issubset(data.keys()): | 244 if set(("service","node")).issubset(data.keys()): |
243 self.service = data["service"] | 245 self.service = data["service"] |
244 self.node = data["node"] | 246 self.node = data["node"] |
245 self.hash = (self.service, self.node) | 247 self.hash = (self.service, self.node) |
248 | |
246 | 249 |
247 class MicroblogEntry(SimplePanel, ClickHandler): | 250 class MicroblogEntry(SimplePanel, ClickHandler): |
248 | 251 |
249 def __init__(self, blog_panel, mblog_entry): | 252 def __init__(self, blog_panel, mblog_entry): |
250 SimplePanel.__init__(self) | 253 SimplePanel.__init__(self) |
332 # we have a meta MicroblogPanel, we publish publicly | 335 # we have a meta MicroblogPanel, we publish publicly |
333 return ("PUBLIC", self.warning_msg_public) | 336 return ("PUBLIC", self.warning_msg_public) |
334 else: | 337 else: |
335 # we only accept one group at the moment | 338 # we only accept one group at the moment |
336 # FIXME: manage several groups | 339 # FIXME: manage several groups |
337 return ("GROUP", self.warning_msg_group % self.accepted_groups[0]) | 340 return ("GROUP", self.warning_msg_group % self.accepted_groups[0]) |
338 | 341 |
339 def onTextEntered(self, text): | 342 def onTextEntered(self, text): |
340 if self.selected_entry: | 343 if self.selected_entry: |
341 # we are entering a comment | 344 # we are entering a comment |
342 comments_node = self.selected_entry.comments | 345 comments_node = self.selected_entry.comments |
381 print ("WARNING: No content found in microblog [%s]", mblog) | 384 print ("WARNING: No content found in microblog [%s]", mblog) |
382 continue | 385 continue |
383 mblog_item = MicroblogItem(mblog) | 386 mblog_item = MicroblogItem(mblog) |
384 self.addEntry(mblog_item) | 387 self.addEntry(mblog_item) |
385 | 388 |
386 def _chronoInsert(self, vpanel, entry, reverse = True): | 389 def _chronoInsert(self, vpanel, entry, reverse=True): |
387 """ Insert an entry in chronological order | 390 """ Insert an entry in chronological order |
388 @param vpanel: VerticalPanel instance | 391 @param vpanel: VerticalPanel instance |
389 @param entry: MicroblogEntry | 392 @param entry: MicroblogEntry |
390 @param reverse: more recent entry on top if True, chronological order else""" | 393 @param reverse: more recent entry on top if True, chronological order else""" |
391 # we look for the right index to insert our entry: | 394 # we look for the right index to insert our entry: |
393 # in the past | 396 # in the past |
394 idx = 0 | 397 idx = 0 |
395 | 398 |
396 for child in vpanel.children: | 399 for child in vpanel.children: |
397 if not isinstance(child, MicroblogEntry): | 400 if not isinstance(child, MicroblogEntry): |
398 idx+=1 | 401 idx += 1 |
399 continue | 402 continue |
400 if reverse: | 403 if reverse: |
401 if child.timestamp < entry.timestamp: | 404 if child.timestamp < entry.timestamp: |
402 break | 405 break |
403 else: | 406 else: |
404 if child.timestamp > entry.timestamp: | 407 if child.timestamp > entry.timestamp: |
405 break | 408 break |
406 idx+=1 | 409 idx += 1 |
407 | 410 |
408 vpanel.insert(entry, idx) | 411 vpanel.insert(entry, idx) |
409 | 412 |
410 def addEntry(self, mblog_item): | 413 def addEntry(self, mblog_item): |
411 """Add an entry to the panel | 414 """Add an entry to the panel |
453 self.selected_entry.removeStyleName('selected_entry') | 456 self.selected_entry.removeStyleName('selected_entry') |
454 if entry: | 457 if entry: |
455 entry.addStyleName('selected_entry') | 458 entry.addStyleName('selected_entry') |
456 self.selected_entry = entry | 459 self.selected_entry = entry |
457 | 460 |
458 | |
459 def updateValue(self, type, jid, value): | 461 def updateValue(self, type, jid, value): |
460 """Update a jid value in entries | 462 """Update a jid value in entries |
461 @param type: one of 'avatar', 'nick' | 463 @param type: one of 'avatar', 'nick' |
462 @param jid: jid concerned | 464 @param jid: jid concerned |
463 @param value: new value""" | 465 @param value: new value""" |
465 for child in vpanel.children: | 467 for child in vpanel.children: |
466 if isinstance(child, MicroblogEntry) and child.author == jid: | 468 if isinstance(child, MicroblogEntry) and child.author == jid: |
467 child.updateAvatar(value) | 469 child.updateAvatar(value) |
468 elif isinstance(child, VerticalPanel): | 470 elif isinstance(child, VerticalPanel): |
469 updateVPanel(child) | 471 updateVPanel(child) |
470 if type=='avatar': | 472 if type == 'avatar': |
471 updateVPanel(self.vpanel) | 473 updateVPanel(self.vpanel) |
472 | 474 |
473 def setAcceptedGroup(self, group): | 475 def setAcceptedGroup(self, group): |
474 """Set the group which can be displayed in this panel | 476 """Set the group which can be displayed in this panel |
475 @param group: string of the group, or list of string | 477 @param group: string of the group, or list of string |
488 for group in self.accepted_groups: | 490 for group in self.accepted_groups: |
489 if self.host.contact_panel.isContactInGroup(group, jid): | 491 if self.host.contact_panel.isContactInGroup(group, jid): |
490 return True | 492 return True |
491 return False | 493 return False |
492 | 494 |
495 | |
493 class StatusPanel(HTMLPanel, ClickHandler): | 496 class StatusPanel(HTMLPanel, ClickHandler): |
494 def __init__(self, host, status=''): | 497 def __init__(self, host, status=''): |
495 self.host = host | 498 self.host = host |
496 self.status = status or ' ' | 499 self.status = status or ' ' |
497 HTMLPanel.__init__(self, self.__getContent()) | 500 HTMLPanel.__init__(self, self.__getContent()) |
498 self.setStyleName('statusPanel') | 501 self.setStyleName('statusPanel') |
499 ClickHandler.__init__(self) | 502 ClickHandler.__init__(self) |
500 self.addClickListener(self) | 503 self.addClickListener(self) |
501 | 504 |
502 def __getContent(self): | 505 def __getContent(self): |
503 return "<span class='status'>%(status)s</span>" % {'status':html_sanitize(self.status)} | 506 return "<span class='status'>%(status)s</span>" % {'status': html_sanitize(self.status)} |
504 | 507 |
505 def changeStatus(self, new_status): | 508 def changeStatus(self, new_status): |
506 self.status = new_status or ' ' | 509 self.status = new_status or ' ' |
507 self.setHTML(self.__getContent()) | 510 self.setHTML(self.__getContent()) |
508 | 511 |
509 def onClick(self, sender): | 512 def onClick(self, sender): |
510 #As status is the default target of uniBar, we don't want to select anything if click on it | 513 #As status is the default target of uniBar, we don't want to select anything if click on it |
511 self.host.setSelected(None) | 514 self.host.setSelected(None) |
515 | |
512 | 516 |
513 class ChatText(HTMLPanel): | 517 class ChatText(HTMLPanel): |
514 | 518 |
515 def __init__(self, timestamp, nick, mymess, msg): | 519 def __init__(self, timestamp, nick, mymess, msg): |
516 _date = datetime.fromtimestamp(float(timestamp or time())) | 520 _date = datetime.fromtimestamp(float(timestamp or time())) |
517 _msg_class = ["chat_text_msg"] | 521 _msg_class = ["chat_text_msg"] |
518 if mymess: | 522 if mymess: |
519 _msg_class.append("chat_text_mymess") | 523 _msg_class.append("chat_text_mymess") |
520 HTMLPanel.__init__(self, "<span class='chat_text_timestamp'>%(timestamp)s</span> <span class='chat_text_nick'>%(nick)s</span> <span class='%(msg_class)s'>%(msg)s</span>" % | 524 HTMLPanel.__init__(self, "<span class='chat_text_timestamp'>%(timestamp)s</span> <span class='chat_text_nick'>%(nick)s</span> <span class='%(msg_class)s'>%(msg)s</span>" % |
521 {"timestamp": _date.strftime("%H:%M"), | 525 {"timestamp": _date.strftime("%H:%M"), |
522 "nick": "[%s]" % html_sanitize(nick), | 526 "nick": "[%s]" % html_sanitize(nick), |
523 "msg_class": ' '.join(_msg_class), | 527 "msg_class": ' '.join(_msg_class), |
524 "msg": html_sanitize(msg)} | 528 "msg": html_sanitize(msg)} |
525 ) | 529 ) |
526 self.setStyleName('chatText') | 530 self.setStyleName('chatText') |
531 | |
527 | 532 |
528 class Occupant(HTML): | 533 class Occupant(HTML): |
529 """Occupant of a MUC room""" | 534 """Occupant of a MUC room""" |
530 | 535 |
531 def __init__(self, nick): | 536 def __init__(self, nick): |
532 self.nick = nick | 537 self.nick = nick |
533 HTML.__init__(self, "<div class='occupant'>%s</div>" % html_sanitize(nick)) | 538 HTML.__init__(self, "<div class='occupant'>%s</div>" % html_sanitize(nick)) |
534 | 539 |
535 def __str__(self): | 540 def __str__(self): |
536 return self.nick | 541 return self.nick |
542 | |
537 | 543 |
538 class OccupantsList(AbsolutePanel): | 544 class OccupantsList(AbsolutePanel): |
539 """Panel user to show occupants of a room""" | 545 """Panel user to show occupants of a room""" |
540 | 546 |
541 def __init__(self): | 547 def __init__(self): |
556 | 562 |
557 def clear(self): | 563 def clear(self): |
558 self.occupants_list.clear() | 564 self.occupants_list.clear() |
559 AbsolutePanel.clear(self) | 565 AbsolutePanel.clear(self) |
560 | 566 |
567 | |
561 class ChatPanel(base_widget.LiberviaWidget): | 568 class ChatPanel(base_widget.LiberviaWidget): |
562 | 569 |
563 def __init__(self, host, target, type_='one2one'): | 570 def __init__(self, host, target, type_='one2one'): |
564 """Panel used for conversation (one 2 one or group chat) | 571 """Panel used for conversation (one 2 one or group chat) |
565 @param host: SatWebFrontend instance | 572 @param host: SatWebFrontend instance |
566 @param target: entity (JID) with who we have a conversation (contact's jid for one 2 one chat, or MUC room) | 573 @param target: entity (JID) with who we have a conversation (contact's jid for one 2 one chat, or MUC room) |
567 @param type: one2one for simple conversation, group for MUC""" | 574 @param type: one2one for simple conversation, group for MUC""" |
568 base_widget.LiberviaWidget.__init__(self, host, target.bare, selectable = True) | 575 base_widget.LiberviaWidget.__init__(self, host, target.bare, selectable=True) |
569 self.vpanel = VerticalPanel() | 576 self.vpanel = VerticalPanel() |
570 self.vpanel.setSize('100%','100%') | 577 self.vpanel.setSize('100%', '100%') |
571 self.type = type_ | 578 self.type = type_ |
572 self.nick = None | 579 self.nick = None |
573 if not target: | 580 if not target: |
574 print "ERROR: Empty target !" | 581 print "ERROR: Empty target !" |
575 return | 582 return |
621 elif self.type == "group": | 628 elif self.type == "group": |
622 msg = "This message will be sent to all the participants of the multi-user room <span class='warningTarget'>%s</span>" % self.target | 629 msg = "This message will be sent to all the participants of the multi-user room <span class='warningTarget'>%s</span>" % self.target |
623 return ("ONE2ONE" if self.type == "one2one" else "GROUP", msg) | 630 return ("ONE2ONE" if self.type == "one2one" else "GROUP", msg) |
624 | 631 |
625 def onTextEntered(self, text): | 632 def onTextEntered(self, text): |
626 mess_type = "groupchat" if self.type=='group' else "chat" | 633 mess_type = "groupchat" if self.type == 'group' else "chat" |
627 self.host.bridge.call('sendMessage', None, str(self.target), text, '', mess_type) | 634 self.host.bridge.call('sendMessage', None, str(self.target), text, '', mess_type) |
628 | 635 |
629 def onQuit(self): | 636 def onQuit(self): |
630 base_widget.LiberviaWidget.onQuit(self) | 637 base_widget.LiberviaWidget.onQuit(self) |
631 if self.type == 'group': | 638 if self.type == 'group': |
632 self.host.bridge.call('mucLeave', None, self.target.bare) | 639 self.host.bridge.call('mucLeave', None, self.target.bare) |
633 | |
634 | 640 |
635 def setUserNick(self, nick): | 641 def setUserNick(self, nick): |
636 """Set the nick of the user, usefull for e.g. change the color of the user""" | 642 """Set the nick of the user, usefull for e.g. change the color of the user""" |
637 self.nick = nick | 643 self.nick = nick |
638 | 644 |
673 _wid.setStyleName('chatTextMe') | 679 _wid.setStyleName('chatTextMe') |
674 else: | 680 else: |
675 _wid.setStyleName('chatTextInfo') | 681 _wid.setStyleName('chatTextInfo') |
676 self.content.add(_wid) | 682 self.content.add(_wid) |
677 | 683 |
678 | |
679 def printMessage(self, from_jid, msg, timestamp=None): | 684 def printMessage(self, from_jid, msg, timestamp=None): |
680 """Print message in chat window. Must be implemented by child class""" | 685 """Print message in chat window. Must be implemented by child class""" |
681 _jid=JID(from_jid) | 686 _jid = JID(from_jid) |
682 nick = _jid.node if self.type=='one2one' else _jid.resource | 687 nick = _jid.node if self.type == 'one2one' else _jid.resource |
683 mymess = _jid.resource == self.nick if self.type == "group" else _jid.bare == self.host.whoami.bare #mymess = True if message comes from local user | 688 mymess = _jid.resource == self.nick if self.type == "group" else _jid.bare == self.host.whoami.bare #mymess = True if message comes from local user |
684 if msg.startswith('/me '): | 689 if msg.startswith('/me '): |
685 self.printInfo('* %s %s' % (nick, msg[4:]),type='me') | 690 self.printInfo('* %s %s' % (nick, msg[4:]), type='me') |
686 return | 691 return |
687 self.content.add(ChatText(timestamp, nick, mymess, msg)) | 692 self.content.add(ChatText(timestamp, nick, mymess, msg)) |
688 self.content_scroll.scrollToBottom() | 693 self.content_scroll.scrollToBottom() |
689 | 694 |
690 def startGame(self, game_type, referee, players): | 695 def startGame(self, game_type, referee, players): |
691 """Configure the chat window to start a game""" | 696 """Configure the chat window to start a game""" |
692 if game_type=="Tarot": | 697 if game_type == "Tarot": |
693 if hasattr(self, "tarot_panel"): | 698 if hasattr(self, "tarot_panel"): |
694 return | 699 return |
695 self.tarot_panel = CardPanel(self, referee, players, self.nick) | 700 self.tarot_panel = CardPanel(self, referee, players, self.nick) |
696 self.vpanel.insert(self.tarot_panel, 0) | 701 self.vpanel.insert(self.tarot_panel, 0) |
697 self.vpanel.setCellHeight(self.tarot_panel, self.tarot_panel.getHeight()) | 702 self.vpanel.setCellHeight(self.tarot_panel, self.tarot_panel.getHeight()) |
698 elif game_type=="RadioCol": | 703 elif game_type == "RadioCol": |
699 #XXX: We can have double panel if we join quickly enough to have the group chat start signal | 704 #XXX: We can have double panel if we join quickly enough to have the group chat start signal |
700 # on invitation + the one triggered on room join | 705 # on invitation + the one triggered on room join |
701 if hasattr(self, "radiocol_panel"): | 706 if hasattr(self, "radiocol_panel"): |
702 return | 707 return |
703 self.radiocol_panel = RadioColPanel(self, referee, self.nick) | 708 self.radiocol_panel = RadioColPanel(self, referee, self.nick) |
705 self.vpanel.setCellHeight(self.radiocol_panel, self.radiocol_panel.getHeight()) | 710 self.vpanel.setCellHeight(self.radiocol_panel, self.radiocol_panel.getHeight()) |
706 | 711 |
707 def getGame(self, game_type): | 712 def getGame(self, game_type): |
708 """Return class managing the game type""" | 713 """Return class managing the game type""" |
709 #TODO: check that the game is launched, and manage errors | 714 #TODO: check that the game is launched, and manage errors |
710 if game_type=="Tarot": | 715 if game_type == "Tarot": |
711 return self.tarot_panel | 716 return self.tarot_panel |
712 elif game_type=="RadioCol": | 717 elif game_type == "RadioCol": |
713 return self.radiocol_panel | 718 return self.radiocol_panel |
719 | |
714 | 720 |
715 class WebPanel(base_widget.LiberviaWidget): | 721 class WebPanel(base_widget.LiberviaWidget): |
716 """ (mini)browser like widget """ | 722 """ (mini)browser like widget """ |
717 | 723 |
718 def __init__(self, host, url=None): | 724 def __init__(self, host, url=None): |
720 @param host: SatWebFrontend instance | 726 @param host: SatWebFrontend instance |
721 """ | 727 """ |
722 base_widget.LiberviaWidget.__init__(self, host) | 728 base_widget.LiberviaWidget.__init__(self, host) |
723 self._vpanel = VerticalPanel() | 729 self._vpanel = VerticalPanel() |
724 self._vpanel.setSize('100%', '100%') | 730 self._vpanel.setSize('100%', '100%') |
725 self._url = dialog.ExtTextBox(enter_cb = self.onUrlClick) | 731 self._url = dialog.ExtTextBox(enter_cb=self.onUrlClick) |
726 self._url.setText(url or "") | 732 self._url.setText(url or "") |
727 self._url.setWidth('100%') | 733 self._url.setWidth('100%') |
728 hpanel = HorizontalPanel() | 734 hpanel = HorizontalPanel() |
729 hpanel.add(self._url) | 735 hpanel.add(self._url) |
730 btn = Button("Go", self.onUrlClick) | 736 btn = Button("Go", self.onUrlClick) |
741 self.setWidget(self._vpanel) | 747 self.setWidget(self._vpanel) |
742 | 748 |
743 def onUrlClick(self, sender): | 749 def onUrlClick(self, sender): |
744 self._frame.setUrl(self._url.getText()) | 750 self._frame.setUrl(self._url.getText()) |
745 | 751 |
752 | |
746 class MainPanel(AbsolutePanel): | 753 class MainPanel(AbsolutePanel): |
747 | 754 |
748 def __init__(self, host): | 755 def __init__(self, host): |
749 self.host=host | 756 self.host = host |
750 AbsolutePanel.__init__(self) | 757 AbsolutePanel.__init__(self) |
751 | 758 |
752 #menu | 759 #menu |
753 menu = Menu(host) | 760 menu = Menu(host) |
754 | 761 |
771 self.tab_panel = base_widget.MainTabPanel(host) | 778 self.tab_panel = base_widget.MainTabPanel(host) |
772 self.discuss_panel = base_widget.WidgetsPanel(self.host, locked=True) | 779 self.discuss_panel = base_widget.WidgetsPanel(self.host, locked=True) |
773 self.tab_panel.add(self.discuss_panel, "Discussions") | 780 self.tab_panel.add(self.discuss_panel, "Discussions") |
774 self.tab_panel.selectTab(0) | 781 self.tab_panel.selectTab(0) |
775 | 782 |
776 header=AbsolutePanel() | 783 header = AbsolutePanel() |
777 header.add(menu) | 784 header.add(menu) |
778 header.add(unibox_panel) | 785 header.add(unibox_panel) |
779 header.add(status) | 786 header.add(status) |
780 header.setStyleName('header') | 787 header.setStyleName('header') |
781 self.add(header) | 788 self.add(header) |
800 if not _elts.length: | 807 if not _elts.length: |
801 tab_bar_h = 0 | 808 tab_bar_h = 0 |
802 else: | 809 else: |
803 tab_bar_h = _elts.item(0).offsetHeight | 810 tab_bar_h = _elts.item(0).offsetHeight |
804 ideal_height = Window.getClientHeight() - tab_bar_h | 811 ideal_height = Window.getClientHeight() - tab_bar_h |
805 self.setHeight("%s%s" % (ideal_height, "px")); | 812 self.setHeight("%s%s" % (ideal_height, "px")) |
806 |