diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 4e39f291df2..5da633a27a6 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -9,6 +9,7 @@ import urlparse import werkzeug import werkzeug.exceptions +import werkzeug.utils import werkzeug.wrappers # optional python-slugify import (https://github.com/un33k/python-slugify) try: @@ -594,6 +595,33 @@ class ir_attachment(osv.osv): return super(ir_attachment, self).create( cr, uid, values, context=context) + def try_remove(self, cr, uid, ids, context=None): + """ Removes a web-based image attachment if it is used by no view + (template) + + Returns a dict mapping attachments which would not be removed (if any) + mapped to the views preventing their removal + """ + Views = self.pool['ir.ui.view'] + attachments_to_remove = [] + # views blocking removal of the attachment + removal_blocked_by = {} + + for attachment in self.browse(cr, uid, ids, context=context): + # in-document URLs are html-escaped, a straight search will not + # find them + url = werkzeug.utils.escape(attachment.website_url) + ids = Views.search(cr, uid, [('arch', 'like', url)], context=context) + + if ids: + removal_blocked_by[attachment.id] = Views.read( + cr, uid, ids, ['name'], context=context) + else: + attachments_to_remove.append(attachment.id) + if attachments_to_remove: + self.unlink(cr, uid, attachments_to_remove, context=context) + return removal_blocked_by + class res_partner(osv.osv): _inherit = "res.partner" diff --git a/addons/website/static/src/css/editor.css b/addons/website/static/src/css/editor.css index df2188e794d..da0fad43caf 100644 --- a/addons/website/static/src/css/editor.css +++ b/addons/website/static/src/css/editor.css @@ -251,6 +251,26 @@ ul.oe_menu_editor .disclose { .existing-attachments .pager .disabled { display: none; } +.existing-attachments .existing-attachment-cell { + position: relative; +} +.existing-attachments .existing-attachment-cell .img { + border: 1px solid #848490; +} +.existing-attachments .existing-attachment-cell .existing-attachment-remove { + position: absolute; + top: 0; + left: 15px; + cursor: pointer; + background: white; + padding: 2px; + border: 1px solid #848490; + border-top: none; + border-left: none; + -moz-border-radius-bottomright: 8px; + -webkit-border-bottom-right-radius: 8px; + border-bottom-right-radius: 8px; +} .cke_widget_wrapper { position: static !important; diff --git a/addons/website/static/src/css/editor.sass b/addons/website/static/src/css/editor.sass index 49b71ffefdf..4571dcd257e 100644 --- a/addons/website/static/src/css/editor.sass +++ b/addons/website/static/src/css/editor.sass @@ -211,9 +211,27 @@ ul.oe_menu_editor .font-icons-selected background-color: #ddd +$attachment-border-color: #848490 +.existing-attachments + .pager .disabled + display: none -.existing-attachments .pager .disabled - display: none + .existing-attachment-cell + position: relative + .img + border: 1px solid $attachment-border-color + .existing-attachment-remove + position: absolute + top: 0 + left: 15px // padding-left on col-* + + cursor: pointer + background: white + padding: 2px + border: 1px solid $attachment-border-color + border-top: none + border-left: none + +border-bottom-right-radius(8px) // wrapper positioned relatively for drag&drop widget which is disabled below. // Breaks completely horribly crazy products listing page, so take it out. diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index f7e3255de24..3915c3daaeb 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -1441,6 +1441,7 @@ this.page += $target.hasClass('previous') ? -1 : 1; this.display_attachments(); }, + 'click .existing-attachment-remove': 'try_remove', }), init: function (parent) { this.image = null; @@ -1473,6 +1474,7 @@ this.display_attachments(); }, display_attachments: function () { + this.$('.help-block').empty(); var per_screen = IMAGES_PER_ROW * IMAGES_ROWS; var from = this.page * per_screen; @@ -1500,6 +1502,34 @@ } this.close() }, + + try_remove: function (e) { + var $help_block = this.$('.help-block').empty(); + var self = this; + var id = parseInt($(e.target).data('id'), 10); + var attachment = _.findWhere(this.records, {id: id}); + + return openerp.jsonRpc('/web/dataset/call_kw', 'call', { + model: 'ir.attachment', + method: 'try_remove', + args: [], + kwargs: { + ids: [id], + context: website.get_context() + } + }).then(function (prevented) { + if (_.isEmpty(prevented)) { + self.records = _.without(self.records, attachment); + self.display_attachments(); + return; + } + $help_block.replaceWith(openerp.qweb.render( + 'website.editor.dialog.image.existing.error', { + views: prevented[id] + } + )); + }); + }, }); function get_selected_link(editor) { diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml index 6c1e387c958..1010ec05127 100644 --- a/addons/website/static/src/xml/website.editor.xml +++ b/addons/website/static/src/xml/website.editor.xml @@ -140,8 +140,9 @@