src/pyams_content/component/paragraph/zmi/text.py
changeset 443 326adf3362d8
parent 415 43f42d74cdb8
equal deleted inserted replaced
442:5dc8421cbcfc 443:326adf3362d8
       
     1 #
       
     2 # Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
       
     3 # All Rights Reserved.
       
     4 #
       
     5 # This software is subject to the provisions of the Zope Public License,
       
     6 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
       
     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
       
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
       
    10 # FOR A PARTICULAR PURPOSE.
       
    11 #
       
    12 from pyams_skin.interfaces.tinymce import ITinyMCEConfiguration
       
    13 
       
    14 __docformat__ = 'restructuredtext'
       
    15 
       
    16 
       
    17 # import standard library
       
    18 
       
    19 # import interfaces
       
    20 from pyams_content.component.association.interfaces import IAssociationTarget
       
    21 from pyams_content.component.association.zmi.interfaces import IAssociationsParentForm
       
    22 from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget, IParagraphContainer, \
       
    23     IParagraphPreview
       
    24 from pyams_content.component.paragraph.interfaces.text import ITextParagraph, TEXT_PARAGRAPH_TYPE
       
    25 from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor, IParagraphContainerView
       
    26 from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
       
    27 from pyams_form.interfaces.form import IInnerForm, IEditFormButtons
       
    28 from pyams_skin.interfaces.viewlet import IToolbarAddingMenu
       
    29 from pyams_skin.layer import IPyAMSLayer
       
    30 from pyams_zmi.interfaces import IPropertiesEditForm
       
    31 from z3c.form.interfaces import INPUT_MODE
       
    32 
       
    33 # import packages
       
    34 from pyams_content.component.association.zmi import AssociationsTable
       
    35 from pyams_content.component.paragraph.text import TextParagraph
       
    36 from pyams_content.component.paragraph.zmi import BaseParagraphAJAXAddForm, BaseParagraphAJAXEditForm, \
       
    37     BaseParagraphAddMenu, BaseParagraphPropertiesEditForm
       
    38 from pyams_content.component.paragraph.zmi.container import ParagraphContainerTable, \
       
    39     ParagraphTitleToolbarViewletManager
       
    40 from pyams_content.features.renderer.zmi import BaseRenderedContentPreview
       
    41 from pyams_content.features.renderer.zmi.widget import RendererFieldWidget
       
    42 from pyams_pagelet.pagelet import pagelet_config
       
    43 from pyams_utils.adapter import adapter_config, ContextRequestAdapter
       
    44 from pyams_utils.traversing import get_parent
       
    45 from pyams_viewlet.viewlet import viewlet_config
       
    46 from pyams_zmi.form import AdminDialogAddForm
       
    47 from pyramid.view import view_config
       
    48 from z3c.form import field, button
       
    49 from zope.interface import implementer, Interface
       
    50 
       
    51 from pyams_content import _
       
    52 
       
    53 
       
    54 #
       
    55 # Text paragraph form interface and custom HTML edit widget
       
    56 #
       
    57 
       
    58 class ITextParagraphForm(Interface):
       
    59     """Marker interface for framed text paragraph form"""
       
    60 
       
    61 
       
    62 @adapter_config(context=(ITextParagraphForm, IPyAMSLayer), provides=ITinyMCEConfiguration)
       
    63 class TextParagraphBodyEditorConfiguration(ContextRequestAdapter):
       
    64     """Custom configuration for 'body' widget editor"""
       
    65 
       
    66     configuration = {
       
    67         'ams-tinymce-menubar': False,
       
    68         'ams-tinymce-plugins': ['lists', ],
       
    69         'ams-tinymce-toolbar': 'undo redo | bold italic | bullist numlist',
       
    70         'ams-tinymce-toolbar1': False,
       
    71         'ams-tinymce-toolbar2': False
       
    72     }
       
    73 
       
    74 
       
    75 #
       
    76 # Framed text paragraph
       
    77 #
       
    78 
       
    79 @viewlet_config(name='add-text-paragraph.menu', context=IParagraphContainerTarget, view=IParagraphContainerView,
       
    80                 layer=IPyAMSLayer, manager=IToolbarAddingMenu, weight=580)
       
    81 class TextParagraphAddMenu(BaseParagraphAddMenu):
       
    82     """Framed text paragraph add menu"""
       
    83 
       
    84     label = _("Framed text...")
       
    85     label_css_class = 'fa fa-fw fa-list-alt'
       
    86     url = 'add-text-paragraph.html'
       
    87     paragraph_type = TEXT_PARAGRAPH_TYPE
       
    88 
       
    89 
       
    90 @pagelet_config(name='add-text-paragraph.html', context=IParagraphContainerTarget, layer=IPyAMSLayer,
       
    91                 permission=MANAGE_CONTENT_PERMISSION)
       
    92 @implementer(ITextParagraphForm)
       
    93 class TextParagraphAddForm(AdminDialogAddForm):
       
    94     """Framed text paragraph add form"""
       
    95 
       
    96     legend = _("Add new framed text paragraph")
       
    97     dialog_class = 'modal-large'
       
    98     icon_css_class = 'fa fa-fw fa-list-alt'
       
    99     label_css_class = 'control-label col-md-2'
       
   100     input_css_class = 'col-md-10'
       
   101 
       
   102     fields = field.Fields(ITextParagraph).omit('__parent__', '__name__', 'visible')
       
   103     ajax_handler = 'add-text-paragraph.json'
       
   104     edit_permission = MANAGE_CONTENT_PERMISSION
       
   105 
       
   106     def updateWidgets(self, prefix=None):
       
   107         super(TextParagraphAddForm, self).updateWidgets(prefix)
       
   108         if 'body' in self.widgets:
       
   109             self.widgets['body'].widget_css_class = 'textarea'
       
   110 
       
   111     def create(self, data):
       
   112         return TextParagraph()
       
   113 
       
   114     def add(self, object):
       
   115         IParagraphContainer(self.context).append(object)
       
   116 
       
   117 
       
   118 @view_config(name='add-text-paragraph.json', context=IParagraphContainerTarget, request_type=IPyAMSLayer,
       
   119              permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
       
   120 class TextParagraphAJAXAddForm(BaseParagraphAJAXAddForm, TextParagraphAddForm):
       
   121     """Framed text paragraph add form, JSON renderer"""
       
   122 
       
   123 
       
   124 @pagelet_config(name='properties.html', context=ITextParagraph, layer=IPyAMSLayer,
       
   125                 permission=MANAGE_CONTENT_PERMISSION)
       
   126 @implementer(ITextParagraphForm)
       
   127 class TextParagraphPropertiesEditForm(BaseParagraphPropertiesEditForm):
       
   128     """Framed text paragraph properties edit form"""
       
   129 
       
   130     legend = _("Edit framed text paragraph properties")
       
   131     dialog_class = 'modal-large'
       
   132     icon_css_class = 'fa fa-fw fa-list-alt'
       
   133     label_css_class = 'control-label col-md-2'
       
   134     input_css_class = 'col-md-10'
       
   135 
       
   136     fields = field.Fields(ITextParagraph).omit('__parent__', '__name__', 'visible')
       
   137     fields['renderer'].widgetFactory = RendererFieldWidget
       
   138 
       
   139     ajax_handler = 'properties.json'
       
   140     edit_permission = MANAGE_CONTENT_PERMISSION
       
   141 
       
   142     def updateWidgets(self, prefix=None):
       
   143         super(TextParagraphPropertiesEditForm, self).updateWidgets(prefix)
       
   144         if 'body' in self.widgets:
       
   145             body_widget = self.widgets['body']
       
   146             for lang in body_widget.langs:
       
   147                 widget = body_widget.widgets[lang]
       
   148                 widget.id = '{id}_{name}'.format(id=widget.id, name=self.context.__name__)
       
   149             body_widget.widget_css_class = 'textarea'
       
   150 
       
   151 
       
   152 class ITextParagraphInnerEditForm(Interface):
       
   153     """Marker interface for framed text paragraph inner form"""
       
   154 
       
   155 
       
   156 @view_config(name='properties.json', context=ITextParagraph, request_type=IPyAMSLayer,
       
   157              permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
       
   158 class TextParagraphPropertiesAJAXEditForm(BaseParagraphAJAXEditForm, TextParagraphPropertiesEditForm):
       
   159     """Framed text paragraph properties edit form, JSON renderer"""
       
   160 
       
   161     def get_ajax_output(self, changes):
       
   162         output = super(TextParagraphPropertiesAJAXEditForm, self).get_ajax_output(changes)
       
   163         if 'body' in changes.get(ITextParagraph, ()):
       
   164             # refresh associations count markers
       
   165             parent = get_parent(self.context, IAssociationTarget)
       
   166             table = ParagraphContainerTable(parent, self.request)
       
   167             viewlet = ParagraphTitleToolbarViewletManager(parent, self.request, table)
       
   168             viewlet.update()
       
   169             output.setdefault('events', []).append({
       
   170                 'event': 'myams.refresh',
       
   171                 'options': {
       
   172                     'handler': 'PyAMS_content.paragraphs.updateToolbar',
       
   173                     'object_name': self.context.__name__,
       
   174                     'toolbar_tag': viewlet.render()
       
   175                 }
       
   176             })
       
   177             # refresh associations table
       
   178             associations_table = AssociationsTable(self.context, self.request)
       
   179             associations_table.update()
       
   180             output.setdefault('events', []).append({
       
   181                 'event': 'myams.refresh',
       
   182                 'options': {
       
   183                     'handler': 'PyAMS_content.associations.refreshAssociations',
       
   184                     'object_id': associations_table.id,
       
   185                     'table': associations_table.render()
       
   186                 }
       
   187             })
       
   188         return output
       
   189 
       
   190 
       
   191 @adapter_config(context=(ITextParagraph, IPyAMSLayer), provides=IParagraphInnerEditor)
       
   192 @implementer(IInnerForm, IPropertiesEditForm, IAssociationsParentForm, ITextParagraphInnerEditForm)
       
   193 class TextParagraphInnerEditForm(TextParagraphPropertiesEditForm):
       
   194     """Framed text paragraph inner edit form"""
       
   195 
       
   196     legend = None
       
   197     ajax_handler = 'inner-properties.json'
       
   198 
       
   199     @property
       
   200     def buttons(self):
       
   201         if self.mode == INPUT_MODE:
       
   202             return button.Buttons(IEditFormButtons)
       
   203         else:
       
   204             return button.Buttons()
       
   205 
       
   206 
       
   207 @view_config(name='inner-properties.json', context=ITextParagraph, request_type=IPyAMSLayer,
       
   208              permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
       
   209 class TextParagraphInnerAJAXEditForm(BaseParagraphAJAXEditForm, TextParagraphInnerEditForm):
       
   210     """Framed text paragraph inner edit form, JSON renderer"""
       
   211 
       
   212     def get_ajax_output(self, changes):
       
   213         output = super(TextParagraphInnerAJAXEditForm, self).get_ajax_output(changes)
       
   214         if 'renderer' in changes.get(ITextParagraph, ()):
       
   215             form = TextParagraphInnerEditForm(self.context, self.request)
       
   216             form.update()
       
   217             output.setdefault('events', []).append({
       
   218                 'event': 'myams.refresh',
       
   219                 'options': {
       
   220                     'object_id': '{0}_{1}_{2}'.format(
       
   221                         self.context.__class__.__name__,
       
   222                         getattr(form.getContent(), '__name__', 'noname').replace('++', ''),
       
   223                         form.id),
       
   224                     'content': form.render()
       
   225                 }
       
   226             })
       
   227         return output
       
   228 
       
   229 
       
   230 #
       
   231 # Framed text paragraph preview
       
   232 #
       
   233 
       
   234 @adapter_config(context=(ITextParagraph, IPyAMSLayer), provides=IParagraphPreview)
       
   235 class TextParagraphPreview(BaseRenderedContentPreview):
       
   236     """Framed text paragraph preview"""