12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094 |
- /**
- * ownCloud
- *
- * @author Bartek Przybylski, Christopher Schäpers, Thomas Tanghus
- * @copyright 2012 Bartek Przybylski bartek@alefzero.eu
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- /* global alert */
- /**
- * this class to ease the usage of jquery dialogs
- * @lends OC.dialogs
- */
- var OCdialogs = {
- // dialog button types
- YES_NO_BUTTONS: 70,
- OK_BUTTONS: 71,
- FILEPICKER_TYPE_CHOOSE: 1,
- FILEPICKER_TYPE_MOVE: 2,
- FILEPICKER_TYPE_COPY: 3,
- FILEPICKER_TYPE_COPY_MOVE: 4,
- // used to name each dialog
- dialogsCounter: 0,
- /**
- * displays alert dialog
- * @param text content of dialog
- * @param title dialog title
- * @param callback which will be triggered when user presses OK
- * @param modal make the dialog modal
- */
- alert:function(text, title, callback, modal) {
- this.message(
- text,
- title,
- 'alert',
- OCdialogs.OK_BUTTON,
- callback,
- modal
- );
- },
- /**
- * displays info dialog
- * @param text content of dialog
- * @param title dialog title
- * @param callback which will be triggered when user presses OK
- * @param modal make the dialog modal
- */
- info:function(text, title, callback, modal) {
- this.message(text, title, 'info', OCdialogs.OK_BUTTON, callback, modal);
- },
- /**
- * displays confirmation dialog
- * @param text content of dialog
- * @param title dialog title
- * @param callback which will be triggered when user presses YES or NO
- * (true or false would be passed to callback respectively)
- * @param modal make the dialog modal
- */
- confirm:function(text, title, callback, modal) {
- return this.message(
- text,
- title,
- 'notice',
- OCdialogs.YES_NO_BUTTONS,
- callback,
- modal
- );
- },
- /**
- * displays confirmation dialog
- * @param text content of dialog
- * @param title dialog title
- * @param callback which will be triggered when user presses YES or NO
- * (true or false would be passed to callback respectively)
- * @param modal make the dialog modal
- */
- confirmHtml:function(text, title, callback, modal) {
- return this.message(
- text,
- title,
- 'notice',
- OCdialogs.YES_NO_BUTTONS,
- callback,
- modal,
- true
- );
- },
- /**
- * displays prompt dialog
- * @param text content of dialog
- * @param title dialog title
- * @param callback which will be triggered when user presses YES or NO
- * (true or false would be passed to callback respectively)
- * @param modal make the dialog modal
- * @param name name of the input field
- * @param password whether the input should be a password input
- */
- prompt: function (text, title, callback, modal, name, password) {
- return $.when(this._getMessageTemplate()).then(function ($tmpl) {
- var dialogName = 'oc-dialog-' + OCdialogs.dialogsCounter + '-content';
- var dialogId = '#' + dialogName;
- var $dlg = $tmpl.octemplate({
- dialog_name: dialogName,
- title : title,
- message : text,
- type : 'notice'
- });
- var input = $('<input/>');
- input.attr('type', password ? 'password' : 'text').attr('id', dialogName + '-input').attr('placeholder', name);
- var label = $('<label/>').attr('for', dialogName + '-input').text(name + ': ');
- $dlg.append(label);
- $dlg.append(input);
- if (modal === undefined) {
- modal = false;
- }
- $('body').append($dlg);
- // wrap callback in _.once():
- // only call callback once and not twice (button handler and close
- // event) but call it for the close event, if ESC or the x is hit
- if (callback !== undefined) {
- callback = _.once(callback);
- }
- var buttonlist = [{
- text : t('core', 'No'),
- click: function () {
- if (callback !== undefined) {
- callback(false, input.val());
- }
- $(dialogId).ocdialog('close');
- }
- }, {
- text : t('core', 'Yes'),
- click : function () {
- if (callback !== undefined) {
- callback(true, input.val());
- }
- $(dialogId).ocdialog('close');
- },
- defaultButton: true
- }
- ];
- $(dialogId).ocdialog({
- closeOnEscape: true,
- modal : modal,
- buttons : buttonlist,
- close : function() {
- // callback is already fired if Yes/No is clicked directly
- if (callback !== undefined) {
- callback(false, input.val());
- }
- }
- });
- input.focus();
- OCdialogs.dialogsCounter++;
- });
- },
- /**
- * show a file picker to pick a file from
- *
- * In order to pick several types of mime types they need to be passed as an
- * array of strings.
- *
- * When no mime type filter is given only files can be selected. In order to
- * be able to select both files and folders "['*', 'httpd/unix-directory']"
- * should be used instead.
- *
- * @param title dialog title
- * @param callback which will be triggered when user presses Choose
- * @param multiselect whether it should be possible to select multiple files
- * @param mimetypeFilter mimetype to filter by - directories will always be included
- * @param modal make the dialog modal
- * @param type Type of file picker : Choose, copy, move, copy and move
- */
- filepicker:function(title, callback, multiselect, mimetypeFilter, modal, type) {
- var self = this;
- this.filepicker.sortField = 'name';
- this.filepicker.sortOrder = 'asc';
- // avoid opening the picker twice
- if (this.filepicker.loading) {
- return;
- }
- if (type === undefined) {
- type = this.FILEPICKER_TYPE_CHOOSE;
- }
- var emptyText = t('core', 'No files in here');
- if (type === this.FILEPICKER_TYPE_COPY || type === this.FILEPICKER_TYPE_MOVE || type === this.FILEPICKER_TYPE_COPY_MOVE) {
- emptyText = t('core', 'No more subfolders in here');
- }
- this.filepicker.loading = true;
- this.filepicker.filesClient = (OCA.Sharing && OCA.Sharing.PublicApp && OCA.Sharing.PublicApp.fileList)? OCA.Sharing.PublicApp.fileList.filesClient: OC.Files.getClient();
- $.when(this._getFilePickerTemplate()).then(function($tmpl) {
- self.filepicker.loading = false;
- var dialogName = 'oc-dialog-filepicker-content';
- if(self.$filePicker) {
- self.$filePicker.ocdialog('close');
- }
- if (mimetypeFilter === undefined || mimetypeFilter === null) {
- mimetypeFilter = [];
- }
- if (typeof(mimetypeFilter) === "string") {
- mimetypeFilter = [mimetypeFilter];
- }
- self.$filePicker = $tmpl.octemplate({
- dialog_name: dialogName,
- title: title,
- emptytext: emptyText
- }).data('path', '').data('multiselect', multiselect).data('mimetype', mimetypeFilter);
- if (modal === undefined) {
- modal = false;
- }
- if (multiselect === undefined) {
- multiselect = false;
- }
- // No grid for IE!
- if (OC.Util.isIE()) {
- self.$filePicker.find('#picker-view-toggle').remove();
- self.$filePicker.find('#picker-filestable').removeClass('view-grid');
- }
- $('body').append(self.$filePicker);
- self.$showGridView = $('input#picker-showgridview');
- self.$showGridView.on('change', _.bind(self._onGridviewChange, self));
- if (!OC.Util.isIE()) {
- self._getGridSettings();
- }
- self.$filePicker.ready(function() {
- self.$fileListHeader = self.$filePicker.find('.filelist thead tr');
- self.$filelist = self.$filePicker.find('.filelist tbody');
- self.$filelistContainer = self.$filePicker.find('.filelist-container');
- self.$dirTree = self.$filePicker.find('.dirtree');
- self.$dirTree.on('click', 'div:not(:last-child)', self, function (event) {
- self._handleTreeListSelect(event, type);
- });
- self.$filelist.on('click', 'tr', function(event) {
- self._handlePickerClick(event, $(this), type);
- });
- self.$fileListHeader.on('click', 'a', function(event) {
- var dir = self.$filePicker.data('path');
- self.filepicker.sortField = $(event.currentTarget).data('sort');
- self.filepicker.sortOrder = self.filepicker.sortOrder === 'asc' ? 'desc' : 'asc';
- self._fillFilePicker(dir);
- });
- self._fillFilePicker('');
- });
- // build buttons
- var functionToCall = function(returnType) {
- if (callback !== undefined) {
- var datapath;
- if (multiselect === true) {
- datapath = [];
- self.$filelist.find('tr.filepicker_element_selected').each(function(index, element) {
- datapath.push(self.$filePicker.data('path') + '/' + $(element).data('entryname'));
- });
- } else {
- datapath = self.$filePicker.data('path');
- var selectedName = self.$filelist.find('tr.filepicker_element_selected').data('entryname');
- if (selectedName) {
- datapath += '/' + selectedName;
- }
- }
- callback(datapath, returnType);
- self.$filePicker.ocdialog('close');
- }
- };
- var chooseCallback = function () {
- functionToCall(OCdialogs.FILEPICKER_TYPE_CHOOSE);
- };
- var copyCallback = function () {
- functionToCall(OCdialogs.FILEPICKER_TYPE_COPY);
- };
- var moveCallback = function () {
- functionToCall(OCdialogs.FILEPICKER_TYPE_MOVE);
- };
- var buttonlist = [];
- if (type === OCdialogs.FILEPICKER_TYPE_CHOOSE) {
- buttonlist.push({
- text: t('core', 'Choose'),
- click: chooseCallback,
- defaultButton: true
- });
- } else {
- if (type === OCdialogs.FILEPICKER_TYPE_COPY || type === OCdialogs.FILEPICKER_TYPE_COPY_MOVE) {
- buttonlist.push({
- text: t('core', 'Copy'),
- click: copyCallback,
- defaultButton: false
- });
- }
- if (type === OCdialogs.FILEPICKER_TYPE_MOVE || type === OCdialogs.FILEPICKER_TYPE_COPY_MOVE) {
- buttonlist.push({
- text: t('core', 'Move'),
- click: moveCallback,
- defaultButton: true
- });
- }
- }
- self.$filePicker.ocdialog({
- closeOnEscape: true,
- // max-width of 600
- width: 600,
- height: 500,
- modal: modal,
- buttons: buttonlist,
- style: {
- buttons: 'aside',
- },
- close: function() {
- try {
- $(this).ocdialog('destroy').remove();
- } catch(e) {}
- self.$filePicker = null;
- }
- });
- // We can access primary class only from oc-dialog.
- // Hence this is one of the approach to get the choose button.
- var getOcDialog = self.$filePicker.closest('.oc-dialog');
- var buttonEnableDisable = getOcDialog.find('.primary');
- if (self.$filePicker.data('mimetype').indexOf("httpd/unix-directory") !== -1) {
- buttonEnableDisable.prop("disabled", false);
- } else {
- buttonEnableDisable.prop("disabled", true);
- }
- })
- .fail(function(status, error) {
- // If the method is called while navigating away
- // from the page, it is probably not needed ;)
- self.filepicker.loading = false;
- if(status !== 0) {
- alert(t('core', 'Error loading file picker template: {error}', {error: error}));
- }
- });
- },
- /**
- * Displays raw dialog
- * You better use a wrapper instead ...
- */
- message:function(content, title, dialogType, buttons, callback, modal, allowHtml) {
- return $.when(this._getMessageTemplate()).then(function($tmpl) {
- var dialogName = 'oc-dialog-' + OCdialogs.dialogsCounter + '-content';
- var dialogId = '#' + dialogName;
- var $dlg = $tmpl.octemplate({
- dialog_name: dialogName,
- title: title,
- message: content,
- type: dialogType
- }, allowHtml ? {escapeFunction: ''} : {});
- if (modal === undefined) {
- modal = false;
- }
- $('body').append($dlg);
- var buttonlist = [];
- switch (buttons) {
- case OCdialogs.YES_NO_BUTTONS:
- buttonlist = [{
- text: t('core', 'No'),
- click: function(){
- if (callback !== undefined) {
- callback(false);
- }
- $(dialogId).ocdialog('close');
- }
- },
- {
- text: t('core', 'Yes'),
- click: function(){
- if (callback !== undefined) {
- callback(true);
- }
- $(dialogId).ocdialog('close');
- },
- defaultButton: true
- }];
- break;
- case OCdialogs.OK_BUTTON:
- var functionToCall = function() {
- $(dialogId).ocdialog('close');
- if(callback !== undefined) {
- callback();
- }
- };
- buttonlist[0] = {
- text: t('core', 'OK'),
- click: functionToCall,
- defaultButton: true
- };
- break;
- }
- $(dialogId).ocdialog({
- closeOnEscape: true,
- modal: modal,
- buttons: buttonlist
- });
- OCdialogs.dialogsCounter++;
- })
- .fail(function(status, error) {
- // If the method is called while navigating away from
- // the page, we still want to deliver the message.
- if(status === 0) {
- alert(title + ': ' + content);
- } else {
- alert(t('core', 'Error loading message template: {error}', {error: error}));
- }
- });
- },
- _fileexistsshown: false,
- /**
- * Displays file exists dialog
- * @param {object} data upload object
- * @param {object} original file with name, size and mtime
- * @param {object} replacement file with name, size and mtime
- * @param {object} controller with onCancel, onSkip, onReplace and onRename methods
- * @return {Promise} jquery promise that resolves after the dialog template was loaded
- */
- fileexists:function(data, original, replacement, controller) {
- var self = this;
- var dialogDeferred = new $.Deferred();
- var getCroppedPreview = function(file) {
- var deferred = new $.Deferred();
- // Only process image files.
- var type = file.type && file.type.split('/').shift();
- if (window.FileReader && type === 'image') {
- var reader = new FileReader();
- reader.onload = function (e) {
- var blob = new Blob([e.target.result]);
- window.URL = window.URL || window.webkitURL;
- var originalUrl = window.URL.createObjectURL(blob);
- var image = new Image();
- image.src = originalUrl;
- image.onload = function () {
- var url = crop(image);
- deferred.resolve(url);
- };
- };
- reader.readAsArrayBuffer(file);
- } else {
- deferred.reject();
- }
- return deferred;
- };
- var crop = function(img) {
- var canvas = document.createElement('canvas'),
- targetSize = 96,
- width = img.width,
- height = img.height,
- x, y, size;
- // Calculate the width and height, constraining the proportions
- if (width > height) {
- y = 0;
- x = (width - height) / 2;
- } else {
- y = (height - width) / 2;
- x = 0;
- }
- size = Math.min(width, height);
- // Set canvas size to the cropped area
- canvas.width = size;
- canvas.height = size;
- var ctx = canvas.getContext("2d");
- ctx.drawImage(img, x, y, size, size, 0, 0, size, size);
- // Resize the canvas to match the destination (right size uses 96px)
- resampleHermite(canvas, size, size, targetSize, targetSize);
- return canvas.toDataURL("image/png", 0.7);
- };
- /**
- * Fast image resize/resample using Hermite filter with JavaScript.
- *
- * @author: ViliusL
- *
- * @param {*} canvas
- * @param {number} W
- * @param {number} H
- * @param {number} W2
- * @param {number} H2
- */
- var resampleHermite = function (canvas, W, H, W2, H2) {
- W2 = Math.round(W2);
- H2 = Math.round(H2);
- var img = canvas.getContext("2d").getImageData(0, 0, W, H);
- var img2 = canvas.getContext("2d").getImageData(0, 0, W2, H2);
- var data = img.data;
- var data2 = img2.data;
- var ratio_w = W / W2;
- var ratio_h = H / H2;
- var ratio_w_half = Math.ceil(ratio_w / 2);
- var ratio_h_half = Math.ceil(ratio_h / 2);
- for (var j = 0; j < H2; j++) {
- for (var i = 0; i < W2; i++) {
- var x2 = (i + j * W2) * 4;
- var weight = 0;
- var weights = 0;
- var weights_alpha = 0;
- var gx_r = 0;
- var gx_g = 0;
- var gx_b = 0;
- var gx_a = 0;
- var center_y = (j + 0.5) * ratio_h;
- for (var yy = Math.floor(j * ratio_h); yy < (j + 1) * ratio_h; yy++) {
- var dy = Math.abs(center_y - (yy + 0.5)) / ratio_h_half;
- var center_x = (i + 0.5) * ratio_w;
- var w0 = dy * dy; //pre-calc part of w
- for (var xx = Math.floor(i * ratio_w); xx < (i + 1) * ratio_w; xx++) {
- var dx = Math.abs(center_x - (xx + 0.5)) / ratio_w_half;
- var w = Math.sqrt(w0 + dx * dx);
- if (w >= -1 && w <= 1) {
- //hermite filter
- weight = 2 * w * w * w - 3 * w * w + 1;
- if (weight > 0) {
- dx = 4 * (xx + yy * W);
- //alpha
- gx_a += weight * data[dx + 3];
- weights_alpha += weight;
- //colors
- if (data[dx + 3] < 255)
- weight = weight * data[dx + 3] / 250;
- gx_r += weight * data[dx];
- gx_g += weight * data[dx + 1];
- gx_b += weight * data[dx + 2];
- weights += weight;
- }
- }
- }
- }
- data2[x2] = gx_r / weights;
- data2[x2 + 1] = gx_g / weights;
- data2[x2 + 2] = gx_b / weights;
- data2[x2 + 3] = gx_a / weights_alpha;
- }
- }
- canvas.getContext("2d").clearRect(0, 0, Math.max(W, W2), Math.max(H, H2));
- canvas.width = W2;
- canvas.height = H2;
- canvas.getContext("2d").putImageData(img2, 0, 0);
- };
- var addConflict = function($conflicts, original, replacement) {
- var $conflict = $conflicts.find('.template').clone().removeClass('template').addClass('conflict');
- var $originalDiv = $conflict.find('.original');
- var $replacementDiv = $conflict.find('.replacement');
- $conflict.data('data',data);
- $conflict.find('.filename').text(original.name);
- $originalDiv.find('.size').text(humanFileSize(original.size));
- $originalDiv.find('.mtime').text(formatDate(original.mtime));
- // ie sucks
- if (replacement.size && replacement.lastModifiedDate) {
- $replacementDiv.find('.size').text(humanFileSize(replacement.size));
- $replacementDiv.find('.mtime').text(formatDate(replacement.lastModifiedDate));
- }
- var path = original.directory + '/' +original.name;
- var urlSpec = {
- file: path,
- x: 96,
- y: 96,
- c: original.etag,
- forceIcon: 0
- };
- var previewpath = Files.generatePreviewUrl(urlSpec);
- // Escaping single quotes
- previewpath = previewpath.replace(/'/g, "%27");
- $originalDiv.find('.icon').css({"background-image": "url('" + previewpath + "')"});
- getCroppedPreview(replacement).then(
- function(path){
- $replacementDiv.find('.icon').css('background-image','url(' + path + ')');
- }, function(){
- path = OC.MimeType.getIconUrl(replacement.type);
- $replacementDiv.find('.icon').css('background-image','url(' + path + ')');
- }
- );
- // connect checkboxes with labels
- var checkboxId = $conflicts.find('.conflict').length;
- $originalDiv.find('input:checkbox').attr('id', 'checkbox_original_'+checkboxId);
- $replacementDiv.find('input:checkbox').attr('id', 'checkbox_replacement_'+checkboxId);
- $conflicts.append($conflict);
- //set more recent mtime bold
- // ie sucks
- if (replacement.lastModifiedDate && replacement.lastModifiedDate.getTime() > original.mtime) {
- $replacementDiv.find('.mtime').css('font-weight', 'bold');
- } else if (replacement.lastModifiedDate && replacement.lastModifiedDate.getTime() < original.mtime) {
- $originalDiv.find('.mtime').css('font-weight', 'bold');
- } else {
- //TODO add to same mtime collection?
- }
- // set bigger size bold
- if (replacement.size && replacement.size > original.size) {
- $replacementDiv.find('.size').css('font-weight', 'bold');
- } else if (replacement.size && replacement.size < original.size) {
- $originalDiv.find('.size').css('font-weight', 'bold');
- } else {
- //TODO add to same size collection?
- }
- //TODO show skip action for files with same size and mtime in bottom row
- // always keep readonly files
- if (original.status === 'readonly') {
- $originalDiv
- .addClass('readonly')
- .find('input[type="checkbox"]')
- .prop('checked', true)
- .prop('disabled', true);
- $originalDiv.find('.message')
- .text(t('core','read-only'));
- }
- };
- //var selection = controller.getSelection(data.originalFiles);
- //if (selection.defaultAction) {
- // controller[selection.defaultAction](data);
- //} else {
- var dialogName = 'oc-dialog-fileexists-content';
- var dialogId = '#' + dialogName;
- if (this._fileexistsshown) {
- // add conflict
- var $conflicts = $(dialogId+ ' .conflicts');
- addConflict($conflicts, original, replacement);
- var count = $(dialogId+ ' .conflict').length;
- var title = n('core',
- '{count} file conflict',
- '{count} file conflicts',
- count,
- {count:count}
- );
- $(dialogId).parent().children('.oc-dialog-title').text(title);
- //recalculate dimensions
- $(window).trigger('resize');
- dialogDeferred.resolve();
- } else {
- //create dialog
- this._fileexistsshown = true;
- $.when(this._getFileExistsTemplate()).then(function($tmpl) {
- var title = t('core','One file conflict');
- var $dlg = $tmpl.octemplate({
- dialog_name: dialogName,
- title: title,
- type: 'fileexists',
- allnewfiles: t('core','New Files'),
- allexistingfiles: t('core','Already existing files'),
- why: t('core','Which files do you want to keep?'),
- what: t('core','If you select both versions, the copied file will have a number added to its name.')
- });
- $('body').append($dlg);
- if (original && replacement) {
- var $conflicts = $dlg.find('.conflicts');
- addConflict($conflicts, original, replacement);
- }
- var buttonlist = [{
- text: t('core', 'Cancel'),
- classes: 'cancel',
- click: function(){
- if ( typeof controller.onCancel !== 'undefined') {
- controller.onCancel(data);
- }
- $(dialogId).ocdialog('close');
- }
- },
- {
- text: t('core', 'Continue'),
- classes: 'continue',
- click: function(){
- if ( typeof controller.onContinue !== 'undefined') {
- controller.onContinue($(dialogId + ' .conflict'));
- }
- $(dialogId).ocdialog('close');
- }
- }];
- $(dialogId).ocdialog({
- width: 500,
- closeOnEscape: true,
- modal: true,
- buttons: buttonlist,
- closeButton: null,
- close: function() {
- self._fileexistsshown = false;
- $(this).ocdialog('destroy').remove();
- }
- });
- $(dialogId).css('height','auto');
- var $primaryButton = $dlg.closest('.oc-dialog').find('button.continue');
- $primaryButton.prop('disabled', true);
- function updatePrimaryButton() {
- var checkedCount = $dlg.find('.conflicts .checkbox:checked').length;
- $primaryButton.prop('disabled', checkedCount === 0);
- }
- //add checkbox toggling actions
- $(dialogId).find('.allnewfiles').on('click', function() {
- var $checkboxes = $(dialogId).find('.conflict .replacement input[type="checkbox"]');
- $checkboxes.prop('checked', $(this).prop('checked'));
- });
- $(dialogId).find('.allexistingfiles').on('click', function() {
- var $checkboxes = $(dialogId).find('.conflict .original:not(.readonly) input[type="checkbox"]');
- $checkboxes.prop('checked', $(this).prop('checked'));
- });
- $(dialogId).find('.conflicts').on('click', '.replacement,.original:not(.readonly)', function() {
- var $checkbox = $(this).find('input[type="checkbox"]');
- $checkbox.prop('checked', !$checkbox.prop('checked'));
- });
- $(dialogId).find('.conflicts').on('click', '.replacement input[type="checkbox"],.original:not(.readonly) input[type="checkbox"]', function() {
- var $checkbox = $(this);
- $checkbox.prop('checked', !$checkbox.prop('checked'));
- });
- //update counters
- $(dialogId).on('click', '.replacement,.allnewfiles', function() {
- var count = $(dialogId).find('.conflict .replacement input[type="checkbox"]:checked').length;
- if (count === $(dialogId+ ' .conflict').length) {
- $(dialogId).find('.allnewfiles').prop('checked', true);
- $(dialogId).find('.allnewfiles + .count').text(t('core','(all selected)'));
- } else if (count > 0) {
- $(dialogId).find('.allnewfiles').prop('checked', false);
- $(dialogId).find('.allnewfiles + .count').text(t('core','({count} selected)',{count:count}));
- } else {
- $(dialogId).find('.allnewfiles').prop('checked', false);
- $(dialogId).find('.allnewfiles + .count').text('');
- }
- updatePrimaryButton();
- });
- $(dialogId).on('click', '.original,.allexistingfiles', function(){
- var count = $(dialogId).find('.conflict .original input[type="checkbox"]:checked').length;
- if (count === $(dialogId+ ' .conflict').length) {
- $(dialogId).find('.allexistingfiles').prop('checked', true);
- $(dialogId).find('.allexistingfiles + .count').text(t('core','(all selected)'));
- } else if (count > 0) {
- $(dialogId).find('.allexistingfiles').prop('checked', false);
- $(dialogId).find('.allexistingfiles + .count')
- .text(t('core','({count} selected)',{count:count}));
- } else {
- $(dialogId).find('.allexistingfiles').prop('checked', false);
- $(dialogId).find('.allexistingfiles + .count').text('');
- }
- updatePrimaryButton();
- });
- dialogDeferred.resolve();
- })
- .fail(function() {
- dialogDeferred.reject();
- alert(t('core', 'Error loading file exists template'));
- });
- }
- //}
- return dialogDeferred.promise();
- },
- // get the gridview setting and set the input accordingly
- _getGridSettings: function() {
- var self = this;
- $.get(OC.generateUrl('/apps/files/api/v1/showgridview'), function(response) {
- self.$showGridView.get(0).checked = response.gridview;
- self.$showGridView.next('#picker-view-toggle')
- .removeClass('icon-toggle-filelist icon-toggle-pictures')
- .addClass(response.gridview ? 'icon-toggle-filelist' : 'icon-toggle-pictures')
- $('.list-container').toggleClass('view-grid', response.gridview);
- });
- },
- _onGridviewChange: function() {
- var show = this.$showGridView.is(':checked');
- // only save state if user is logged in
- if (OC.currentUser) {
- $.post(OC.generateUrl('/apps/files/api/v1/showgridview'), {
- show: show
- });
- }
- this.$showGridView.next('#picker-view-toggle')
- .removeClass('icon-toggle-filelist icon-toggle-pictures')
- .addClass(show ? 'icon-toggle-filelist' : 'icon-toggle-pictures')
- $('.list-container').toggleClass('view-grid', show);
- },
- _getFilePickerTemplate: function() {
- var defer = $.Deferred();
- if(!this.$filePickerTemplate) {
- var self = this;
- $.get(OC.filePath('core', 'templates', 'filepicker.html'), function(tmpl) {
- self.$filePickerTemplate = $(tmpl);
- self.$listTmpl = self.$filePickerTemplate.find('.filelist tbody tr:first-child').detach();
- defer.resolve(self.$filePickerTemplate);
- })
- .fail(function(jqXHR, textStatus, errorThrown) {
- defer.reject(jqXHR.status, errorThrown);
- });
- } else {
- defer.resolve(this.$filePickerTemplate);
- }
- return defer.promise();
- },
- _getMessageTemplate: function() {
- var defer = $.Deferred();
- if(!this.$messageTemplate) {
- var self = this;
- $.get(OC.filePath('core', 'templates', 'message.html'), function(tmpl) {
- self.$messageTemplate = $(tmpl);
- defer.resolve(self.$messageTemplate);
- })
- .fail(function(jqXHR, textStatus, errorThrown) {
- defer.reject(jqXHR.status, errorThrown);
- });
- } else {
- defer.resolve(this.$messageTemplate);
- }
- return defer.promise();
- },
- _getFileExistsTemplate: function () {
- var defer = $.Deferred();
- if (!this.$fileexistsTemplate) {
- var self = this;
- $.get(OC.filePath('files', 'templates', 'fileexists.html'), function (tmpl) {
- self.$fileexistsTemplate = $(tmpl);
- defer.resolve(self.$fileexistsTemplate);
- })
- .fail(function () {
- defer.reject();
- });
- } else {
- defer.resolve(this.$fileexistsTemplate);
- }
- return defer.promise();
- },
- _getFileList: function(dir, mimeType) { //this is only used by the spreedme app atm
- if (typeof(mimeType) === "string") {
- mimeType = [mimeType];
- }
- return $.getJSON(
- OC.filePath('files', 'ajax', 'list.php'),
- {
- dir: dir,
- mimetypes: JSON.stringify(mimeType)
- }
- );
- },
- /**
- * fills the filepicker with files
- */
- _fillFilePicker:function(dir) {
- var self = this;
- this.$filelist.empty();
- this.$filePicker.find('.emptycontent').hide();
- this.$filelistContainer.addClass('icon-loading');
- this.$filePicker.data('path', dir);
- var filter = this.$filePicker.data('mimetype');
- if (typeof(filter) === "string") {
- filter = [filter];
- }
- self.$fileListHeader.find('.sort-indicator').addClass('hidden').removeClass('icon-triangle-n').removeClass('icon-triangle-s');
- self.$fileListHeader.find('[data-sort=' + self.filepicker.sortField + '] .sort-indicator').removeClass('hidden');
- if (self.filepicker.sortOrder === 'asc') {
- self.$fileListHeader.find('[data-sort=' + self.filepicker.sortField + '] .sort-indicator').addClass('icon-triangle-n');
- } else {
- self.$fileListHeader.find('[data-sort=' + self.filepicker.sortField + '] .sort-indicator').addClass('icon-triangle-s');
- }
- self.filepicker.filesClient.getFolderContents(dir).then(function(status, files) {
- if (filter && filter.length > 0 && filter.indexOf('*') === -1) {
- files = files.filter(function (file) {
- return file.type === 'dir' || filter.indexOf(file.mimetype) !== -1;
- });
- }
- var Comparators = {
- name: function(fileInfo1, fileInfo2) {
- if (fileInfo1.type === 'dir' && fileInfo2.type !== 'dir') {
- return -1;
- }
- if (fileInfo1.type !== 'dir' && fileInfo2.type === 'dir') {
- return 1;
- }
- return OC.Util.naturalSortCompare(fileInfo1.name, fileInfo2.name);
- },
- size: function(fileInfo1, fileInfo2) {
- return fileInfo1.size - fileInfo2.size;
- },
- mtime: function(fileInfo1, fileInfo2) {
- return fileInfo1.mtime - fileInfo2.mtime;
- }
- };
- var comparator = Comparators[self.filepicker.sortField] || Comparators.name;
- files = files.sort(function(file1, file2) {
- var isFavorite = function(fileInfo) {
- return fileInfo.tags && fileInfo.tags.indexOf(OC.TAG_FAVORITE) >= 0;
- };
- if (isFavorite(file1) && !isFavorite(file2)) {
- return -1;
- } else if (!isFavorite(file1) && isFavorite(file2)) {
- return 1;
- }
- return self.filepicker.sortOrder === 'asc' ? comparator(file1, file2) : -comparator(file1, file2);
- });
- self._fillSlug();
- if (files.length === 0) {
- self.$filePicker.find('.emptycontent').show();
- self.$fileListHeader.hide();
- } else {
- self.$filePicker.find('.emptycontent').hide();
- self.$fileListHeader.show();
- }
- $.each(files, function(idx, entry) {
- entry.icon = OC.MimeType.getIconUrl(entry.mimetype);
- var simpleSize, sizeColor;
- if (typeof(entry.size) !== 'undefined' && entry.size >= 0) {
- simpleSize = humanFileSize(parseInt(entry.size, 10), true);
- sizeColor = Math.round(160 - Math.pow((entry.size / (1024 * 1024)), 2));
- } else {
- simpleSize = t('files', 'Pending');
- sizeColor = 80;
- }
- var $row = self.$listTmpl.octemplate({
- type: entry.type,
- dir: dir,
- filename: entry.name,
- date: OC.Util.relativeModifiedDate(entry.mtime),
- size: simpleSize,
- sizeColor: sizeColor,
- icon: entry.icon
- });
- if (entry.type === 'file') {
- var urlSpec = {
- file: dir + '/' + entry.name,
- x: 100,
- y: 100
- };
- var img = new Image();
- var previewUrl = OC.generateUrl('/core/preview.png?') + $.param(urlSpec);
- img.onload = function() {
- if (img.width > 5) {
- $row.find('td.filename').attr('style', 'background-image:url(' + previewUrl + ')');
- }
- };
- img.src = previewUrl;
- }
- self.$filelist.append($row);
- });
- self.$filelistContainer.removeClass('icon-loading');
- });
- },
- /**
- * fills the tree list with directories
- */
- _fillSlug: function() {
- this.$dirTree.empty();
- var self = this;
- var dir;
- var path = this.$filePicker.data('path');
- var $template = $('<div data-dir="{dir}"><a>{name}</a></div>').addClass('crumb');
- if(path) {
- var paths = path.split('/');
- $.each(paths, function(index, dir) {
- dir = paths.pop();
- if(dir === '') {
- return false;
- }
- self.$dirTree.prepend($template.octemplate({
- dir: paths.join('/') + '/' + dir,
- name: dir
- }));
- });
- }
- $template.octemplate({
- dir: '',
- name: '' // Ugly but works ;)
- }, {escapeFunction: null}).prependTo(this.$dirTree);
- },
- /**
- * handle selection made in the tree list
- */
- _handleTreeListSelect:function(event, type) {
- var self = event.data;
- var dir = $(event.target).closest('.crumb').data('dir');
- self._fillFilePicker(dir);
- var getOcDialog = (event.target).closest('.oc-dialog');
- var buttonEnableDisable = $('.primary', getOcDialog);
- this._changeButtonsText(type, dir.split(/[/]+/).pop());
- if (this.$filePicker.data('mimetype').indexOf("httpd/unix-directory") !== -1) {
- buttonEnableDisable.prop("disabled", false);
- } else {
- buttonEnableDisable.prop("disabled", true);
- }
- },
- /**
- * handle clicks made in the filepicker
- */
- _handlePickerClick:function(event, $element, type) {
- var getOcDialog = this.$filePicker.closest('.oc-dialog');
- var buttonEnableDisable = getOcDialog.find('.primary');
- if ($element.data('type') === 'file') {
- if (this.$filePicker.data('multiselect') !== true || !event.ctrlKey) {
- this.$filelist.find('.filepicker_element_selected').removeClass('filepicker_element_selected');
- }
- $element.toggleClass('filepicker_element_selected');
- buttonEnableDisable.prop("disabled", false);
- } else if ( $element.data('type') === 'dir' ) {
- this._fillFilePicker(this.$filePicker.data('path') + '/' + $element.data('entryname'));
- this._changeButtonsText(type, $element.data('entryname'));
- if (this.$filePicker.data('mimetype').indexOf("httpd/unix-directory") !== -1) {
- buttonEnableDisable.prop("disabled", false);
- } else {
- buttonEnableDisable.prop("disabled", true);
- }
- }
- },
- /**
- * Handle
- * @param type of action
- * @param dir on which to change buttons text
- * @private
- */
- _changeButtonsText: function(type, dir) {
- var copyText = dir === '' ? t('core', 'Copy') : t('core', 'Copy to {folder}', {folder: dir});
- var moveText = dir === '' ? t('core', 'Move') : t('core', 'Move to {folder}', {folder: dir});
- var buttons = $('.oc-dialog-buttonrow button');
- switch (type) {
- case this.FILEPICKER_TYPE_CHOOSE:
- break;
- case this.FILEPICKER_TYPE_COPY:
- buttons.text(copyText);
- break;
- case this.FILEPICKER_TYPE_MOVE:
- buttons.text(moveText);
- break;
- case this.FILEPICKER_TYPE_COPY_MOVE:
- buttons.eq(0).text(copyText);
- buttons.eq(1).text(moveText);
- break;
- }
- }
- };
|