--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/search/zmi/__init__.py Wed Nov 07 17:29:54 2018 +0100
@@ -0,0 +1,198 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+from z3c.form import field
+from zope.interface import Interface
+from zope.intid import IIntIds
+
+from pyams_content.features.search import ISearchFolder, SearchFolder
+from pyams_content.interfaces import MANAGE_SITE_PERMISSION
+from pyams_content.shared.common.zmi.summary import SharedContentDublinCoreSummary, SharedContentWorkflowHistorySummary, \
+ SharedContentWorkflowPublicationState
+from pyams_content.shared.site.interfaces import ISiteContainer
+from pyams_content.shared.site.zmi import SiteManagerFoldersSelectorFieldWidget
+from pyams_content.shared.site.zmi.folder import ISiteFolderAddFormFields
+from pyams_form.form import AJAXAddForm, ajax_config
+from pyams_form.interfaces.form import IInnerSubForm
+from pyams_i18n.interfaces import II18n, INegotiator
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_security.zmi.interfaces import IObjectSecurityMenu
+from pyams_skin.interfaces import IContentTitle, IPageHeader
+from pyams_skin.interfaces.viewlet import IMenuHeader, IToolbarAddingMenu, IContextActions
+from pyams_skin.layer import IPyAMSLayer
+from pyams_skin.page import DefaultPageHeaderAdapter, HeaderContentProvider
+from pyams_skin.viewlet.toolbar import ToolbarMenuItem
+from pyams_utils.adapter import ContextRequestAdapter, ContextRequestViewAdapter, NullAdapter, adapter_config
+from pyams_utils.registry import get_utility
+from pyams_utils.unicode import translate_string
+from pyams_utils.url import absolute_url
+from pyams_viewlet.viewlet import contentprovider_config, viewlet_config
+from pyams_workflow.interfaces import IWorkflowPublicationInfo
+from pyams_zmi.form import AdminDialogAddForm
+from pyams_zmi.interfaces.menu import IContentManagementMenu
+from pyams_zmi.layer import IAdminLayer
+
+from pyams_content import _
+
+
+@adapter_config(context=(ISearchFolder, IPyAMSLayer, Interface), provides=IPageHeader)
+class SearchFolderPropertiesHeaderAdapter(DefaultPageHeaderAdapter):
+ """Search folder header adapter"""
+
+ back_url = '/admin#properties.html'
+ back_target = None
+
+ icon_class = 'fa fa-fw fa-edit'
+
+
+@adapter_config(context=(ISearchFolder, IContentManagementMenu), provides=IMenuHeader)
+class SearchFolderContentMenuHeader(ContextRequestAdapter):
+ """Search folder menu header adapter"""
+
+ header = _("This search folder")
+
+
+@adapter_config(context=(ISearchFolder, IPyAMSLayer, Interface), provides=IContentTitle)
+class SearchFolderTitleAdapter(ContextRequestViewAdapter):
+ """Search folder title adapter"""
+
+ @property
+ def title(self):
+ translate = self.request.localizer.translate
+ return translate(_("Search folder « {title} »")).format(
+ title=II18n(self.context).query_attribute('title', request=self.request))
+
+
+@viewlet_config(name='add-search-folder.menu', context=ISiteContainer, layer=IAdminLayer, view=Interface,
+ manager=IToolbarAddingMenu, permission=MANAGE_SITE_PERMISSION, weight=11)
+class SearchFolderAddMenu(ToolbarMenuItem):
+ """Search folder add menu"""
+
+ label = _("Add search folder...")
+ label_css_class = 'fa fa-fw fa-search'
+ url = 'add-search-folder.html'
+ modal_target = True
+
+
+@pagelet_config(name='add-search-folder.html', context=ISiteContainer, layer=IPyAMSLayer,
+ permission=MANAGE_SITE_PERMISSION)
+@ajax_config(name='add-search-folder.json', context=ISiteContainer, layer=IPyAMSLayer, base=AJAXAddForm)
+class SearchFolderAddForm(AdminDialogAddForm):
+ """Search folder add form"""
+
+ @property
+ def title(self):
+ return II18n(self.context).query_attribute('title', request=self.request)
+
+ legend = _("Add search folder")
+ icon_css_class = 'fa fa-fw fa-search'
+
+ fields = field.Fields(ISiteFolderAddFormFields)
+ fields['parent'].widgetFactory = SiteManagerFoldersSelectorFieldWidget
+
+ edit_permission = MANAGE_SITE_PERMISSION
+
+ def updateWidgets(self, prefix=None):
+ super(SearchFolderAddForm, self).updateWidgets(prefix)
+ if 'parent' in self.widgets:
+ self.widgets['parent'].permission = MANAGE_SITE_PERMISSION
+
+ def create(self, data):
+ return SearchFolder()
+
+ def update_content(self, content, data):
+ data = data.get(self, data)
+ # initialize
+ content.title = data['title']
+ content.short_name = data['title']
+ content.notepad = data['notepad']
+ intids = get_utility(IIntIds)
+ parent = intids.queryObject(data.get('parent'))
+ if parent is not None:
+ negotiator = get_utility(INegotiator)
+ title = II18n(content).get_attribute('title', lang=negotiator.server_language)
+ name = translate_string(title, force_lower=True, spaces='-')
+ if name in parent:
+ index = 1
+ new_name = '{name}-{index:02}'.format(name=name, index=index)
+ while new_name in parent:
+ index += 1
+ new_name = '{name}-{index:02}'.format(name=name, index=index)
+ name = new_name
+ parent[name] = content
+
+ def add(self, content):
+ pass
+
+ def nextURL(self):
+ return absolute_url(self.context, self.request, 'admin#site-tree.html')
+
+ def get_ajax_output(self, changes):
+ return {'status': 'reload'}
+
+
+#
+# Search folder content providers
+#
+
+@contentprovider_config(name='content_header', context=ISearchFolder, view=Interface, layer=IPyAMSLayer)
+class SearchFolderHeaderContentProvider(HeaderContentProvider):
+ """Search folder header content provider"""
+
+
+#
+# Custom search folders adapters
+#
+
+@adapter_config(name='workflow-publication-state',
+ context=(ISearchFolder, IPyAMSLayer, SharedContentDublinCoreSummary),
+ provides=IInnerSubForm)
+class SearchFolderWorkflowPublicationState(SharedContentWorkflowPublicationState):
+ """Search folder workflow publication state is disabled"""
+
+ fields = field.Fields(IWorkflowPublicationInfo).select('publication_effective_date',
+ 'publication_expiration_date')
+
+
+@adapter_config(name='workflow-history-summary',
+ context=(ISearchFolder, IPyAMSLayer, SharedContentDublinCoreSummary),
+ provides=IInnerSubForm)
+class SearchFolderWorkflowHistorySummary(SharedContentWorkflowHistorySummary):
+ """Search folder workflow history summary"""
+
+ fields = field.Fields(IWorkflowPublicationInfo).select('first_publication_date')
+
+
+@viewlet_config(name='change-owner.menu', context=ISearchFolder, layer=IPyAMSLayer,
+ view=Interface, manager=IObjectSecurityMenu, permission=MANAGE_SITE_PERMISSION, weight=10)
+class SearchFolderOwnerChangeMenu(NullAdapter):
+ """Search folder owner change menu is disabled"""
+
+
+@viewlet_config(name='duplication.divider', context=ISearchFolder, layer=IPyAMSLayer,
+ view=Interface, manager=IContextActions, permission=MANAGE_SITE_PERMISSION, weight=49)
+class SearchFolderDuplicationMenuDivider(NullAdapter):
+ """Search folder duplication menu divider is disabled"""
+
+
+@viewlet_config(name='duplication.menu', context=ISearchFolder, layer=IPyAMSLayer,
+ view=Interface, manager=IContextActions, permission=MANAGE_SITE_PERMISSION, weight=50)
+class SearchFolderDuplicateMenu(NullAdapter):
+ """Search folder duplication menu item is disabled"""
+
+
+@viewlet_config(name='ask-review.menu', context=ISearchFolder, layer=IPyAMSLayer,
+ view=Interface, manager=IContextActions, permission=MANAGE_SITE_PERMISSION, weight=10)
+class SearchFolderReviewMenu(NullAdapter):
+ """Search folder review menu is disabled"""