diff --git a/src/pfwbged/folder/configure.zcml b/src/pfwbged/folder/configure.zcml index 5cdc1f9..049e60b 100644 --- a/src/pfwbged/folder/configure.zcml +++ b/src/pfwbged/folder/configure.zcml @@ -56,4 +56,11 @@ editview=".portlet.EditForm" /> + + diff --git a/src/pfwbged/folder/folder.py b/src/pfwbged/folder/folder.py index b840aba..810d8f2 100644 --- a/src/pfwbged/folder/folder.py +++ b/src/pfwbged/folder/folder.py @@ -92,7 +92,7 @@ class Folder(Container): parents.append(item.folder.to_object) return parents - def child_folders(self): + def child_folders_brains(self): intids = component.getUtility(IIntIds) intid_catalog = component.getUtility(ICatalog) try: @@ -118,9 +118,13 @@ class Folder(Container): uuids.append(IUUID(document)) portal_catalog = api.portal.get_tool('portal_catalog') - children = portal_catalog.searchResults({'UID': uuids}) + return portal_catalog.searchResults({'UID': uuids}) - return [IContentListingObject(x) for x in children] + def child_folders(self): + return [IContentListingObject(x) for x in self.child_folders_brains()] + + def child_folders_objects(self): + return [x.getObject() for x in self.child_folders_brains()] def intid(self): intids = component.getUtility(IIntIds) diff --git a/src/pfwbged/folder/input_recurse.pt b/src/pfwbged/folder/input_recurse.pt new file mode 100644 index 0000000..5bb7b08 --- /dev/null +++ b/src/pfwbged/folder/input_recurse.pt @@ -0,0 +1,29 @@ + + +
  • + + + + + Selected Item Title + + +
      + +
    +
    +
  • +
    +
    diff --git a/src/pfwbged/folder/link.py b/src/pfwbged/folder/link.py index 44bc04a..5353d52 100644 --- a/src/pfwbged/folder/link.py +++ b/src/pfwbged/folder/link.py @@ -1,9 +1,14 @@ from AccessControl import getSecurityManager from zope.interface import Interface, implements, implementer from zope.cachedescriptors.property import CachedProperty +from zope.component import getMultiAdapter, getUtility +from Products.CMFCore.utils import getToolByName +from Products.CMFPlone.utils import base_hasattr from five import grok from plone.directives import form +from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile + from plone.dexterity.content import Item from plone.supermodel import model @@ -12,24 +17,156 @@ from plone.formwidget.contenttree import ObjPathSourceBinder from plone import api from z3c.relationfield.schema import RelationChoice +from plone.app.contentlisting.realobject import RealContentListingObject from . import _ -from plone.formwidget.contenttree.widget import ContentTreeWidget +from plone.app.layout.navigation.interfaces import INavtreeStrategy +from plone.formwidget.contenttree.utils import closest_content +import plone.formwidget.contenttree.widget import z3c.form.widget +from zc.relation.interfaces import ICatalog +from zope.app.intid.interfaces import IIntIds + + +class FolderListingObject(RealContentListingObject): + children = [] + selectable = True + show_children = True + + def intid(self): + intids = getUtility(IIntIds) + intid_catalog = getUtility(ICatalog) + intid = intids.getId(self.getObject()) + return intid + + +class Fetch(plone.formwidget.contenttree.widget.Fetch): + recurse_template = ViewPageTemplateFile('input_recurse.pt') + + def __call__(self): + # We want to check that the user was indeed allowed to access the + # form for this widget. We can only this now, since security isn't + # applied yet during traversal. + self.validate_access() + + widget = self.context + context = widget.context + + # Update the widget before accessing the source. + # The source was only bound without security applied + # during traversal before. + widget.update() + source = widget.bound_source + + # Convert token from request to the path to the object + token = self.request.form.get('href', None) + level = self.request.form.get('rel', 0) + + children = [] + if level == '0': + current_user = api.user.get_current() + current_user_id = current_user.getId() + members_folder = getattr(api.portal.get(), 'Members') + if base_hasattr(members_folder, current_user_id): + folder = members_folder[current_user_id] + children.append(FolderListingObject(folder)) + children[-1].Title = _('Home Folder') + + dossiers_folder = getattr(api.portal.get(), 'dossiers') + for group in api.group.get_groups(user=current_user): + if base_hasattr(dossiers_folder, group.id): + folder = dossiers_folder[group.id] + children.append(FolderListingObject(folder)) + + else: + parent_folder = api.portal.get().restrictedTraverse(str(token)) + for folder in parent_folder.child_folders_objects(): + children.append(FolderListingObject(folder)) + + self.request.response.setHeader('X-Theme-Disabled', 'True') + if not children: + return '' + return self.fragment_template(children=children, level=int(level)) + + +class ContentTreeWidget(plone.formwidget.contenttree.widget.ContentTreeWidget): + show_all_content_types = False + + def js_extra(self): + # this is copied from parent class, the only difference is the URL + # used for Ajax requests. + source = self.bound_source + form_url = self.request.getURL() + url = "%s/++widget++%s/@@foldertree-fetch" % (form_url, self.name) + + return """\ + + $('#%(id)s-widgets-query').each(function() { + if($(this).siblings('input.searchButton').length > 0) { return; } + $(document.createElement('input')) + .attr({ + 'type': 'button', + 'value': '%(button_val)s' + }) + .addClass('searchButton') + .click( function () { + var parent = $(this).parents("*[id$='-autocomplete']") + var window = parent.siblings("*[id$='-contenttree-window']") + window.showDialog('%(url)s', %(expandSpeed)d); + $('#' + parent.attr('id').replace('autocomplete', 'contenttree')).contentTree( + { + script: '%(url)s', + folderEvent: '%(folderEvent)s', + selectEvent: '%(selectEvent)s', + expandSpeed: %(expandSpeed)d, + collapseSpeed: %(collapseSpeed)s, + multiFolder: %(multiFolder)s, + multiSelect: %(multiSelect)s, + rootUrl: '%(rootUrl)s' + }, + function(event, selected, data, title) { + // alert(event + ', ' + selected + ', ' + data + ', ' + title); + } + ); + }).insertAfter($(this)); + }); + $('#%(id)s-contenttree-window').find('.contentTreeAdd').unbind('click').click(function () { + $(this).contentTreeAdd(); + }); + $('#%(id)s-contenttree-window').find('.contentTreeCancel').unbind('click').click(function () { + $(this).contentTreeCancel(); + }); + $('#%(id)s-widgets-query').after(" "); + + """ % dict(url=url, + id=self.name.replace('.', '-'), + folderEvent=self.folderEvent, + selectEvent=self.selectEvent, + expandSpeed=self.expandSpeed, + collapseSpeed=self.collapseSpeed, + multiFolder=str(self.multiFolder).lower(), + multiSelect=str(self.multi_select).lower(), + rootUrl=source.navigation_tree_query['path']['query'], + name=self.name, + klass=self.klass, + title=self.title, + button_val=_(u'Browse...')) + + + + @implementer(z3c.form.interfaces.IFieldWidget) def ContentTreeFieldWidget(field, request): - tree_widget = ContentTreeWidget(request) - tree_widget.show_all_content_types = False - return z3c.form.widget.FieldWidget(field, tree_widget) + return z3c.form.widget.FieldWidget(field, ContentTreeWidget(request)) class ILink(model.Schema): """ """ folder = RelationChoice(title=_(u'Folder'), required=True, source=ObjPathSourceBinder( - navigation_tree_query={'portal_type': ('Folder', 'pfwbgedfolder',)})) + navigation_tree_query={'portal_type': ('pfwbgedfolder',)})) form.widget(folder=ContentTreeFieldWidget)