* @cfg {String} icon (info-sign|check|...) glyphicon name
* @cfg {Boolean} hidden (true|false) hide the element
* @cfg {Boolean} expandable (true|false) default false
+ * @cfg {Boolean} expanded (true|false) default true
* @cfg {String} rheader contet on the right of header
*
h.push({
tag: 'i',
- cls: 'fa fa-minus'
+ cls: (this.expanded ? 'fa fa-minus' : 'fa fa-plus')
});
+
}
h.push(
{
tag: 'span',
cls : 'panel-title',
- html : this.header
+ html : (this.expandable ? ' ' : '') + this.header
},
{
tag: 'span',
cfg.cn.push({
cls : 'panel-heading',
+ style : this.expandable ? 'cursor: pointer' : '',
cn : h
});
body = false;
cfg.cn.push({
- cls : 'panel-body',
+ cls : 'panel-body' + (this.expanded ? '' : ' hide'),
html : this.html
});
this.expanded = true;
- this.el.select('.panel-body',true).first().setVisibilityMode(Roo.Element.DISPLAY).show();
-
+ //this.el.select('.panel-body',true).first().setVisibilityMode(Roo.Element.DISPLAY).show();
+
+ this.el.select('.panel-body',true).first().removeClass('hide');
+
var toggleEl = this.toggleEl();
if(!toggleEl){
this.expanded = false;
- this.el.select('.panel-body',true).first().setVisibilityMode(Roo.Element.DISPLAY).hide();
+ //this.el.select('.panel-body',true).first().setVisibilityMode(Roo.Element.DISPLAY).hide();
+ this.el.select('.panel-body',true).first().addClass('hide');
var toggleEl = this.toggleEl();
if (this.buttons.length) {
Roo.each(this.buttons, function(bb) {
- b = Roo.apply({}, bb);
+ var b = Roo.apply({}, bb);
b.xns = b.xns || Roo.bootstrap;
b.xtype = b.xtype || 'Button';
if (typeof(b.listeners) == 'undefined') {
if (this.allow_close) {
this.closeEl.on('click', this.hide, this);
}
+
+ var _this = this;
+
+ window.addEventListener("resize", function() { _this.resize(); } );
},
+
+ resize : function()
+ {
+ this.maskEl.setSize(Roo.lib.Dom.getViewWidth(true), Roo.lib.Dom.getViewHeight(true));
+ },
+
show : function() {
if (!this.rendered) {
},
setActive : function(state, fire, is_was_active)
{
- if (this.active && !state & this.navId) {
+ if (this.active && !state && this.navId) {
this.was_active = true;
var nv = Roo.bootstrap.NavGroup.get(this.navId);
if (nv) {
* @cfg {boolean} condensed Format condensed
* @cfg {boolean} responsive Format condensed
* @cfg {Boolean} loadMask (true|false) default false
- * @cfg {Boolean} tfoot (true|false) generate tfoot, default true
- * @cfg {Boolean} thead (true|false) generate thead, default true
- * @cfg {Boolean} RowSelection (true|false) default false
- * @cfg {Boolean} CellSelection (true|false) default false
+ * @cfg {Boolean} footerShow (true|false) generate tfoot, default true
+ * @cfg {Boolean} headerShow (true|false) generate thead, default true
+ * @cfg {Boolean} rowSelection (true|false) default false
+ * @cfg {Boolean} cellSelection (true|false) default false
* @cfg {Roo.bootstrap.PagingToolbar} footer a paging toolbar
*
Roo.bootstrap.Table = function(config){
Roo.bootstrap.Table.superclass.constructor.call(this, config);
+ // BC...
+ this.rowSelection = (typeof(config.RowSelection) != 'undefined') ? config.RowSelection : this.rowSelection;
+ this.cellSelection = (typeof(config.CellSelection) != 'undefined') ? config.CellSelection : this.cellSelection;
+ this.headerShow = (typeof(config.thead) != 'undefined') ? config.thead : this.headerShow;
+ this.footerShow = (typeof(config.tfoot) != 'undefined') ? config.tfoot : this.footerShow;
+
+
if (this.sm) {
this.selModel = Roo.factory(this.sm, Roo.bootstrap.Table);
this.sm = this.selModel;
cm : false,
store : false,
loadMask : false,
- tfoot : true,
- thead : true,
- RowSelection : false,
- CellSelection : false,
+ footerShow : true,
+ headerShow : true,
+
+ rowSelection : false,
+ cellSelection : false,
layout : false,
// Roo.Element - the tbody
}
if(this.store || this.cm){
- if(this.thead){
+ if(this.headerShow){
cfg.cn.push(this.renderHeader());
}
cfg.cn.push(this.renderBody());
- if(this.tfoot){
+ if(this.footerShow){
cfg.cn.push(this.renderFooter());
}
{
var cell = Roo.get(el);
- if(!cell || (!this.CellSelection && !this.RowSelection)){
+ if(!cell || (!this.cellSelection && !this.rowSelection)){
return;
}
var cellIndex = cell.dom.cellIndex;
var rowIndex = this.getRowIndex(row);
- if(this.CellSelection){
+ // why??? - should these not be based on SelectionModel?
+ if(this.cellSelection){
this.fireEvent('cellclick', this, cell, rowIndex, cellIndex, e);
}
- if(this.RowSelection){
+ if(this.rowSelection){
this.fireEvent('rowclick', this, row, rowIndex, e);
}
for(var i = 0, len = cm.getColumnCount(); i < len; i++){
var config = cm.config[i];
-
+
var c = {
tag: 'th',
style : '',
html: cm.getColumnHeader(i)
};
+ var hh = '';
+
+ if(typeof(config.lgHeader) != 'undefined'){
+ hh += '<span class="hidden-xs hidden-sm hidden-md">' + config.lgHeader + '</span>';
+ }
+
+ if(typeof(config.mdHeader) != 'undefined'){
+ hh += '<span class="hidden-xs hidden-sm hidden-lg">' + config.mdHeader + '</span>';
+ }
+
+ if(typeof(config.smHeader) != 'undefined'){
+ hh += '<span class="hidden-xs hidden-md hidden-lg">' + config.smHeader + '</span>';
+ }
+
+ if(typeof(config.xsHeader) != 'undefined'){
+ hh += '<span class="hidden-sm hidden-md hidden-lg">' + config.xsHeader + '</span>';
+ }
+
+ if(hh.length){
+ c.html = hh;
+ }
+
if(typeof(config.tooltip) != 'undefined'){
c.tooltip = config.tooltip;
}
* @cfg {String} autocomplete - default is new-password see: https://developers.google.com/web/fundamentals/input/form/label-and-name-inputs?hl=en
* @cfg {String} align (left|center|right) Default left
+ * @cfg {Boolean} forceFeedback (true|false) Default false
+ *
*
*
*
readOnly : false,
align : false,
formatedValue : false,
+ forceFeedback : false,
parentLabelAlign : function()
{
this.inputEl().on("blur", this.onBlur, this);
this.inputEl().relayEvent('keyup', this);
-
+
// reference to original value for reset
this.originalValue = this.getValue();
//Roo.form.TextField.superclass.initEvents.call(this);
this.el.removeClass([this.invalidClass, this.validClass]);
+ var feedback = this.el.select('.form-control-feedback', true).first();
+
+ if(feedback){
+ this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
+ }
+
if(this.disabled || this.allowBlank){
return;
}
this.el.addClass(this.validClass);
- if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank && this.getValue().length){
+ if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank && (this.getValue().length || this.forceFeedback)){
var feedback = this.el.select('.form-control-feedback', true).first();
this.el.removeClass([this.invalidClass, this.validClass]);
+ var feedback = this.el.select('.form-control-feedback', true).first();
+
+ if(feedback){
+ this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
+ }
+
if(this.disabled || this.allowBlank){
return;
}
if(feedback){
this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
- if(this.getValue().length){
+ if(this.getValue().length || this.forceFeedback){
this.el.select('.form-control-feedback', true).first().addClass([this.invalidFeedbackClass]);
}
this.syncValue();
this.validate();
+
+ if(this.tickable && !Roo.isTouch){
+ this.view.refresh();
+ }
},
inputEl: function ()
{
this.renderTouchView();
+ this.touchViewEl.on('scroll', function(){
+ this.el.dom.scrollTop = 0;
+ }, this);
+
this.inputEl().on("click", this.showTouchView, this);
this.touchViewFooterEl.select('.roo-touch-view-cancel', true).first().on('click', this.hideTouchView, this);
this.touchViewFooterEl.select('.roo-touch-view-ok', true).first().on('click', this.setTouchViewValue, this);
var listHeight = this.touchViewListGroup.getHeight();
+ var _this = this;
+
if(firstChecked && listHeight > bodyHeight){
- firstChecked.findParent('li').scrollIntoView(this.touchViewListGroup.dom);
+ (function() { firstChecked.findParent('li').scrollIntoView(_this.touchViewListGroup.dom); }).defer(500);
}
},
this.hideTouchView();
+ this.fireEvent('select', this, r, rowIndex);
+
return;
}
this.addItem(r.data);
this.tickItems.push(r.data);
-
-
}
},
setTitle: function(str)
{
+ this.title = str;
this.el.select('.popover-title',true).first().dom.innerHTML = str;
},
setContent: function(str)
{
+ this.html = str;
this.el.select('.popover-content',true).first().dom.innerHTML = str;
},
// as it get's added to the bottom of the page.
// set content.
this.el.select('.popover-title',true).first().dom.innerHtml = this.title;
if (this.html !== false) {
- this.el.select('.popover-content',true).first().dom.innerHtml = this.title;
+ this.el.select('.popover-content',true).first().dom.innerHtml = this.html;
}
this.el.removeClass(['fade','top','bottom', 'left', 'right','in']);
if (!this.title.length) {
//arrow.set(align[2],
this.el.addClass('in');
- this.hoverState = null;
+
if (this.el.hasClass('fade')) {
// fade it?
this.el.setXY([0,0]);
this.el.removeClass('in');
this.el.hide();
+ this.hoverState = null;
}
//html : 'submit'
pressed : toggle ? false : null,
listeners : {}
- }
+ };
a.listeners[toggle ? 'toggle' : 'click'] = function() {
handler ? handler.call(_this,this) :_this.onBtnClick.call(_this, cmd || id);
- }
+ };
children.push(a);
return a;
}
/**
* @class Roo.bootstrap.PagingToolbar
- * @extends Roo.Row
+ * @extends Roo.bootstrap.NavSimplebar
* A specialized toolbar that is bound to a {@link Roo.data.Store} and provides automatic paging controls.
* @constructor
* Create a new PagingToolbar
* @param {Object} config The config object
+ * @param {Roo.data.Store} store
*/
Roo.bootstrap.PagingToolbar = function(config)
{
// old args format still supported... - xtype is prefered..
// created from xtype...
- var ds = config.dataSource;
+
+ this.ds = config.dataSource;
+
+ if (config.store && !this.ds) {
+ this.store= Roo.factory(config.store, Roo.data);
+ this.ds = this.store;
+ this.ds.xmodule = this.xmodule || false;
+ }
+
this.toolbarItems = [];
if (config.items) {
this.toolbarItems = config.items;
-// config.items = [];
}
Roo.bootstrap.PagingToolbar.superclass.constructor.call(this, config);
- this.ds = ds;
+
this.cursor = 0;
- if (ds) {
- this.bind(ds);
+
+ if (this.ds) {
+ this.bind(this.ds);
}
this.navgroup = new Roo.bootstrap.NavGroup({ cls: 'pagination' });
var _this = this;
if(this.buttons){
- Roo.each(_this.buttons, function(e){
+ Roo.each(_this.buttons, function(e){ // this might need to use render????
Roo.factory(e).onRender(_this.el, null);
});
}
preventDefault: true,
listeners : { click : this.onClick.createDelegate(this, ["refresh"]) }
});
-
+
},
// private
}
-
-
if (this.currentTip.el) {
- this.currentTip.el.hide(); // force hiding...
+ this.currentTip.el.setVisibilityMode(Roo.Element.DISPLAY).hide(); // force hiding...
}
//Roo.log(ev);
var bindEl = el;
//this.el.setXY([0,0]);
this.el.show();
//this.el.dom.style.display='block';
- this.el.addClass(placement);
//this.el.appendTo(on_el);
if (autoPlace) {
// fixme..
}
+
var align = Roo.bootstrap.Tooltip.alignment[placement];
+
+ var xy = this.el.getAlignToXY(this.bindEl, align[0], align[1]);
+
+ if(placement == 'top' || placement == 'bottom'){
+ if(xy[0] < 0){
+ placement = 'right';
+ }
+
+ if(xy[0] + this.el.getWidth() > Roo.lib.Dom.getViewWidth()){
+ placement = 'left';
+ }
+ }
+
+ align = Roo.bootstrap.Tooltip.alignment[placement];
+
this.el.alignTo(this.bindEl, align[0],align[1]);
//var arrow = this.el.select('.arrow',true).first();
//arrow.set(align[2],
+ this.el.addClass(placement);
+
this.el.addClass('in fade');
+
this.hoverState = null;
if (this.el.hasClass('fade')) {
});
+
+/*
+* Licence: LGPL
+*/
+
+/**
+ * @class Roo.bootstrap.UploadCropbox
+ * @extends Roo.bootstrap.Component
+ * Bootstrap UploadCropbox class
+ * @cfg {String} emptyText show when image has been loaded
+ * @cfg {String} rotateNotify show when image too small to rotate
+ * @cfg {Number} errorTimeout default 3000
+ * @cfg {Number} minWidth default 300
+ * @cfg {Number} minHeight default 300
+ * @cfg {Array} buttons default ['rotateLeft', 'pictureBtn', 'rotateRight']
+ * @cfg {Boolean} isDocument (true|false) default false
+ * @cfg {String} url action url
+ *
+ * @constructor
+ * Create a new UploadCropbox
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.UploadCropbox = function(config){
+ Roo.bootstrap.UploadCropbox.superclass.constructor.call(this, config);
+
+ this.addEvents({
+ /**
+ * @event beforeselectfile
+ * Fire before select file
+ * @param {Roo.bootstrap.UploadCropbox} this
+ */
+ "beforeselectfile" : true,
+ /**
+ * @event initial
+ * Fire after initEvent
+ * @param {Roo.bootstrap.UploadCropbox} this
+ */
+ "initial" : true,
+ /**
+ * @event crop
+ * Fire after initEvent
+ * @param {Roo.bootstrap.UploadCropbox} this
+ * @param {String} data
+ */
+ "crop" : true,
+ /**
+ * @event prepare
+ * Fire when preparing the file data
+ * @param {Roo.bootstrap.UploadCropbox} this
+ * @param {Object} file
+ */
+ "prepare" : true,
+ /**
+ * @event exception
+ * Fire when get exception
+ * @param {Roo.bootstrap.UploadCropbox} this
+ * @param {XMLHttpRequest} xhr
+ */
+ "exception" : true,
+ /**
+ * @event beforeloadcanvas
+ * Fire before load the canvas
+ * @param {Roo.bootstrap.UploadCropbox} this
+ * @param {String} src
+ */
+ "beforeloadcanvas" : true,
+ /**
+ * @event trash
+ * Fire when trash image
+ * @param {Roo.bootstrap.UploadCropbox} this
+ */
+ "trash" : true,
+ /**
+ * @event download
+ * Fire when download the image
+ * @param {Roo.bootstrap.UploadCropbox} this
+ */
+ "download" : true,
+ /**
+ * @event footerbuttonclick
+ * Fire when footerbuttonclick
+ * @param {Roo.bootstrap.UploadCropbox} this
+ * @param {String} type
+ */
+ "footerbuttonclick" : true,
+ /**
+ * @event resize
+ * Fire when resize
+ * @param {Roo.bootstrap.UploadCropbox} this
+ */
+ "resize" : true,
+ /**
+ * @event rotate
+ * Fire when rotate the image
+ * @param {Roo.bootstrap.UploadCropbox} this
+ * @param {String} pos
+ */
+ "rotate" : true,
+ /**
+ * @event inspect
+ * Fire when inspect the file
+ * @param {Roo.bootstrap.UploadCropbox} this
+ * @param {Object} file
+ */
+ "inspect" : true,
+ /**
+ * @event upload
+ * Fire when xhr upload the file
+ * @param {Roo.bootstrap.UploadCropbox} this
+ * @param {Object} data
+ */
+ "upload" : true,
+ /**
+ * @event arrange
+ * Fire when arrange the file data
+ * @param {Roo.bootstrap.UploadCropbox} this
+ * @param {Object} formData
+ */
+ "arrange" : true
+ });
+
+ this.buttons = this.buttons || Roo.bootstrap.UploadCropbox.footer.STANDARD;
+};
+
+Roo.extend(Roo.bootstrap.UploadCropbox, Roo.bootstrap.Component, {
+
+ emptyText : 'Click to upload image',
+ rotateNotify : 'Image is too small to rotate',
+ errorTimeout : 3000,
+ scale : 0,
+ baseScale : 1,
+ rotate : 0,
+ dragable : false,
+ pinching : false,
+ mouseX : 0,
+ mouseY : 0,
+ cropData : false,
+ minWidth : 300,
+ minHeight : 300,
+ file : false,
+ exif : {},
+ baseRotate : 1,
+ cropType : 'image/jpeg',
+ buttons : false,
+ canvasLoaded : false,
+ isDocument : false,
+
+ getAutoCreate : function()
+ {
+ var cfg = {
+ tag : 'div',
+ cls : 'roo-upload-cropbox',
+ cn : [
+ {
+ tag : 'div',
+ cls : 'roo-upload-cropbox-body',
+ style : 'cursor:pointer',
+ cn : [
+ {
+ tag : 'input',
+ cls : 'roo-upload-cropbox-selector',
+ type : 'file'
+ },
+ {
+ tag : 'div',
+ cls : 'roo-upload-cropbox-preview'
+ },
+ {
+ tag : 'div',
+ cls : 'roo-upload-cropbox-thumb'
+ },
+ {
+ tag : 'div',
+ cls : 'roo-upload-cropbox-empty-notify',
+ html : this.emptyText
+ },
+ {
+ tag : 'div',
+ cls : 'roo-upload-cropbox-error-notify alert alert-danger',
+ html : this.rotateNotify
+ }
+ ]
+ },
+ {
+ tag : 'div',
+ cls : 'roo-upload-cropbox-footer',
+ cn : {
+ tag : 'div',
+ cls : 'btn-group btn-group-justified roo-upload-cropbox-btn-group',
+ cn : []
+ }
+ }
+ ]
+ };
+
+ return cfg;
+ },
+
+ onRender : function(ct, position)
+ {
+ Roo.bootstrap.UploadCropbox.superclass.onRender.call(this, ct, position);
+
+ if (this.buttons.length) {
+
+ Roo.each(this.buttons, function(bb) {
+
+ var btn = this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);
+
+ btn.on('click', this.onFooterButtonClick.createDelegate(this, [bb.action], true));
+
+ }, this);
+ }
+ },
+
+ initEvents : function()
+ {
+ this.urlAPI = (window.createObjectURL && window) ||
+ (window.URL && URL.revokeObjectURL && URL) ||
+ (window.webkitURL && webkitURL);
+
+ this.bodyEl = this.el.select('.roo-upload-cropbox-body', true).first();
+ this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ this.selectorEl = this.el.select('.roo-upload-cropbox-selector', true).first();
+ this.selectorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+ this.selectorEl.hide();
+
+ this.previewEl = this.el.select('.roo-upload-cropbox-preview', true).first();
+ this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ this.thumbEl = this.el.select('.roo-upload-cropbox-thumb', true).first();
+ this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+ this.thumbEl.hide();
+
+ this.notifyEl = this.el.select('.roo-upload-cropbox-empty-notify', true).first();
+ this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ this.errorEl = this.el.select('.roo-upload-cropbox-error-notify', true).first();
+ this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+ this.errorEl.hide();
+
+ this.footerEl = this.el.select('.roo-upload-cropbox-footer', true).first();
+ this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+ this.footerEl.hide();
+
+ this.setThumbBoxSize();
+
+ this.bind();
+
+ this.resize();
+
+ this.fireEvent('initial', this);
+ },
+
+ bind : function()
+ {
+ var _this = this;
+
+ window.addEventListener("resize", function() { _this.resize(); } );
+
+ this.bodyEl.on('click', this.beforeSelectFile, this);
+
+ if(Roo.isTouch){
+ this.bodyEl.on('touchstart', this.onTouchStart, this);
+ this.bodyEl.on('touchmove', this.onTouchMove, this);
+ this.bodyEl.on('touchend', this.onTouchEnd, this);
+ }
+
+ if(!Roo.isTouch){
+ this.bodyEl.on('mousedown', this.onMouseDown, this);
+ this.bodyEl.on('mousemove', this.onMouseMove, this);
+ var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel';
+ this.bodyEl.on(mousewheel, this.onMouseWheel, this);
+ Roo.get(document).on('mouseup', this.onMouseUp, this);
+ }
+
+ this.selectorEl.on('change', this.onFileSelected, this);
+ },
+
+ reset : function()
+ {
+ this.scale = 0;
+ this.baseScale = 1;
+ this.rotate = 0;
+ this.baseRotate = 1;
+ this.dragable = false;
+ this.pinching = false;
+ this.mouseX = 0;
+ this.mouseY = 0;
+ this.cropData = false;
+ this.notifyEl.dom.innerHTML = this.emptyText;
+
+ this.selectorEl.dom.value = '';
+
+ },
+
+ resize : function()
+ {
+ if(this.fireEvent('resize', this) != false){
+ this.setThumbBoxPosition();
+ this.setCanvasPosition();
+ }
+ },
+
+ onFooterButtonClick : function(e, el, o, type)
+ {
+ switch (type) {
+ case 'rotate-left' :
+ this.onRotateLeft(e);
+ break;
+ case 'rotate-right' :
+ this.onRotateRight(e);
+ break;
+ case 'picture' :
+ this.beforeSelectFile(e);
+ break;
+ case 'trash' :
+ this.trash(e);
+ break;
+ case 'crop' :
+ this.crop(e);
+ break;
+ case 'download' :
+ this.download(e);
+ break;
+ default :
+ break;
+ }
+
+ this.fireEvent('footerbuttonclick', this, type);
+ },
+
+ beforeSelectFile : function(e)
+ {
+ e.preventDefault();
+
+ if(this.fireEvent('beforeselectfile', this) != false){
+ this.selectorEl.dom.click();
+ }
+ },
+
+ onFileSelected : function(e)
+ {
+ e.preventDefault();
+
+ if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){
+ return;
+ }
+
+ var file = this.selectorEl.dom.files[0];
+
+ if(this.fireEvent('inspect', this, file) != false){
+ this.prepare(file);
+ }
+
+ },
+
+ trash : function(e)
+ {
+ this.fireEvent('trash', this);
+ },
+
+ download : function(e)
+ {
+ this.fireEvent('download', this);
+ },
+
+ loadCanvas : function(src)
+ {
+ if(this.fireEvent('beforeloadcanvas', this, src) != false){
+
+ this.reset();
+
+ this.imageEl = document.createElement('img');
+
+ var _this = this;
+
+ this.imageEl.addEventListener("load", function(){ _this.onLoadCanvas(); });
+
+ this.imageEl.src = src;
+ }
+ },
+
+ onLoadCanvas : function()
+ {
+ this.imageEl.OriginWidth = this.imageEl.naturalWidth || this.imageEl.width;
+ this.imageEl.OriginHeight = this.imageEl.naturalHeight || this.imageEl.height;
+
+ this.bodyEl.un('click', this.beforeSelectFile, this);
+
+ this.notifyEl.hide();
+ this.thumbEl.show();
+ this.footerEl.show();
+
+ this.baseRotateLevel();
+
+ if(this.isDocument){
+ this.setThumbBoxSize();
+ }
+
+ this.setThumbBoxPosition();
+
+ this.baseScaleLevel();
+
+ this.draw();
+
+ this.resize();
+
+ this.canvasLoaded = true;
+
+ },
+
+ setCanvasPosition : function()
+ {
+ if(!this.canvasEl){
+ return;
+ }
+
+ var pw = Math.ceil((this.bodyEl.getWidth() - this.canvasEl.width) / 2);
+ var ph = Math.ceil((this.bodyEl.getHeight() - this.canvasEl.height) / 2);
+
+ this.previewEl.setLeft(pw);
+ this.previewEl.setTop(ph);
+
+ },
+
+ onMouseDown : function(e)
+ {
+ e.stopEvent();
+
+ this.dragable = true;
+ this.pinching = false;
+
+ if(this.isDocument && (this.canvasEl.width < this.thumbEl.getWidth() || this.canvasEl.height < this.thumbEl.getHeight())){
+ this.dragable = false;
+ return;
+ }
+
+ this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
+ this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
+
+ },
+
+ onMouseMove : function(e)
+ {
+ e.stopEvent();
+
+ if(!this.canvasLoaded){
+ return;
+ }
+
+ if (!this.dragable){
+ return;
+ }
+
+ var minX = Math.ceil(this.thumbEl.getLeft(true));
+ var minY = Math.ceil(this.thumbEl.getTop(true));
+
+ var maxX = Math.ceil(minX + this.thumbEl.getWidth() - this.canvasEl.width);
+ var maxY = Math.ceil(minY + this.thumbEl.getHeight() - this.canvasEl.height);
+
+ var x = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
+ var y = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
+
+ x = x - this.mouseX;
+ y = y - this.mouseY;
+
+ var bgX = Math.ceil(x + this.previewEl.getLeft(true));
+ var bgY = Math.ceil(y + this.previewEl.getTop(true));
+
+ bgX = (minX < bgX) ? minX : ((maxX > bgX) ? maxX : bgX);
+ bgY = (minY < bgY) ? minY : ((maxY > bgY) ? maxY : bgY);
+
+ this.previewEl.setLeft(bgX);
+ this.previewEl.setTop(bgY);
+
+ this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
+ this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
+ },
+
+ onMouseUp : function(e)
+ {
+ e.stopEvent();
+
+ this.dragable = false;
+ },
+
+ onMouseWheel : function(e)
+ {
+ e.stopEvent();
+
+ this.startScale = this.scale;
+
+ this.scale = (e.getWheelDelta() == 1) ? (this.scale + 1) : (this.scale - 1);
+
+ if(!this.zoomable()){
+ this.scale = this.startScale;
+ return;
+ }
+
+ this.draw();
+
+ return;
+ },
+
+ zoomable : function()
+ {
+ var minScale = this.thumbEl.getWidth() / this.minWidth;
+
+ if(this.minWidth < this.minHeight){
+ minScale = this.thumbEl.getHeight() / this.minHeight;
+ }
+
+ var width = Math.ceil(this.imageEl.OriginWidth * this.getScaleLevel() / minScale);
+ var height = Math.ceil(this.imageEl.OriginHeight * this.getScaleLevel() / minScale);
+
+ if(
+ this.isDocument &&
+ (this.rotate == 0 || this.rotate == 180) &&
+ (
+ width > this.imageEl.OriginWidth ||
+ height > this.imageEl.OriginHeight ||
+ (width < this.minWidth && height < this.minHeight)
+ )
+ ){
+ return false;
+ }
+
+ if(
+ this.isDocument &&
+ (this.rotate == 90 || this.rotate == 270) &&
+ (
+ width > this.imageEl.OriginWidth ||
+ height > this.imageEl.OriginHeight ||
+ (width < this.minHeight && height < this.minWidth)
+ )
+ ){
+ return false;
+ }
+
+ if(
+ !this.isDocument &&
+ (this.rotate == 0 || this.rotate == 180) &&
+ (
+ width < this.minWidth ||
+ width > this.imageEl.OriginWidth ||
+ height < this.minHeight ||
+ height > this.imageEl.OriginHeight
+ )
+ ){
+ return false;
+ }
+
+ if(
+ !this.isDocument &&
+ (this.rotate == 90 || this.rotate == 270) &&
+ (
+ width < this.minHeight ||
+ width > this.imageEl.OriginWidth ||
+ height < this.minWidth ||
+ height > this.imageEl.OriginHeight
+ )
+ ){
+ return false;
+ }
+
+ return true;
+
+ },
+
+ onRotateLeft : function(e)
+ {
+ if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){
+
+ var minScale = this.thumbEl.getWidth() / this.minWidth;
+
+ var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());
+ var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());
+
+ this.startScale = this.scale;
+
+ while (this.getScaleLevel() < minScale){
+
+ this.scale = this.scale + 1;
+
+ if(!this.zoomable()){
+ break;
+ }
+
+ if(
+ Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||
+ Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()
+ ){
+ continue;
+ }
+
+ this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;
+
+ this.draw();
+
+ return;
+ }
+
+ this.scale = this.startScale;
+
+ this.onRotateFail();
+
+ return false;
+ }
+
+ this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;
+
+ if(this.isDocument){
+ this.setThumbBoxSize();
+ this.setThumbBoxPosition();
+ this.setCanvasPosition();
+ }
+
+ this.draw();
+
+ this.fireEvent('rotate', this, 'left');
+
+ },
+
+ onRotateRight : function(e)
+ {
+ if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){
+
+ var minScale = this.thumbEl.getWidth() / this.minWidth;
+
+ var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());
+ var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());
+
+ this.startScale = this.scale;
+
+ while (this.getScaleLevel() < minScale){
+
+ this.scale = this.scale + 1;
+
+ if(!this.zoomable()){
+ break;
+ }
+
+ if(
+ Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||
+ Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()
+ ){
+ continue;
+ }
+
+ this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;
+
+ this.draw();
+
+ return;
+ }
+
+ this.scale = this.startScale;
+
+ this.onRotateFail();
+
+ return false;
+ }
+
+ this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;
+
+ if(this.isDocument){
+ this.setThumbBoxSize();
+ this.setThumbBoxPosition();
+ this.setCanvasPosition();
+ }
+
+ this.draw();
+
+ this.fireEvent('rotate', this, 'right');
+ },
+
+ onRotateFail : function()
+ {
+ this.errorEl.show(true);
+
+ var _this = this;
+
+ (function() { _this.errorEl.hide(true); }).defer(this.errorTimeout);
+ },
+
+ draw : function()
+ {
+ this.previewEl.dom.innerHTML = '';
+
+ var canvasEl = document.createElement("canvas");
+
+ var contextEl = canvasEl.getContext("2d");
+
+ canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
+ canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
+ var center = this.imageEl.OriginWidth / 2;
+
+ if(this.imageEl.OriginWidth < this.imageEl.OriginHeight){
+ canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
+ canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
+ center = this.imageEl.OriginHeight / 2;
+ }
+
+ contextEl.scale(this.getScaleLevel(), this.getScaleLevel());
+
+ contextEl.translate(center, center);
+ contextEl.rotate(this.rotate * Math.PI / 180);
+
+ contextEl.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);
+
+ this.canvasEl = document.createElement("canvas");
+
+ this.contextEl = this.canvasEl.getContext("2d");
+
+ switch (this.rotate) {
+ case 0 :
+
+ this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
+ this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
+
+ this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+
+ break;
+ case 90 :
+
+ this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
+ this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
+
+ if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+ this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+ break;
+ }
+
+ this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+
+ break;
+ case 180 :
+
+ this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
+ this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
+
+ if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+ this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+ break;
+ }
+
+ this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+
+ break;
+ case 270 :
+
+ this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
+ this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
+
+ if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+ this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+ break;
+ }
+
+ this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+
+ break;
+ default :
+ break;
+ }
+
+ this.previewEl.appendChild(this.canvasEl);
+
+ this.setCanvasPosition();
+ },
+
+ crop : function()
+ {
+ if(!this.canvasLoaded){
+ return;
+ }
+
+ var imageCanvas = document.createElement("canvas");
+
+ var imageContext = imageCanvas.getContext("2d");
+
+ imageCanvas.width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;
+ imageCanvas.height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;
+
+ var center = imageCanvas.width / 2;
+
+ imageContext.translate(center, center);
+
+ imageContext.rotate(this.rotate * Math.PI / 180);
+
+ imageContext.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);
+
+ var canvas = document.createElement("canvas");
+
+ var context = canvas.getContext("2d");
+
+ canvas.width = this.minWidth;
+ canvas.height = this.minHeight;
+
+ switch (this.rotate) {
+ case 0 :
+
+ var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());
+ var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());
+
+ var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+ var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+
+ var targetWidth = this.minWidth - 2 * x;
+ var targetHeight = this.minHeight - 2 * y;
+
+ var scale = 1;
+
+ if((x == 0 && y == 0) || (x == 0 && y > 0)){
+ scale = targetWidth / width;
+ }
+
+ if(x > 0 && y == 0){
+ scale = targetHeight / height;
+ }
+
+ if(x > 0 && y > 0){
+ scale = targetWidth / width;
+
+ if(width < height){
+ scale = targetHeight / height;
+ }
+ }
+
+ context.scale(scale, scale);
+
+ var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
+ var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
+
+ sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+ sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+
+ context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+
+ break;
+ case 90 :
+
+ var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());
+ var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());
+
+ var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+ var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+
+ var targetWidth = this.minWidth - 2 * x;
+ var targetHeight = this.minHeight - 2 * y;
+
+ var scale = 1;
+
+ if((x == 0 && y == 0) || (x == 0 && y > 0)){
+ scale = targetWidth / width;
+ }
+
+ if(x > 0 && y == 0){
+ scale = targetHeight / height;
+ }
+
+ if(x > 0 && y > 0){
+ scale = targetWidth / width;
+
+ if(width < height){
+ scale = targetHeight / height;
+ }
+ }
+
+ context.scale(scale, scale);
+
+ var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
+ var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
+
+ sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+ sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+
+ sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;
+
+ context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+
+ break;
+ case 180 :
+
+ var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());
+ var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());
+
+ var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+ var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+
+ var targetWidth = this.minWidth - 2 * x;
+ var targetHeight = this.minHeight - 2 * y;
+
+ var scale = 1;
+
+ if((x == 0 && y == 0) || (x == 0 && y > 0)){
+ scale = targetWidth / width;
+ }
+
+ if(x > 0 && y == 0){
+ scale = targetHeight / height;
+ }
+
+ if(x > 0 && y > 0){
+ scale = targetWidth / width;
+
+ if(width < height){
+ scale = targetHeight / height;
+ }
+ }
+
+ context.scale(scale, scale);
+
+ var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
+ var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
+
+ sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+ sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+
+ sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);
+ sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;
+
+ context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+
+ break;
+ case 270 :
+
+ var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());
+ var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());
+
+ var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+ var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+
+ var targetWidth = this.minWidth - 2 * x;
+ var targetHeight = this.minHeight - 2 * y;
+
+ var scale = 1;
+
+ if((x == 0 && y == 0) || (x == 0 && y > 0)){
+ scale = targetWidth / width;
+ }
+
+ if(x > 0 && y == 0){
+ scale = targetHeight / height;
+ }
+
+ if(x > 0 && y > 0){
+ scale = targetWidth / width;
+
+ if(width < height){
+ scale = targetHeight / height;
+ }
+ }
+
+ context.scale(scale, scale);
+
+ var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
+ var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
+
+ sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+ sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+
+ sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);
+
+ context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+
+ break;
+ default :
+ break;
+ }
+
+ this.cropData = canvas.toDataURL(this.cropType);
+
+ if(this.fireEvent('crop', this, this.cropData) !== false){
+ this.process(this.file, this.cropData);
+ }
+
+ return;
+
+ },
+
+ setThumbBoxSize : function()
+ {
+ var width, height;
+
+ if(this.isDocument && typeof(this.imageEl) != 'undefined'){
+ width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.max(this.minWidth, this.minHeight) : Math.min(this.minWidth, this.minHeight);
+ height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.min(this.minWidth, this.minHeight) : Math.max(this.minWidth, this.minHeight);
+
+ this.minWidth = width;
+ this.minHeight = height;
+
+ if(this.rotate == 90 || this.rotate == 270){
+ this.minWidth = height;
+ this.minHeight = width;
+ }
+ }
+
+ height = 300;
+ width = Math.ceil(this.minWidth * height / this.minHeight);
+
+ if(this.minWidth > this.minHeight){
+ width = 300;
+ height = Math.ceil(this.minHeight * width / this.minWidth);
+ }
+
+ this.thumbEl.setStyle({
+ width : width + 'px',
+ height : height + 'px'
+ });
+
+ return;
+
+ },
+
+ setThumbBoxPosition : function()
+ {
+ var x = Math.ceil((this.bodyEl.getWidth() - this.thumbEl.getWidth()) / 2 );
+ var y = Math.ceil((this.bodyEl.getHeight() - this.thumbEl.getHeight()) / 2);
+
+ this.thumbEl.setLeft(x);
+ this.thumbEl.setTop(y);
+
+ },
+
+ baseRotateLevel : function()
+ {
+ this.baseRotate = 1;
+
+ if(
+ typeof(this.exif) != 'undefined' &&
+ typeof(this.exif[Roo.bootstrap.UploadCropbox['tags']['Orientation']]) != 'undefined' &&
+ [1, 3, 6, 8].indexOf(this.exif[Roo.bootstrap.UploadCropbox['tags']['Orientation']]) != -1
+ ){
+ this.baseRotate = this.exif[Roo.bootstrap.UploadCropbox['tags']['Orientation']];
+ }
+
+ this.rotate = Roo.bootstrap.UploadCropbox['Orientation'][this.baseRotate];
+
+ },
+
+ baseScaleLevel : function()
+ {
+ var width, height;
+
+ if(this.isDocument){
+
+ if(this.baseRotate == 6 || this.baseRotate == 8){
+
+ height = this.thumbEl.getHeight();
+ this.baseScale = height / this.imageEl.OriginWidth;
+
+ if(this.imageEl.OriginHeight * this.baseScale > this.thumbEl.getWidth()){
+ width = this.thumbEl.getWidth();
+ this.baseScale = width / this.imageEl.OriginHeight;
+ }
+
+ return;
+ }
+
+ height = this.thumbEl.getHeight();
+ this.baseScale = height / this.imageEl.OriginHeight;
+
+ if(this.imageEl.OriginWidth * this.baseScale > this.thumbEl.getWidth()){
+ width = this.thumbEl.getWidth();
+ this.baseScale = width / this.imageEl.OriginWidth;
+ }
+
+ return;
+ }
+
+ if(this.baseRotate == 6 || this.baseRotate == 8){
+
+ width = this.thumbEl.getHeight();
+ this.baseScale = width / this.imageEl.OriginHeight;
+
+ if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getWidth()){
+ height = this.thumbEl.getWidth();
+ this.baseScale = height / this.imageEl.OriginHeight;
+ }
+
+ if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+ height = this.thumbEl.getWidth();
+ this.baseScale = height / this.imageEl.OriginHeight;
+
+ if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getHeight()){
+ width = this.thumbEl.getHeight();
+ this.baseScale = width / this.imageEl.OriginWidth;
+ }
+ }
+
+ return;
+ }
+
+ width = this.thumbEl.getWidth();
+ this.baseScale = width / this.imageEl.OriginWidth;
+
+ if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getHeight()){
+ height = this.thumbEl.getHeight();
+ this.baseScale = height / this.imageEl.OriginHeight;
+ }
+
+ if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+
+ height = this.thumbEl.getHeight();
+ this.baseScale = height / this.imageEl.OriginHeight;
+
+ if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getWidth()){
+ width = this.thumbEl.getWidth();
+ this.baseScale = width / this.imageEl.OriginWidth;
+ }
+
+ }
+
+ return;
+ },
+
+ getScaleLevel : function()
+ {
+ return this.baseScale * Math.pow(1.1, this.scale);
+ },
+
+ onTouchStart : function(e)
+ {
+ if(!this.canvasLoaded){
+ this.beforeSelectFile(e);
+ return;
+ }
+
+ var touches = e.browserEvent.touches;
+
+ if(!touches){
+ return;
+ }
+
+ if(touches.length == 1){
+ this.onMouseDown(e);
+ return;
+ }
+
+ if(touches.length != 2){
+ return;
+ }
+
+ var coords = [];
+
+ for(var i = 0, finger; finger = touches[i]; i++){
+ coords.push(finger.pageX, finger.pageY);
+ }
+
+ var x = Math.pow(coords[0] - coords[2], 2);
+ var y = Math.pow(coords[1] - coords[3], 2);
+
+ this.startDistance = Math.sqrt(x + y);
+
+ this.startScale = this.scale;
+
+ this.pinching = true;
+ this.dragable = false;
+
+ },
+
+ onTouchMove : function(e)
+ {
+ if(!this.pinching && !this.dragable){
+ return;
+ }
+
+ var touches = e.browserEvent.touches;
+
+ if(!touches){
+ return;
+ }
+
+ if(this.dragable){
+ this.onMouseMove(e);
+ return;
+ }
+
+ var coords = [];
+
+ for(var i = 0, finger; finger = touches[i]; i++){
+ coords.push(finger.pageX, finger.pageY);
+ }
+
+ var x = Math.pow(coords[0] - coords[2], 2);
+ var y = Math.pow(coords[1] - coords[3], 2);
+
+ this.endDistance = Math.sqrt(x + y);
+
+ this.scale = this.startScale + Math.floor(Math.log(this.endDistance / this.startDistance) / Math.log(1.1));
+
+ if(!this.zoomable()){
+ this.scale = this.startScale;
+ return;
+ }
+
+ this.draw();
+
+ },
+
+ onTouchEnd : function(e)
+ {
+ this.pinching = false;
+ this.dragable = false;
+
+ },
+
+ process : function(file, crop)
+ {
+ this.xhr = new XMLHttpRequest();
+
+ if(typeof(this.file.id) != 'undefined' && this.file.id * 1 > 0){
+ return;
+ }
+
+ file.xhr = this.xhr;
+
+ this.xhr.open(this.method, this.url, true);
+
+ var headers = {
+ "Accept": "application/json",
+ "Cache-Control": "no-cache",
+ "X-Requested-With": "XMLHttpRequest"
+ };
+
+ for (var headerName in headers) {
+ var headerValue = headers[headerName];
+ if (headerValue) {
+ this.xhr.setRequestHeader(headerName, headerValue);
+ }
+ }
+
+ var _this = this;
+
+ this.xhr.onload = function()
+ {
+ _this.xhrOnLoad(_this.xhr);
+ }
+
+ this.xhr.onerror = function()
+ {
+ _this.xhrOnError(_this.xhr);
+ }
+
+ var formData = new FormData();
+
+ formData.append('returnHTML', 'NO');
+
+ if(crop){
+ formData.append('crop', crop);
+ }
+
+ formData.append(this.paramName, file, file.name);
+
+ if(this.fireEvent('arrange', this, formData) != false){
+ this.xhr.send(formData);
+ };
+ },
+
+ xhrOnLoad : function(xhr)
+ {
+ if (xhr.readyState !== 4) {
+ this.fireEvent('exception', this, xhr);
+ return;
+ }
+
+ var response = Roo.decode(xhr.responseText);
+
+ if(!response.success){
+ this.fireEvent('exception', this, xhr);
+ return;
+ }
+
+ var response = Roo.decode(xhr.responseText);
+
+ this.fireEvent('upload', this, response);
+
+ },
+
+ xhrOnError : function()
+ {
+ Roo.log('xhr on error');
+
+ var response = Roo.decode(xhr.responseText);
+
+ Roo.log(response);
+
+ },
+
+ uploadFromSource : function(file, crop)
+ {
+ this.xhr = new XMLHttpRequest();
+
+ this.xhr.open(this.method, this.url, true);
+
+ var headers = {
+ "Accept": "application/json",
+ "Cache-Control": "no-cache",
+ "X-Requested-With": "XMLHttpRequest"
+ };
+
+ for (var headerName in headers) {
+ var headerValue = headers[headerName];
+ if (headerValue) {
+ this.xhr.setRequestHeader(headerName, headerValue);
+ }
+ }
+
+ var _this = this;
+
+ this.xhr.onload = function()
+ {
+ _this.xhrOnLoad(_this.xhr);
+ }
+
+ this.xhr.onerror = function()
+ {
+ _this.xhrOnError(_this.xhr);
+ }
+
+ var formData = new FormData();
+
+ formData.append('returnHTML', 'NO');
+
+ formData.append('crop', crop);
+
+ if(typeof(file.filename) != 'undefined'){
+ formData.append('filename', file.filename);
+ }
+
+ if(typeof(file.mimetype) != 'undefined'){
+ formData.append('mimetype', file.mimetype);
+ }
+
+ if(this.fireEvent('arrange', this, formData) != false){
+ this.xhr.send(formData);
+ };
+ },
+
+ prepare : function(file)
+ {
+ this.file = false;
+ this.exif = {};
+
+ if(typeof(file) === 'string'){
+ this.loadCanvas(file);
+ return;
+ }
+
+ if(!file || !this.urlAPI){
+ return;
+ }
+
+ this.file = file;
+ this.cropType = file.type;
+
+ var _this = this;
+
+ if(this.fireEvent('prepare', this, this.file) != false){
+
+ var reader = new FileReader();
+
+ reader.onload = function (e) {
+ if (e.target.error) {
+ Roo.log(e.target.error);
+ return;
+ }
+
+ var buffer = e.target.result,
+ dataView = new DataView(buffer),
+ offset = 2,
+ maxOffset = dataView.byteLength - 4,
+ markerBytes,
+ markerLength;
+
+ if (dataView.getUint16(0) === 0xffd8) {
+ while (offset < maxOffset) {
+ markerBytes = dataView.getUint16(offset);
+
+ if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) || markerBytes === 0xfffe) {
+ markerLength = dataView.getUint16(offset + 2) + 2;
+ if (offset + markerLength > dataView.byteLength) {
+ Roo.log('Invalid meta data: Invalid segment size.');
+ break;
+ }
+
+ if(markerBytes == 0xffe1){
+ _this.parseExifData(
+ dataView,
+ offset,
+ markerLength
+ );
+ }
+
+ offset += markerLength;
+
+ continue;
+ }
+
+ break;
+ }
+
+ }
+
+ var url = _this.urlAPI.createObjectURL(_this.file);
+
+ _this.loadCanvas(url);
+
+ return;
+ }
+
+ reader.readAsArrayBuffer(this.file);
+
+ }
+
+ },
+
+ parseExifData : function(dataView, offset, length)
+ {
+ var tiffOffset = offset + 10,
+ littleEndian,
+ dirOffset;
+
+ if (dataView.getUint32(offset + 4) !== 0x45786966) {
+ // No Exif data, might be XMP data instead
+ return;
+ }
+
+ // Check for the ASCII code for "Exif" (0x45786966):
+ if (dataView.getUint32(offset + 4) !== 0x45786966) {
+ // No Exif data, might be XMP data instead
+ return;
+ }
+ if (tiffOffset + 8 > dataView.byteLength) {
+ Roo.log('Invalid Exif data: Invalid segment size.');
+ return;
+ }
+ // Check for the two null bytes:
+ if (dataView.getUint16(offset + 8) !== 0x0000) {
+ Roo.log('Invalid Exif data: Missing byte alignment offset.');
+ return;
+ }
+ // Check the byte alignment:
+ switch (dataView.getUint16(tiffOffset)) {
+ case 0x4949:
+ littleEndian = true;
+ break;
+ case 0x4D4D:
+ littleEndian = false;
+ break;
+ default:
+ Roo.log('Invalid Exif data: Invalid byte alignment marker.');
+ return;
+ }
+ // Check for the TIFF tag marker (0x002A):
+ if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) {
+ Roo.log('Invalid Exif data: Missing TIFF marker.');
+ return;
+ }
+ // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:
+ dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
+
+ this.parseExifTags(
+ dataView,
+ tiffOffset,
+ tiffOffset + dirOffset,
+ littleEndian
+ );
+ },
+
+ parseExifTags : function(dataView, tiffOffset, dirOffset, littleEndian)
+ {
+ var tagsNumber,
+ dirEndOffset,
+ i;
+ if (dirOffset + 6 > dataView.byteLength) {
+ Roo.log('Invalid Exif data: Invalid directory offset.');
+ return;
+ }
+ tagsNumber = dataView.getUint16(dirOffset, littleEndian);
+ dirEndOffset = dirOffset + 2 + 12 * tagsNumber;
+ if (dirEndOffset + 4 > dataView.byteLength) {
+ Roo.log('Invalid Exif data: Invalid directory size.');
+ return;
+ }
+ for (i = 0; i < tagsNumber; i += 1) {
+ this.parseExifTag(
+ dataView,
+ tiffOffset,
+ dirOffset + 2 + 12 * i, // tag offset
+ littleEndian
+ );
+ }
+ // Return the offset to the next directory:
+ return dataView.getUint32(dirEndOffset, littleEndian);
+ },
+
+ parseExifTag : function (dataView, tiffOffset, offset, littleEndian)
+ {
+ var tag = dataView.getUint16(offset, littleEndian);
+
+ this.exif[tag] = this.getExifValue(
+ dataView,
+ tiffOffset,
+ offset,
+ dataView.getUint16(offset + 2, littleEndian), // tag type
+ dataView.getUint32(offset + 4, littleEndian), // tag length
+ littleEndian
+ );
+ },
+
+ getExifValue : function (dataView, tiffOffset, offset, type, length, littleEndian)
+ {
+ var tagType = Roo.bootstrap.UploadCropbox.exifTagTypes[type],
+ tagSize,
+ dataOffset,
+ values,
+ i,
+ str,
+ c;
+
+ if (!tagType) {
+ Roo.log('Invalid Exif data: Invalid tag type.');
+ return;
+ }
+
+ tagSize = tagType.size * length;
+ // Determine if the value is contained in the dataOffset bytes,
+ // or if the value at the dataOffset is a pointer to the actual data:
+ dataOffset = tagSize > 4 ?
+ tiffOffset + dataView.getUint32(offset + 8, littleEndian) : (offset + 8);
+ if (dataOffset + tagSize > dataView.byteLength) {
+ Roo.log('Invalid Exif data: Invalid data offset.');
+ return;
+ }
+ if (length === 1) {
+ return tagType.getValue(dataView, dataOffset, littleEndian);
+ }
+ values = [];
+ for (i = 0; i < length; i += 1) {
+ values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian);
+ }
+
+ if (tagType.ascii) {
+ str = '';
+ // Concatenate the chars:
+ for (i = 0; i < values.length; i += 1) {
+ c = values[i];
+ // Ignore the terminating NULL byte(s):
+ if (c === '\u0000') {
+ break;
+ }
+ str += c;
+ }
+ return str;
+ }
+ return values;
+ }
+
+});
+
+Roo.apply(Roo.bootstrap.UploadCropbox, {
+ tags : {
+ 'Orientation': 0x0112
+ },
+
+ Orientation: {
+ 1: 0, //'top-left',
+// 2: 'top-right',
+ 3: 180, //'bottom-right',
+// 4: 'bottom-left',
+// 5: 'left-top',
+ 6: 90, //'right-top',
+// 7: 'right-bottom',
+ 8: 270 //'left-bottom'
+ },
+
+ exifTagTypes : {
+ // byte, 8-bit unsigned int:
+ 1: {
+ getValue: function (dataView, dataOffset) {
+ return dataView.getUint8(dataOffset);
+ },
+ size: 1
+ },
+ // ascii, 8-bit byte:
+ 2: {
+ getValue: function (dataView, dataOffset) {
+ return String.fromCharCode(dataView.getUint8(dataOffset));
+ },
+ size: 1,
+ ascii: true
+ },
+ // short, 16 bit int:
+ 3: {
+ getValue: function (dataView, dataOffset, littleEndian) {
+ return dataView.getUint16(dataOffset, littleEndian);
+ },
+ size: 2
+ },
+ // long, 32 bit int:
+ 4: {
+ getValue: function (dataView, dataOffset, littleEndian) {
+ return dataView.getUint32(dataOffset, littleEndian);
+ },
+ size: 4
+ },
+ // rational = two long values, first is numerator, second is denominator:
+ 5: {
+ getValue: function (dataView, dataOffset, littleEndian) {
+ return dataView.getUint32(dataOffset, littleEndian) /
+ dataView.getUint32(dataOffset + 4, littleEndian);
+ },
+ size: 8
+ },
+ // slong, 32 bit signed int:
+ 9: {
+ getValue: function (dataView, dataOffset, littleEndian) {
+ return dataView.getInt32(dataOffset, littleEndian);
+ },
+ size: 4
+ },
+ // srational, two slongs, first is numerator, second is denominator:
+ 10: {
+ getValue: function (dataView, dataOffset, littleEndian) {
+ return dataView.getInt32(dataOffset, littleEndian) /
+ dataView.getInt32(dataOffset + 4, littleEndian);
+ },
+ size: 8
+ }
+ },
+
+ footer : {
+ STANDARD : [
+ {
+ tag : 'div',
+ cls : 'btn-group roo-upload-cropbox-rotate-left',
+ action : 'rotate-left',
+ cn : [
+ {
+ tag : 'button',
+ cls : 'btn btn-default',
+ html : '<i class="fa fa-undo"></i>'
+ }
+ ]
+ },
+ {
+ tag : 'div',
+ cls : 'btn-group roo-upload-cropbox-picture',
+ action : 'picture',
+ cn : [
+ {
+ tag : 'button',
+ cls : 'btn btn-default',
+ html : '<i class="fa fa-picture-o"></i>'
+ }
+ ]
+ },
+ {
+ tag : 'div',
+ cls : 'btn-group roo-upload-cropbox-rotate-right',
+ action : 'rotate-right',
+ cn : [
+ {
+ tag : 'button',
+ cls : 'btn btn-default',
+ html : '<i class="fa fa-repeat"></i>'
+ }
+ ]
+ }
+ ],
+ DOCUMENT : [
+ {
+ tag : 'div',
+ cls : 'btn-group roo-upload-cropbox-rotate-left',
+ action : 'rotate-left',
+ cn : [
+ {
+ tag : 'button',
+ cls : 'btn btn-default',
+ html : '<i class="fa fa-undo"></i>'
+ }
+ ]
+ },
+ {
+ tag : 'div',
+ cls : 'btn-group roo-upload-cropbox-download',
+ action : 'download',
+ cn : [
+ {
+ tag : 'button',
+ cls : 'btn btn-default',
+ html : '<i class="fa fa-download"></i>'
+ }
+ ]
+ },
+ {
+ tag : 'div',
+ cls : 'btn-group roo-upload-cropbox-crop',
+ action : 'crop',
+ cn : [
+ {
+ tag : 'button',
+ cls : 'btn btn-default',
+ html : '<i class="fa fa-crop"></i>'
+ }
+ ]
+ },
+ {
+ tag : 'div',
+ cls : 'btn-group roo-upload-cropbox-trash',
+ action : 'trash',
+ cn : [
+ {
+ tag : 'button',
+ cls : 'btn btn-default',
+ html : '<i class="fa fa-trash"></i>'
+ }
+ ]
+ },
+ {
+ tag : 'div',
+ cls : 'btn-group roo-upload-cropbox-rotate-right',
+ action : 'rotate-right',
+ cn : [
+ {
+ tag : 'button',
+ cls : 'btn btn-default',
+ html : '<i class="fa fa-repeat"></i>'
+ }
+ ]
+ }
+ ],
+ ROTATOR : [
+ {
+ tag : 'div',
+ cls : 'btn-group roo-upload-cropbox-rotate-left',
+ action : 'rotate-left',
+ cn : [
+ {
+ tag : 'button',
+ cls : 'btn btn-default',
+ html : '<i class="fa fa-undo"></i>'
+ }
+ ]
+ },
+ {
+ tag : 'div',
+ cls : 'btn-group roo-upload-cropbox-rotate-right',
+ action : 'rotate-right',
+ cn : [
+ {
+ tag : 'button',
+ cls : 'btn btn-default',
+ html : '<i class="fa fa-repeat"></i>'
+ }
+ ]
+ }
+ ]
+ }
+});
+
+/*
+* Licence: LGPL
+*/
+
+/**
+ * @class Roo.bootstrap.DocumentManager
+ * @extends Roo.bootstrap.Component
+ * Bootstrap DocumentManager class
+ * @cfg {String} paramName default 'imageUpload'
+ * @cfg {String} method default POST
+ * @cfg {String} url action url
+ * @cfg {Number} boxes number of boxes, 0 is no limit.. default 0
+ * @cfg {Boolean} multiple multiple upload default true
+ * @cfg {Number} thumbSize default 300
+ * @cfg {String} fieldLabel
+ * @cfg {Number} labelWidth default 4
+ * @cfg {String} labelAlign (left|top) default left
+ * @cfg {Boolean} editable (true|false) allow edit when upload a image default true
+ *
+ * @constructor
+ * Create a new DocumentManager
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.DocumentManager = function(config){
+ Roo.bootstrap.DocumentManager.superclass.constructor.call(this, config);
+
+ this.addEvents({
+ /**
+ * @event initial
+ * Fire when initial the DocumentManager
+ * @param {Roo.bootstrap.DocumentManager} this
+ */
+ "initial" : true,
+ /**
+ * @event inspect
+ * inspect selected file
+ * @param {Roo.bootstrap.DocumentManager} this
+ * @param {File} file
+ */
+ "inspect" : true,
+ /**
+ * @event exception
+ * Fire when xhr load exception
+ * @param {Roo.bootstrap.DocumentManager} this
+ * @param {XMLHttpRequest} xhr
+ */
+ "exception" : true,
+ /**
+ * @event prepare
+ * prepare the form data
+ * @param {Roo.bootstrap.DocumentManager} this
+ * @param {Object} formData
+ */
+ "prepare" : true,
+ /**
+ * @event remove
+ * Fire when remove the file
+ * @param {Roo.bootstrap.DocumentManager} this
+ * @param {Object} file
+ */
+ "remove" : true,
+ /**
+ * @event refresh
+ * Fire after refresh the file
+ * @param {Roo.bootstrap.DocumentManager} this
+ */
+ "refresh" : true,
+ /**
+ * @event click
+ * Fire after click the image
+ * @param {Roo.bootstrap.DocumentManager} this
+ * @param {Object} file
+ */
+ "click" : true,
+ /**
+ * @event edit
+ * Fire when upload a image and editable set to true
+ * @param {Roo.bootstrap.DocumentManager} this
+ * @param {Object} file
+ */
+ "edit" : true,
+ /**
+ * @event beforeselectfile
+ * Fire before select file
+ * @param {Roo.bootstrap.DocumentManager} this
+ */
+ "beforeselectfile" : true
+
+ });
+};
+
+Roo.extend(Roo.bootstrap.DocumentManager, Roo.bootstrap.Component, {
+
+ boxes : 0,
+ inputName : '',
+ thumbSize : 300,
+ multiple : true,
+ files : [],
+ method : 'POST',
+ url : '',
+ paramName : 'imageUpload',
+ fieldLabel : '',
+ labelWidth : 4,
+ labelAlign : 'left',
+ editable : true,
+ delegates : [],
+
+ getAutoCreate : function()
+ {
+ var managerWidget = {
+ tag : 'div',
+ cls : 'roo-document-manager',
+ cn : [
+ {
+ tag : 'input',
+ cls : 'roo-document-manager-selector',
+ type : 'file'
+ },
+ {
+ tag : 'div',
+ cls : 'roo-document-manager-uploader',
+ cn : [
+ {
+ tag : 'div',
+ cls : 'roo-document-manager-upload-btn',
+ html : '<i class="fa fa-plus"></i>'
+ }
+ ]
+
+ }
+ ]
+ };
+
+ var content = [
+ {
+ tag : 'div',
+ cls : 'column col-md-12',
+ cn : managerWidget
+ }
+ ];
+
+ if(this.fieldLabel.length){
+
+ content = [
+ {
+ tag : 'div',
+ cls : 'column col-md-12',
+ html : this.fieldLabel
+ },
+ {
+ tag : 'div',
+ cls : 'column col-md-12',
+ cn : managerWidget
+ }
+ ];
+
+ if(this.labelAlign == 'left'){
+ content = [
+ {
+ tag : 'div',
+ cls : 'column col-md-' + this.labelWidth,
+ html : this.fieldLabel
+ },
+ {
+ tag : 'div',
+ cls : 'column col-md-' + (12 - this.labelWidth),
+ cn : managerWidget
+ }
+ ];
+
+ }
+ }
+
+ var cfg = {
+ tag : 'div',
+ cls : 'row clearfix',
+ cn : content
+ };
+
+ return cfg;
+
+ },
+
+ initEvents : function()
+ {
+ this.managerEl = this.el.select('.roo-document-manager', true).first();
+ this.managerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ this.selectorEl = this.el.select('.roo-document-manager-selector', true).first();
+ this.selectorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+ this.selectorEl.hide();
+
+ if(this.multiple){
+ this.selectorEl.attr('multiple', 'multiple');
+ }
+
+ this.selectorEl.on('change', this.onFileSelected, this);
+
+ this.uploader = this.el.select('.roo-document-manager-uploader', true).first();
+ this.uploader.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ this.uploader.on('click', this.onUploaderClick, this);
+
+ this.renderProgressDialog();
+
+ var _this = this;
+
+ window.addEventListener("resize", function() { _this.refresh(); } );
+
+ this.fireEvent('initial', this);
+ },
+
+ renderProgressDialog : function()
+ {
+ var _this = this;
+
+ this.progressDialog = new Roo.bootstrap.Modal({
+ cls : 'roo-document-manager-progress-dialog',
+ allow_close : false,
+ title : '',
+ buttons : [
+ {
+ name :'cancel',
+ weight : 'danger',
+ html : 'Cancel'
+ }
+ ],
+ listeners : {
+ btnclick : function() {
+ _this.uploadCancel();
+ this.hide();
+ }
+ }
+ });
+
+ this.progressDialog.render(Roo.get(document.body));
+
+ this.progress = new Roo.bootstrap.Progress({
+ cls : 'roo-document-manager-progress',
+ active : true,
+ striped : true
+ });
+
+ this.progress.render(this.progressDialog.getChildContainer());
+
+ this.progressBar = new Roo.bootstrap.ProgressBar({
+ cls : 'roo-document-manager-progress-bar',
+ aria_valuenow : 0,
+ aria_valuemin : 0,
+ aria_valuemax : 12,
+ panel : 'success'
+ });
+
+ this.progressBar.render(this.progress.getChildContainer());
+ },
+
+ onUploaderClick : function(e)
+ {
+ e.preventDefault();
+
+ if(this.fireEvent('beforeselectfile', this) != false){
+ this.selectorEl.dom.click();
+ }
+
+ },
+
+ onFileSelected : function(e)
+ {
+ e.preventDefault();
+
+ if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){
+ return;
+ }
+
+ Roo.each(this.selectorEl.dom.files, function(file){
+ if(this.fireEvent('inspect', this, file) != false){
+ this.files.push(file);
+ }
+ }, this);
+
+ this.queue();
+
+ },
+
+ queue : function()
+ {
+ this.selectorEl.dom.value = '';
+
+ if(!this.files.length){
+ return;
+ }
+
+ if(this.boxes > 0 && this.files.length > this.boxes){
+ this.files = this.files.slice(0, this.boxes);
+ }
+
+ this.uploader.show();
+
+ if(this.boxes > 0 && this.files.length > this.boxes - 1){
+ this.uploader.hide();
+ }
+
+ var _this = this;
+
+ var files = [];
+
+ var docs = [];
+
+ Roo.each(this.files, function(file){
+
+ if(typeof(file.id) != 'undefined' && file.id * 1 > 0){
+ var f = this.renderPreview(file);
+ files.push(f);
+ return;
+ }
+
+ if(file.type.indexOf('image') != -1){
+ this.delegates.push(
+ (function(){
+ _this.process(file);
+ }).createDelegate(this)
+ );
+
+ return;
+ }
+
+ docs.push(
+ (function(){
+ _this.process(file);
+ }).createDelegate(this)
+ );
+
+ }, this);
+
+ this.files = files;
+
+ this.delegates = this.delegates.concat(docs);
+
+ if(!this.delegates.length){
+ this.refresh();
+ return;
+ }
+
+ this.progressBar.aria_valuemax = this.delegates.length;
+
+ this.arrange();
+
+ return;
+ },
+
+ arrange : function()
+ {
+ if(!this.delegates.length){
+ this.progressDialog.hide();
+ this.refresh();
+ return;
+ }
+
+ var delegate = this.delegates.shift();
+
+ this.progressDialog.show();
+
+ this.progressDialog.setTitle((this.progressBar.aria_valuemax - this.delegates.length) + ' / ' + this.progressBar.aria_valuemax);
+
+ this.progressBar.update(this.progressBar.aria_valuemax - this.delegates.length);
+
+ delegate();
+ },
+
+ refresh : function()
+ {
+ this.uploader.show();
+
+ if(this.boxes > 0 && this.files.length > this.boxes - 1){
+ this.uploader.hide();
+ }
+
+ Roo.isTouch ? this.closable(false) : this.closable(true);
+
+ this.fireEvent('refresh', this);
+ },
+
+ onRemove : function(e, el, o)
+ {
+ e.preventDefault();
+
+ this.fireEvent('remove', this, o);
+
+ },
+
+ remove : function(o)
+ {
+ var files = [];
+
+ Roo.each(this.files, function(file){
+ if(typeof(file.id) == 'undefined' || file.id * 1 < 1 || file.id != o.id){
+ files.push(file);
+ return;
+ }
+
+ o.target.remove();
+
+ }, this);
+
+ this.files = files;
+
+ this.refresh();
+ },
+
+ clear : function()
+ {
+ Roo.each(this.files, function(file){
+ if(!file.target){
+ return;
+ }
+
+ file.target.remove();
+
+ }, this);
+
+ this.files = [];
+
+ this.refresh();
+ },
+
+ onClick : function(e, el, o)
+ {
+ e.preventDefault();
+
+ this.fireEvent('click', this, o);
+
+ },
+
+ closable : function(closable)
+ {
+ Roo.each(this.managerEl.select('.roo-document-manager-preview > button.close', true).elements, function(el){
+
+ el.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ if(closable){
+ el.show();
+ return;
+ }
+
+ el.hide();
+
+ }, this);
+ },
+
+ xhrOnLoad : function(xhr)
+ {
+ Roo.each(this.managerEl.select('.roo-document-manager-loading', true).elements, function(el){
+ el.remove();
+ }, this);
+
+ if (xhr.readyState !== 4) {
+ this.arrange();
+ this.fireEvent('exception', this, xhr);
+ return;
+ }
+
+ var response = Roo.decode(xhr.responseText);
+
+ if(!response.success){
+ this.arrange();
+ this.fireEvent('exception', this, xhr);
+ return;
+ }
+
+ var file = this.renderPreview(response.data);
+
+ this.files.push(file);
+
+ this.arrange();
+
+ },
+
+ xhrOnError : function()
+ {
+ Roo.log('xhr on error');
+
+ var response = Roo.decode(xhr.responseText);
+
+ Roo.log(response);
+
+ this.arrange();
+ },
+
+ process : function(file)
+ {
+ if(this.editable && file.type.indexOf('image') != -1){
+ this.fireEvent('edit', this, file);
+ return;
+ }
+
+ this.uploadStart(file, false);
+
+ return;
+ },
+
+ uploadStart : function(file, crop)
+ {
+ this.xhr = new XMLHttpRequest();
+
+ if(typeof(file.id) != 'undefined' && file.id * 1 > 0){
+ this.arrange();
+ return;
+ }
+
+ file.xhr = this.xhr;
+
+ this.managerEl.createChild({
+ tag : 'div',
+ cls : 'roo-document-manager-loading',
+ cn : [
+ {
+ tag : 'div',
+ tooltip : file.name,
+ cls : 'roo-document-manager-thumb',
+ html : '<i class="fa fa-circle-o-notch fa-spin"></i>'
+ }
+ ]
+
+ });
+
+ this.xhr.open(this.method, this.url, true);
+
+ var headers = {
+ "Accept": "application/json",
+ "Cache-Control": "no-cache",
+ "X-Requested-With": "XMLHttpRequest"
+ };
+
+ for (var headerName in headers) {
+ var headerValue = headers[headerName];
+ if (headerValue) {
+ this.xhr.setRequestHeader(headerName, headerValue);
+ }
+ }
+
+ var _this = this;
+
+ this.xhr.onload = function()
+ {
+ _this.xhrOnLoad(_this.xhr);
+ }
+
+ this.xhr.onerror = function()
+ {
+ _this.xhrOnError(_this.xhr);
+ }
+
+ var formData = new FormData();
+
+ formData.append('returnHTML', 'NO');
+
+ if(crop){
+ formData.append('crop', crop);
+ }
+
+ formData.append(this.paramName, file, file.name);
+
+ if(this.fireEvent('prepare', this, formData) != false){
+ this.xhr.send(formData);
+ };
+ },
+
+ uploadCancel : function()
+ {
+ this.xhr.abort();
+
+ this.delegates = [];
+
+ Roo.each(this.managerEl.select('.roo-document-manager-loading', true).elements, function(el){
+ el.remove();
+ }, this);
+
+ this.arrange();
+ },
+
+ renderPreview : function(file)
+ {
+ if(typeof(file.target) != 'undefined' && file.target){
+ return file;
+ }
+
+ var previewEl = this.managerEl.createChild({
+ tag : 'div',
+ cls : 'roo-document-manager-preview',
+ cn : [
+ {
+ tag : 'div',
+ tooltip : file.filename,
+ cls : 'roo-document-manager-thumb',
+ html : '<img src="' + baseURL +'/Images/Thumb/' + this.thumbSize + '/' + file.id + '/' + file.filename + '">'
+ },
+ {
+ tag : 'button',
+ cls : 'close',
+ html : '<i class="fa fa-times-circle"></i>'
+ }
+ ]
+ });
+
+ var close = previewEl.select('button.close', true).first();
+
+ close.on('click', this.onRemove, this, file);
+
+ file.target = previewEl;
+
+ var image = previewEl.select('img', true).first();
+
+ var _this = this;
+
+ image.dom.addEventListener("load", function(){ _this.onPreviewLoad(file, image); });
+
+ image.on('click', this.onClick, this, file);
+
+ return file;
+
+ },
+
+ onPreviewLoad : function(file, image)
+ {
+ if(typeof(file.target) == 'undefined' || !file.target){
+ return;
+ }
+
+ var width = image.dom.naturalWidth || image.dom.width;
+ var height = image.dom.naturalHeight || image.dom.height;
+
+ if(width > height){
+ file.target.addClass('wide');
+ return;
+ }
+
+ file.target.addClass('tall');
+ return;
+
+ },
+
+ uploadFromSource : function(file, crop)
+ {
+ this.xhr = new XMLHttpRequest();
+
+ this.managerEl.createChild({
+ tag : 'div',
+ cls : 'roo-document-manager-loading',
+ cn : [
+ {
+ tag : 'div',
+ tooltip : file.name,
+ cls : 'roo-document-manager-thumb',
+ html : '<i class="fa fa-circle-o-notch fa-spin"></i>'
+ }
+ ]
+
+ });
+
+ this.xhr.open(this.method, this.url, true);
+
+ var headers = {
+ "Accept": "application/json",
+ "Cache-Control": "no-cache",
+ "X-Requested-With": "XMLHttpRequest"
+ };
+
+ for (var headerName in headers) {
+ var headerValue = headers[headerName];
+ if (headerValue) {
+ this.xhr.setRequestHeader(headerName, headerValue);
+ }
+ }
+
+ var _this = this;
+
+ this.xhr.onload = function()
+ {
+ _this.xhrOnLoad(_this.xhr);
+ }
+
+ this.xhr.onerror = function()
+ {
+ _this.xhrOnError(_this.xhr);
+ }
+
+ var formData = new FormData();
+
+ formData.append('returnHTML', 'NO');
+
+ formData.append('crop', crop);
+
+ if(typeof(file.filename) != 'undefined'){
+ formData.append('filename', file.filename);
+ }
+
+ if(typeof(file.mimetype) != 'undefined'){
+ formData.append('mimetype', file.mimetype);
+ }
+
+ if(this.fireEvent('prepare', this, formData) != false){
+ this.xhr.send(formData);
+ };
+ }
+});
+
+/*
+* Licence: LGPL
+*/
+
+/**
+ * @class Roo.bootstrap.DocumentViewer
+ * @extends Roo.bootstrap.Component
+ * Bootstrap DocumentViewer class
+ *
+ * @constructor
+ * Create a new DocumentViewer
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.DocumentViewer = function(config){
+ Roo.bootstrap.DocumentViewer.superclass.constructor.call(this, config);
+
+ this.addEvents({
+ /**
+ * @event initial
+ * Fire after initEvent
+ * @param {Roo.bootstrap.DocumentViewer} this
+ */
+ "initial" : true,
+ /**
+ * @event click
+ * Fire after click
+ * @param {Roo.bootstrap.DocumentViewer} this
+ */
+ "click" : true,
+ /**
+ * @event trash
+ * Fire after trash button
+ * @param {Roo.bootstrap.DocumentViewer} this
+ */
+ "trash" : true
+
+ });
+};
+
+Roo.extend(Roo.bootstrap.DocumentViewer, Roo.bootstrap.Component, {
+
+ getAutoCreate : function()
+ {
+ var cfg = {
+ tag : 'div',
+ cls : 'roo-document-viewer',
+ cn : [
+ {
+ tag : 'div',
+ cls : 'roo-document-viewer-body',
+ cn : [
+ {
+ tag : 'div',
+ cls : 'roo-document-viewer-thumb',
+ cn : [
+ {
+ tag : 'img',
+ cls : 'roo-document-viewer-image'
+ }
+ ]
+ }
+ ]
+ },
+ {
+ tag : 'div',
+ cls : 'roo-document-viewer-footer',
+ cn : {
+ tag : 'div',
+ cls : 'btn-group btn-group-justified roo-document-viewer-btn-group',
+ cn : [
+ {
+ tag : 'div',
+ cls : 'btn-group',
+ cn : [
+ {
+ tag : 'button',
+ cls : 'btn btn-default roo-document-viewer-trash',
+ html : '<i class="fa fa-trash"></i>'
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ };
+
+ return cfg;
+ },
+
+ initEvents : function()
+ {
+
+ this.bodyEl = this.el.select('.roo-document-viewer-body', true).first();
+ this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ this.thumbEl = this.el.select('.roo-document-viewer-thumb', true).first();
+ this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ this.imageEl = this.el.select('.roo-document-viewer-image', true).first();
+ this.imageEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ this.footerEl = this.el.select('.roo-document-viewer-footer', true).first();
+ this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ this.trashBtn = this.el.select('.roo-document-viewer-trash', true).first();
+ this.trashBtn.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ this.bodyEl.on('click', this.onClick, this);
+
+ this.trashBtn.on('click', this.onTrash, this);
+
+ },
+
+ initial : function()
+ {
+// this.thumbEl.setStyle('line-height', this.thumbEl.getHeight(true) + 'px');
+
+
+ this.fireEvent('initial', this);
+
+ },
+
+ onClick : function(e)
+ {
+ e.preventDefault();
+
+ this.fireEvent('click', this);
+ },
+
+ onTrash : function(e)
+ {
+ e.preventDefault();
+
+ this.fireEvent('trash', this);
+ }
+
+});
+/*
+ * - LGPL
+ *
+ * nav progress bar
+ *
+ */
+
+/**
+ * @class Roo.bootstrap.NavProgressBar
+ * @extends Roo.bootstrap.Component
+ * Bootstrap NavProgressBar class
+ *
+ * @constructor
+ * Create a new nav progress bar
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.NavProgressBar = function(config){
+ Roo.bootstrap.NavProgressBar.superclass.constructor.call(this, config);
+
+ this.bullets = this.bullets || [];
+
+// Roo.bootstrap.NavProgressBar.register(this);
+ this.addEvents({
+ /**
+ * @event changed
+ * Fires when the active item changes
+ * @param {Roo.bootstrap.NavProgressBar} this
+ * @param {Roo.bootstrap.NavProgressItem} selected The item selected
+ * @param {Roo.bootstrap.NavProgressItem} prev The previously selected item
+ */
+ 'changed': true
+ });
+
+};
+
+Roo.extend(Roo.bootstrap.NavProgressBar, Roo.bootstrap.Component, {
+
+ bullets : [],
+ barItems : [],
+
+
+ getAutoCreate : function()
+ {
+ var cfg = Roo.apply({}, Roo.bootstrap.NavProgressBar.superclass.getAutoCreate.call(this));
+
+ cfg = {
+ tag : 'ul',
+ cls: 'roo-navigation-bar'
+ }
+
+ return cfg;
+
+ },
+
+ onRender : function(ct, position)
+ {
+ Roo.bootstrap.NavProgressBar.superclass.onRender.call(this, ct, position);
+
+ if(this.bullets.length){
+ Roo.each(this.bullets, function(b){
+ this.addItem(b);
+ }, this);
+ }
+
+ },
+
+ addItem : function(cfg)
+ {
+ var item = new Roo.bootstrap.NavProgressItem(cfg);
+
+ item.parentId = this.id;
+ item.render(this.el, null);
+
+ this.barItems.push(item);
+
+ this.formatBullets();
+
+ return item;
+ },
+
+ getActive : function()
+ {
+ var active = false;
+
+ Roo.each(this.barItems, function(v){
+
+ if (!v.isActive()) {
+ return;
+ }
+
+ active = v;
+ return false;
+
+ });
+
+ return active;
+ },
+
+ setActiveItem : function(item)
+ {
+ var prev = false;
+
+ Roo.each(this.barItems, function(v){
+ if (v.rid == item.rid) {
+ return ;
+ }
+
+ if (v.isActive()) {
+ v.setActive(false);
+ prev = v;
+ }
+ });
+
+ item.setActive(true);
+
+ this.fireEvent('changed', this, item, prev);
+ },
+
+ getBarItem: function(rid)
+ {
+ var ret = false;
+
+ Roo.each(this.barItems, function(e) {
+ if (e.rid != rid) {
+ return;
+ }
+
+ ret = e;
+ return false;
+ });
+
+ return ret;
+ },
+
+ indexOfItem : function(item)
+ {
+ var index = false;
+
+ Roo.each(this.barItems, function(v, i){
+
+ if (v.rid != item.rid) {
+ return;
+ }
+
+ index = i;
+ return false
+ });
+
+ return index;
+ },
+
+ setActiveNext : function()
+ {
+ var i = this.indexOfItem(this.getActive());
+
+ if (i > this.barItems.length) {
+ return;
+ }
+
+ this.setActiveItem(this.barItems[i+1]);
+ },
+
+ setActivePrev : function()
+ {
+ var i = this.indexOfItem(this.getActive());
+
+ if (i < 1) {
+ return;
+ }
+
+ this.setActiveItem(this.barItems[i-1]);
+ },
+
+ formatBullets : function()
+ {
+ if(!this.barItems.length){
+ return;
+ }
+
+ var width = 100 / this.barItems.length;
+
+ Roo.each(this.barItems, function(i){
+ i.el.setStyle('width', width + '%');
+ }, this);
+ }
+
+});
+/*
+ * - LGPL
+ *
+ * Nav Progress Item
+ *
+ */
+
+/**
+ * @class Roo.bootstrap.NavProgressItem
+ * @extends Roo.bootstrap.Component
+ * Bootstrap NavProgressItem class
+ * @cfg {String} rid the reference id
+ * @cfg {Boolean} active (true|false) Is item active default false
+ * @cfg {Boolean} disabled (true|false) Is item active default false
+ * @cfg {String} html
+ * @cfg {String} position (top|bottom) text position default bottom
+ * @cfg {String} icon show icon instead of number
+ * @cfg {Boolean} forceIcon (true|false) true to force show icon..if set to false, Roo.isTouch showing icon, otherwish number
+ *
+ * @constructor
+ * Create a new NavProgressItem
+ * @param {Object} config The config object
+ */
+Roo.bootstrap.NavProgressItem = function(config){
+ Roo.bootstrap.NavProgressItem.superclass.constructor.call(this, config);
+ this.addEvents({
+ // raw events
+ /**
+ * @event click
+ * The raw click event for the entire grid.
+ * @param {Roo.bootstrap.NavProgressItem} this
+ * @param {Roo.EventObject} e
+ */
+ "click" : true
+ });
+
+};
+
+Roo.extend(Roo.bootstrap.NavProgressItem, Roo.bootstrap.Component, {
+
+ rid : '',
+ active : false,
+ disabled : false,
+ html : '',
+ position : 'bottom',
+ icon : false,
+ forceIcon : false,
+
+ getAutoCreate : function()
+ {
+ var iconCls = 'roo-navigation-bar-item-icon';
+
+ if((this.forceIcon && this.icon) || !this.forceIcon && Roo.isTouch){
+ iconCls += ' ' + this.icon;
+ }
+
+ var cfg = {
+ tag: 'li',
+ cls: 'roo-navigation-bar-item',
+ cn : [
+ {
+ tag : 'i',
+ cls : iconCls
+ },
+ {
+ tag : 'span',
+ cls : 'roo-navigation-bar-item-text ' + this.position,
+ html : this.html
+ }
+ ]
+ }
+
+ if(this.active){
+ cfg.cls += ' active';
+ }
+ if(this.disabled){
+ cfg.cls += ' disabled';
+ }
+
+ return cfg;
+ },
+
+ disable : function()
+ {
+ this.setDisabled(true);
+ },
+
+ enable : function()
+ {
+ this.setDisabled(false);
+ },
+
+ initEvents: function()
+ {
+ this.iconEl = this.el.select('.roo-navigation-bar-item-icon', true).first();
+ this.textEl = this.el.select('.roo-navigation-bar-item-text', true).first();
+
+ if(Roo.isTouch){
+ this.textEl.setVisibilityMode(Roo.Element.DISPLAY).hide();
+ }
+
+ this.iconEl.on('click', this.onClick, this);
+
+ },
+
+ onClick : function(e)
+ {
+ e.preventDefault();
+
+ if(this.disabled){
+ return;
+ }
+
+ if(this.fireEvent('click', this, e) === false){
+ return;
+ };
+
+ this.parent().setActiveItem(this);
+ },
+
+ isActive: function ()
+ {
+ return this.active;
+ },
+
+ setActive : function(state)
+ {
+ if(this.active == state){
+ return;
+ }
+
+ this.active = state;
+
+ if (state) {
+ this.el.addClass('active');
+ return;
+ }
+
+ this.el.removeClass('active');
+
+ return;
+ },
+
+ setDisabled : function(state)
+ {
+ if(this.disabled == state){
+ return;
+ }
+
+ this.disabled = state;
+
+ if (state) {
+ this.el.addClass('disabled');
+ return;
+ }
+
+ this.el.removeClass('disabled');
+ },
+
+ tooltipEl : function()
+ {
+ return this.el.select('.roo-navigation-bar-item-icon', true).first();;
+ }
+});
+
+
\ No newline at end of file