src/pyams_content/component/paragraph/zmi/container.py
changeset 22 c270ea8f041e
parent 7 cbc55162b64e
child 32 66baddd786d5
equal deleted inserted replaced
21:dc45cba8c8f8 22:c270ea8f041e
     7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
     7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
     8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
    10 # FOR A PARTICULAR PURPOSE.
    10 # FOR A PARTICULAR PURPOSE.
    11 #
    11 #
       
    12 from zope.contentprovider.interfaces import IContentProvider
       
    13 
    12 from pyams_form.interfaces.form import IFormSecurityContext
    14 from pyams_form.interfaces.form import IFormSecurityContext
       
    15 from pyams_viewlet.interfaces import IViewletManager
       
    16 from pyams_viewlet.manager import viewletmanager_config, WeightOrderedViewletManager, TemplateBasedViewletManager
    13 
    17 
    14 __docformat__ = 'restructuredtext'
    18 __docformat__ = 'restructuredtext'
    15 
    19 
    16 
    20 
    17 # import standard library
    21 # import standard library
    21 from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
    25 from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
    22 from pyams_content.component.extfile.interfaces import IExtFileLinksContainerTarget, IExtFileLinksContainer
    26 from pyams_content.component.extfile.interfaces import IExtFileLinksContainerTarget, IExtFileLinksContainer
    23 from pyams_content.component.gallery.interfaces import IGalleryLinksContainerTarget, IGalleryLinksContainer
    27 from pyams_content.component.gallery.interfaces import IGalleryLinksContainerTarget, IGalleryLinksContainer
    24 from pyams_content.component.links.interfaces import ILinkLinksContainerTarget, ILinkLinksContainer
    28 from pyams_content.component.links.interfaces import ILinkLinksContainerTarget, ILinkLinksContainer
    25 from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget, IParagraphContainer, IBaseParagraph
    29 from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget, IParagraphContainer, IBaseParagraph
    26 from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor
    30 from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor, IParagraphTitleToolbar
    27 from pyams_i18n.interfaces import II18n
    31 from pyams_i18n.interfaces import II18n
    28 from pyams_skin.interfaces import IInnerPage, IPageHeader
    32 from pyams_skin.interfaces import IInnerPage, IPageHeader
    29 from pyams_skin.layer import IPyAMSLayer
    33 from pyams_skin.layer import IPyAMSLayer
    30 from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
    34 from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
    31 from pyams_zmi.interfaces.menu import IPropertiesMenu
    35 from pyams_zmi.interfaces.menu import IPropertiesMenu
    42 from pyams_template.template import template_config
    46 from pyams_template.template import template_config
    43 from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter, ContextAdapter
    47 from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter, ContextAdapter
    44 from pyams_utils.url import absolute_url
    48 from pyams_utils.url import absolute_url
    45 from pyramid.exceptions import NotFound
    49 from pyramid.exceptions import NotFound
    46 from pyramid.view import view_config
    50 from pyramid.view import view_config
    47 from pyams_viewlet.viewlet import viewlet_config
    51 from pyams_viewlet.viewlet import viewlet_config, Viewlet
    48 from pyams_zmi.view import AdminView
    52 from pyams_zmi.view import AdminView
    49 from pyramid.decorator import reify
    53 from pyramid.decorator import reify
    50 from z3c.table.column import GetAttrColumn
    54 from z3c.table.column import GetAttrColumn
    51 from zope.interface import implementer
    55 from zope.interface import implementer
    52 
    56 
   178 def ShowHideColumnSecurityContextFactory(column):
   182 def ShowHideColumnSecurityContextFactory(column):
   179     """Show/hide column security context factory"""
   183     """Show/hide column security context factory"""
   180     return column.table.context
   184     return column.table.context
   181 
   185 
   182 
   186 
   183 @adapter_config(name='files', context=(IParagraphContainerTarget, IPyAMSLayer, ParagraphContainerTable),
   187 @viewletmanager_config(name='pyams_paragraph.title_toolbar', context=IBaseParagraph, layer=IPyAMSLayer,
   184                 provides=IColumn)
   188                        view=ParagraphContainerTable, provides=IParagraphTitleToolbar)
   185 class ParagraphContainerExtFileLinksColumn(ActionColumn):
   189 @template_config(template='templates/paragraph-title-toolbar.pt', layer=IPyAMSLayer)
   186     """Paragraphs container external files links column"""
   190 @implementer(IParagraphTitleToolbar)
   187 
   191 class ParagraphTitleToolbarViewletManager(TemplateBasedViewletManager, WeightOrderedViewletManager):
       
   192     """Paragraph title toolbar viewlet manager"""
       
   193 
       
   194 
       
   195 @viewlet_config(name='files', context=IExtFileLinksContainerTarget, layer=IPyAMSLayer, view=ParagraphContainerTable,
       
   196                 manager=IParagraphTitleToolbar, permission=VIEW_SYSTEM_PERMISSION, weight=10)
       
   197 @template_config(template='templates/paragraph-title-icon.pt', layer=IPyAMSLayer)
       
   198 class ParagraphContainerExtFileLinksAction(Viewlet):
       
   199     """Paragraph container external files links column"""
       
   200 
       
   201     action_class = 'action extfiles nowrap width-40'
   188     icon_class = 'fa fa-fw fa-file-text-o'
   202     icon_class = 'fa fa-fw fa-file-text-o'
   189     icon_hint = _("External files")
   203     icon_hint = _("External files")
   190 
   204 
   191     cssClasses = {'td': 'action extfiles nowrap'}
       
   192 
       
   193     url = 'extfile-links.html'
   205     url = 'extfile-links.html'
   194     modal_target = True
   206     modal_target = True
   195 
   207 
   196     weight = 10
   208     @property
   197 
   209     def count(self):
   198     def renderCell(self, item):
   210         return len(IExtFileLinksContainer(self.context).files or ())
   199         if not IExtFileLinksContainerTarget.providedBy(item):
   211 
   200             return ''
   212 
   201         action = '{action} <span class="count">{{count}}</span>'.format(
   213 @viewlet_config(name='links', context=ILinkLinksContainerTarget, layer=IPyAMSLayer, view=ParagraphContainerTable,
   202             action=super(ParagraphContainerExtFileLinksColumn, self).renderCell(item))
   214                 manager=IParagraphTitleToolbar, permission=VIEW_SYSTEM_PERMISSION, weight=20)
   203         length = len(IExtFileLinksContainer(item).files or ())
   215 @template_config(template='templates/paragraph-title-icon.pt', layer=IPyAMSLayer)
   204         if length:
   216 class ParagraphContainerLinkLinksAction(Viewlet):
   205             action = action.format(count='({0})'.format(length))
   217     """Paragraph container links links column"""
   206         else:
   218 
   207             action = action.format(count='')
   219     action_class = 'action links nowrap width-40'
   208         return action
       
   209 
       
   210 
       
   211 @adapter_config(name='links', context=(IParagraphContainerTarget, IPyAMSLayer, ParagraphContainerTable),
       
   212                 provides=IColumn)
       
   213 class ParagraphContainerLinkLinksColumn(ActionColumn):
       
   214     """Paragraphs container links links column"""
       
   215 
       
   216     icon_class = 'fa fa-fw fa-link'
   220     icon_class = 'fa fa-fw fa-link'
   217     icon_hint = _("Useful links")
   221     icon_hint = _("Useful links")
   218 
   222 
   219     cssClasses = {'td': 'action links nowrap'}
       
   220 
       
   221     url = 'link-links.html'
   223     url = 'link-links.html'
   222     modal_target = True
   224     modal_target = True
   223 
   225 
   224     weight = 15
   226     @property
   225 
   227     def count(self):
   226     def renderCell(self, item):
   228         return len(ILinkLinksContainer(self.context).links or ())
   227         if not ILinkLinksContainerTarget.providedBy(item):
   229 
   228             return ''
   230 
   229         action = '{action} <span class="count">{{count}}</span>'.format(
   231 @viewlet_config(name='gallery', context=IGalleryLinksContainerTarget, layer=IPyAMSLayer, view=ParagraphContainerTable,
   230             action=super(ParagraphContainerLinkLinksColumn, self).renderCell(item))
   232                 manager=IParagraphTitleToolbar, permission=VIEW_SYSTEM_PERMISSION, weight=30)
   231         length = len(ILinkLinksContainer(item).links or ())
   233 @template_config(template='templates/paragraph-title-icon.pt', layer=IPyAMSLayer)
   232         if length:
   234 class ParagraphContainerGalleryLinksAction(Viewlet):
   233             action = action.format(count='({0})'.format(length))
   235     """Paragraph container gallery links column"""
   234         else:
   236 
   235             action = action.format(count='')
   237     action_class = 'action galleries nowrap width-40'
   236         return action
       
   237 
       
   238 
       
   239 @adapter_config(name='gallery', context=(IParagraphContainerTarget, IPyAMSLayer, ParagraphContainerTable),
       
   240                 provides=IColumn)
       
   241 class ParagraphContainerGalleryLinksColumn(ActionColumn):
       
   242     """Paragraphs container gallery links column"""
       
   243 
       
   244     icon_class = 'fa fa-fw fa-picture-o'
   238     icon_class = 'fa fa-fw fa-picture-o'
   245     icon_hint = _("Images galleries")
   239     icon_hint = _("Images galleries")
   246 
   240 
   247     cssClasses = {'td': 'action galleries nowrap'}
       
   248 
       
   249     url = 'gallery-links.html'
   241     url = 'gallery-links.html'
   250     modal_target = True
   242     modal_target = True
   251 
   243 
   252     weight = 20
   244     @property
   253 
   245     def count(self):
   254     def renderCell(self, item):
   246         return len(IGalleryLinksContainer(self.context).galleries or ())
   255         if not IGalleryLinksContainerTarget.providedBy(item):
       
   256             return ''
       
   257         action = '{action} <span class="count">{{count}}</span>'.format(
       
   258             action=super(ParagraphContainerGalleryLinksColumn, self).renderCell(item))
       
   259         length = len(IGalleryLinksContainer(item).galleries or ())
       
   260         if length:
       
   261             action = action.format(count='({0})'.format(length))
       
   262         else:
       
   263             action = action.format(count='')
       
   264         return action
       
   265 
   247 
   266 
   248 
   267 @adapter_config(name='name', context=(IParagraphContainerTarget, IPyAMSLayer, ParagraphContainerTable),
   249 @adapter_config(name='name', context=(IParagraphContainerTarget, IPyAMSLayer, ParagraphContainerTable),
   268                 provides=IColumn)
   250                 provides=IColumn)
   269 class ParagraphContainerTitleColumn(I18nColumn, WfModifiedContentColumnMixin, GetAttrColumn):
   251 class ParagraphContainerTitleColumn(I18nColumn, WfModifiedContentColumnMixin, GetAttrColumn):
   281                '</span> '.format(
   263                '</span> '.format(
   282                     title=self.request.localizer.translate(_("Click to open/close all paragraphs editors"))) + \
   264                     title=self.request.localizer.translate(_("Click to open/close all paragraphs editors"))) + \
   283                super(ParagraphContainerTitleColumn, self).renderHeadCell()
   265                super(ParagraphContainerTitleColumn, self).renderHeadCell()
   284 
   266 
   285     def renderCell(self, item):
   267     def renderCell(self, item):
   286         return '<div><span class="small hint" title="{title}" data-ams-hint-gravity="e"' \
   268         registry = self.request.registry
       
   269         provider = registry.queryMultiAdapter((item, self.request, self.table), IContentProvider,
       
   270                                               name='pyams_paragraph.title_toolbar')
       
   271         if provider is not None:
       
   272             provider.update()
       
   273             provider = provider.render()
       
   274         else:
       
   275             provider = ''
       
   276         return '<div>{provider}<span class="small hint" title="{title}" data-ams-hint-gravity="e"' \
   287                '      data-ams-stop-propagation="true" ' \
   277                '      data-ams-stop-propagation="true" ' \
   288                '      data-ams-click-handler="PyAMS_content.paragraphs.switchEditor">' \
   278                '      data-ams-click-handler="PyAMS_content.paragraphs.switchEditor">' \
   289                '    <i class="fa fa-plus-square-o"></i>' \
   279                '    <i class="fa fa-plus-square-o"></i>' \
   290                '</span> '.format(
   280                '</span> '.format(provider=provider,
   291                     title=self.request.localizer.translate(_("Click to open/close paragraph editor"))) + \
   281                                  title=self.request.localizer.translate(_("Click to open/close paragraph editor"))) + \
   292                '<span class="title">{0}</span>'.format(super(ParagraphContainerTitleColumn, self).renderCell(item)) + \
   282                '<span class="title">{0}</span>'.format(super(ParagraphContainerTitleColumn, self).renderCell(item)) + \
   293                '</div><div class="inner-table-form editor margin-x-10 margin-bottom-0"></div>'
   283                '</div><div class="inner-table-form editor margin-x-10 margin-bottom-0"></div>'
   294 
   284 
   295     def getValue(self, obj):
   285     def getValue(self, obj):
   296         return II18n(obj).query_attribute('title', request=self.request) or '--'
   286         return II18n(obj).query_attribute('title', request=self.request) or '--'