prevent creating files with a / the name
[owncloud:owncloud.git] / apps / files / js / files.js
1 var uploadingFiles = {};
2 Files={
3         cancelUpload:function(filename) {
4                 if(uploadingFiles[filename]) {
5                         uploadingFiles[filename].abort();
6                         delete uploadingFiles[filename];
7                         return true;
8                 }
9                 return false;
10         },
11         cancelUploads:function() {
12                 $.each(uploadingFiles,function(index,file) {
13                         if(typeof file['abort'] === 'function') {
14                                 file.abort();
15                                 var filename = $('tr').filterAttr('data-file',index);
16                                 filename.hide();
17                                 filename.find('input[type="checkbox"]').removeAttr('checked');
18                                 filename.removeClass('selected');
19                         } else {
20                                 $.each(file,function(i,f) {
21                                         f.abort();
22                                         delete file[i];
23                                 });
24                         }
25                         delete uploadingFiles[index];
26                 });
27                 procesSelection();
28         }
29 }
30 $(document).ready(function() {
31         $('#fileList tr').each(function(){
32                 //little hack to set unescape filenames in attribute
33                 $(this).attr('data-file',decodeURIComponent($(this).attr('data-file')));
34         });
35
36         if($('tr[data-file]').length==0){
37                 $('.file_upload_filename').addClass('highlight');
38         }
39
40         $('#file_action_panel').attr('activeAction', false);
41
42         //drag/drop of files
43         $('#fileList tr[data-write="true"] td.filename').draggable(dragOptions);
44         $('#fileList tr[data-type="dir"][data-write="true"] td.filename').droppable(folderDropOptions);
45         $('div.crumb:not(.last)').droppable(crumbDropOptions);
46         $('ul#apps>li:first-child').data('dir','');
47         if($('div.crumb').length){
48                 $('ul#apps>li:first-child').droppable(crumbDropOptions);
49         }
50
51         // Triggers invisible file input
52         $('.file_upload_button_wrapper').live('click', function() {
53                 $(this).parent().children('.file_upload_start').trigger('click');
54                 return false;
55         });
56
57         // Sets the file-action buttons behaviour :
58         $('tr').live('mouseenter',function(event) {
59                 FileActions.display($(this).children('td.filename'), $(this).attr('data-file'), $(this).attr('data-type'));
60         });
61         $('tr').live('mouseleave',function(event) {
62                 FileActions.hide();
63         });
64
65         var lastChecked;
66
67         // Sets the file link behaviour :
68         $('td.filename a').live('click',function(event) {
69                 event.preventDefault();
70                 if (event.ctrlKey || event.shiftKey) {
71                         if (event.shiftKey) {
72                                 var last = $(lastChecked).parent().parent().prevAll().length;
73                                 var first = $(this).parent().parent().prevAll().length;
74                                 var start = Math.min(first, last);
75                                 var end = Math.max(first, last);
76                                 var rows = $(this).parent().parent().parent().children('tr');
77                                 for (var i = start; i < end; i++) {
78                                         $(rows).each(function(index) {
79                                                 if (index == i) {
80                                                         var checkbox = $(this).children().children('input:checkbox');
81                                                         $(checkbox).attr('checked', 'checked');
82                                                         $(checkbox).parent().parent().addClass('selected');
83                                                 }
84                                         });
85                                 }
86                         }
87                         var checkbox = $(this).parent().children('input:checkbox');
88                         lastChecked = checkbox;
89                         if ($(checkbox).attr('checked')) {
90                                 $(checkbox).removeAttr('checked');
91                                 $(checkbox).parent().parent().removeClass('selected');
92                                 $('#select_all').removeAttr('checked');
93                         } else {
94                                 $(checkbox).attr('checked', 'checked');
95                                 $(checkbox).parent().parent().toggleClass('selected');
96                                 var selectedCount=$('td.filename input:checkbox:checked').length;
97                                 if (selectedCount == $('td.filename input:checkbox').length) {
98                                         $('#select_all').attr('checked', 'checked');
99                                 }
100                         }
101                         procesSelection();
102                 } else {
103                         var filename=$(this).parent().parent().attr('data-file');
104                         var tr=$('tr').filterAttr('data-file',filename);
105                         var renaming=tr.data('renaming');
106                         if(!renaming && !FileList.isLoading(filename)){
107                                 var mime=$(this).parent().parent().data('mime');
108                                 var type=$(this).parent().parent().data('type');
109                                 var action=FileActions.getDefault(mime,type);
110                                 if(action){
111                                         action(filename);
112                                 }
113                         }
114                 }
115
116         });
117
118         // Sets the select_all checkbox behaviour :
119         $('#select_all').click(function() {
120                 if($(this).attr('checked')){
121                         // Check all
122                         $('td.filename input:checkbox').attr('checked', true);
123                         $('td.filename input:checkbox').parent().parent().addClass('selected');
124                 }else{
125                         // Uncheck all
126                         $('td.filename input:checkbox').attr('checked', false);
127                         $('td.filename input:checkbox').parent().parent().removeClass('selected');
128                 }
129                 procesSelection();
130         });
131
132         $('td.filename input:checkbox').live('change',function(event) {
133                 if (event.shiftKey) {
134                         var last = $(lastChecked).parent().parent().prevAll().length;
135                         var first = $(this).parent().parent().prevAll().length;
136                         var start = Math.min(first, last);
137                         var end = Math.max(first, last);
138                         var rows = $(this).parent().parent().parent().children('tr');
139                         for (var i = start; i < end; i++) {
140                                 $(rows).each(function(index) {
141                                         if (index == i) {
142                                                 var checkbox = $(this).children().children('input:checkbox');
143                                                 $(checkbox).attr('checked', 'checked');
144                                                 $(checkbox).parent().parent().addClass('selected');
145                                         }
146                                 });
147                         }
148                 }
149                 var selectedCount=$('td.filename input:checkbox:checked').length;
150                 $(this).parent().parent().toggleClass('selected');
151                 if(!$(this).attr('checked')){
152                         $('#select_all').attr('checked',false);
153                 }else{
154                         if(selectedCount==$('td.filename input:checkbox').length){
155                                 $('#select_all').attr('checked',true);
156                         }
157                 }
158                 procesSelection();
159         });
160
161         $('#file_newfolder_name').click(function(){
162                 if($('#file_newfolder_name').val() == 'New Folder'){
163                         $('#file_newfolder_name').val('');
164                 }
165         });
166
167         $('.download').click('click',function(event) {
168                 var files=getSelectedFiles('name').join(';');
169                 var dir=$('#dir').val()||'/';
170                 $('#notification').text(t('files','generating ZIP-file, it may take some time.'));
171                 $('#notification').fadeIn();
172                 window.location=OC.filePath('files', 'ajax', 'download.php') + '?'+ $.param({ dir: dir, files: files });
173                 return false;
174         });
175
176         $('.delete').click(function(event) {
177                 var files=getSelectedFiles('name');
178                 event.preventDefault();
179                 FileList.do_delete(files);
180                 return false;
181         });
182
183         // drag&drop support using jquery.fileupload
184         // TODO use OC.dialogs
185         $(document).bind('drop dragover', function (e) {
186                         e.preventDefault(); // prevent browser from doing anything, if file isn't dropped in dropZone
187         });
188
189         $(function() {
190                 $('.file_upload_start').fileupload({
191                         dropZone: $('#content'), // restrict dropZone to content div
192                         add: function(e, data) {
193                                 var files = data.files;
194                                 var totalSize=0;
195                                 if(files){
196                                         for(var i=0;i<files.length;i++){
197                                                 if(files[i].size ==0 && files[i].type== '')
198                                                 {
199                                                         OC.dialogs.alert(t('files', 'Unable to upload your file as it is a directory or has 0 bytes'), t('files', 'Upload Error'));
200                                                         return;
201                                                 }
202                                                 totalSize+=files[i].size;
203                                                 if(FileList.deleteFiles && FileList.deleteFiles.indexOf(files[i].name)!=-1){//finish delete if we are uploading a deleted file
204                                                         FileList.finishDelete(function(){
205                                                                 $('.file_upload_start').change();
206                                                         });
207                                                         return;
208                                                 }
209                                         }
210                                 }
211                                 if(totalSize>$('#max_upload').val()){
212                                         $( '#uploadsize-message' ).dialog({
213                                                 modal: true,
214                                                 buttons: {
215                                                         Close: function() {
216                                                                 $( this ).dialog( 'close' );
217                                                         }
218                                                 }
219                                         });
220                                 }else{
221                                         var date=new Date();
222                                         if(files){
223                                                 for(var i=0;i<files.length;i++){
224                                                         if(files[i].size>0){
225                                                                 var size=files[i].size;
226                                                         }else{
227                                                                 var size=t('files','Pending');
228                                                         }
229                                                         if(files && !dirName){
230                                                                 FileList.addFile(getUniqueName(files[i].name),size,date,true);
231                                                         } else if(dirName) {
232                                                                 var uploadtext = $('tr').filterAttr('data-type', 'dir').filterAttr('data-file', dirName).find('.uploadtext')
233                                                                 var currentUploads = parseInt(uploadtext.attr('currentUploads'));
234                                                                 currentUploads += 1;
235                                                                 uploadtext.attr('currentUploads', currentUploads);
236                                                                 if(currentUploads === 1) {
237                                                                         var img = OC.imagePath('core', 'loading.gif');
238                                                                         var tr=$('tr').filterAttr('data-file',dirName);
239                                                                         tr.find('td.filename').attr('style','background-image:url('+img+')');
240                                                                         uploadtext.text('1 file uploading');
241                                                                         uploadtext.show();
242                                                                 } else {
243                                                                         uploadtext.text(currentUploads + ' files uploading')
244                                                                 }
245                                                         }
246                                                 }
247                                         }else{
248                                                 var filename=this.value.split('\\').pop(); //ie prepends C:\fakepath\ in front of the filename
249                                                 FileList.addFile(getUniqueName(filename),'Pending',date,true);
250                                         }
251                                         if($.support.xhrFileUpload) {
252                                                 for(var i=0;i<files.length;i++){
253                                                         var fileName = files[i].name
254                                                         var dropTarget = $(e.originalEvent.target).closest('tr');
255                                                         if(dropTarget && dropTarget.attr('data-type') === 'dir') { // drag&drop upload to folder
256                                                                 var dirName = dropTarget.attr('data-file')
257                                                                 var jqXHR =  $('.file_upload_start').fileupload('send', {files: files[i],
258                                                                                 formData: function(form) {
259                                                                                         var formArray = form.serializeArray();
260                                                                                         formArray[1]['value'] = dirName;
261                                                                                         return formArray;
262                                                                                 }}).success(function(result, textStatus, jqXHR) {
263                                                                                         var response;
264                                                                                         response=jQuery.parseJSON(result);
265                                                                                         if(response[0] == undefined || response[0].status != 'success') {
266                                                                                                 $('#notification').text(t('files', response.data.message));
267                                                                                                 $('#notification').fadeIn();
268                                                                                         }
269                                                                                         var file=response[0];
270                                                                                         delete uploadingFiles[dirName][file.name];
271                                                                                         var currentUploads = parseInt(uploadtext.attr('currentUploads'));
272                                                                                         currentUploads -= 1;
273                                                                                         uploadtext.attr('currentUploads', currentUploads);
274                                                                                         if(currentUploads === 0) {
275                                                                                                 var img = OC.imagePath('core', 'filetypes/folder.png');
276                                                                                                 var tr=$('tr').filterAttr('data-file',dirName);
277                                                                                                 tr.find('td.filename').attr('style','background-image:url('+img+')');
278                                                                                                 uploadtext.text('');
279                                                                                                 uploadtext.hide();
280                                                                                         } else {
281                                                                                                 uploadtext.text(currentUploads + ' files uploading')
282                                                                                         }
283                                                                                 })
284                                                                 .error(function(jqXHR, textStatus, errorThrown) {
285                                                                         if(errorThrown === 'abort') {
286                                                                                 var currentUploads = parseInt(uploadtext.attr('currentUploads'));
287                                                                                 currentUploads -= 1;
288                                                                                 uploadtext.attr('currentUploads', currentUploads);
289                                                                                 if(currentUploads === 0) {
290                                                                                         var img = OC.imagePath('core', 'filetypes/folder.png');
291                                                                                         var tr=$('tr').filterAttr('data-file',dirName);
292                                                                                         tr.find('td.filename').attr('style','background-image:url('+img+')');
293                                                                                         uploadtext.text('');
294                                                                                         uploadtext.hide();
295                                                                                 } else {
296                                                                                         uploadtext.text(currentUploads + ' files uploading')
297                                                                                 }
298                                                                                 $('#notification').hide();
299                                                                                 $('#notification').text(t('files', 'Upload cancelled.'));
300                                                                                 $('#notification').fadeIn();
301                                                                         }
302                                                                 });
303                                                                 //TODO test with filenames containing slashes
304                                                                 if(uploadingFiles[dirName] === undefined) {
305                                                                         uploadingFiles[dirName] = {};
306                                                                 }
307                                                                 uploadingFiles[dirName][fileName] = jqXHR;
308                                                         } else {
309                                                                 var jqXHR =  $('.file_upload_start').fileupload('send', {files: files[i]})
310                                                                                 .success(function(result, textStatus, jqXHR) {
311                                                                                         var response;
312                                                                                         response=jQuery.parseJSON(result);
313                                                                                         if(response[0] != undefined && response[0].status == 'success') {
314                                                                                                 var file=response[0];
315                                                                                                 delete uploadingFiles[file.name];
316                                                                                                 $('tr').filterAttr('data-file',file.name).data('mime',file.mime);
317                                                                                                 var size = $('tr').filterAttr('data-file',file.name).find('td.filesize').text();
318                                                                                                 if(size==t('files','Pending')){
319                                                                                                         $('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size);
320                                                                                                 }
321                                                                                                 FileList.loadingDone(file.name);
322                                                                                         } else {
323                                                                                                 $('#notification').text(t('files', response.data.message));
324                                                                                                 $('#notification').fadeIn();
325                                                                                                 $('#fileList > tr').not('[data-mime]').fadeOut();
326                                                                                                 $('#fileList > tr').not('[data-mime]').remove();
327                                                                                         }
328                                                                                 })
329                                                                 .error(function(jqXHR, textStatus, errorThrown) {
330                                                                         if(errorThrown === 'abort') {
331                                                                                 $('#notification').hide();
332                                                                                 $('#notification').text(t('files', 'Upload cancelled.'));
333                                                                                 $('#notification').fadeIn();
334                                                                         }
335                                                                 });
336                                                                 uploadingFiles[files[i].name] = jqXHR;
337                                                         }
338                                                 }
339                                         }else{
340                                                 data.submit().success(function(data, status) {
341                                                         response = jQuery.parseJSON(data[0].body.innerText);
342                                                         if(response[0] != undefined && response[0].status == 'success') {
343                                                                 var file=response[0];
344                                                                 delete uploadingFiles[file.name];
345                                                                 $('tr').filterAttr('data-file',file.name).data('mime',file.mime);
346                                                                 var size = $('tr').filterAttr('data-file',file.name).find('td.filesize').text();
347                                                                 if(size==t('files','Pending')){
348                                                                         $('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size);
349                                                                 }
350                                                                 FileList.loadingDone(file.name);
351                                                         } else {
352                                                                 $('#notification').text(t('files', response.data.message));
353                                                                 $('#notification').fadeIn();
354                                                                 $('#fileList > tr').not('[data-mime]').fadeOut();
355                                                                 $('#fileList > tr').not('[data-mime]').remove();
356                                                         }
357                                                 });
358                                         }
359                                 }
360                         },
361                         fail: function(e, data) {
362                                 // TODO: cancel upload & display error notification
363                         },
364                         progress: function(e, data) {
365                                 // TODO: show nice progress bar in file row
366                         },
367                         progressall: function(e, data) {
368                                 var progress = (data.loaded/data.total)*100;
369                                 $('#uploadprogressbar').progressbar('value',progress);
370                         },
371                         start: function(e, data) {
372                                 $('#uploadprogressbar').progressbar({value:0});
373                                 $('#uploadprogressbar').fadeIn();
374                                 if(data.dataType != 'iframe ') {
375                                         $('#upload input.stop').show();
376                                 }
377                         },
378                         stop: function(e, data) {
379                                 if(data.dataType != 'iframe ') {
380                                         $('#upload input.stop').hide();
381                                 }       
382                                 $('#uploadprogressbar').progressbar('value',100);
383                                 $('#uploadprogressbar').fadeOut();
384                         }
385                 })
386         });
387
388         //add multiply file upload attribute to all browsers except konqueror (which crashes when it's used)
389         if(navigator.userAgent.search(/konqueror/i)==-1){
390                 $('.file_upload_start').attr('multiple','multiple')
391         }
392
393         //if the breadcrumb is to long, start by replacing foldernames with '...' except for the current folder
394         var crumb=$('div.crumb').first();
395         while($('div.controls').height()>40 && crumb.next('div.crumb').length>0){
396                 crumb.children('a').text('...');
397                 crumb=crumb.next('div.crumb');
398         }
399         //if that isn't enough, start removing items from the breacrumb except for the current folder and it's parent
400         var crumb=$('div.crumb').first();
401         var next=crumb.next('div.crumb');
402         while($('div.controls').height()>40 && next.next('div.crumb').length>0){
403                 crumb.remove();
404                 crumb=next;
405                 next=crumb.next('div.crumb');
406         }
407         //still not enough, start shorting down the current folder name
408         var crumb=$('div.crumb>a').last();
409         while($('div.controls').height()>40 && crumb.text().length>6){
410                 var text=crumb.text()
411                 text=text.substr(0,text.length-6)+'...';
412                 crumb.text(text);
413         }
414
415         $(window).click(function(){
416                 $('#new>ul').hide();
417                 $('#new').removeClass('active');
418                 $('button.file_upload_filename').removeClass('active');
419                 $('#new li').each(function(i,element){
420                         if($(element).children('p').length==0){
421                                 $(element).children('input').remove();
422                                 $(element).append('<p>'+$(element).data('text')+'</p>');
423                         }
424                 });
425         });
426         $('#new').click(function(event){
427                 event.stopPropagation();
428         });
429         $('#new>a').click(function(){
430                 $('#new>ul').toggle();
431                 $('#new').toggleClass('active');
432                 $('button.file_upload_filename').toggleClass('active');
433         });
434         $('#new li').click(function(){
435                 if($(this).children('p').length==0){
436                         return;
437                 }
438
439                 $('#new li').each(function(i,element){
440                         if($(element).children('p').length==0){
441                                 $(element).children('input').remove();
442                                 $(element).append('<p>'+$(element).data('text')+'</p>');
443                         }
444                 });
445
446                 var type=$(this).data('type');
447                 var text=$(this).children('p').text();
448                 $(this).data('text',text);
449                 $(this).children('p').remove();
450                 var input=$('<input>');
451                 $(this).append(input);
452                 input.focus();
453                 input.change(function(){
454                         var name=$(this).val();
455                         if(name.indexOf('/')!=-1){
456                                 $('#notification').text(t('files','Invalid name, \'/\' is not allowed.'));
457                                 $('#notification').fadeIn();
458                                 return;
459                         }
460                         switch(type){
461                                 case 'file':
462                                         $.post(
463                                                 OC.filePath('files','ajax','newfile.php'),
464                                                 {dir:$('#dir').val(),filename:name,content:" \n"},
465                                                 function(data){
466                                                         var date=new Date();
467                                                         FileList.addFile(name,0,date);
468                                                         var tr=$('tr').filterAttr('data-file',name);
469                                                         tr.data('mime','text/plain');
470                                                         getMimeIcon('text/plain',function(path){
471                                                                 tr.find('td.filename').attr('style','background-image:url('+path+')');
472                                                         });
473                                                 }
474                                         );
475                                         break;
476                                 case 'folder':
477                                         $.post(
478                                                 OC.filePath('files','ajax','newfolder.php'),
479                                                 {dir:$('#dir').val(),foldername:name},
480                                                 function(data){
481                                                         var date=new Date();
482                                                         FileList.addDir(name,0,date);
483                                                 }
484                                         );
485                                         break;
486                                 case 'web':
487                                         if(name.substr(0,8)!='https://' && name.substr(0,7)!='http://'){
488                                                 name='http://'.name;
489                                         }
490                                         var localName=name;
491                                         if(localName.substr(localName.length-1,1)=='/'){//strip /
492                                                 localName=localName.substr(0,localName.length-1)
493                                         }
494                                         if(localName.indexOf('/')){//use last part of url
495                                                 localName=localName.split('/').pop();
496                                         }else{//or the domain
497                                                 localName=(localName.match(/:\/\/(.[^/]+)/)[1]).replace('www.','');
498                                         }
499                                         $.post(
500                                                 OC.filePath('files','ajax','newfile.php'),
501                                                 {dir:$('#dir').val(),source:name,filename:localName},
502                                                 function(result){
503                                                         if(result.status == 'success'){
504                                                                 var date=new Date();
505                                                                 FileList.addFile(localName,0,date);
506                                                                 var tr=$('tr').filterAttr('data-file',localName);
507                                                                 tr.data('mime',result.data.mime);
508                                                                 getMimeIcon(result.data.mime,function(path){
509                                                                         tr.find('td.filename').attr('style','background-image:url('+path+')');
510                                                                 });
511                                                         }else{
512
513                                                         }
514                                                 }
515                                         );
516                                         break;
517                         }
518                         var li=$(this).parent();
519                         $(this).remove();
520                         li.append('<p>'+li.data('text')+'</p>');
521                         $('#new>a').click();
522                 });
523         });
524
525         //check if we need to scan the filesystem
526         $.get(OC.filePath('files','ajax','scan.php'),{checkonly:'true'}, function(response) {
527                 if(response.data.done){
528                         scanFiles();
529                 }
530         }, "json");
531 });
532
533 function scanFiles(force,dir){
534         if(!dir){
535                 dir='';
536         }
537         force=!!force; //cast to bool
538         scanFiles.scanning=true;
539         $('#scanning-message').show();
540         $('#fileList').remove();
541         var scannerEventSource=new OC.EventSource(OC.filePath('files','ajax','scan.php'),{force:force,dir:dir});
542         scanFiles.cancel=scannerEventSource.close.bind(scannerEventSource);
543         scannerEventSource.listen('scanning',function(data){
544                 $('#scan-count').text(data.count+' files scanned');
545                 $('#scan-current').text(data.file+'/');
546         });
547         scannerEventSource.listen('success',function(success){
548                 scanFiles.scanning=false;
549                 if(success){
550                         window.location.reload();
551                 }else{
552                         alert('error while scanning');
553                 }
554         });
555 }
556 scanFiles.scanning=false;
557
558 function boolOperationFinished(data, callback) {
559         result = jQuery.parseJSON(data.responseText);
560         if(result.status == 'success'){
561                 callback.call();
562         } else {
563                 alert(result.data.message);
564         }
565 }
566
567 function updateBreadcrumb(breadcrumbHtml) {
568         $('p.nav').empty().html(breadcrumbHtml);
569 }
570
571 //options for file drag/dropp
572 var dragOptions={
573         distance: 20, revert: 'invalid', opacity: 0.7,
574         stop: function(event, ui) {
575                 $('#fileList tr td.filename').addClass('ui-draggable');
576         }
577 };
578 var folderDropOptions={
579         drop: function( event, ui ) {
580                 var file=ui.draggable.parent().data('file');
581                 var target=$(this).find('.nametext').text().trim();
582                 var dir=$('#dir').val();
583                 $.ajax({
584                         url: OC.filePath('files', 'ajax', 'move.php'),
585                         data: "dir="+encodeURIComponent(dir)+"&file="+encodeURIComponent(file)+'&target='+encodeURIComponent(dir)+'/'+encodeURIComponent(target),
586                         complete: function(data){boolOperationFinished(data, function(){
587                                 var el = $('#fileList tr').filterAttr('data-file',file).find('td.filename');
588                                 el.draggable('destroy');
589                                 FileList.remove(file);
590                         });}
591                 });
592         }
593 }
594 var crumbDropOptions={
595         drop: function( event, ui ) {
596                 var file=ui.draggable.text().trim();
597                 var target=$(this).data('dir');
598                 var dir=$('#dir').val();
599                 while(dir.substr(0,1)=='/'){//remove extra leading /'s
600                                 dir=dir.substr(1);
601                 }
602                 dir='/'+dir;
603                 if(dir.substr(-1,1)!='/'){
604                         dir=dir+'/';
605                 }
606                 if(target==dir || target+'/'==dir){
607                         return;
608                 }
609                 $.ajax({
610                         url: OC.filePath('files', 'ajax', 'move.php'),
611                  data: "dir="+encodeURIComponent(dir)+"&file="+encodeURIComponent(file)+'&target='+encodeURIComponent(target),
612                  complete: function(data){boolOperationFinished(data, function(){
613                          FileList.remove(file);
614                  });}
615                 });
616         },
617         tolerance: 'pointer'
618 }
619
620 function procesSelection(){
621         var selected=getSelectedFiles();
622         var selectedFiles=selected.filter(function(el){return el.type=='file'});
623         var selectedFolders=selected.filter(function(el){return el.type=='dir'});
624         if(selectedFiles.length==0 && selectedFolders.length==0){
625                 $('#headerName>span.name').text(t('files','Name'));
626                 $('#headerSize').text(t('files','Size'));
627                 $('#modified').text(t('files','Modified'));
628                 $('th').removeClass('multiselect');
629                 $('.selectedActions').hide();
630                 $('thead').removeClass('fixed');
631                 $('#headerName').css('width','auto');
632                 $('#headerSize').css('width','auto');
633                 $('#headerDate').css('width','auto');
634                 $('table').css('padding-top','0');
635         }else{
636                 var width={name:$('#headerName').css('width'),size:$('#headerSize').css('width'),date:$('#headerDate').css('width')};
637                 $('#headerName').css('width',width.name);
638                 $('#headerSize').css('width',width.size);
639                 $('#headerDate').css('width',width.date);
640                 $('.selectedActions').show();
641                 var totalSize=0;
642                 for(var i=0;i<selectedFiles.length;i++){
643                         totalSize+=selectedFiles[i].size;
644                 };
645                 for(var i=0;i<selectedFolders.length;i++){
646                         totalSize+=selectedFolders[i].size;
647                 };
648                 simpleSize=simpleFileSize(totalSize);
649                 $('#headerSize').text(simpleSize);
650                 $('#headerSize').attr('title',humanFileSize(totalSize));
651                 var selection='';
652                 if(selectedFolders.length>0){
653                         if(selectedFolders.length==1){
654                                 selection+='1 '+t('files','folder');
655                         }else{
656                                 selection+=selectedFolders.length+' '+t('files','folders');
657                         }
658                         if(selectedFiles.length>0){
659                                 selection+=' & ';
660                         }
661                 }
662                 if(selectedFiles.length>0){
663                         if(selectedFiles.length==1){
664                                 selection+='1 '+t('files','file');
665                         }else{
666                                 selection+=selectedFiles.length+' '+t('files','files');
667                         }
668                 }
669                 $('#headerName>span.name').text(selection);
670                 $('#modified').text('');
671                 $('th').addClass('multiselect');
672         }
673 }
674
675 /**
676  * @brief get a list of selected files
677  * @param string property (option) the property of the file requested
678  * @return array
679  *
680  * possible values for property: name, mime, size and type
681  * if property is set, an array with that property for each file is returnd
682  * if it's ommited an array of objects with all properties is returned
683  */
684 function getSelectedFiles(property){
685         var elements=$('td.filename input:checkbox:checked').parent().parent();
686         var files=[];
687         elements.each(function(i,element){
688                 var file={
689                         name:$(element).attr('data-file'),
690                         mime:$(element).data('mime'),
691                         type:$(element).data('type'),
692                         size:$(element).data('size'),
693                 };
694                 if(property){
695                         files.push(file[property]);
696                 }else{
697                         files.push(file);
698                 }
699         });
700         return files;
701 }
702
703 function relative_modified_date(timestamp) {
704         var timediff = Math.round((new Date()).getTime() / 1000) - timestamp;
705         var diffminutes = Math.round(timediff/60);
706         var diffhours = Math.round(diffminutes/60);
707         var diffdays = Math.round(diffhours/24);
708         var diffmonths = Math.round(diffdays/31);
709         var diffyears = Math.round(diffdays/365);
710         if(timediff < 60) { return t('files','seconds ago'); }
711         else if(timediff < 120) { return '1 '+t('files','minute ago'); }
712         else if(timediff < 3600) { return diffminutes+' '+t('files','minutes ago'); }
713         //else if($timediff < 7200) { return '1 hour ago'; }
714         //else if($timediff < 86400) { return $diffhours.' hours ago'; }
715         else if(timediff < 86400) { return t('files','today'); }
716         else if(timediff < 172800) { return t('files','yesterday'); }
717         else if(timediff < 2678400) { return diffdays+' '+t('files','days ago'); }
718         else if(timediff < 5184000) { return t('files','last month'); }
719         //else if($timediff < 31556926) { return $diffmonths.' months ago'; }
720         else if(timediff < 31556926) { return t('files','months ago'); }
721         else if(timediff < 63113852) { return t('files','last year'); }
722         else { return diffyears+' '+t('files','years ago'); }
723 }
724
725 function getMimeIcon(mime, ready){
726         if(getMimeIcon.cache[mime]){
727                 ready(getMimeIcon.cache[mime]);
728         }else{
729                 $.get( OC.filePath('files','ajax','mimeicon.php')+'?mime='+mime, function(path){
730                         getMimeIcon.cache[mime]=path;
731                         ready(getMimeIcon.cache[mime]);
732                 });
733         }
734 }
735 getMimeIcon.cache={};
736
737 function getUniqueName(name){
738         if($('tr').filterAttr('data-file',name).length>0){
739                 var parts=name.split('.');
740                 var extension=parts.pop();
741                 var base=parts.join('.');
742                 numMatch=base.match(/\((\d+)\)/);
743                 var num=2;
744                 if(numMatch && numMatch.length>0){
745                         num=parseInt(numMatch[numMatch.length-1])+1;
746                         base=base.split('(')
747                         base.pop();
748                         base=base.join('(').trim();
749                 }
750                 name=base+' ('+num+').'+extension;
751                 return getUniqueName(name);
752         }
753         return name;
754 }