+1








14bffd983e
This commit adapts the community codebase to the rewriting of the /web application in owl. Co-authored-by: Aaron Bohy <aab@odoo.com> Co-authored-by: Bruno Boi <boi@odoo.com> Co-authored-by: Géry Debongnie <ged@odoo.com> Co-authored-by: Samuel Degueldre <sad@odoo.com> Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com> Co-authored-by: Simon Genin (ges) <ges@odoo.com> Co-authored-by: Francois (fge) <fge@odoo.com> Co-authored-by: Michael Mattiello (mcm) <mcm@odoo.com> Co-authored-by: Julien Mougenot <jum@odoo.com> Co-authored-by: Lucas Perais (lpe) <lpe@odoo.com> Co-authored-by: Jorge Pinna Puissant <jpp@odoo.com>
416 lines
12 KiB
JavaScript
416 lines
12 KiB
JavaScript
/** @odoo-module **/
|
|
|
|
import core from 'web.core';
|
|
import Widget from 'web.Widget';
|
|
import { hidePDFJSButtons } from '@web/legacy/js/libs/pdfjs';
|
|
|
|
var QWeb = core.qweb;
|
|
|
|
var SCROLL_ZOOM_STEP = 0.1;
|
|
var ZOOM_STEP = 0.5;
|
|
|
|
/**
|
|
* This widget is deprecated, and should instead use AttachmentViewer component.
|
|
* @see `mail/static/src/components/attachment_viewer/attachment_viewer.js`
|
|
* TODO: remove this widget when it's not longer used
|
|
*
|
|
* @deprecated
|
|
*/
|
|
var DocumentViewer = Widget.extend({
|
|
template: "DocumentViewer",
|
|
events: {
|
|
'click .o_download_btn': '_onDownload',
|
|
'click .o_viewer_img': '_onImageClicked',
|
|
'click .o_viewer_video': '_onVideoClicked',
|
|
'click .move_next': '_onNext',
|
|
'click .move_previous': '_onPrevious',
|
|
'click .o_rotate': '_onRotate',
|
|
'click .o_zoom_in': '_onZoomIn',
|
|
'click .o_zoom_out': '_onZoomOut',
|
|
'click .o_zoom_reset': '_onZoomReset',
|
|
'click .o_close_btn, .o_viewer_img_wrapper': '_onClose',
|
|
'click .o_print_btn': '_onPrint',
|
|
'DOMMouseScroll .o_viewer_content': '_onScroll', // Firefox
|
|
'mousewheel .o_viewer_content': '_onScroll', // Chrome, Safari, IE
|
|
'keydown': '_onKeydown',
|
|
'keyup': '_onKeyUp',
|
|
'mousedown .o_viewer_img': '_onStartDrag',
|
|
'mousemove .o_viewer_content': '_onDrag',
|
|
'mouseup .o_viewer_content': '_onEndDrag'
|
|
},
|
|
/**
|
|
* The documentViewer takes an array of objects describing attachments in
|
|
* argument, and the ID of an active attachment (the one to display first).
|
|
* Documents that are not of type image or video are filtered out.
|
|
*
|
|
* @override
|
|
* @param {Array<Object>} attachments list of attachments
|
|
* @param {integer} activeAttachmentID
|
|
*/
|
|
init: function (parent, attachments, activeAttachmentID) {
|
|
this._super.apply(this, arguments);
|
|
this.attachment = _.filter(attachments, function (attachment) {
|
|
var match = attachment.type === 'url' ? attachment.url.match("(youtu|.png|.jpg|.gif)") : attachment.mimetype.match("(image|video|application/pdf|text)");
|
|
if (match) {
|
|
attachment.fileType = match[1];
|
|
if (match[1].match("(.png|.jpg|.gif)")) {
|
|
attachment.fileType = 'image';
|
|
}
|
|
if (match[1] === 'youtu') {
|
|
var youtube_array = attachment.url.split('/');
|
|
var youtube_token = youtube_array[youtube_array.length-1];
|
|
if (youtube_token.indexOf('watch') !== -1) {
|
|
youtube_token = youtube_token.split('v=')[1];
|
|
var amp = youtube_token.indexOf('&')
|
|
if (amp !== -1){
|
|
youtube_token = youtube_token.substring(0, amp);
|
|
}
|
|
}
|
|
attachment.youtube = youtube_token;
|
|
}
|
|
return true;
|
|
}
|
|
});
|
|
this.activeAttachment = _.findWhere(attachments, {id: activeAttachmentID});
|
|
this.modelName = 'ir.attachment';
|
|
this._reset();
|
|
},
|
|
/**
|
|
* Do some actions after the widget is appended to the DOM
|
|
* @override
|
|
*/
|
|
setElement: function () {
|
|
const result = this._super(...arguments);
|
|
this._hidePdfButtonsIfPresent();
|
|
return result;
|
|
},
|
|
/**
|
|
* Open a modal displaying the active attachment
|
|
* @override
|
|
*/
|
|
start: function () {
|
|
this.$el.modal('show');
|
|
this.$el.on('hidden.bs.modal', _.bind(this._onDestroy, this));
|
|
this.$('.o_viewer_img').on("load", _.bind(this._onImageLoaded, this));
|
|
this.$('[data-toggle="tooltip"]').tooltip({delay: 0});
|
|
return this._super.apply(this, arguments);
|
|
},
|
|
/**
|
|
* @override
|
|
*/
|
|
destroy: function () {
|
|
if (this.isDestroyed()) {
|
|
return;
|
|
}
|
|
this.$el.modal('hide');
|
|
this.$el.remove();
|
|
this._super.apply(this, arguments);
|
|
},
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Private
|
|
//---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Hide some buttons in PDF.js
|
|
* @override
|
|
*/
|
|
_hidePdfButtonsIfPresent: function () {
|
|
if (this.activeAttachment.mimetype === 'application/pdf') {
|
|
hidePDFJSButtons(this.el);
|
|
}
|
|
},
|
|
/**
|
|
* @private
|
|
*/
|
|
_next: function () {
|
|
var index = _.findIndex(this.attachment, this.activeAttachment);
|
|
index = (index + 1) % this.attachment.length;
|
|
this.activeAttachment = this.attachment[index];
|
|
this._updateContent();
|
|
},
|
|
/**
|
|
* @private
|
|
*/
|
|
_previous: function () {
|
|
var index = _.findIndex(this.attachment, this.activeAttachment);
|
|
index = index === 0 ? this.attachment.length - 1 : index - 1;
|
|
this.activeAttachment = this.attachment[index];
|
|
this._updateContent();
|
|
},
|
|
/**
|
|
* @private
|
|
*/
|
|
_reset: function () {
|
|
this.scale = 1;
|
|
this.dragStartX = this.dragstopX = 0;
|
|
this.dragStartY = this.dragstopY = 0;
|
|
},
|
|
/**
|
|
* Render the active attachment
|
|
*
|
|
* @private
|
|
*/
|
|
_updateContent: function () {
|
|
this.$('.o_viewer_content').html(QWeb.render('DocumentViewer.Content', {
|
|
widget: this
|
|
}));
|
|
this.$('.o_viewer_img').on("load", _.bind(this._onImageLoaded, this));
|
|
this._hidePdfButtonsIfPresent();
|
|
this.$('[data-toggle="tooltip"]').tooltip({delay: 0});
|
|
this._reset();
|
|
},
|
|
/**
|
|
* Get CSS transform property based on scale and angle
|
|
*
|
|
* @private
|
|
* @param {float} scale
|
|
* @param {float} angle
|
|
*/
|
|
_getTransform: function(scale, angle) {
|
|
return 'scale3d(' + scale + ', ' + scale + ', 1) rotate(' + angle + 'deg)';
|
|
},
|
|
/**
|
|
* Rotate image clockwise by provided angle
|
|
*
|
|
* @private
|
|
* @param {float} angle
|
|
*/
|
|
_rotate: function (angle) {
|
|
this._reset();
|
|
var new_angle = (this.angle || 0) + angle;
|
|
this.$('.o_viewer_img').css('transform', this._getTransform(this.scale, new_angle));
|
|
this.$('.o_viewer_img').css('max-width', new_angle % 180 !== 0 ? $(document).height() : '100%');
|
|
this.$('.o_viewer_img').css('max-height', new_angle % 180 !== 0 ? $(document).width() : '100%');
|
|
this.angle = new_angle;
|
|
},
|
|
/**
|
|
* Zoom in/out image by provided scale
|
|
*
|
|
* @private
|
|
* @param {integer} scale
|
|
*/
|
|
_zoom: function (scale) {
|
|
if (scale > 0.5) {
|
|
this.$('.o_viewer_img').css('transform', this._getTransform(scale, this.angle || 0));
|
|
this.scale = scale;
|
|
}
|
|
this.$('.o_zoom_reset').add('.o_zoom_out').toggleClass('disabled', scale === 1);
|
|
},
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Handlers
|
|
//--------------------------------------------------------------------------
|
|
|
|
/**
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onClose: function (e) {
|
|
e.preventDefault();
|
|
this.destroy();
|
|
},
|
|
/**
|
|
* When popup close complete destroyed modal even DOM footprint too
|
|
*
|
|
* @private
|
|
*/
|
|
_onDestroy: function () {
|
|
this.destroy();
|
|
},
|
|
/**
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onDownload: function (e) {
|
|
e.preventDefault();
|
|
window.location = '/web/content/' + this.modelName + '/' + this.activeAttachment.id + '/' + 'datas' + '?download=true';
|
|
},
|
|
/**
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onDrag: function (e) {
|
|
e.preventDefault();
|
|
if (this.enableDrag) {
|
|
var $image = this.$('.o_viewer_img');
|
|
var $zoomer = this.$('.o_viewer_zoomer');
|
|
var top = $image.prop('offsetHeight') * this.scale > $zoomer.height() ? e.clientY - this.dragStartY : 0;
|
|
var left = $image.prop('offsetWidth') * this.scale > $zoomer.width() ? e.clientX - this.dragStartX : 0;
|
|
$zoomer.css("transform", "translate3d("+ left +"px, " + top + "px, 0)");
|
|
$image.css('cursor', 'move');
|
|
}
|
|
},
|
|
/**
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onEndDrag: function (e) {
|
|
e.preventDefault();
|
|
if (this.enableDrag) {
|
|
this.enableDrag = false;
|
|
this.dragstopX = e.clientX - this.dragStartX;
|
|
this.dragstopY = e.clientY - this.dragStartY;
|
|
this.$('.o_viewer_img').css('cursor', '');
|
|
}
|
|
},
|
|
/**
|
|
* On click of image do not close modal so stop event propagation
|
|
*
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onImageClicked: function (e) {
|
|
e.stopPropagation();
|
|
},
|
|
/**
|
|
* Remove loading indicator when image loaded
|
|
* @private
|
|
*/
|
|
_onImageLoaded: function () {
|
|
this.$('.o_loading_img').hide();
|
|
},
|
|
/**
|
|
* Move next previous attachment on keyboard right left key
|
|
*
|
|
* @private
|
|
* @param {KeyEvent} e
|
|
*/
|
|
_onKeydown: function (e){
|
|
switch (e.which) {
|
|
case $.ui.keyCode.RIGHT:
|
|
e.preventDefault();
|
|
this._next();
|
|
break;
|
|
case $.ui.keyCode.LEFT:
|
|
e.preventDefault();
|
|
this._previous();
|
|
break;
|
|
}
|
|
},
|
|
/**
|
|
* Close popup on ESCAPE keyup
|
|
*
|
|
* @private
|
|
* @param {KeyEvent} e
|
|
*/
|
|
_onKeyUp: function (e) {
|
|
switch (e.which) {
|
|
case $.ui.keyCode.ESCAPE:
|
|
e.preventDefault();
|
|
this._onClose(e);
|
|
break;
|
|
}
|
|
},
|
|
/**
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onNext: function (e) {
|
|
e.preventDefault();
|
|
this._next();
|
|
},
|
|
/**
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onPrevious: function (e) {
|
|
e.preventDefault();
|
|
this._previous();
|
|
},
|
|
/**
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onPrint: function (e) {
|
|
e.preventDefault();
|
|
var src = this.$('.o_viewer_img').prop('src');
|
|
var script = QWeb.render('PrintImage', {
|
|
src: src
|
|
});
|
|
var printWindow = window.open('about:blank', "_new");
|
|
printWindow.document.open();
|
|
printWindow.document.write(script);
|
|
printWindow.document.close();
|
|
},
|
|
/**
|
|
* Zoom image on scroll
|
|
*
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onScroll: function (e) {
|
|
var scale;
|
|
if (e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0) {
|
|
scale = this.scale + SCROLL_ZOOM_STEP;
|
|
this._zoom(scale);
|
|
} else {
|
|
scale = this.scale - SCROLL_ZOOM_STEP;
|
|
this._zoom(scale);
|
|
}
|
|
},
|
|
/**
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onStartDrag: function (e) {
|
|
e.preventDefault();
|
|
this.enableDrag = true;
|
|
this.dragStartX = e.clientX - (this.dragstopX || 0);
|
|
this.dragStartY = e.clientY - (this.dragstopY || 0);
|
|
},
|
|
/**
|
|
* On click of video do not close modal so stop event propagation
|
|
* and provide play/pause the video instead of quitting it
|
|
*
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onVideoClicked: function (e) {
|
|
e.stopPropagation();
|
|
var videoElement = e.target;
|
|
if (videoElement.paused) {
|
|
videoElement.play();
|
|
} else {
|
|
videoElement.pause();
|
|
}
|
|
},
|
|
/**
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onRotate: function (e) {
|
|
e.preventDefault();
|
|
this._rotate(90);
|
|
},
|
|
/**
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onZoomIn: function (e) {
|
|
e.preventDefault();
|
|
var scale = this.scale + ZOOM_STEP;
|
|
this._zoom(scale);
|
|
},
|
|
/**
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onZoomOut: function (e) {
|
|
e.preventDefault();
|
|
var scale = this.scale - ZOOM_STEP;
|
|
this._zoom(scale);
|
|
},
|
|
/**
|
|
* @private
|
|
* @param {MouseEvent} e
|
|
*/
|
|
_onZoomReset: function (e) {
|
|
e.preventDefault();
|
|
this.$('.o_viewer_zoomer').css("transform", "");
|
|
this._zoom(1);
|
|
},
|
|
});
|
|
|
|
export default DocumentViewer;
|