diff --git a/apps/files_trashbin/ajax/undelete.php b/apps/files_trashbin/ajax/undelete.php index f55629d695..05b5e7a5ee 100644 --- a/apps/files_trashbin/ajax/undelete.php +++ b/apps/files_trashbin/ajax/undelete.php @@ -4,11 +4,34 @@ if(!OC_User::isLoggedIn()) { exit; } -$timestamp = isset( $_REQUEST['timestamp'] ) ? $_REQUEST['timestamp'] : ''; -$filename = isset( $_REQUEST['filename'] ) ? trim($_REQUEST['filename'], '/\\') : ''; +$files = $_REQUEST['files']; +$list = explode(';', $files); + +$error = array(); + +$i = 0; +foreach ($list as $file) { + $delimiter = strrpos($file, '.d'); + $filename = substr($file, 0, $delimiter); + $timestamp = substr($file, $delimiter+2); + + if ( !OCA_Trash\Trashbin::restore($filename, $timestamp) ) { + $error[] = $filename; + } else { + $success[$i]['filename'] = $filename; + $success[$i]['timestamp'] = $timestamp; + $i++; + } -if ( OCA_Trash\Trashbin::restore($filename, $timestamp) ) { - OCP\JSON::success(array("data" => array('filename'=>$filename, 'timestamp' => $timestamp))); -} else { - OCP\JSON::error(array("data" => array("message" => "Couldn't restore ".$filename))); } + +if ( $error ) { + $filelist = ''; + foreach ( $error as $e ) { + $filelist .= $e.', '; + } + OCP\JSON::error(array("data" => array("message" => "Couldn't restore ".rtrim($filelist,', '), "success" => $success, "error" => $error))); +} else { + OCP\JSON::success(array("data" => array("success" => $success))); +} + diff --git a/apps/files_trashbin/css/trash.css b/apps/files_trashbin/css/trash.css index bd6341c6fb..e0dd8c6e93 100644 --- a/apps/files_trashbin/css/trash.css +++ b/apps/files_trashbin/css/trash.css @@ -19,12 +19,12 @@ body { color:#fff; } -#header #download { +#header #undelete { font-weight:700; margin-left:2em; } -#header #download img { +#header #undelete img { padding-left:.1em; padding-right:.3em; vertical-align:text-bottom; diff --git a/apps/files_trashbin/js/trash.js b/apps/files_trashbin/js/trash.js index 075dc6c315..8f3786f15e 100644 --- a/apps/files_trashbin/js/trash.js +++ b/apps/files_trashbin/js/trash.js @@ -1,20 +1,145 @@ + $(document).ready(function() { if (typeof FileActions !== 'undefined') { FileActions.register('all', 'Undelete', OC.PERMISSION_READ, '', function(filename) { var tr=$('tr').filterAttr('data-file', filename); $.post(OC.filePath('files_trashbin','ajax','undelete.php'), - {timestamp:tr.attr('data-timestamp'),filename:tr.attr('data-filename')}, + {files:tr.attr('data-filename')+'.d'+tr.attr('data-timestamp')}, function(result){ - if (result.status == 'success') { - var row = document.getElementById(result.data.filename+'.d'+result.data.timestamp); + for (var i = 0; i < result.data.success.length; i++) { + var row = document.getElementById(result.data.success[i].filename+'.d'+result.data.success[i].timestamp); row.parentNode.removeChild(row); - } else { + } + if (result.status != 'success') { OC.dialogs.alert(result.data.message, 'Error'); } }); }); }; + + // Sets the select_all checkbox behaviour : + $('#select_all').click(function() { + if($(this).attr('checked')){ + // Check all + $('td.filename input:checkbox').attr('checked', true); + $('td.filename input:checkbox').parent().parent().addClass('selected'); + }else{ + // Uncheck all + $('td.filename input:checkbox').attr('checked', false); + $('td.filename input:checkbox').parent().parent().removeClass('selected'); + } + procesSelection(); + }); -}); \ No newline at end of file + $('td.filename input:checkbox').live('change',function(event) { + if (event.shiftKey) { + var last = $(lastChecked).parent().parent().prevAll().length; + var first = $(this).parent().parent().prevAll().length; + var start = Math.min(first, last); + var end = Math.max(first, last); + var rows = $(this).parent().parent().parent().children('tr'); + for (var i = start; i < end; i++) { + $(rows).each(function(index) { + if (index == i) { + var checkbox = $(this).children().children('input:checkbox'); + $(checkbox).attr('checked', 'checked'); + $(checkbox).parent().parent().addClass('selected'); + } + }); + } + } + var selectedCount=$('td.filename input:checkbox:checked').length; + $(this).parent().parent().toggleClass('selected'); + if(!$(this).attr('checked')){ + $('#select_all').attr('checked',false); + }else{ + if(selectedCount==$('td.filename input:checkbox').length){ + $('#select_all').attr('checked',true); + } + } + procesSelection(); + }); + + $('.undelete').click('click',function(event) { + var fileslist=getSelectedFiles('file').join(';'); + $.post(OC.filePath('files_trashbin','ajax','undelete.php'), + {files:fileslist}, + function(result){ + for (var i = 0; i < result.data.success.length; i++) { + var row = document.getElementById(result.data.success[i].filename+'.d'+result.data.success[i].timestamp); + row.parentNode.removeChild(row); + } + if (result.status != 'success') { + OC.dialogs.alert(result.data.message, 'Error'); + } + }); + }); + + +}); + +function procesSelection(){ + var selected=getSelectedFiles(); + var selectedFiles=selected.filter(function(el){return el.type=='file'}); + var selectedFolders=selected.filter(function(el){return el.type=='dir'}); + if(selectedFiles.length==0 && selectedFolders.length==0) { + $('#headerName>span.name').text(t('files','Name')); + $('#modified').text(t('files','Deleted')); + $('table').removeClass('multiselect'); + $('.selectedActions').hide(); + } + else { + $('.selectedActions').show(); + var selection=''; + if(selectedFolders.length>0){ + if(selectedFolders.length==1){ + selection+=t('files','1 folder'); + }else{ + selection+=t('files','{count} folders',{count: selectedFolders.length}); + } + if(selectedFiles.length>0){ + selection+=' & '; + } + } + if(selectedFiles.length>0){ + if(selectedFiles.length==1){ + selection+=t('files','1 file'); + }else{ + selection+=t('files','{count} files',{count: selectedFiles.length}); + } + } + $('#headerName>span.name').text(selection); + $('#modified').text(''); + $('table').addClass('multiselect'); + } +} + +/** + * @brief get a list of selected files + * @param string property (option) the property of the file requested + * @return array + * + * possible values for property: name, mime, size and type + * if property is set, an array with that property for each file is returnd + * if it's ommited an array of objects with all properties is returned + */ +function getSelectedFiles(property){ + var elements=$('td.filename input:checkbox:checked').parent().parent(); + var files=[]; + elements.each(function(i,element){ + var file={ + name:$(element).attr('data-filename'), + file:$(element).attr('data-file'), + timestamp:$(element).attr('data-timestamp'), + type:$(element).attr('data-type') + }; + if(property){ + files.push(file[property]); + }else{ + files.push(file); + } + }); + return files; +} \ No newline at end of file diff --git a/apps/files_trashbin/lib/trash.php b/apps/files_trashbin/lib/trash.php index 1b0b9cef4b..abfcf847ac 100644 --- a/apps/files_trashbin/lib/trash.php +++ b/apps/files_trashbin/lib/trash.php @@ -77,7 +77,7 @@ class Trashbin { * @param $timestamp time when the file was deleted */ public static function restore($filename, $timestamp) { - + $user = \OCP\User::getUser(); $view = new \OC_FilesystemView('/'.$user); diff --git a/apps/files_trashbin/templates/index.php b/apps/files_trashbin/templates/index.php index a412379d53..a9cb216b1f 100644 --- a/apps/files_trashbin/templates/index.php +++ b/apps/files_trashbin/templates/index.php @@ -16,13 +16,12 @@ t( 'Name' ); ?> - - - Download + + t('Undelete')?> -