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 |
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 '--' |