changeset 599:a6b9809b9a68 frontends_multi_profiles

merged souliane commits
author Goffi <goffi@goffi.org>
date Fri, 06 Feb 2015 19:31:30 +0100
parents ed6d8f7c6026 (diff) e11e34ac0f67 (current diff)
children 32dbbc941123
files
diffstat 7 files changed, 131 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- a/src/browser/libervia_main.py	Fri Feb 06 17:52:26 2015 +0100
+++ b/src/browser/libervia_main.py	Fri Feb 06 19:31:30 2015 +0100
@@ -505,7 +505,7 @@
             mblog_entry = blog.MicroblogItem(data)
 
             for widget in self.widgets.getWidgets(blog.MicroblogPanel):
-                self.addBlogEntry(widget, sender, _groups, mblog_entry)
+                widget.addEntryIfAccepted(sender, _groups, mblog_entry)
 
             if sender == self.whoami.bare:
                 found = False
@@ -533,24 +533,15 @@
                         self.mblog_cache.remove(entry)
                         break
 
-    def addBlogEntry(self, mblog_panel, sender, _groups, mblog_entry):
-        """Check if an entry can go in MicroblogPanel and add to it
-        @param mblog_panel: MicroblogPanel instance
-        @param sender: jid of the entry sender
-        @param _groups: groups which can receive this entry
-        @param mblog_entry: panels.MicroblogItem instance"""
-        if mblog_entry.type == "comment" or mblog_panel.isJidAccepted(sender) or (_groups == None and self.whoami and sender == self.whoami.bare) \
-           or (_groups and _groups.intersection(mblog_panel.accepted_groups)):
-            mblog_panel.addEntry(mblog_entry)
-
     def FillMicroblogPanel(self, mblog_panel):
         """Fill a microblog panel with entries in cache
+
         @param mblog_panel: MicroblogPanel instance
         """
         #XXX: only our own entries are cached
         for cache_entry in self.mblog_cache:
             _groups, mblog_entry = cache_entry
-            self.addBlogEntry(mblog_panel, self.whoami.bare, *cache_entry)
+            mblog_panel.addEntryIfAccepted(self.whoami.bare, *cache_entry)
 
     def getEntityMBlog(self, entity):
         log.info("geting mblog for entity [%s]" % (entity,))
--- a/src/browser/public/libervia.css	Fri Feb 06 17:52:26 2015 +0100
+++ b/src/browser/public/libervia.css	Fri Feb 06 19:31:30 2015 +0100
@@ -813,6 +813,12 @@
 
 /* BorderWidgets */
 
+.borderWidgetOnDrag {
+    background-color: lightgray;
+    border: 1px dashed #000;
+    border-radius: 1em;
+}
+
 .bottomBorderWidget {
     height: 10px !important;
 }
@@ -821,6 +827,14 @@
     width: 10px !important;
 }
 
+.leftBorderWidget {
+    float: right;
+}
+
+.rightBorderWidget {
+    float: left;
+}
+
 /* Microblog */
 
 .microblogPanel {
--- a/src/browser/sat_browser/base_widget.py	Fri Feb 06 17:52:26 2015 +0100
+++ b/src/browser/sat_browser/base_widget.py	Fri Feb 06 19:31:30 2015 +0100
@@ -20,6 +20,7 @@
 import pyjd  # this is dummy in pyjs
 from sat.core.log import getLogger
 log = getLogger(__name__)
+from sat_frontends.quick_frontend import quick_widgets
 from pyjamas.ui.SimplePanel import SimplePanel
 from pyjamas.ui.AbsolutePanel import AbsolutePanel
 from pyjamas.ui.VerticalPanel import VerticalPanel
@@ -47,23 +48,42 @@
 
 class DragLabel(DragWidget):
 
-    def __init__(self, text, _type):
+    def __init__(self, text, type_, host=None):
+        """Base of Drag n Drop mecanism in Libervia
+
+        @param text: data embedded with in drag n drop operation
+        @param type_: type of data that we are dragging
+        @param host: if not None, the host will be use to highlight BorderWidgets
+        """
         DragWidget.__init__(self)
+        self.host = host
         self._text = text
-        self._type = _type
+        self.type_ = type_
 
     def onDragStart(self, event):
         dt = event.dataTransfer
-        dt.setData('text/plain', "%s\n%s" % (self._text, self._type))
+        dt.setData('text/plain', "%s\n%s" % (self._text, self.type_))
         dt.setDragImage(self.getElement(), 15, 15)
+        if self.host is not None:
+            current_panel = self.host.tab_panel.getCurrentPanel()
+            for widget in current_panel.widgets:
+                if isinstance(widget, BorderWidget):
+                    widget.addStyleName('borderWidgetOnDrag')
+
+    def onDragEnd(self, event):
+        if self.host is not None:
+            current_panel = self.host.tab_panel.getCurrentPanel()
+            for widget in current_panel.widgets:
+                if isinstance(widget, BorderWidget):
+                    widget.removeStyleName('borderWidgetOnDrag')
 
 
 class LiberviaDragWidget(DragLabel):
     """ A DragLabel which keep the widget being dragged as class value """
     current = None  # widget currently dragged
 
-    def __init__(self, text, _type, widget):
-        DragLabel.__init__(self, text, _type)
+    def __init__(self, text, type_, widget):
+        DragLabel.__init__(self, text, type_, widget.host)
         self.widget = widget
 
     def onDragStart(self, event):
@@ -71,6 +91,7 @@
         DragLabel.onDragStart(self, event)
 
     def onDragEnd(self, event):
+        DragLabel.onDragEnd(self, event)
         LiberviaDragWidget.current = None
 
 
@@ -84,8 +105,14 @@
         self.setStyleName('dropCell')
 
     @classmethod
-    def addDropKey(cls, key, callback):
-        DropCell.drop_keys[key] = callback
+    def addDropKey(cls, key, cb):
+        """Add a association between a key and a class to create on drop
+
+        @param key: key to be associated (e.g. "CONTACT", "CHAT")
+        @param cb: either a LiberviaWidget instance, or a callback which return one
+        """
+        DropCell.drop_keys[key] = cb
+
 
     def onDragEnter(self, event):
         if self == LiberviaDragWidget.current:
@@ -148,7 +175,7 @@
             log.warning("unmanaged item type")
             return
         if isinstance(self, LiberviaWidget):
-            self.host.unregisterWidget(self)
+            # self.host.unregisterWidget(self) # FIXME
             self.onQuit()
             if not isinstance(_new_panel, LiberviaWidget):
                 log.warning("droping an object which is not a class of LiberviaWidget")
@@ -164,7 +191,8 @@
         for panel in _unempty_panels:
             td_elt = panel.getElement().parentNode
             DOM.setStyleAttribute(td_elt, "width", "%s%%" % _width)"""
-        #FIXME: delete object ? Check the right way with pyjamas
+        if isinstance(self, quick_widgets.QuickWidget):
+            self.host.widgets.deleteWidget(self)
 
 
 class WidgetMenuBar(base_menu.GenericMenuBar):
@@ -554,7 +582,11 @@
                                                  # dropping a widget there will add a new row
         td_elt = _bottom.getElement().parentNode
         DOM.setStyleAttribute(td_elt, "height", "1px")  # needed so the cell adapt to the size of the border (specially in webkit)
-        self._max_cols = 1  # give the maximum number of columns i a raw
+        self._max_cols = 1  # give the maximum number of columns in a raw
+
+    @property
+    def widgets(self):
+        return iter(self.flextable)
 
     def isLocked(self):
         return self.locked
@@ -563,17 +595,16 @@
         """Change the widget in the given location, add row or columns when necessary"""
         log.debug("changing widget: %s %s %s" % (wid.getDebugName(), row, col))
         last_row = max(0, self.flextable.getRowCount() - 1)
-        try:
-            prev_wid = self.flextable.getWidget(row, col)
-        except:
-            log.error("Trying to change an unexisting widget !")
-            return
+        # try:  # FIXME: except without exception specified !
+        prev_wid = self.flextable.getWidget(row, col)
+        # except:
+        #     log.error("Trying to change an unexisting widget !")
+        #     return
 
         cellFormatter = self.flextable.getFlexCellFormatter()
 
         if isinstance(prev_wid, BorderWidget):
             # We are on a border, we must create a row and/or columns
-            log.debug("BORDER WIDGET")
             prev_wid.removeStyleName('dragover')
 
             if isinstance(prev_wid, BottomBorderWidget):
--- a/src/browser/sat_browser/blog.py	Fri Feb 06 17:52:26 2015 +0100
+++ b/src/browser/sat_browser/blog.py	Fri Feb 06 19:31:30 2015 +0100
@@ -215,7 +215,7 @@
         self.entry_dialog.setWidth('auto')
         try:
             self.toggle_syntax_button.removeFromParent()
-        except TypeError:
+        except (AttributeError, TypeError):
             pass
 
     def __setBubble(self, edit=False):
@@ -234,7 +234,7 @@
         self.bubble.addStyleName("bubble")
         try:
             self.toggle_syntax_button.removeFromParent()
-        except TypeError:
+        except (AttributeError, TypeError):
             pass
         self.entry_dialog.add(self.bubble)
         self.edit(edit)
@@ -297,7 +297,7 @@
             entry = self
         try:
             entry.toggle_syntax_button.removeFromParent()
-        except TypeError:
+        except (AttributeError, TypeError):
             pass
         entry.bubble.edit(edit)
         if edit:
@@ -372,6 +372,9 @@
         self.vpanel.setStyleName('microblogPanel')
         self.setWidget(self.vpanel)
 
+    def __str__(self):
+        return u"Blog Widget [target: {}, profile: {}]".format(self.target, self.profile)
+
     @property
     def target(self):
         return tuple(self.accepted_groups)
@@ -411,33 +414,23 @@
         assert(first.type == 'main_item')
         return first if first.empty else None
 
-    @classmethod
-    def registerClass(cls):
-        base_widget.LiberviaWidget.addDropKey("GROUP", cls.createPanel)
-        base_widget.LiberviaWidget.addDropKey("CONTACT_TITLE", cls.createMetaPanel)
+    @staticmethod
+    def onGroupDrop(host, item):
+        """Generic panel creation for one, several or all groups (meta).
 
-    @classmethod
-    def createPanel(cls, host, item):
-        """Generic panel creation for one, several or all groups (meta).
         @parem host: the SatWebFrontend instance
         @param item: single group as a string, list of groups
          (as an array) or None (for the meta group = "all groups")
         @return: the created MicroblogPanel
         """
-        _items = item if isinstance(item, list) else ([] if item is None else [item])
-        _type = 'ALL' if _items == [] else 'GROUP'
+        items_ = tuple(item) if isinstance(item, list) else (() if item is None else (item,))
+        type_ = 'ALL' if items_ == () else 'GROUP'
         # XXX: pyjamas doesn't support use of cls directly
-        _new_panel = MicroblogPanel(host, _items)
-        host.FillMicroblogPanel(_new_panel)
-        host.bridge.call('getMassiveLastMblogs', _new_panel.massiveInsert, _type, _items, 10)
-        host.setSelected(_new_panel)
-        _new_panel.refresh()
-        return _new_panel
-
-    @classmethod
-    def createMetaPanel(cls, host, item):
-        """Needed for the drop keys to not be mixed between meta panel and panel for "Contacts" group"""
-        return MicroblogPanel.createPanel(host, None)
+        widget = host.widgets.getOrCreateWidget(MicroblogPanel, items_, profile=C.PROF_KEY_NONE, on_new_widget=None, on_existing_widget=C.WIDGET_RECREATE)
+        host.FillMicroblogPanel(widget)
+        host.bridge.getMassiveLastMblogs(type_, items_, 10, profile=C.PROF_KEY_NONE, callback=widget.massiveInsert)
+        widget.refresh() # FIXME: needed ?
+        return widget
 
     @property
     def accepted_groups(self):
@@ -544,8 +537,23 @@
 
         vpanel.insert(entry, idx)
 
-    def addEntry(self, data):
+
+    def addEntryIfAccepted(self, sender, groups, mblog_entry):
+        """Check if an entry can go in MicroblogPanel and add to it
+
+        @param sender: jid of the entry sender
+        @param groups: groups which can receive this entry
+        @param mblog_entry: panels.MicroblogItem instance
+        """
+        if (mblog_entry.type == "comment"
+            or self.isJidAccepted(sender)
+            or (groups == None and sender == self.host.profiles[self.profile].whoami.bare)
+            or (groups and groups.intersection(self.accepted_groups))):
+            self.addEntry(mblog_entry)
+
+    def addEntry(self, data, ignore_invalid=False):
         """Add an entry to the panel
+
         @param data: dict containing the item data
         @return: the added entry, or None
         """
@@ -686,13 +694,21 @@
             self._accepted_groups = groups
         self._accepted_groups.sort()
 
-    def isJidAccepted(self, jid_s):
-        """Tell if a jid is actepted and shown in this panel
-        @param jid_s: jid
-        @return: True if the jid is accepted"""
+    def isJidAccepted(self, jid_):
+        """Tell if a jid is actepted and must be shown in this panel
+
+        @param jid_(jid.JID): jid to check
+        @return: True if the jid is accepted
+        """
         if self.accept_all():
             return True
         for group in self._accepted_groups:
-            if self.host.contact_panel.isContactInGroup(group, jid_s):
+            if self.host.contact_lists[self.profile].isEntityInGroup(jid_, group):
                 return True
         return False
+
+
+base_widget.LiberviaWidget.addDropKey("GROUP", MicroblogPanel.onGroupDrop)
+
+# Needed for the drop keys to not be mixed between meta panel and panel for "Contacts" group
+base_widget.LiberviaWidget.addDropKey("CONTACT_TITLE", lambda host, item: MicroblogPanel.onGroupDrop(host, None))
--- a/src/browser/sat_browser/chat.py	Fri Feb 06 17:52:26 2015 +0100
+++ b/src/browser/sat_browser/chat.py	Fri Feb 06 19:31:30 2015 +0100
@@ -77,7 +77,8 @@
 
         @param host: SatWebFrontend instance
         @param target: entity (jid.JID) with who we have a conversation (contact's jid for one 2 one chat, or MUC room)
-        @param type: one2one for simple conversation, group for MUC"""
+        @param type: one2one for simple conversation, group for MUC
+        """
         QuickChat.__init__(self, host, target, type_, profiles=profiles)
         self.vpanel = VerticalPanel()
         self.vpanel.setSize('100%', '100%')
@@ -127,20 +128,16 @@
         assert len(self.profiles) == 1 and not self.PROFILES_MULTIPLE and not self.PROFILES_ALLOW_NONE
         return list(self.profiles)[0]
 
-    @classmethod
-    def registerClass(cls):
-        base_widget.LiberviaWidget.addDropKey("CONTACT", cls.createPanel)
-
-    @classmethod
-    def createPanel(cls, host, item, type_=C.CHAT_ONE2ONE):
-        assert(item)
-        _contact = item if isinstance(item, jid.JID) else jid.JID(item)
-        host.contact_panel.setContactMessageWaiting(_contact.bare, False)
-        _new_panel = Chat(host, _contact, type_)  # XXX: pyjamas doesn't seems to support creating with cls directly
-        _new_panel.historyPrint()
-        host.setSelected(_new_panel)
-        _new_panel.refresh()
-        return _new_panel
+    # @classmethod
+    # def createPanel(cls, host, item, type_=C.CHAT_ONE2ONE):
+    #     assert(item)
+    #     _contact = item if isinstance(item, jid.JID) else jid.JID(item)
+    #     host.contact_panel.setContactMessageWaiting(_contact.bare, False)
+    #     _new_panel = Chat(host, _contact, type_)  # XXX: pyjamas doesn't seems to support creating with cls directly
+    #     _new_panel.historyPrint()
+    #     host.setSelected(_new_panel)
+    #     _new_panel.refresh()
+    #     return _new_panel
 
     def refresh(self):
         """Refresh the display of this widget. If the unibox is disabled,
@@ -361,4 +358,6 @@
         #TODO
         pass
 
+
 quick_widgets.register(QuickChat, Chat)
+base_widget.LiberviaWidget.addDropKey("CONTACT", lambda host, item: host.widgets.getOrCreateWidget(Chat, jid.JID(item), profile=C.PROF_KEY_NONE, on_new_widget=None, on_existing_widget=C.WIDGET_RECREATE))
--- a/src/browser/sat_browser/contact_list.py	Fri Feb 06 17:52:26 2015 +0100
+++ b/src/browser/sat_browser/contact_list.py	Fri Feb 06 19:31:30 2015 +0100
@@ -73,10 +73,9 @@
 class GroupLabel(base_widget.DragLabel, Label, ClickHandler):
     def __init__(self, host, group):
         self.group = group
-        self.host = host
         Label.__init__(self, group)  # , Element=DOM.createElement('div')
         self.setStyleName('group')
-        base_widget.DragLabel.__init__(self, group, "GROUP")
+        base_widget.DragLabel.__init__(self, group, "GROUP", host)
         ClickHandler.__init__(self)
         self.addClickListener(self)
 
@@ -125,8 +124,7 @@
 
     def __init__(self, host, jid_, name=None, click_listener=None, handle_menu=None):
         VerticalPanel.__init__(self, StyleName='contactBox', VerticalAlignment='middle')
-        base_widget.DragLabel.__init__(self, jid_, "CONTACT")
-        self.host = host
+        base_widget.DragLabel.__init__(self, jid_, "CONTACT", host)
         self.jid = jid_
         self.label = ContactLabel(jid_, name)
         self.avatar = ContactMenuBar(self, host) if handle_menu else Image()
@@ -306,9 +304,8 @@
 class ContactTitleLabel(base_widget.DragLabel, Label, ClickHandler):
     def __init__(self, host, text):
         Label.__init__(self, text)  # , Element=DOM.createElement('div')
-        self.host = host
         self.setStyleName('contactTitle')
-        base_widget.DragLabel.__init__(self, text, "CONTACT_TITLE")
+        base_widget.DragLabel.__init__(self, text, "CONTACT_TITLE", host)
         ClickHandler.__init__(self)
         self.addClickListener(self)
 
@@ -348,7 +345,7 @@
         try:
             # XXX: Pyjamas doesn't do the set casting if None is present
             _keys.remove(None)
-        except KeyError:
+        except (KeyError, ValueError): # XXX: error raised depend on pyjama's compilation options
             pass
         current_groups = set(_keys)
         shown_groups = self._group_panel.getGroups()
--- a/src/browser/sat_browser/richtext.py	Fri Feb 06 17:52:26 2015 +0100
+++ b/src/browser/sat_browser/richtext.py	Fri Feb 06 19:31:30 2015 +0100
@@ -51,6 +51,7 @@
         @param afterEditCb: method to be called when the edition is done
         @param options: list of UI options (see self.readOptions)
         """
+        FlexTable.__init__(self) # FIXME
         self.host = host
         self._debug = False  # TODO: don't forget to set  it False before commit
         self.wysiwyg = False
@@ -84,7 +85,7 @@
         else:
             self.title_offset = self.toolbar_offset = self.content_offset = y_offset
             self.command_offset = self.content_offset + 1
-        FlexTable.__init__(self, self.command_offset + (0 if self.no_command else 1), 2)
+        # FlexTable.__init__(self, rowspan=self.command_offset + (0 if self.no_command else 1), colspan=2) # FIXME
         self.addStyleName(self.style['main'])
 
     def addEditListener(self, listener):
@@ -174,14 +175,14 @@
             self.wysiwyg = wysiwyg
             try:
                 self.wysiwyg_button.setChecked(wysiwyg)
-            except TypeError:
+            except (AttributeError, TypeError):
                 pass
             try:
                 if wysiwyg:
                     self.syntax_label.addStyleName('transparent')
                 else:
                     self.syntax_label.removeStyleName('transparent')
-            except TypeError:
+            except (AttributeError, TypeError):
                 pass
             if not wysiwyg:
                 self.display.removeStyleName('richTextWysiwyg')