from AccessControl import getSecurityManager from zope.interface import Interface, implements, implementer from zope.cachedescriptors.property import CachedProperty from zope.i18n import translate 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 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 .folder import IFolder 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): 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); window.css('top', window.position().top-50 + 'px'); $('#' + 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=translate(_(u'Browse...'), context=self.request)) @implementer(z3c.form.interfaces.IFieldWidget) def ContentTreeFieldWidget(field, request): 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': ('pfwbgedfolder',)}, portal_type=('pfwbgedfolder',))) form.widget(folder=ContentTreeFieldWidget) class Link(Item): """ """ implements(ILink) from collective.dms.basecontent.dmsdocument import IDmsDocument grok.templatedir('templates') grok.context(IDmsDocument) from collective.dms.basecontent.browser.viewlets import BaseViewlet from collective.dms.basecontent.browser import column from collective.dms.basecontent.browser.table import Table class LinksTable(Table): @CachedProperty def values(self): links = [] sm = getSecurityManager() portal_catalog = api.portal.get_tool('portal_catalog') folder_path = '/'.join(self.context.getPhysicalPath()) query = {'path': {'query' : folder_path}, 'portal_type': 'pfwbgedlink', 'sort_on': 'sortable_title', 'sort_order': 'ascending'} results = portal_catalog.searchResults(query) for brain in results: link = brain.getObject() target = link.folder.to_object if sm.checkPermission('View', target): links.append(brain) return links class TitleColumn(column.TitleColumn): grok.name('dms.title') grok.adapts(Interface, Interface, LinksTable) def getLinkContent(self, item): t = item.getObject().folder.to_object.context_title() if isinstance(t, str): t = unicode(t, 'utf-8') return t def getLinkURL(self, item): return item.getObject().folder.to_object.absolute_url() class DeleteColumn(column.DeleteColumn): grok.name('dms.delete') grok.adapts(Interface, Interface, LinksTable) iconName = "++resource++unlink_icon.png" class LinkViewlet(BaseViewlet): grok.order(15) label = _(u"Filed in folders") __table__ = LinksTable class FolderBelowContentViewletManager(grok.ViewletManager): grok.context(IFolder) grok.name('folder.belowcontent') class LinkFolderViewlet(LinkViewlet): grok.context(IFolder) grok.viewletmanager(FolderBelowContentViewletManager)