src/pyams_content/component/paragraph/zmi/pictogram.py
changeset 1411 cd12f6f824e2
parent 1243 837612af4dc3
equal deleted inserted replaced
1410:94a8e382238f 1411:cd12f6f824e2
     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 
       
    13 __docformat__ = 'restructuredtext'
       
    14 
    12 
    15 import json
    13 import json
    16 
    14 
    17 from pyramid.decorator import reify
    15 from pyramid.decorator import reify
    18 from pyramid.events import subscriber
    16 from pyramid.events import subscriber
    23 from z3c.table.interfaces import IColumn, IValues
    21 from z3c.table.interfaces import IColumn, IValues
    24 from zope.interface import Interface, Invalid, implementer
    22 from zope.interface import Interface, Invalid, implementer
    25 
    23 
    26 from pyams_content.component.paragraph import BaseParagraph
    24 from pyams_content.component.paragraph import BaseParagraph
    27 from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget
    25 from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget
    28 from pyams_content.component.paragraph.interfaces.pictogram import IPictogramContainer, IPictogramContainerTarget, \
    26 from pyams_content.component.paragraph.interfaces.pictogram import IPictogramContainer, \
    29     IPictogramItem, IPictogramParagraph, PICTOGRAM_PARAGRAPH_TYPE
    27     IPictogramContainerTarget, IPictogramItem, IPictogramParagraph, PICTOGRAM_PARAGRAPH_TYPE
    30 from pyams_content.component.paragraph.pictogram import PictogramItem, PictogramParagraph
    28 from pyams_content.component.paragraph.pictogram import PictogramItem, PictogramParagraph
    31 from pyams_content.component.paragraph.zmi import BaseParagraphAJAXAddForm, BaseParagraphAJAXEditForm, \
    29 from pyams_content.component.paragraph.zmi import BaseParagraphAJAXAddForm, \
    32     BaseParagraphAddForm, BaseParagraphAddMenu, BaseParagraphPropertiesEditForm, IParagraphInnerEditFormButtons
    30     BaseParagraphAJAXEditForm, BaseParagraphAddForm, BaseParagraphAddMenu, \
       
    31     BaseParagraphPropertiesEditForm, IParagraphInnerEditFormButtons
    33 from pyams_content.component.paragraph.zmi import IParagraphContainerView
    32 from pyams_content.component.paragraph.zmi import IParagraphContainerView
    34 from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor
    33 from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor
    35 from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
    34 from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
    36 from pyams_content.reference.pictograms.zmi.widget import PictogramSelectFieldWidget
    35 from pyams_content.reference.pictograms.zmi.widget import PictogramSelectFieldWidget
    37 from pyams_content.shared.common import IWfSharedContent
    36 from pyams_content.shared.common import IWfSharedContent
    38 from pyams_file.zmi.image import render_image
    37 from pyams_file.image import render_image
    39 from pyams_form.form import AJAXAddForm, ajax_config
    38 from pyams_form.form import AJAXAddForm, ajax_config
    40 from pyams_form.interfaces.form import IInnerForm, IInnerSubForm
    39 from pyams_form.interfaces.form import IInnerForm, IInnerSubForm
    41 from pyams_form.security import ProtectedFormObjectMixin
    40 from pyams_form.security import ProtectedFormObjectMixin
    42 from pyams_i18n.column import I18nAttrColumn
    41 from pyams_i18n.column import I18nAttrColumn
    43 from pyams_i18n.interfaces import II18n
    42 from pyams_i18n.interfaces import II18n
    44 from pyams_pagelet.pagelet import pagelet_config
    43 from pyams_pagelet.pagelet import pagelet_config
    45 from pyams_skin.container import switch_element_visibility
    44 from pyams_skin.container import switch_element_visibility
    46 from pyams_skin.event import get_json_switched_table_refresh_event, get_json_table_row_refresh_event, \
    45 from pyams_skin.event import get_json_switched_table_refresh_event, \
    47     get_json_widget_refresh_event
    46     get_json_table_row_refresh_event, get_json_widget_refresh_event
    48 from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IWidgetTitleViewletManager
    47 from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IWidgetTitleViewletManager
    49 from pyams_skin.layer import IPyAMSLayer
    48 from pyams_skin.layer import IPyAMSLayer
    50 from pyams_skin.table import BaseTable, I18nColumn, SorterColumn, TrashColumn, VisibilitySwitcherColumn
    49 from pyams_skin.table import BaseTable, I18nColumn, SorterColumn, TrashColumn, \
       
    50     VisibilitySwitcherColumn
    51 from pyams_skin.viewlet.toolbar import ToolbarAction
    51 from pyams_skin.viewlet.toolbar import ToolbarAction
    52 from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
    52 from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
    53 from pyams_utils.text import get_text_start
    53 from pyams_utils.text import get_text_start
    54 from pyams_utils.traversing import get_parent
    54 from pyams_utils.traversing import get_parent
    55 from pyams_utils.url import absolute_url
    55 from pyams_utils.url import absolute_url
    56 from pyams_viewlet.viewlet import viewlet_config
    56 from pyams_viewlet.viewlet import viewlet_config
    57 from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm
    57 from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm
    58 from pyams_zmi.interfaces import IPropertiesEditForm
    58 from pyams_zmi.interfaces import IPropertiesEditForm
    59 from pyams_zmi.zmi.table import InnerTableView
    59 from pyams_zmi.zmi.table import InnerTableView
    60 
    60 
       
    61 
       
    62 __docformat__ = 'restructuredtext'
       
    63 
    61 from pyams_content import _
    64 from pyams_content import _
    62 
    65 
    63 
    66 
    64 class IPictogramsView(Interface):
    67 class IPictogramsView(Interface):
    65     """Pictograms view marker interface"""
    68     """Pictograms view marker interface"""
    67 
    70 
    68 class IPictogramsParentForm(Interface):
    71 class IPictogramsParentForm(Interface):
    69     """Pictograms parent form marker interface"""
    72     """Pictograms parent form marker interface"""
    70 
    73 
    71 
    74 
    72 @viewlet_config(name='add-pictogram-paragraph.menu', context=IParagraphContainerTarget, view=IParagraphContainerView,
    75 @viewlet_config(name='add-pictogram-paragraph.menu', context=IParagraphContainerTarget,
    73                 layer=IPyAMSLayer, manager=IToolbarAddingMenu, weight=600)
    76                 view=IParagraphContainerView, layer=IPyAMSLayer, manager=IToolbarAddingMenu,
       
    77                 weight=600)
    74 class PictogramParagraphAddMenu(BaseParagraphAddMenu):
    78 class PictogramParagraphAddMenu(BaseParagraphAddMenu):
    75     """Pictogram paragraph add menu"""
    79     """Pictogram paragraph add menu"""
    76 
    80 
    77     label = _("Pictograms...")
    81     label = _("Pictograms...")
    78     label_css_class = 'fa fa-fw ' + PictogramParagraph.icon_class
    82     label_css_class = 'fa fa-fw ' + PictogramParagraph.icon_class
    79     url = 'add-pictogram-paragraph.html'
    83     url = 'add-pictogram-paragraph.html'
    80     paragraph_type = PICTOGRAM_PARAGRAPH_TYPE
    84     paragraph_type = PICTOGRAM_PARAGRAPH_TYPE
    81 
    85 
    82 
    86 
    83 @pagelet_config(name='add-pictogram-paragraph.html', context=IParagraphContainerTarget, layer=IPyAMSLayer,
    87 @pagelet_config(name='add-pictogram-paragraph.html', context=IParagraphContainerTarget,
    84                 permission=MANAGE_CONTENT_PERMISSION)
    88                 layer=IPyAMSLayer, permission=MANAGE_CONTENT_PERMISSION)
    85 @ajax_config(name='add-pictogram-paragraph.json', context=IParagraphContainerTarget, layer=IPyAMSLayer,
    89 @ajax_config(name='add-pictogram-paragraph.json', context=IParagraphContainerTarget,
    86              base=BaseParagraphAJAXAddForm)
    90              layer=IPyAMSLayer, base=BaseParagraphAJAXAddForm)
    87 class PictogramParagraphAddForm(BaseParagraphAddForm):
    91 class PictogramParagraphAddForm(BaseParagraphAddForm):
    88     """Pictogram paragraph add form"""
    92     """Pictogram paragraph add form"""
    89 
    93 
    90     legend = _("Add new pictogram paragraph")
    94     legend = _("Add new pictogram paragraph")
    91 
    95 
   113     def get_ajax_output(self, changes):
   117     def get_ajax_output(self, changes):
   114         output = super(self.__class__, self).get_ajax_output(changes)
   118         output = super(self.__class__, self).get_ajax_output(changes)
   115         updated = changes.get(IPictogramParagraph, ())
   119         updated = changes.get(IPictogramParagraph, ())
   116         if 'renderer' in updated:
   120         if 'renderer' in updated:
   117             output.setdefault('events', []).append(
   121             output.setdefault('events', []).append(
   118                 get_json_widget_refresh_event(self.context, self.request, PictogramParagraphInnerEditForm, 'renderer'))
   122                 get_json_widget_refresh_event(self.context, self.request,
       
   123                                               PictogramParagraphInnerEditForm, 'renderer'))
   119         return output
   124         return output
   120 
   125 
   121 
   126 
   122 @adapter_config(context=(IPictogramParagraph, IPyAMSLayer), provides=IParagraphInnerEditor)
   127 @adapter_config(context=(IPictogramParagraph, IPyAMSLayer), provides=IParagraphInnerEditor)
   123 @ajax_config(name='inner-properties.json', context=IPictogramParagraph, layer=IPyAMSLayer,
   128 @ajax_config(name='inner-properties.json', context=IPictogramParagraph, layer=IPyAMSLayer,
   178     @reify
   183     @reify
   179     def values(self):
   184     def values(self):
   180         return list(super(PictogramsTable, self).values)
   185         return list(super(PictogramsTable, self).values)
   181 
   186 
   182 
   187 
   183 @adapter_config(context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable), provides=IValues)
   188 @adapter_config(context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable),
       
   189                 provides=IValues)
   184 class PictogramsTableValuesAdapter(ContextRequestViewAdapter):
   190 class PictogramsTableValuesAdapter(ContextRequestViewAdapter):
   185     """Pictograms table values adapter"""
   191     """Pictograms table values adapter"""
   186 
   192 
   187     @property
   193     @property
   188     def values(self):
   194     def values(self):
   189         return IPictogramContainer(self.context).values()
   195         return IPictogramContainer(self.context).values()
   190 
   196 
   191 
   197 
   192 @adapter_config(name='sorter', context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable), provides=IColumn)
   198 @adapter_config(name='sorter',
       
   199                 context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable),
       
   200                 provides=IColumn)
   193 class PictogramsTableSorterColumn(ProtectedFormObjectMixin, SorterColumn):
   201 class PictogramsTableSorterColumn(ProtectedFormObjectMixin, SorterColumn):
   194     """Pictograms table sorter column"""
   202     """Pictograms table sorter column"""
   195 
   203 
   196 
   204 
   197 @view_config(name='set-pictograms-order.json', context=IPictogramContainer, request_type=IPyAMSLayer,
   205 @view_config(name='set-pictograms-order.json', context=IPictogramContainer,
   198              permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
   206              request_type=IPyAMSLayer, permission=MANAGE_CONTENT_PERMISSION,
       
   207              renderer='json', xhr=True)
   199 def set_pictograms_order(request):
   208 def set_pictograms_order(request):
   200     """Update pictograms order"""
   209     """Update pictograms order"""
   201     order = list(map(str, json.loads(request.params.get('names'))))
   210     order = list(map(str, json.loads(request.params.get('names'))))
   202     request.context.updateOrder(order)
   211     request.context.updateOrder(order)
   203     return {'status': 'success'}
   212     return {'status': 'success'}
   204 
   213 
   205 
   214 
   206 @adapter_config(name='show-hide', context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable),
   215 @adapter_config(name='show-hide',
       
   216                 context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable),
   207                 provides=IColumn)
   217                 provides=IColumn)
   208 class PictogramsTableShowHideColumn(ProtectedFormObjectMixin, VisibilitySwitcherColumn):
   218 class PictogramsTableShowHideColumn(ProtectedFormObjectMixin, VisibilitySwitcherColumn):
   209     """Pictograms container visibility switcher column"""
   219     """Pictograms container visibility switcher column"""
   210 
   220 
   211 
   221 
   212 @view_config(name='switch-pictogram-visibility.json', context=IPictogramContainer, request_type=IPyAMSLayer,
   222 @view_config(name='switch-pictogram-visibility.json', context=IPictogramContainer,
   213              permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
   223              request_type=IPyAMSLayer, permission=MANAGE_CONTENT_PERMISSION,
       
   224              renderer='json', xhr=True)
   214 def switch_pictogram_visibility(request):
   225 def switch_pictogram_visibility(request):
   215     """Set pictogram visibility"""
   226     """Set pictogram visibility"""
   216     return switch_element_visibility(request, IPictogramContainer)
   227     return switch_element_visibility(request, IPictogramContainer)
   217 
   228 
   218 
   229 
   219 @adapter_config(name='image', context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable), provides=IColumn)
   230 @adapter_config(name='image',
       
   231                 context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable),
       
   232                 provides=IColumn)
   220 class PictogramsTableImageColumn(GetAttrColumn):
   233 class PictogramsTableImageColumn(GetAttrColumn):
   221     """Pictogram image column"""
   234     """Pictogram image column"""
   222 
   235 
   223     header = ''
   236     header = ''
   224     weight = 3
   237     weight = 3
   233             if image:
   246             if image:
   234                 return render_image(image, 48, 48, self.request, timestamp=True)
   247                 return render_image(image, 48, 48, self.request, timestamp=True)
   235         return '--'
   248         return '--'
   236 
   249 
   237 
   250 
   238 @adapter_config(name='name', context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable), provides=IColumn)
   251 @adapter_config(name='name',
       
   252                 context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable),
       
   253                 provides=IColumn)
   239 class PictogramsTableNameColumn(I18nColumn, I18nAttrColumn):
   254 class PictogramsTableNameColumn(I18nColumn, I18nAttrColumn):
   240     """Pictograms table name column"""
   255     """Pictograms table name column"""
   241 
   256 
   242     _header = _("pictogram-item-header", default="Header")
   257     _header = _("pictogram-item-header", default="Header")
   243     attrName = 'label'
   258     attrName = 'label'
   250             if pictogram is not None:
   265             if pictogram is not None:
   251                 value = II18n(pictogram).query_attribute('header', request=self.request)
   266                 value = II18n(pictogram).query_attribute('header', request=self.request)
   252         return value or BaseParagraph.empty_title
   267         return value or BaseParagraph.empty_title
   253 
   268 
   254 
   269 
   255 @adapter_config(name='body', context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable), provides=IColumn)
   270 @adapter_config(name='body',
       
   271                 context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable),
       
   272                 provides=IColumn)
   256 class PictogramsTableBodyColumn(I18nColumn, I18nAttrColumn):
   273 class PictogramsTableBodyColumn(I18nColumn, I18nAttrColumn):
   257     """Pictograms table body column"""
   274     """Pictograms table body column"""
   258 
   275 
   259     _header = _("Associated text")
   276     _header = _("Associated text")
   260     attrName = 'body'
   277     attrName = 'body'
   265         if not value:
   282         if not value:
   266             return BaseParagraph.empty_title
   283             return BaseParagraph.empty_title
   267         return get_text_start(value, 80, 10)
   284         return get_text_start(value, 80, 10)
   268 
   285 
   269 
   286 
   270 @adapter_config(name='trash', context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable), provides=IColumn)
   287 @adapter_config(name='trash',
       
   288                 context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable),
       
   289                 provides=IColumn)
   271 class PictogramsTableTrashColumn(ProtectedFormObjectMixin, TrashColumn):
   290 class PictogramsTableTrashColumn(ProtectedFormObjectMixin, TrashColumn):
   272     """Pictograms table trash column"""
   291     """Pictograms table trash column"""
   273 
   292 
   274 
   293 
   275 @adapter_config(name='pictograms', context=(IPictogramContainerTarget, IPyAMSLayer, IPictogramsParentForm),
   294 @adapter_config(name='pictograms',
       
   295                 context=(IPictogramContainerTarget, IPyAMSLayer, IPictogramsParentForm),
   276                 provides=IInnerSubForm)
   296                 provides=IInnerSubForm)
   277 @implementer(IPictogramsView)
   297 @implementer(IPictogramsView)
   278 class PictogramsView(InnerTableView):
   298 class PictogramsView(InnerTableView):
   279     """Pictograms view"""
   299     """Pictograms view"""
   280 
   300 
   286 
   306 
   287 #
   307 #
   288 # Pictograms forms
   308 # Pictograms forms
   289 #
   309 #
   290 
   310 
   291 @viewlet_config(name='add-pictogram.action', context=IPictogramContainerTarget, layer=IPyAMSLayer, view=IPictogramsView,
   311 @viewlet_config(name='add-pictogram.action', context=IPictogramContainerTarget,
   292                 manager=IWidgetTitleViewletManager, permission=MANAGE_CONTENT_PERMISSION, weight=1)
   312                 layer=IPyAMSLayer, view=IPictogramsView, manager=IWidgetTitleViewletManager,
       
   313                 permission=MANAGE_CONTENT_PERMISSION, weight=1)
   293 class PictogramAddAction(ToolbarAction):
   314 class PictogramAddAction(ToolbarAction):
   294     """Pictogram add action"""
   315     """Pictogram add action"""
   295 
   316 
   296     label = _("Add pictogram")
   317     label = _("Add pictogram")
   297     label_css_class = 'fa fa-fw fa-plus'
   318     label_css_class = 'fa fa-fw fa-plus'
   327 
   348 
   328     def get_ajax_output(self, changes):
   349     def get_ajax_output(self, changes):
   329         return {
   350         return {
   330             'status': 'success',
   351             'status': 'success',
   331             'message': self.request.localizer.translate(_("Pictogram was correctly added")),
   352             'message': self.request.localizer.translate(_("Pictogram was correctly added")),
   332             'events': [get_json_switched_table_refresh_event(self.context, self.request, PictogramsTable), ]
   353             'events': [get_json_switched_table_refresh_event(self.context, self.request,
       
   354                                                              PictogramsTable), ]
   333         }
   355         }
   334 
   356 
   335 
   357 
   336 @subscriber(IDataExtractedEvent, form_selector=PictogramAddForm)
   358 @subscriber(IDataExtractedEvent, form_selector=PictogramAddForm)
   337 def handle_pictogram_add_form_data_extraction(event):
   359 def handle_pictogram_add_form_data_extraction(event):
   339     data = event.data
   361     data = event.data
   340     if not data.get('pictogram_name'):
   362     if not data.get('pictogram_name'):
   341         event.form.widgets.errors += (Invalid(_("You must select a pictogram!")), )
   363         event.form.widgets.errors += (Invalid(_("You must select a pictogram!")), )
   342 
   364 
   343 
   365 
   344 @pagelet_config(name='properties.html', context=IPictogramItem, layer=IPyAMSLayer, permission=MANAGE_CONTENT_PERMISSION)
   366 @pagelet_config(name='properties.html', context=IPictogramItem, layer=IPyAMSLayer,
       
   367                 permission=MANAGE_CONTENT_PERMISSION)
   345 @ajax_config(name='properties.json', context=IPictogramItem, layer=IPyAMSLayer)
   368 @ajax_config(name='properties.json', context=IPictogramItem, layer=IPyAMSLayer)
   346 class PictogramPropertiesEditForm(AdminDialogEditForm):
   369 class PictogramPropertiesEditForm(AdminDialogEditForm):
   347     """Pictogram properties edit form"""
   370     """Pictogram properties edit form"""
   348 
   371 
   349     prefix = 'pictogram_properties.'
   372     prefix = 'pictogram_properties.'
   365         output = super(self.__class__, self).get_ajax_output(changes)
   388         output = super(self.__class__, self).get_ajax_output(changes)
   366         updated = changes.get(IPictogramItem, ())
   389         updated = changes.get(IPictogramItem, ())
   367         if updated:
   390         if updated:
   368             target = get_parent(self.context, IPictogramContainerTarget)
   391             target = get_parent(self.context, IPictogramContainerTarget)
   369             output.setdefault('events', []).append(
   392             output.setdefault('events', []).append(
   370                 get_json_table_row_refresh_event(target, self.request, PictogramsTable, self.context))
   393                 get_json_table_row_refresh_event(target, self.request,
       
   394                                                  PictogramsTable, self.context))
   371         return output
   395         return output
   372 
   396 
   373 
   397 
   374 @subscriber(IDataExtractedEvent, form_selector=PictogramPropertiesEditForm)
   398 @subscriber(IDataExtractedEvent, form_selector=PictogramPropertiesEditForm)
   375 def handle_pictogram_edit_form_data_extraction(event):
   399 def handle_pictogram_edit_form_data_extraction(event):