Added support for virtual collections, multi-folder search,

skip/overwrite questions on file move/copy, other improvements
This commit is contained in:
Aleksander Machniak 2013-05-16 13:08:58 +02:00
parent 06e7b093ba
commit 716a464a6d
9 changed files with 496 additions and 143 deletions

View file

@ -1,7 +1,7 @@
<?php
// URL of kolab-chwala installation
$rcmail_config['kolab_files_url'] = 'https://' . $_SERVER["HTTP_HOST"] . '/chwala';
$rcmail_config['kolab_files_url'] = 'https://localhost/kolab-chwala/public_html';
// List of files list columns. Available are: name, size, mtime, type
$rcmail_config['kolab_files_list_cols'] = array('name', 'mtime', 'size');
@ -12,4 +12,7 @@ $rcmail_config['kolab_files_sort_col'] = 'name';
// Order of the files list sort
$rcmail_config['kolab_files_sort_order'] = 'asc';
// Number of concurent requests for searching and collections listing. Default: 1
$rcmail_config['kolab_files_search_threads'] = 1;
?>

View file

@ -64,12 +64,10 @@ window.rcmail && rcmail.addEventListener('init', function() {
rcmail.file_list.addEventListener('dblclick', function(o){ p.msglist_dbl_click(o); });
rcmail.file_list.addEventListener('click', function(o){ p.msglist_click(o); });
rcmail.file_list.addEventListener('keypress', function(o){ p.msglist_keypress(o); });
*/
rcmail.file_list.addEventListener('select', function(o){ kolab_files_list_select(o); });
/*
rcmail.file_list.addEventListener('dragstart', function(o){ p.drag_start(o); });
rcmail.file_list.addEventListener('dragmove', function(e){ p.drag_move(e); });
*/
rcmail.file_list.addEventListener('select', function(o){ kolab_files_list_select(o); });
rcmail.file_list.addEventListener('dragend', function(e){ kolab_files_drag_end(e); });
rcmail.file_list.addEventListener('column_replace', function(e){ kolab_files_set_coltypes(e); });
rcmail.file_list.addEventListener('listupdate', function(e){ rcmail.triggerEvent('listupdate', e); });
@ -110,8 +108,9 @@ function kolab_files_init()
file_api.set_env({
token: kolab_files_token(),
url: rcmail.env.files_url,
sort_column: 'name',
sort_reverse: 0
sort_col: 'name',
sort_reverse: false,
search_threads: rcmail.env.search_threads
});
file_api.translations = rcmail.labels;
@ -201,10 +200,10 @@ function kolab_files_selector_dialog()
if (list.length) {
// display upload indicator and cancel button
var content = '<span>' + rcmail.get_label('uploading' + (list.length > 1 ? 'many' : '')) + '</span>',
var content = '<span>' + rcmail.get_label('kolab_files.attaching') + '</span>',
id = new Date().getTime();
rcmail.add2attachment_list(id, { name:'', html:content, classname:'uploading', complete:false });
rcmail.add2attachment_list(id, {name:'', html:content, classname:'uploading', complete:false});
// send request
rcmail.http_post('plugin.kolab_files', {
@ -396,7 +395,7 @@ kolab_files_set_list_options = function(cols, sort_col, sort_order)
}
if (update == 1)
file_api.file_list({sort: sort_col, reverse: sort_order == 'DESC'});
rcmail.command('files-list', {sort: sort_col, reverse: sort_order == 'DESC'});
else if (update) {
rcmail.http_post('files/prefs', {
kolab_files_list_cols: oldcols,
@ -514,7 +513,7 @@ rcube_webmail.prototype.files_sort = function(props)
params.sort = sort_col;
params.reverse = sort_order == 'DESC';
file_api.file_list(params);
this.command('files-list', params);
};
rcube_webmail.prototype.files_search = function()
@ -522,7 +521,7 @@ rcube_webmail.prototype.files_search = function()
var value = $(this.gui_objects.filesearchbox).val();
if (value)
file_api.file_search(value);
file_api.file_search(value, $('#search_all_folders').is(':checked'));
else
file_api.file_search_reset();
};
@ -567,6 +566,12 @@ rcube_webmail.prototype.files_upload = function(form)
file_api.file_upload(form);
};
rcube_webmail.prototype.files_list = function(param)
{
// just rcmail wrapper, to handle command busy states
file_api.file_list(param);
}
rcube_webmail.prototype.files_list_update = function(head)
{
var list = this.file_list;
@ -625,10 +630,11 @@ function kolab_files_ui()
rcmail.http_error(request, status, err);
};
// folders list request
this.folder_list = function()
{
this.req = this.set_busy(true, 'loading');
this.get('folder_list', {}, 'folder_list_response');
this.request('folder_list', {}, 'folder_list_response');
};
// folder list response handler
@ -638,7 +644,8 @@ function kolab_files_ui()
return;
var first, elem = $('#files-folder-list'),
list = $('<ul class="listing"></ul>');
list = $('<ul class="listing"></ul>'),
collections = !rcmail.env.action.match(/^(preview|show)$/) ? ['audio', 'video', 'image', 'document'] : [];
elem.html('').append(list);
@ -672,33 +679,71 @@ function kolab_files_ui()
first = i;
});
// add virtual collections
$.each(collections, function(i, n) {
var row = $('<li class="mailbox collection ' + n + '"></li>');
row.attr('id', 'folder-collection-' + n)
.append($('<span class="name">').text(rcmail.gettext('kolab_files.collection_' + n)))
.click(function() { file_api.folder_select(n, true); });
list.append(row);
});
// select first folder?
if (this.env.folder || first)
this.folder_select(this.env.folder ? this.env.folder : first);
if (this.env.folder)
this.folder_select(this.env.folder);
else if (this.env.collection)
this.folder_select(this.env.collection, true);
else if (first)
this.folder_select(first);
// add tree icons
this.folder_list_tree(this.env.folders);
};
this.folder_select = function(i)
this.folder_select = function(folder, is_collection)
{
var list = $('#files-folder-list > ul');
if (rcmail.busy)
return;
$('li.selected', list).removeClass('selected');
rcmail.enable_command('files-list', true);
if (is_collection) {
var found = $('#folder-collection-' + folder, list).addClass('selected');
rcmail.enable_command('files-folder-delete', 'files-upload', false);
this.env.folder = null;
rcmail.command('files-list', {collection: folder});
}
else {
var found = $('#' + this.env.folders[folder].id, list).addClass('selected');
rcmail.enable_command('files-folder-delete', 'files-upload', true);
this.env.folder = folder;
this.env.collection = null;
rcmail.command('files-list', {folder: folder});
}
};
this.folder_unselect = function()
{
var list = $('#files-folder-list > ul');
$('li.selected', list).removeClass('selected');
$('#' + this.env.folders[i].id, list).addClass('selected');
this.env.folder = i;
rcmail.enable_command('files-folder-delete', 'files-upload', true);
// list files in selected folder
this.file_list();
rcmail.enable_command('files-folder-delete', 'files-upload', false);
this.env.folder = null;
this.env.collection = null;
};
// folder create request
this.folder_create = function(folder)
{
this.req = this.set_busy(true, 'kolab_files.foldercreating');
this.get('folder_create', {folder: folder}, 'folder_create_response');
this.request('folder_create', {folder: folder}, 'folder_create_response');
};
// folder create response handler
@ -717,7 +762,7 @@ function kolab_files_ui()
this.folder_delete = function(folder)
{
this.req = this.set_busy(true, 'kolab_files.folderdeleting');
this.get('folder_delete', {folder: folder}, 'folder_delete_response');
this.request('folder_delete', {folder: folder}, 'folder_delete_response');
};
// folder delete response handler
@ -727,7 +772,7 @@ function kolab_files_ui()
return;
this.env.folder = null;
rcmail.enable_command('files-folder-delete', 'files-folder-rename', false);
rcmail.enable_command('files-folder-delete', 'files-folder-rename', 'files-list', false);
this.display_message('kolab_files.folderdeletenotice', 'confirmation');
// refresh folders list
@ -736,14 +781,22 @@ function kolab_files_ui()
this.file_list = function(params)
{
if (!this.env.folder || !rcmail.gui_objects.filelist)
if (!rcmail.gui_objects.filelist)
return;
if (!params)
params = {};
params.folder = this.env.folder;
if (params.all_folders) {
params.collection = null;
params.folder = null;
this.folder_unselect();
}
if (params.collection == undefined)
params.collection = this.env.collection;
if (params.folder == undefined)
params.folder = this.env.folder;
if (params.sort == undefined)
params.sort = this.env.sort_col;
if (params.reverse == undefined)
@ -751,16 +804,25 @@ function kolab_files_ui()
if (params.search == undefined)
params.search = this.env.search;
this.env.folder = params.folder;
this.env.collection = params.collection;
this.env.sort_col = params.sort;
this.env.sort_reverse = params.reverse;
this.req = this.set_busy(true, 'loading');
rcmail.enable_command(rcmail.env.file_commands, false);
rcmail.enable_command(rcmail.env.file_commands_all, false);
// empty the list
this.env.file_list = [];
rcmail.file_list.clear();
this.get('file_list', params, 'file_list_response');
// request
if (params.collection || params.all_folders)
this.file_list_loop(params);
else if (this.env.folder) {
this.req = this.set_busy(true, 'loading');
this.request('file_list', params, 'file_list_response');
}
};
// file list response handler
@ -771,51 +833,174 @@ function kolab_files_ui()
var i = 0, table = $('#filelist');
$('tbody', table).empty();
$.each(response.result, function(key, data) {
var c, col, row = '';
i++;
for (c in rcmail.env.coltypes) {
c = rcmail.env.coltypes[c];
if (c == 'name')
col = '<td class="name filename ' + file_api.file_type_class(data.type) + '">'
+ '<span>' + escapeHTML(data.name) + '</span></td>';
else if (c == 'mtime')
col = '<td class="mtime">' + data.mtime + '</td>';
else if (c == 'size')
col = '<td class="size">' + file_api.file_size(data.size) + '</td>';
else if (c == 'options')
col = '<td class="options"></td>'; // @TODO
else
col = '<td class="' + c + '"></td>';
row += col;
}
row = $('<tr>')
.html(row)
.attr({id: 'rcmrow' + i, 'data-file': key});
// table.append(row);
rcmail.file_list.insert_row(row.get([0]));
var row = file_api.file_list_row(key, data, i);
rcmail.file_list.insert_row(row);
});
};
this.file_select = function(e, row)
// call file_list request for every folder (used for search and virt. collections)
this.file_list_loop = function(params)
{
var table = $('#filelist');
// $('tr.selected', table).removeClass('selected');
$(row).addClass('selected');
var i, folders = [], limit = Math.max(this.env.search_threads || 1, 1);
if (params.collection) {
if (!params.search)
params.search = {};
params.search['class'] = params.collection;
delete params['collection'];
}
delete params['all_folders'];
$.each(this.env.folders, function(i, f) {
if (!f.virtual)
folders.push(i);
});
this.env.folders_loop = folders;
this.env.folders_loop_params = params;
this.env.folders_loop_lock = false;
for (i=0; i<folders.length && i<limit; i++) {
this.req = this.set_busy(true, 'loading');
params.folder = folders.shift();
this.request('file_list', params, 'file_list_loop_response');
}
};
this.file_search = function(value)
// file list response handler for loop'ed request
this.file_list_loop_response = function(response)
{
var i, folders = this.env.folders_loop,
params = this.env.folders_loop_params,
limit = Math.max(this.env.search_threads || 1, 1),
valid = this.response(response);
for (i=0; i<folders.length && i<limit; i++) {
this.req = this.set_busy(true, 'loading');
params.folder = folders.shift();
this.request('file_list', params, 'file_list_loop_response');
}
if (!valid)
return;
this.file_list_loop_result_add(response.result);
};
// add files from list request to the table (with sorting)
this.file_list_loop_result_add = function(result)
{
// chack if result (hash-array) is empty
if (!object_is_empty(result))
return;
if (this.env.folders_loop_lock) {
setTimeout(function() { file_api.file_list_loop_result_add(result); }, 100);
return;
}
// lock table, other list responses will wait
this.env.folders_loop_lock = true;
var n, i, len, elem, list = [], rows = [],
index = this.env.file_list.length,
table = rcmail.file_list;
for (n=0, len=index; n<len; n++) {
elem = this.env.file_list[n];
for (i in result) {
if (this.sort_compare(elem, result[i]) < 0)
break;
var row = this.file_list_row(i, result[i], index++);
table.insert_row(row, elem.row);
result[i].row = row;
list.push(result[i]);
delete result[i];
}
list.push(elem);
}
// add the rest of rows
$.each(result, function(key, data) {
var row = file_api.file_list_row(key, data, index++);
table.insert_row(row);
result[key].row = row;
list.push(result[key]);
});
this.env.file_list = list;
this.env.folders_loop_lock = false;
};
// sort files list (without API request)
this.file_list_sort = function(col, reverse)
{
var n, len, list = this.env.file_list,
table = $('#filelist'), tbody = $('<tbody>');
this.env.sort_col = col;
this.env.sort_reverse = reverse;
if (!list || !list.length)
return;
// sort the list
list.sort(function (a, b) {
return file_api.sort_compare(a, b);
});
// add rows to the new body
for (n=0, len=list.length; n<len; n++) {
tbody.append(list[n].row);
}
// replace table bodies
$('tbody', table).replaceWith(tbody);
};
this.file_list_row = function(file, data, index)
{
var c, col, row = '';
for (c in rcmail.env.coltypes) {
c = rcmail.env.coltypes[c];
if (c == 'name')
col = '<td class="name filename ' + this.file_type_class(data.type) + '">'
+ '<span>' + escapeHTML(data.name) + '</span></td>';
else if (c == 'mtime')
col = '<td class="mtime">' + data.mtime + '</td>';
else if (c == 'size')
col = '<td class="size">' + this.file_size(data.size) + '</td>';
else if (c == 'options')
col = '<td class="options"></td>'; // @TODO
else
col = '<td class="' + c + '"></td>';
row += col;
}
row = $('<tr>')
.html(row)
.attr({id: 'rcmrow' + index, 'data-file': file});
// collection (or search) lists files from all folders
// display file name with full path as title
if (!this.env.folder)
$('td.name span', row).attr('title', file);
return row.get(0);
};
this.file_search = function(value, all_folders)
{
if (value) {
this.env.search = {name: value};
this.file_list({search: this.env.search});
rcmail.command('files-list', {search: this.env.search, all_folders: all_folders});
}
else
this.search_reset();
@ -825,7 +1010,7 @@ function kolab_files_ui()
{
if (this.env.search) {
this.env.search = null;
this.file_list();
rcmail.command('files-list');
}
};
@ -844,7 +1029,7 @@ function kolab_files_ui()
this.file_delete = function(files)
{
this.req = this.set_busy(true, 'kolab_files.filedeleting');
this.get('file_delete', {file: files}, 'file_delete_response');
this.request('file_delete', {file: files}, 'file_delete_response');
};
// file(s) delete response handler
@ -863,13 +1048,22 @@ function kolab_files_ui()
if (!files || !files.length || !folder)
return;
var list = {};
var count = 0, list = {};
$.each(files, function(i, v) {
list[v] = folder + file_api.env.directory_separator + file_api.file_name(v);
var name = folder + file_api.env.directory_separator + file_api.file_name(v);
if (name != v) {
list[v] = name;
count++;
}
});
if (!count)
return;
this.req = this.set_busy(true, 'kolab_files.filemoving');
this.get('file_move', {file: list}, 'file_move_response');
this.request('file_move', {file: list}, 'file_move_response');
};
// file(s) move response handler
@ -878,8 +1072,12 @@ function kolab_files_ui()
if (!this.response(response))
return;
this.display_message('kolab_files.filemovenotice', 'confirmation');
this.file_list();
if (response.result && response.result.already_exist && response.result.already_exist.length)
this.file_move_ask_user(response.result.already_exist, true);
else {
this.display_message('kolab_files.filemovenotice', 'confirmation');
this.file_list();
}
};
// file(s) copy request
@ -888,13 +1086,22 @@ function kolab_files_ui()
if (!files || !files.length || !folder)
return;
var list = {};
var count = 0, list = {};
$.each(files, function(i, v) {
list[v] = folder + file_api.env.directory_separator + file_api.file_name(v);
var name = folder + file_api.env.directory_separator + file_api.file_name(v);
if (name != v) {
list[v] = name;
count++;
}
});
if (!count)
return;
this.req = this.set_busy(true, 'kolab_files.filecopying');
this.get('file_copy', {file: list}, 'file_copy_response');
this.request('file_copy', {file: list}, 'file_copy_response');
};
// file(s) copy response handler
@ -903,7 +1110,88 @@ function kolab_files_ui()
if (!this.response(response))
return;
this.display_message('kolab_files.filecopynotice', 'confirmation');
if (response.result && response.result.already_exist && response.result.already_exist.length)
this.file_move_ask_user(response.result.already_exist);
else
this.display_message('kolab_files.filecopynotice', 'confirmation');
};
// when file move/copy operation returns file-exists error
// this displays a dialog where user can decide to skip
// or overwrite destination file(s)
this.file_move_ask_user = function(list, move)
{
var file = list[0], buttons = {},
text = rcmail.gettext('kolab_files.filemoveconfirm').replace('$file', file.dst)
dialog = $('<div></div>');
buttons[rcmail.gettext('kolab_files.fileoverwrite')] = function() {
var file = list.shift(), f = {},
action = move ? 'file_move' : 'file_copy';
f[file.src] = file.dst;
file_api.file_move_ask_list = list;
file_api.file_move_ask_mode = move;
dialog.dialog('destroy').remove();
file_api.req = file_api.set_busy(true, move ? 'kolab_files.filemoving' : 'kolab_files.filecopying');
file_api.request(action, {file: f, overwrite: 1}, 'file_move_ask_user_response');
};
if (list.length > 1)
buttons[rcmail.gettext('kolab_files.fileoverwriteall')] = function() {
var f = {}, action = move ? 'file_move' : 'file_copy';
$.each(list, function() { f[this.src] = this.dst; });
dialog.dialog('destroy').remove();
file_api.req = file_api.set_busy(true, move ? 'kolab_files.filemoving' : 'kolab_files.filecopying');
file_api.request(action, {file: f, overwrite: 1}, action + '_response');
};
var skip_func = function() {
list.shift();
dialog.dialog('destroy').remove();
if (list.length)
file_api.file_move_ask_user(list, move);
else if (move)
file_api.file_list();
};
buttons[rcmail.gettext('kolab_files.fileskip')] = skip_func;
if (list.length > 1)
buttons[rcmail.gettext('kolab_files.fileskipall')] = function() {
dialog.dialog('destroy').remove();
if (move)
file_api.file_list();
};
// open jquery UI dialog
dialog.dialog({
modal: true,
resizable: !bw.ie6,
closeOnEscape: (!bw.ie6 && !bw.ie7), // disable for performance reasons
close: skip_func,
buttons: buttons,
minWidth: 400,
width: 400
}).html(text).show();
};
// file move (with overwrite) response handler
this.file_move_ask_user_response = function(response)
{
var move = this.file_move_ask_mode, list = this.file_move_ask_list;
this.response(response);
if (list && list.length)
this.file_move_ask_user(list, mode);
else {
this.display_message('kolab_files.file' + (move ? 'move' : 'copy') + 'notice', 'confirmation');
if (move)
this.file_list();
}
};
// file upload request
@ -915,7 +1203,7 @@ function kolab_files_ui()
if (files) {
// submit form and read server response
this.async_upload_form(form, 'file_create', function(event) {
this.file_upload_form(form, 'file_upload', function(event) {
var doc, response;
try {
doc = this.contentDocument ? this.contentDocument : this.contentWindow.document;
@ -939,7 +1227,7 @@ function kolab_files_ui()
};
// post the given form to a hidden iframe
this.async_upload_form = function(form, action, onload)
this.file_upload_form = function(form, action, onload)
{
var ts = rcmail.display_message(rcmail.get_label('kolab_files.uploading'), 'loading', 1000),
frame_name = 'fileupload'+ts;

View file

@ -44,7 +44,7 @@ class kolab_files_engine
*/
public function ui()
{
$this->plugin->add_texts('localization/', true);
$this->plugin->add_texts('localization/');
// set templates of Files UI and widgets
if ($this->rc->task == 'mail') {
@ -67,6 +67,11 @@ class kolab_files_engine
'label' => 'kolab_files.saveto',
), 'attachmentmenu');
}
$this->plugin->add_label('save', 'cancel',
'saveall', 'fromcloud', 'attachsel', 'selectfiles', 'attaching',
'collection_audio', 'collection_video', 'collection_image', 'collection_document'
);
}
else if ($this->rc->task == 'files') {
$template = 'files';
@ -155,7 +160,7 @@ class kolab_files_engine
$out = $this->rc->output->form_tag($attrib, $out);
}
$this->rc->output->add_label('kolab_files.foldercreating', 'kolab_files.create');
$this->plugin->add_label('foldercreating', 'create', 'foldercreate', 'cancel');
$this->rc->output->add_gui_object('folder-create-form', $attrib['id']);
return $out;
@ -185,6 +190,7 @@ class kolab_files_engine
// add form tag around text field
if (empty($attrib['form'])) {
$out = $this->rc->output->form_tag(array(
'action' => '?_task=files',
'name' => "filesearchform",
'onsubmit' => rcmail_output::JS_OBJECT_NAME . ".command('files-search'); return false",
), $out);
@ -198,8 +204,6 @@ class kolab_files_engine
*/
public function file_list($attrib)
{
// $this->rc->output->add_label('');
// define list of cols to be displayed based on parameter or config
if (empty($attrib['columns'])) {
$list_cols = $this->rc->config->get('kolab_files_list_cols');
@ -211,7 +215,6 @@ class kolab_files_engine
$a_show_cols = preg_split('/[\s,;]+/', strip_quotes($attrib['columns']));
}
// make sure 'name' and 'options' column is present
if (!in_array('name', $a_show_cols)) {
array_unshift($a_show_cols, 'name');
@ -241,6 +244,7 @@ class kolab_files_engine
$this->rc->output->set_env('sort_col', $_SESSION['kolab_files_sort_col']);
$this->rc->output->set_env('sort_order', $_SESSION['kolab_files_sort_order']);
$this->rc->output->set_env('coltypes', $a_show_cols);
$this->rc->output->set_env('search_threads', $this->rc->config->get('kolab_files_search_threads'));
$this->rc->output->include_script('list.js');
@ -263,7 +267,7 @@ class kolab_files_engine
protected function file_list_head($attrib, $a_show_cols)
{
$skin_path = $_SESSION['skin_path'];
$image_tag = html::img(array('src' => "%s%s", 'alt' => "%s"));
// $image_tag = html::img(array('src' => "%s%s", 'alt' => "%s"));
// check to see if we have some settings for sorting
$sort_col = $_SESSION['kolab_files_sort_col'];
@ -456,12 +460,12 @@ class kolab_files_engine
protected function action_index()
{
$this->rc->output->add_label(
'kolab_files.folderdeleting', 'kolab_files.folderdeleteconfirm',
'kolab_files.foldercreating', 'kolab_files.uploading',
'kolab_files.filedeleting', 'kolab_files.filedeletenotice', 'kolab_files.filedeleteconfirm',
'kolab_files.filemoving', 'kolab_files.filemovenotice',
'kolab_files.filecopying', 'kolab_files.filecopynotice'
$this->plugin->add_label(
'folderdeleting', 'folderdeleteconfirm', 'foldercreating', 'uploading', 'attaching',
'filedeleting', 'filedeletenotice', 'filedeleteconfirm',
'filemoving', 'filemovenotice', 'filecopying', 'filecopynotice',
'collection_audio', 'collection_video', 'collection_image', 'collection_document',
'fileskip', 'fileskipall', 'fileoverwrite', 'fileoverwriteall', 'filemoveconfirm'
);
$this->rc->output->set_pagetitle($this->plugin->gettext('files'));
@ -511,14 +515,13 @@ class kolab_files_engine
*/
protected function action_save_file()
{
$source = rcube_utils::get_input_value('source', rcube_utils::INPUT_POST);
// $source = rcube_utils::get_input_value('source', rcube_utils::INPUT_POST);
$uid = rcube_utils::get_input_value('uid', rcube_utils::INPUT_POST);
$dest = rcube_utils::get_input_value('dest', rcube_utils::INPUT_POST);
$id = rcube_utils::get_input_value('id', rcube_utils::INPUT_POST);
$name = rcube_utils::get_input_value('name', rcube_utils::INPUT_POST);
$temp_dir = unslashify($this->rc->config->get('temp_dir'));
$storage = $this->rc->get_storage();
$message = new rcube_message($uid);
$request = $this->get_request();
$url = $request->getUrl();
@ -528,7 +531,7 @@ class kolab_files_engine
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setHeader('X-Session-Token', $this->get_api_token());
$url->setQueryVariables(array('method' => 'file_create', 'folder' => $dest));
$url->setQueryVariables(array('method' => 'file_upload', 'folder' => $dest));
$request->setUrl($url);
foreach ($message->attachments as $attach_prop) {

View file

@ -27,7 +27,13 @@ $labels['view'] = 'View';
$labels['viewfile'] = 'View file';
$labels['deletefile'] = 'Delete selected file(s)';
$labels['collection_audio'] = 'Audio';
$labels['collection_video'] = 'Video';
$labels['collection_image'] = 'Images';
$labels['collection_document'] = 'Documents';
$labels['uploading'] = 'Uploading file(s)...';
$labels['attaching'] = 'Attaching file(s)...';
$labels['foldercreating'] = 'Creating folder...';
$labels['folderdeleting'] = 'Deleting folder...';
$labels['folderdeleteconfirm'] = 'Are you sure you want to delete selected folder?';
@ -44,4 +50,11 @@ $labels['filedeletenotice'] = 'File(s) deleted successfully.';
$labels['filemovenotice'] = 'File(s) moved successfully.';
$labels['filecopynotice'] = 'File(s) copied successfully.';
$labels['allfolders'] = 'search in all folders';
$labels['fileskip'] = 'Skip';
$labels['fileskipall'] = 'Skip all';
$labels['fileoverwrite'] = 'Overwrite';
$labels['fileoverwriteall'] = 'Overwrite all';
$labels['filemoveconfirm'] = 'This action is going to overwrite the destination file: <b>$file</b>.';
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View file

@ -46,6 +46,12 @@
display: inline;
}
#quicksearchbar #filesearchmenulink {
position: absolute;
top: 5px;
left: 6px;
}
#folderlistbox {
position: absolute;
top: 42px;
@ -83,6 +89,34 @@
color: #376572;
}
#files-folder-list ul li.mailbox.collection span.name {
background: url(images/folders.png) 5px 0 no-repeat;
}
#files-folder-list ul li.mailbox.collection.audio span.name {
background-position: 5px -95px;
}
#files-folder-list ul li.mailbox.collection.video span.name {
background-position: 5px -143px;
}
#files-folder-list ul li.mailbox.collection.document span.name {
background-position: 5px 0;
}
#files-folder-list ul li.mailbox.collection.image span.name {
background-position: 5px -48px;
}
#files-folder-list ul li.mailbox.collection.audio.selected span.name {
background-position: 5px -119px;
}
#files-folder-list ul li.mailbox.collection.video.selected span.name {
background-position: 5px -167px;
}
#files-folder-list ul li.mailbox.collection.document.selected span.name {
background-position: 5px -24px;
}
#files-folder-list ul li.mailbox.collection.image.selected span.name {
background-position: 5px -72px;
}
#files-folder-list ul li span.branch {
display: inline-block;
}
@ -107,7 +141,7 @@
}
#filelist tr td.size {
width: 60px;
width: 80px;
text-align: right;
}

View file

@ -1,10 +1,7 @@
<div id="files-compose-dialog" class="uidialog">
<div id="quicksearchbar" class="searchbox">
<roundcube:object name="file-search-form" id="filesearchbox" />
<!--
<roundcube:button name="searchmenulink" id="searchmenulink" class="iconbutton searchoptions" onclick="UI.show_popup('searchmenu');return false" title="searchmod" content=" " />
-->
<a id="searchmenulink" class="iconbutton searchoptions"> </a>
<roundcube:button name="filesearchmenulink" id="filesearchmenulink" class="iconbutton searchoptions" onclick="UI.show_popup('filesearchmenu');return false" title="searchmod" content=" " />
<roundcube:button command="files-search-reset" id="searchreset" class="iconbutton reset" title="resetsearch" content=" " />
</div>
@ -16,3 +13,9 @@
<roundcube:object name="filelist" id="filelist" class="records-table sortheader" />
</div>
</div>
<div id="filesearchmenu" class="popupmenu" style="z-index: 2000">
<ul class="toolbarmenu">
<li><label><input type="checkbox" name="all_folders" value="1" id="search_all_folders" /> <span><roundcube:label name="kolab_files.allfolders" /></span></label></li>
</ul>
</div>

View file

@ -22,10 +22,7 @@
<div id="quicksearchbar" class="quicksearchbox">
<roundcube:object name="file-search-form" id="quicksearchbox" />
<!--
<roundcube:button name="searchmenulink" id="searchmenulink" class="iconbutton searchoptions" onclick="UI.show_popup('searchmenu');return false" title="searchmod" content=" " />
-->
<a id="searchmenulink" class="iconbutton searchoptions"> </a>
<roundcube:button name="filesearchmenulink" id="filesearchmenulink" class="iconbutton searchoptions" onclick="UI.show_popup('filesearchmenu');return false" title="searchmod" content=" " />
<roundcube:button command="files-search-reset" id="searchreset" class="iconbutton reset" title="resetsearch" content=" " />
</div>
@ -63,47 +60,53 @@
<div id="listoptions" class="propform popupdialog">
<roundcube:if condition="!in_array('kolab_files_list_cols', (array)config:dont_override)" />
<fieldset class="floating">
<legend><roundcube:label name="listcolumns" /></legend>
<ul class="proplist">
<li><label class="disabled"><input type="checkbox" name="list_col[]" value="options" checked="checked" disabled="disabled" /> <span><roundcube:label name="options" /></span></label></li>
<li><label class="disabled"><input type="checkbox" name="list_col[]" value="name" checked="checked" disabled="disabled" /> <span><roundcube:label name="kolab_files.name" /></span></label></li>
<li><label><input type="checkbox" name="list_col[]" value="mtime" /> <span><roundcube:label name="kolab_files.mtime" /></span></label></li>
<li><label><input type="checkbox" name="list_col[]" value="size" /> <span><roundcube:label name="size" /></span></label></li>
</ul>
</fieldset>
<roundcube:endif />
<roundcube:if condition="!in_array('kolab_files_sort_col', (array)config:dont_override)" />
<fieldset class="floating">
<legend><roundcube:label name="listsorting" /></legend>
<ul class="proplist">
<li><label><input type="radio" name="sort_col" value="name" /> <span><roundcube:label name="kolab_files.name" /></span></label></li>
<li><label><input type="radio" name="sort_col" value="mtime" /> <span><roundcube:label name="kolab_files.mtime" /></span></label></li>
<li><label><input type="radio" name="sort_col" value="size" /> <span><roundcube:label name="size" /></span></label></li>
</ul>
</fieldset>
<roundcube:endif />
<roundcube:if condition="!in_array('kolab_files_sort_order', (array)config:dont_override)" />
<fieldset class="floating">
<legend><roundcube:label name="listorder" /></legend>
<ul class="proplist">
<li><label><input type="radio" name="sort_ord" value="ASC" /> <span><roundcube:label name="asc" /></span></label></li>
<li><label><input type="radio" name="sort_ord" value="DESC" /> <span><roundcube:label name="desc" /></span></label></li>
</ul>
</fieldset>
<roundcube:endif />
<br style="clear:both" />
<div class="formbuttons">
<roundcube:button command="menu-save" id="listmenusave" type="input" class="button mainaction" label="save" />
<roundcube:button command="menu-open" id="listmenucancel" type="input" class="button" label="cancel" />
</div>
<fieldset class="floating">
<legend><roundcube:label name="listcolumns" /></legend>
<ul class="proplist">
<li><label class="disabled"><input type="checkbox" name="list_col[]" value="options" checked="checked" disabled="disabled" /> <span><roundcube:label name="options" /></span></label></li>
<li><label class="disabled"><input type="checkbox" name="list_col[]" value="name" checked="checked" disabled="disabled" /> <span><roundcube:label name="kolab_files.name" /></span></label></li>
<li><label><input type="checkbox" name="list_col[]" value="mtime" /> <span><roundcube:label name="kolab_files.mtime" /></span></label></li>
<li><label><input type="checkbox" name="list_col[]" value="size" /> <span><roundcube:label name="size" /></span></label></li>
</ul>
</fieldset>
<roundcube:endif />
<roundcube:if condition="!in_array('kolab_files_sort_col', (array)config:dont_override)" />
<fieldset class="floating">
<legend><roundcube:label name="listsorting" /></legend>
<ul class="proplist">
<li><label><input type="radio" name="sort_col" value="name" /> <span><roundcube:label name="kolab_files.name" /></span></label></li>
<li><label><input type="radio" name="sort_col" value="mtime" /> <span><roundcube:label name="kolab_files.mtime" /></span></label></li>
<li><label><input type="radio" name="sort_col" value="size" /> <span><roundcube:label name="size" /></span></label></li>
</ul>
</fieldset>
<roundcube:endif />
<roundcube:if condition="!in_array('kolab_files_sort_order', (array)config:dont_override)" />
<fieldset class="floating">
<legend><roundcube:label name="listorder" /></legend>
<ul class="proplist">
<li><label><input type="radio" name="sort_ord" value="ASC" /> <span><roundcube:label name="asc" /></span></label></li>
<li><label><input type="radio" name="sort_ord" value="DESC" /> <span><roundcube:label name="desc" /></span></label></li>
</ul>
</fieldset>
<roundcube:endif />
<br style="clear:both" />
<div class="formbuttons">
<roundcube:button command="menu-save" id="listmenusave" type="input" class="button mainaction" label="save" />
<roundcube:button command="menu-open" id="listmenucancel" type="input" class="button" label="cancel" />
</div>
</div>
<div id="dragfilemenu" class="popupmenu">
<ul class="toolbarmenu">
<li><roundcube:button command="files-move" onclick="return kolab_files_drag_menu_action('files-move')" label="move" classAct="active" /></li>
<li><roundcube:button command="files-copy" onclick="return kolab_files_drag_menu_action('files-copy')" label="copy" classAct="active" /></li>
</ul>
<ul class="toolbarmenu">
<li><roundcube:button command="files-move" onclick="return kolab_files_drag_menu_action('files-move')" label="move" classAct="active" /></li>
<li><roundcube:button command="files-copy" onclick="return kolab_files_drag_menu_action('files-copy')" label="copy" classAct="active" /></li>
</ul>
</div>
<div id="filesearchmenu" class="popupmenu">
<ul class="toolbarmenu">
<li><label><input type="checkbox" name="all_folders" value="1" id="search_all_folders" /> <span><roundcube:label name="kolab_files.allfolders" /></span></label></li>
</ul>
</div>
<roundcube:include file="/includes/footer.html" />

View file

@ -7,11 +7,17 @@ function kolab_files_ui_init()
rcmail.addEventListener('menu-open', kolab_files_show_listoptions);
rcmail.addEventListener('menu-save', kolab_files_save_listoptions);
var dragmenu = $('#dragfilemenu');
if (dragmenu.length) {
var menu = $('#dragfilemenu');
if (menu.length) {
rcmail.gui_object('file_dragmenu', 'dragfilemenu');
UI.add_popup('dragfilemenu', {sticky: 1});
}
menu = $('#filesearchmenu');
if (menu.length) {
rcmail.gui_object('file_searchmenu', 'filesearchmenu');
UI.add_popup('filesearchmenu', {sticky: 1});
}
});
kolab_files_upload_input('#filestoolbar a.upload');