# HG changeset patch # User Thierry Florac # Date 1545327991 -3600 # Node ID bac63d15b2597ee10df22025378a40d5c8607b05 # Parent ed538dc075cd796af4cca80242b02a32e25c7936 Added inner editor for text files diff -r ed538dc075cd -r bac63d15b259 src/pyams_file/locales/fr/LC_MESSAGES/pyams_file.mo Binary file src/pyams_file/locales/fr/LC_MESSAGES/pyams_file.mo has changed diff -r ed538dc075cd -r bac63d15b259 src/pyams_file/locales/fr/LC_MESSAGES/pyams_file.po --- a/src/pyams_file/locales/fr/LC_MESSAGES/pyams_file.po Thu Dec 20 09:59:19 2018 +0100 +++ b/src/pyams_file/locales/fr/LC_MESSAGES/pyams_file.po Thu Dec 20 18:46:31 2018 +0100 @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE 1.0\n" -"POT-Creation-Date: 2018-11-28 17:19+0100\n" +"POT-Creation-Date: 2018-12-20 18:42+0100\n" "PO-Revision-Date: 2015-02-06 21:39+0100\n" "Last-Translator: Thierry Florac \n" "Language-Team: French\n" @@ -16,82 +16,108 @@ "Generated-By: Lingua 3.8\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: src/pyams_file/image.py:51 src/pyams_file/image.py:52 +#: src/pyams_file/image.py:49 src/pyams_file/image.py:50 msgid "Default thumbnail" msgstr "Vignette par défaut" -#: src/pyams_file/image.py:100 +#: src/pyams_file/image.py:98 msgid "Custom selections" msgstr "Sélections spécifiques" -#: src/pyams_file/image.py:176 +#: src/pyams_file/image.py:174 msgid "Portrait thumbnail" msgstr "Vignette portrait" -#: src/pyams_file/image.py:186 +#: src/pyams_file/image.py:184 msgid "Square thumbnail" msgstr "Vignette carrée" -#: src/pyams_file/image.py:196 +#: src/pyams_file/image.py:194 msgid "Panoramic thumbnail" msgstr "Vignette panoramique" -#: src/pyams_file/image.py:213 +#: src/pyams_file/image.py:211 msgid "Banner thumbnail" msgstr "Bandeau" -#: src/pyams_file/image.py:222 +#: src/pyams_file/image.py:220 msgid "Responsive selections" msgstr "Sélections responsives" -#: src/pyams_file/image.py:229 +#: src/pyams_file/image.py:227 msgid "Smartphone thumbnail" msgstr "Smartphone" -#: src/pyams_file/image.py:237 +#: src/pyams_file/image.py:235 msgid "Tablet thumbnail" msgstr "Tablette" -#: src/pyams_file/image.py:245 +#: src/pyams_file/image.py:243 msgid "Medium screen thumbnail" msgstr "Terminaux moyens" -#: src/pyams_file/image.py:253 +#: src/pyams_file/image.py:251 msgid "Large screen thumbnail" msgstr "Grands terminaux" -#: src/pyams_file/interfaces/__init__.py:110 -msgid "Title" -msgstr "Titre" +#: src/pyams_file/widget/templates/media-input.pt:7 +#: src/pyams_file/widget/templates/file-input.pt:7 +msgid "Browse..." +msgstr "Parcourir..." + +#: src/pyams_file/widget/templates/media-input.pt:8 +#: src/pyams_file/widget/templates/file-input.pt:8 +msgid "Please select a file..." +msgstr "Veuillez sélectionner un fichier..." + +#: src/pyams_file/widget/templates/media-input.pt:19 +#: src/pyams_file/widget/templates/file-input.pt:19 +msgid "Delete content" +msgstr "Supprimer ce contenu" -#: src/pyams_file/interfaces/__init__.py:113 -msgid "Description" -msgstr "Description" +#: src/pyams_file/widget/templates/media-input.pt:27 +#: src/pyams_file/widget/templates/media-input.pt:62 +#: src/pyams_file/widget/templates/media-input.pt:93 +#: src/pyams_file/widget/templates/file-input.pt:31 +#: src/pyams_file/widget/templates/file-display.pt:14 +#: src/pyams_file/widget/templates/media-display.pt:10 +#: src/pyams_file/widget/templates/media-display.pt:38 +#: src/pyams_file/widget/templates/media-display.pt:62 +msgid "Current value:" +msgstr "Contenu actuel :" -#: src/pyams_file/interfaces/__init__.py:116 -msgid "Save file as..." +#: src/pyams_file/widget/templates/media-input.pt:42 +#: src/pyams_file/widget/templates/media-input.pt:79 +#: src/pyams_file/widget/templates/media-input.pt:108 +#: src/pyams_file/widget/templates/file-input.pt:45 +#: src/pyams_file/widget/templates/file-display.pt:21 +#: src/pyams_file/widget/templates/media-display.pt:19 +#: src/pyams_file/widget/templates/media-display.pt:49 +#: src/pyams_file/widget/templates/media-display.pt:70 +msgid "Download" msgstr "Enregistrer sous..." -#: src/pyams_file/interfaces/__init__.py:117 -msgid "Name under which the file will be saved" -msgstr "Nom proposé automatiquement lors de l'enregistrement du fichier" - -#: src/pyams_file/interfaces/__init__.py:120 -msgid "Language" -msgstr "Langue" - -#: src/pyams_file/interfaces/__init__.py:121 -msgid "File's content language" -msgstr "Langue du contenu du fichier" +#: src/pyams_file/widget/templates/media-input.pt:54 +#: src/pyams_file/widget/templates/media-display.pt:30 +msgid "Zoom image" +msgstr "Agrandir l'image" #: src/pyams_file/zmi/file.py:42 msgid "Properties..." msgstr "Propriétés" -#: src/pyams_file/zmi/file.py:56 +#: src/pyams_file/zmi/file.py:57 msgid "Update file properties" msgstr "Mise à jour des propriétés" +#: src/pyams_file/zmi/file.py:92 +msgid "Edit file..." +msgstr "Éditer le contenu" + +#: src/pyams_file/zmi/file.py:108 +msgid "Edit file content" +msgstr "Editer le contenu du fichier" + #: src/pyams_file/zmi/image.py:120 msgid "Rotate image to right..." msgstr "Tourner l'image vers la droite" @@ -325,47 +351,29 @@ "L'image sera redimensionnée (sans jamais être agrandie !) pour être aussi " "grande que possible en fonction des contraintes indiquées." -#: src/pyams_file/widget/templates/media-input.pt:7 -#: src/pyams_file/widget/templates/file-input.pt:7 -msgid "Browse..." -msgstr "Parcourir..." - -#: src/pyams_file/widget/templates/media-input.pt:8 -#: src/pyams_file/widget/templates/file-input.pt:8 -msgid "Please select a file..." -msgstr "Veuillez sélectionner un fichier..." - -#: src/pyams_file/widget/templates/media-input.pt:19 -#: src/pyams_file/widget/templates/file-input.pt:19 -msgid "Delete content" -msgstr "Supprimer ce contenu" +#: src/pyams_file/interfaces/__init__.py:110 +msgid "Title" +msgstr "Titre" -#: src/pyams_file/widget/templates/media-input.pt:27 -#: src/pyams_file/widget/templates/media-input.pt:62 -#: src/pyams_file/widget/templates/media-input.pt:93 -#: src/pyams_file/widget/templates/media-display.pt:10 -#: src/pyams_file/widget/templates/media-display.pt:38 -#: src/pyams_file/widget/templates/media-display.pt:62 -#: src/pyams_file/widget/templates/file-input.pt:31 -#: src/pyams_file/widget/templates/file-display.pt:14 -msgid "Current value:" -msgstr "Contenu actuel :" +#: src/pyams_file/interfaces/__init__.py:113 +msgid "Description" +msgstr "Description" -#: src/pyams_file/widget/templates/media-input.pt:42 -#: src/pyams_file/widget/templates/media-input.pt:79 -#: src/pyams_file/widget/templates/media-input.pt:108 -#: src/pyams_file/widget/templates/media-display.pt:19 -#: src/pyams_file/widget/templates/media-display.pt:49 -#: src/pyams_file/widget/templates/media-display.pt:70 -#: src/pyams_file/widget/templates/file-input.pt:45 -#: src/pyams_file/widget/templates/file-display.pt:21 -msgid "Download" +#: src/pyams_file/interfaces/__init__.py:116 +msgid "Save file as..." msgstr "Enregistrer sous..." -#: src/pyams_file/widget/templates/media-input.pt:54 -#: src/pyams_file/widget/templates/media-display.pt:30 -msgid "Zoom image" -msgstr "Agrandir l'image" +#: src/pyams_file/interfaces/__init__.py:117 +msgid "Name under which the file will be saved" +msgstr "Nom proposé automatiquement lors de l'enregistrement du fichier" + +#: src/pyams_file/interfaces/__init__.py:120 +msgid "Language" +msgstr "Langue" + +#: src/pyams_file/interfaces/__init__.py:121 +msgid "File's content language" +msgstr "Langue du contenu du fichier" #~ msgid "${size} Kb" #~ msgstr "${size} Ko" diff -r ed538dc075cd -r bac63d15b259 src/pyams_file/locales/pyams_file.pot --- a/src/pyams_file/locales/pyams_file.pot Thu Dec 20 09:59:19 2018 +0100 +++ b/src/pyams_file/locales/pyams_file.pot Thu Dec 20 18:46:31 2018 +0100 @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE 1.0\n" -"POT-Creation-Date: 2018-11-28 17:19+0100\n" +"POT-Creation-Date: 2018-12-20 18:42+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" @@ -16,82 +16,108 @@ "Content-Transfer-Encoding: 8bit\n" "Generated-By: Lingua 3.10.dev0\n" -#: ./src/pyams_file/image.py:51 ./src/pyams_file/image.py:52 +#: ./src/pyams_file/image.py:49 ./src/pyams_file/image.py:50 msgid "Default thumbnail" msgstr "" -#: ./src/pyams_file/image.py:100 +#: ./src/pyams_file/image.py:98 msgid "Custom selections" msgstr "" -#: ./src/pyams_file/image.py:176 +#: ./src/pyams_file/image.py:174 msgid "Portrait thumbnail" msgstr "" -#: ./src/pyams_file/image.py:186 +#: ./src/pyams_file/image.py:184 msgid "Square thumbnail" msgstr "" -#: ./src/pyams_file/image.py:196 +#: ./src/pyams_file/image.py:194 msgid "Panoramic thumbnail" msgstr "" -#: ./src/pyams_file/image.py:213 +#: ./src/pyams_file/image.py:211 msgid "Banner thumbnail" msgstr "" -#: ./src/pyams_file/image.py:222 +#: ./src/pyams_file/image.py:220 msgid "Responsive selections" msgstr "" -#: ./src/pyams_file/image.py:229 +#: ./src/pyams_file/image.py:227 msgid "Smartphone thumbnail" msgstr "" -#: ./src/pyams_file/image.py:237 +#: ./src/pyams_file/image.py:235 msgid "Tablet thumbnail" msgstr "" -#: ./src/pyams_file/image.py:245 +#: ./src/pyams_file/image.py:243 msgid "Medium screen thumbnail" msgstr "" -#: ./src/pyams_file/image.py:253 +#: ./src/pyams_file/image.py:251 msgid "Large screen thumbnail" msgstr "" -#: ./src/pyams_file/interfaces/__init__.py:110 -msgid "Title" +#: ./src/pyams_file/widget/templates/media-input.pt:7 +#: ./src/pyams_file/widget/templates/file-input.pt:7 +msgid "Browse..." msgstr "" -#: ./src/pyams_file/interfaces/__init__.py:113 -msgid "Description" +#: ./src/pyams_file/widget/templates/media-input.pt:8 +#: ./src/pyams_file/widget/templates/file-input.pt:8 +msgid "Please select a file..." +msgstr "" + +#: ./src/pyams_file/widget/templates/media-input.pt:19 +#: ./src/pyams_file/widget/templates/file-input.pt:19 +msgid "Delete content" msgstr "" -#: ./src/pyams_file/interfaces/__init__.py:116 -msgid "Save file as..." +#: ./src/pyams_file/widget/templates/media-input.pt:27 +#: ./src/pyams_file/widget/templates/media-input.pt:62 +#: ./src/pyams_file/widget/templates/media-input.pt:93 +#: ./src/pyams_file/widget/templates/file-input.pt:31 +#: ./src/pyams_file/widget/templates/file-display.pt:14 +#: ./src/pyams_file/widget/templates/media-display.pt:10 +#: ./src/pyams_file/widget/templates/media-display.pt:38 +#: ./src/pyams_file/widget/templates/media-display.pt:62 +msgid "Current value:" msgstr "" -#: ./src/pyams_file/interfaces/__init__.py:117 -msgid "Name under which the file will be saved" +#: ./src/pyams_file/widget/templates/media-input.pt:42 +#: ./src/pyams_file/widget/templates/media-input.pt:79 +#: ./src/pyams_file/widget/templates/media-input.pt:108 +#: ./src/pyams_file/widget/templates/file-input.pt:45 +#: ./src/pyams_file/widget/templates/file-display.pt:21 +#: ./src/pyams_file/widget/templates/media-display.pt:19 +#: ./src/pyams_file/widget/templates/media-display.pt:49 +#: ./src/pyams_file/widget/templates/media-display.pt:70 +msgid "Download" msgstr "" -#: ./src/pyams_file/interfaces/__init__.py:120 -msgid "Language" -msgstr "" - -#: ./src/pyams_file/interfaces/__init__.py:121 -msgid "File's content language" +#: ./src/pyams_file/widget/templates/media-input.pt:54 +#: ./src/pyams_file/widget/templates/media-display.pt:30 +msgid "Zoom image" msgstr "" #: ./src/pyams_file/zmi/file.py:42 msgid "Properties..." msgstr "" -#: ./src/pyams_file/zmi/file.py:56 +#: ./src/pyams_file/zmi/file.py:57 msgid "Update file properties" msgstr "" +#: ./src/pyams_file/zmi/file.py:92 +msgid "Edit file..." +msgstr "" + +#: ./src/pyams_file/zmi/file.py:108 +msgid "Edit file content" +msgstr "" + #: ./src/pyams_file/zmi/image.py:120 msgid "Rotate image to right..." msgstr "" @@ -261,44 +287,26 @@ "possible within given limits" msgstr "" -#: ./src/pyams_file/widget/templates/media-input.pt:7 -#: ./src/pyams_file/widget/templates/file-input.pt:7 -msgid "Browse..." +#: ./src/pyams_file/interfaces/__init__.py:110 +msgid "Title" msgstr "" -#: ./src/pyams_file/widget/templates/media-input.pt:8 -#: ./src/pyams_file/widget/templates/file-input.pt:8 -msgid "Please select a file..." +#: ./src/pyams_file/interfaces/__init__.py:113 +msgid "Description" msgstr "" -#: ./src/pyams_file/widget/templates/media-input.pt:19 -#: ./src/pyams_file/widget/templates/file-input.pt:19 -msgid "Delete content" +#: ./src/pyams_file/interfaces/__init__.py:116 +msgid "Save file as..." msgstr "" -#: ./src/pyams_file/widget/templates/media-input.pt:27 -#: ./src/pyams_file/widget/templates/media-input.pt:62 -#: ./src/pyams_file/widget/templates/media-input.pt:93 -#: ./src/pyams_file/widget/templates/media-display.pt:10 -#: ./src/pyams_file/widget/templates/media-display.pt:38 -#: ./src/pyams_file/widget/templates/media-display.pt:62 -#: ./src/pyams_file/widget/templates/file-input.pt:31 -#: ./src/pyams_file/widget/templates/file-display.pt:14 -msgid "Current value:" +#: ./src/pyams_file/interfaces/__init__.py:117 +msgid "Name under which the file will be saved" msgstr "" -#: ./src/pyams_file/widget/templates/media-input.pt:42 -#: ./src/pyams_file/widget/templates/media-input.pt:79 -#: ./src/pyams_file/widget/templates/media-input.pt:108 -#: ./src/pyams_file/widget/templates/media-display.pt:19 -#: ./src/pyams_file/widget/templates/media-display.pt:49 -#: ./src/pyams_file/widget/templates/media-display.pt:70 -#: ./src/pyams_file/widget/templates/file-input.pt:45 -#: ./src/pyams_file/widget/templates/file-display.pt:21 -msgid "Download" +#: ./src/pyams_file/interfaces/__init__.py:120 +msgid "Language" msgstr "" -#: ./src/pyams_file/widget/templates/media-input.pt:54 -#: ./src/pyams_file/widget/templates/media-display.pt:30 -msgid "Zoom image" +#: ./src/pyams_file/interfaces/__init__.py:121 +msgid "File's content language" msgstr "" diff -r ed538dc075cd -r bac63d15b259 src/pyams_file/zmi/file.py --- a/src/pyams_file/zmi/file.py Thu Dec 20 09:59:19 2018 +0100 +++ b/src/pyams_file/zmi/file.py Thu Dec 20 18:46:31 2018 +0100 @@ -9,33 +9,33 @@ # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # +from pyams_utils.interfaces.data import IObjectData __docformat__ = 'restructuredtext' - -# import standard library +from z3c.form import field +from z3c.form.browser.textarea import TextAreaFieldWidget +from zope.interface import Interface, implementer, alsoProvides -# import interfaces from pyams_file.interfaces import IFile, IFileInfo, IFileModifierForm +from pyams_file.zmi import FileModifierAction +from pyams_form.form import ajax_config +from pyams_pagelet.pagelet import pagelet_config from pyams_skin.interfaces.viewlet import IContextActions from pyams_skin.layer import IPyAMSLayer -from pyams_utils.interfaces import VIEW_PERMISSION, MANAGE_SYSTEM_PERMISSION - -# import packages -from pyams_file.zmi import FileModifierAction -from pyams_form.form import AJAXEditForm -from pyams_pagelet.pagelet import pagelet_config +from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION from pyams_viewlet.viewlet import viewlet_config from pyams_zmi.form import AdminDialogEditForm -from pyramid.view import view_config -from z3c.form import field -from zope.interface import implementer, Interface from pyams_file import _ +# +# File properties form +# + @viewlet_config(name='file.properties.action', context=IFile, layer=IPyAMSLayer, view=Interface, - manager=IContextActions, permission=MANAGE_SYSTEM_PERMISSION, weight=1) + manager=IContextActions, weight=1) class FilePropertiesAction(FileModifierAction): """File properties action""" @@ -46,7 +46,8 @@ modal_target = True -@pagelet_config(name='properties.html', context=IFile, layer=IPyAMSLayer, permission=VIEW_PERMISSION) +@pagelet_config(name='properties.html', context=IFile, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION) +@ajax_config(name='properties.json', context=IFile, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION) @implementer(IFileModifierForm) class FilePropertiesEditForm(AdminDialogEditForm): """File properties edit form""" @@ -57,19 +58,12 @@ icon_css_class = 'fa fa-fw fa-edit' fields = field.Fields(IFileInfo) - ajax_handler = 'properties.json' edit_permission = None @property def title(self): return self.context.title or self.context.filename - -@view_config(name='properties.json', context=IFile, request_type=IPyAMSLayer, - permission=VIEW_PERMISSION, renderer='json', xhr=True) -class FilePropertiesAJAXEditForm(AJAXEditForm, FilePropertiesEditForm): - """File properties edit form, AJAX renderer""" - def get_ajax_output(self, changes): info_changes = changes.get(IFileInfo, ()) if ('title' in info_changes) or ('filename' in info_changes): @@ -78,5 +72,55 @@ 'message': self.request.localizer.translate(self.successMessage) } else: - return super(FilePropertiesAJAXEditForm, self).get_ajax_output(changes) + return super(self.__class__, self).get_ajax_output(changes) + + +# +# Text file editor +# + +@viewlet_config(name='file.editor.action', context=IFile, layer=IPyAMSLayer, view=Interface, + manager=IContextActions, weight=2) +class FileContentEditorAction(FileModifierAction): + """Text file content editor action""" + + def __new__(cls, context, request, view, manager): + if not (context.content_type.startswith('text/') or context.content_type.startswith('image/svg')): + return None + return FileModifierAction.__new__(cls) + + label = _("Edit file...") + label_css_class = 'fa fa-fw-md fa-pencil' + + url = 'edit-content.html' + modal_target = True + +@pagelet_config(name='edit-content.html', context=IFile, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION) +@ajax_config(name='edit-content.json', context=IFile, layer=IPyAMSLayer) +@implementer(IFileModifierForm) +class FileContentEditorForm(AdminDialogEditForm): + """Text file content edit form""" + + prefix = 'file_content.' + dialog_class = 'modal-max' + + legend = _("Edit file content") + icon_css_class = 'fa fa-fw fa-pencil' + label_css_class = 'control-label col-md-1' + input_css_class = 'col-md-11' + + fields = field.Fields(IFile).select('data') + fields['data'].widgetFactory = TextAreaFieldWidget + + edit_permission = None + + def updateWidgets(self, prefix=None): + super(FileContentEditorForm, self).updateWidgets(prefix) + if 'data' in self.widgets: + widget = self.widgets['data'] + widget.widget_css_class = 'input height-500 monospace text-editor' + widget.object_data = { + 'ams-editor-filename': self.context.filename + } + alsoProvides(widget, IObjectData)