Skip to content
Permalink
Browse files

[IMP] web,web_editor,website,website_blog: add image preview dialog

  • Loading branch information...
seb-odoo committed May 15, 2019
1 parent 12c5448 commit 3561f05c705a5c17e021fea2e4af1924fbe6acc4
@@ -1049,7 +1049,7 @@ def _content_image(self, xmlid=None, model='ir.attachment', id=None, field='data
if not (width or height):
width, height = odoo.tools.image_guess_size_from_field_name(field)

image_base64 = image_process(image_base64, (width, height), crop=crop)
image_base64 = image_process(image_base64, size=(int(width), int(height)), crop=crop, quality=int(kwargs.get('quality', 0)))

content = base64.b64decode(image_base64)
headers = http.set_safe_image_headers(headers, content)
@@ -153,20 +153,35 @@ def _update_checklist_recursive (self, li, checked, children=False, ancestors=Fa
return True

@http.route('/web_editor/attachment/add_datas', type='json', auth='user', methods=['POST'], website=True)
def add_datas(self, filename, datas, disable_optimization=False, res_id=False, res_model='ir.ui.view', filters=False, **kwargs):
if not disable_optimization:
def add_datas(self, filename, datas, quality=0, width=0, height=0, res_id=False, res_model='ir.ui.view', filters=False, **kwargs):
if width or height or quality:
try:
datas = tools.image_process(datas, verify_resolution=True)
datas = tools.image_process(datas, size=(width, height), quality=quality, verify_resolution=True)
except OSError:
pass # not an image
attachment = self._attachment_create(name=filename, datas=datas, res_id=res_id, res_model=res_model, filters=filters)
return attachment._get_media_info()

@http.route('/web_editor/attachment/add_url', type='json', auth='user', methods=['POST'], website=True)
def add_document_url(self, url, res_id=False, res_model='ir.ui.view', filters=False, **kwargs):
def add_url(self, url, res_id=False, res_model='ir.ui.view', filters=False, **kwargs):
attachment = self._attachment_create(url=url, res_id=res_id, res_model=res_model, filters=filters)
return attachment._get_media_info()

@http.route('/web_editor/attachment/<model("ir.attachment"):attachment>/update', type='json', auth='user', methods=['POST'], website=True)
def attachment_update(self, attachment, filename=None, width=0, height=0, quality=0):
if attachment.type == 'url':
raise UserError(_("You cannot change the quality, the width or the filename of an URL attachment."))
data = {}
if filename:
data['datas_fname'] = filename
if width or height or quality:
try:
data['datas'] = tools.image_process(attachment.datas, size=(width, height), quality=quality)
except OSError:
pass # not an image
attachment.write(data)
return attachment._get_media_info()

@http.route('/web_editor/attachment/remove', type='json', auth='user', website=True)
def remove(self, ids, **kwargs):
""" Removes a web-based image attachment if it is used by no view (template)
@@ -61,7 +61,12 @@ var MediaPlugin = AbstractPlugin.extend({
media = $mediaParent[0];
$mediaParent = $mediaParent.parent();
}

// if the image is for a field, the model should handle the resize
var mediaWidth = $(media).parent().data('oeField') ? 1920 : $(media).width();

var mediaDialog = new weWidgets.MediaDialog(this.options.parent, {
mediaWidth: mediaWidth,
onlyImages: $mediaParent.data('oeField') === 'image' || $mediaParent.data('oeType') === 'image',
},
$(media).clone()[0]
@@ -0,0 +1,137 @@
odoo.define('wysiwyg.widgets.image_preview_dialog', function (require) {
'use strict';

var core = require('web.core');
var Dialog = require('web.Dialog');
var utils = require('web.utils');

var _t = core._t;

var ImagePreviewDialog = Dialog.extend({
template: 'wysiwyg.widgets.image.preview',
xmlDependencies: ['/web_editor/static/src/xml/wysiwyg.xml'],

events: _.extend({}, Dialog.prototype.events, {
'click .o_we_width_preset': '_onClickWidthPreset',
'input #o_we_quality_input': '_onInputQuality',
'input #o_we_width': '_updatePreview',
'input .js_quality_range': '_updatePreview',
}),
/**
* @constructor
*/
init: function (parent, options, attachment, promise, optimizedWidth) {
var self = this;
this._super(parent, _.extend({}, {
title: _t("Improve your Image"),
size: 'large',
buttons: [
{text: _t("Optimize & Rename"), classes: 'btn-primary', close: false, click: this._onOptimize.bind(this)},
{text: _t("Only Rename"), classes: 'btn-secondary', close: false, click: this._onRename.bind(this)},
{text: _t("Keep Original"), close: true}
],
}, options));
this.on('closed', this, this._onClosed);

this.attachment = attachment;
this.defaultQuality = 80;
this.promise = promise;
this.optimizedWidth = Math.min(optimizedWidth || attachment.image_width, attachment.image_width);

this.widthRadios = _.sortBy([
{'width': this.optimizedWidth, 'text': _('Default')},
{'width': 64, 'text': '64'},
{'width': 128, 'text': '128'},
{'width': 256, 'text': '256'},
{'width': 512, 'text': '512'},
{'width': 1024, 'text': '1024'},
{'width': this.attachment.image_width, 'text': _('Original')},
], 'width');
this.widthRadios = _.map(this.widthRadios, function (el) {
el.disabled = el.width > self.attachment.image_width;
return el;
});
// TODO SEB check with SBU for how to handle quality setting for png, svg, ...
this._updatePreview = _.debounce(this._updatePreview.bind(this), 300);
},
/**
* @override
*/
start: function () {
var promise = this._super.apply(this, arguments);
this.$previewImage = this.$('.js_preview_image');
this.$qualityRange = this.$('.js_quality_range');
this.$qualityInput = this.$('#o_we_quality_input');
this.$filename = this.$('#o_we_filename');
this.$widthInput = this.$('#o_we_width');
this.$configColumn = this.$('#o_we_config_column');
this.$previewColumn = this.$('#o_we_preview_column');
this.$previewError = this.$('#o_we_preview_error');
this._updatePreview();
return promise;
},
/**
* Requests a preview for the current settings and displays it.
*
* @private
* @returns {Promise}
*/
_updatePreview: function () {
var quality = parseInt(this.$qualityRange.val());
this.$qualityInput.val(quality);
var width = parseInt(this.$widthInput.val());
this.$previewImage.attr('src', _.str.sprintf('/web/image/%s/%sx0?quality=%s',
this.attachment.id, width, quality));
},
_onInputQuality: function () {
var quality = parseInt(this.$qualityInput.val());
this.$qualityRange.val(quality);
this._updatePreview();
},
/**
* Handles clicking on the save button, which is resolving the promise with
* the current settings.
*/
_onOptimize: function (ev, onlyRename) {
var self = this;
var filename = this.$filename.val();
if (!filename || this.$widthInput.val() > this.attachment.image_width || this.$widthInput.val() < 0) {
return Promise.reject();
}
var params = {
'filename': filename,
};
if (!onlyRename) {
params['quality'] = parseInt(this.$qualityRange.val());
params['width'] = parseInt(this.$widthInput.val());
}
return this._rpc({
route: _.str.sprintf('/web_editor/attachment/%d/update', this.attachment.id),
params: params,
}).then(function (attachment) {
self.promise.resolve(attachment);
self.close();
});
},
_onRename: function (ev) {
this._onOptimize(ev, true);
},
/**
* Does nothing if called after save, otherwise resolves with the original
* attachment.
*/
_onClosed: function () {
this.promise.resolve(this.attachment);
},
_onClickWidthPreset: function (ev) {
ev.preventDefault();
this.$widthInput.val(parseInt($(ev.target).data('width')));
this._updatePreview();
},

});

return {
ImagePreviewDialog: ImagePreviewDialog,
};
});
Oops, something went wrong.

0 comments on commit 3561f05

Please sign in to comment.
You can’t perform that action at this time.